⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linux-kernel.diff

📁 基于linux内核2.6.9的mpls补丁
💻 DIFF
📖 第 1 页 / 共 5 页
字号:
+ */++void spec_nh_remove(struct spec_nh *spec)+{+	struct list_head *head;+	struct spec_nh *spec1;++	spin_lock_bh(&spec_nh_lock);+	head = &spec_nh_base[ntohs(spec->type) & 15];++	list_for_each_entry(spec1, head, list) {+		if (spec == spec1) {+			list_del_rcu(&spec->list);+			goto out;+		}+	}+	printk(KERN_WARNING "spec_nh_remove: %p not found.\n", spec);+out:+	spin_unlock_bh(&spec_nh_lock);++	synchronize_net();++}++/**+ *	spec_nh_find - find a special nexthop handler by it's protocol type+ *	@proto: protocol type declaration+ *+ *	Search the kernels list of special nexthops handlers looking for+ *	a handler for this specific protocol.+ */+struct spec_nh *spec_nh_find(unsigned short proto)+{+	struct list_head *head;+	struct spec_nh *spec;++	spin_lock_bh(&spec_nh_lock);+	head = &spec_nh_base[ntohs(proto) & 15];++	list_for_each_entry(spec, head, list) {+		if (proto == spec->type) {+			goto out;+		}+	}+	spec = NULL;+out:+	spin_unlock_bh(&spec_nh_lock);++	return spec;+}++/*+ * Proc filesystem directory entries.+ */+										+/*+ *      /proc/net/spec_nh+ */+										+static struct proc_dir_entry *proc_spec_nh_dir;+										+/*+ *      /proc/net/spec_nh/config+ */+										+static struct proc_dir_entry *proc_spec_nh_conf;++/*+ *      Names of the proc directory entries+ */+										+static const char name_root[]    = "spec_nh";+static const char name_conf[]    = "config";++/*+ * The following few functions build the content of /proc/net/spec_nh/config+ */++/* starting at spec, find the next registered protocol */+struct spec_nh *spec_nh_skip(struct spec_nh *spec)+{+	struct list_head *head;+	struct spec_nh *spec1;+	int next = 0;+	int slot = 0;++	if (spec)+		slot = ntohs(spec->type) & 15;+	else+		next = 1;+		+	for (;slot < 16;slot++) {+		head = &spec_nh_base[slot];+		list_for_each_entry(spec1, head, list) {+			if (next)+				return spec1;++			if (spec1 == spec)+				next = 1;+		}+	}++	return NULL;+}++										+/* start read of /proc/net/spec_nh/config */+static void *spec_nh_seq_start(struct seq_file *seq, loff_t *pos)+{+	struct spec_nh *spec;+	loff_t i = 1;++	spin_lock_bh(&spec_nh_lock);++	if (*pos == 0)+		return SEQ_START_TOKEN;++	for (spec = spec_nh_skip(NULL); spec && i < *pos;+		spec = spec_nh_skip(spec), ++i);+										+	return (i == *pos) ? spec : NULL;+}++static void *spec_nh_seq_next(struct seq_file *seq, void *v, loff_t *pos)+{+	++*pos;+										+	return spec_nh_skip((v == SEQ_START_TOKEN)+			    ? NULL+			    : (struct spec_nh *)v);+}+										+static void spec_nh_seq_stop(struct seq_file *seq, void *v)+{+	spin_unlock_bh(&spec_nh_lock);+}++static int spec_nh_seq_show(struct seq_file *seq, void *v)+{+	struct spec_nh* spec = (struct spec_nh*)v;+	if (v != SEQ_START_TOKEN)+		seq_printf(seq, "0x%04x\t%s\n",+		    ntohs(spec->type), spec->name ? spec->name : "(none)");+	return 0;+}++/*+ *      Generic /proc/net/spec_nh/<file> file and inode operations+ */+										+static struct seq_operations spec_nh_seq_ops = {+	.start = spec_nh_seq_start,+	.next = spec_nh_seq_next,+	.stop = spec_nh_seq_stop,+	.show = spec_nh_seq_show,+};+										+static int spec_nh_seq_open(struct inode *inode, struct file *file)+{+	return seq_open(file, &spec_nh_seq_ops);+}+										+static struct file_operations spec_nh_fops = {+	.owner   = THIS_MODULE,+	.open    = spec_nh_seq_open,+	.read    = seq_read,+	.llseek  = seq_lseek,+	.release = seq_release,+};++/*+ *      Clean up /proc/net/spec_nh entries+ */+										+void spec_nh_proc_cleanup(void)+{+	if (proc_spec_nh_conf)+		remove_proc_entry(name_conf, proc_spec_nh_dir);+										+	if (proc_spec_nh_dir)+		proc_net_remove(name_root);+}++int __init spec_nh_proc_init(void)+{+	proc_spec_nh_dir = proc_mkdir(name_root, proc_net);+	if (proc_spec_nh_dir) {+		proc_spec_nh_conf = create_proc_entry(name_conf,+						   S_IFREG|S_IRUSR|S_IWUSR,+						   proc_spec_nh_dir);+		if (proc_spec_nh_conf) {+			proc_spec_nh_conf->proc_fops = &spec_nh_fops;+			return 0;+		}+	}+	spec_nh_proc_cleanup();+	return -ENOBUFS;+}++void __init spec_nh_init(void)+{+	int err;+	int i;++	for (i = 0; i < 16; i++)+		INIT_LIST_HEAD(&spec_nh_base[i]);++	/* proc file system initialization */+	err = spec_nh_proc_init();+	if (err < 0) {+		printk(KERN_ERR+		       "%s: can't create entry in proc filesystem!\n",+		       __FUNCTION__);+	}+}++static void __exit spec_nh_cleanup(void)+{+	spec_nh_proc_cleanup();+	synchronize_net();+}++EXPORT_SYMBOL(spec_nh_add);+EXPORT_SYMBOL(spec_nh_remove);+EXPORT_SYMBOL(spec_nh_find);diff -uNr linux-kernel/net/ipv4/fib_semantics.c mpls-kernel-1/net/ipv4/fib_semantics.c--- linux-kernel/net/ipv4/fib_semantics.c	2004-10-22 13:40:45.000000000 -0500+++ mpls-kernel-1/net/ipv4/fib_semantics.c	2005-01-05 01:10:11.000000000 -0600@@ -185,6 +185,8 @@ #ifdef CONFIG_NET_CLS_ROUTE 		    nh->nh_tclassid != onh->nh_tclassid || #endif+		    nh->nh_spec_proto != onh->nh_spec_proto ||+		    nh->nh_spec_data != onh->nh_spec_data || 		    ((nh->nh_flags^onh->nh_flags)&~RTNH_F_DEAD)) 			return -1; 		onh++;@@ -309,6 +311,8 @@ 		nh->nh_flags = (r->rtm_flags&~0xFF) | nhp->rtnh_flags; 		nh->nh_oif = nhp->rtnh_ifindex; 		nh->nh_weight = nhp->rtnh_hops + 1;+		nh->nh_spec_proto = nhp->rtnh_spec_proto;+		nh->nh_spec_data = nhp->rtnh_spec_data; 		if (attrlen) { 			nh->nh_gw = fib_get_attr32(RTNH_DATA(nhp), attrlen, RTA_GATEWAY); #ifdef CONFIG_NET_CLS_ROUTE@@ -336,6 +340,8 @@  	if (rta->rta_oif || rta->rta_gw) { 		if ((!rta->rta_oif || *rta->rta_oif == fi->fib_nh->nh_oif) &&+		    (!rta->rta_spec_proto || *rta->rta_spec_proto == fi->fib_nh->nh_spec_proto) &&+		    (!rta->rta_spec_data || memcmp(rta->rta_spec_data, &fi->fib_nh->nh_spec_data, 4) == 0) && 		    (!rta->rta_gw  || memcmp(rta->rta_gw, &fi->fib_nh->nh_gw, 4) == 0)) 			return 0; 		return 1;@@ -355,6 +361,12 @@ 			return -EINVAL; 		if (nhp->rtnh_ifindex && nhp->rtnh_ifindex != nh->nh_oif) 			return 1;+		if (nhp->rtnh_spec_data &&+		    nhp->rtnh_spec_data != nh->nh_spec_data)+			return 1;+		if (nhp->rtnh_spec_proto &&+		    nhp->rtnh_spec_proto != nh->nh_spec_proto)+			return 1; 		if (attrlen) { 			gw = fib_get_attr32(RTNH_DATA(nhp), attrlen, RTA_GATEWAY); 			if (gw && gw != nh->nh_gw)@@ -659,6 +671,10 @@ 			goto err_inval; 		if (rta->rta_gw && memcmp(&fi->fib_nh->nh_gw, rta->rta_gw, 4)) 			goto err_inval;+		if (rta->rta_spec_proto && +		    (fi->fib_nh->nh_spec_proto != *rta->rta_spec_proto ||+		    fi->fib_nh->nh_spec_data != *rta->rta_spec_data))+			goto err_inval; #ifdef CONFIG_NET_CLS_ROUTE 		if (rta->rta_flow && memcmp(&fi->fib_nh->nh_tclassid, rta->rta_flow, 4)) 			goto err_inval;@@ -680,6 +696,13 @@ #ifdef CONFIG_IP_ROUTE_MULTIPATH 		nh->nh_weight = 1; #endif+		if (rta->rta_spec_proto) {+			nh->nh_spec_proto = *rta->rta_spec_proto;+			if (rta->rta_spec_data)+				nh->nh_spec_data = *rta->rta_spec_data;+			else+				nh->nh_spec_data = 0;+		} 	}  	if (fib_props[r->rtm_type].error) {@@ -873,6 +896,12 @@ 			RTA_PUT(skb, RTA_GATEWAY, 4, &fi->fib_nh->nh_gw); 		if (fi->fib_nh->nh_oif) 			RTA_PUT(skb, RTA_OIF, sizeof(int), &fi->fib_nh->nh_oif);+		if (fi->fib_nh->nh_spec_proto) {+			RTA_PUT(skb, RTA_SPEC_PROTO, sizeof(unsigned short),+				&fi->fib_nh->nh_spec_proto);+			RTA_PUT(skb, RTA_SPEC_DATA, sizeof(u32),+				&fi->fib_nh->nh_spec_data);+		} 	} #ifdef CONFIG_IP_ROUTE_MULTIPATH 	if (fi->fib_nhs > 1) {@@ -889,6 +918,8 @@ 			nhp->rtnh_flags = nh->nh_flags & 0xFF; 			nhp->rtnh_hops = nh->nh_weight-1; 			nhp->rtnh_ifindex = nh->nh_oif;+			nhp->rtnh_spec_proto = nh->nh_spec_proto;+			nhp->rtnh_spec_data = nh->nh_spec_data; 			if (nh->nh_gw) 				RTA_PUT(skb, RTA_GATEWAY, 4, &nh->nh_gw); 			nhp->rtnh_len = skb->tail - (unsigned char*)nhp;diff -uNr linux-kernel/net/ipv4/ip_output.c mpls-kernel-1/net/ipv4/ip_output.c--- linux-kernel/net/ipv4/ip_output.c	2004-10-22 13:40:45.000000000 -0500+++ mpls-kernel-1/net/ipv4/ip_output.c	2005-01-05 01:10:11.000000000 -0600@@ -176,6 +176,11 @@ 	struct net_device *dev = dst->dev; 	int hh_len = LL_RESERVED_SPACE(dev); +	if (dst->child) {+		skb->dst = dst_pop(skb->dst);+		return dst_output(skb);+	}+ 	/* Be paranoid, rather than too clever. */ 	if (unlikely(skb_headroom(skb) < hh_len && dev->hard_header)) { 		struct sk_buff *skb2;diff -uNr linux-kernel/net/ipv4/Kconfig mpls-kernel-1/net/ipv4/Kconfig--- linux-kernel/net/ipv4/Kconfig	2004-10-22 13:40:45.000000000 -0500+++ mpls-kernel-1/net/ipv4/Kconfig	2005-01-05 01:10:09.000000000 -0600@@ -158,6 +158,15 @@ 	  operating on your network. Read <file:Documentation/nfsroot.txt> for 	  details. +config IP_MPLS+	tristate "IP: MPLS support"+	depends on INET && MPLS+	---help---+	  If you say Y here, the kernel will support being an ingress and+	  egress LER for IPv4 packets++	  If unsure, say N.+ # not yet ready.. #   bool '    IP: ARP support' CONFIG_IP_PNP_ARP		 config NET_IPIPdiff -uNr linux-kernel/net/ipv4/Makefile mpls-kernel-1/net/ipv4/Makefile--- linux-kernel/net/ipv4/Makefile	2004-10-22 13:40:45.000000000 -0500+++ mpls-kernel-1/net/ipv4/Makefile	2005-01-05 01:10:09.000000000 -0600@@ -20,6 +20,7 @@ obj-$(CONFIG_INET_IPCOMP) += ipcomp.o obj-$(CONFIG_INET_TUNNEL) += xfrm4_tunnel.o  obj-$(CONFIG_IP_PNP) += ipconfig.o+obj-$(CONFIG_IP_MPLS) += mpls4.o obj-$(CONFIG_NETFILTER)	+= netfilter/ obj-$(CONFIG_IP_VS) += ipvs/ diff -uNr linux-kernel/net/ipv4/mpls4.c mpls-kernel-1/net/ipv4/mpls4.c--- linux-kernel/net/ipv4/mpls4.c	1969-12-31 18:00:00.000000000 -0600+++ mpls-kernel-1/net/ipv4/mpls4.c	2005-01-07 08:09:51.000000000 -0600@@ -0,0 +1,390 @@+/* mpls4.c: IPv4 MPLS protocol driver.+ *+ * Copyright (C) 2003 David S. Miller (davem@redhat.com)+ *+ * Changes:+ *	JLEU: 	Add ICMP handling+ *		Add nexthop printing+ *		Change nexthop resolve signature+ *	JLEU:	Added mpls4_cache_flush()+ *	JLEU:	un/register reserved labels in fini/init+ *	JLEU:	removed sysfs print routin+ */++#include <linux/module.h>+#include <linux/socket.h>+#include <linux/skbuff.h>+#include <linux/in.h>+#include <linux/init.h>+#include <net/dsfield.h>+#include <net/neighbour.h>+#include <net/route.h>+#include <net/ip.h>+#include <net/mpls.h>+#include <net/icmp.h>+#include <net/checksum.h>++static void mpls4_cache_flush(void)+{+	rt_cache_flush(0);+}++static void mpls4_set_ttl(struct sk_buff *skb, int ttl)+{+	skb->nh.iph->ttl = ttl;+	ip_send_check(skb->nh.iph);+}++static int mpls4_get_ttl(struct sk_buff *skb)+{+	return skb->nh.iph->ttl;+}++static void mpls4_change_dsfield(struct sk_buff *skb, int ds)+{+	ipv4_change_dsfield(skb->nh.iph, 0x3, ds << 2);+}++static int mpls4_get_dsfield(struct sk_buff *skb)+{+	return ipv4_get_dsfield(skb->nh.iph) >> 2;+}++struct mpls_icmp_common {+#if defined(__LITTLE_ENDIAN_BITFIELD)+	__u8    res1:4,+		version:4;+#elif defined (__BIG_ENDIAN_BITFIELD)+	__u8    version:4,+		res1:4;+#else+#error  "Please fix <asm/byteorder.h>"+#endif+	__u8	res2;+	__u16	check;+};++struct mpls_icmp_object {+	__u16	length;+	__u8	class;+	__u8	type;+};++/* we can probably used a modified ip_append_data to build this */+static struct sk_buff*+mpls4_build_icmp(struct sk_buff *skb, int type, unsigned int icmp_data,+	int mpls)+{+	unsigned char buf[576];+

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -