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

📄 linux-kernel.diff

📁 基于linux内核2.6.9的mpls补丁
💻 DIFF
📖 第 1 页 / 共 5 页
字号:
+	struct icmphdr *icmph;+	struct sk_buff *nskb;+	unsigned char *data;+	struct rtable *rt;+	struct iphdr *iph;++	unsigned int icmp_start = 0;+	unsigned int len = 0;+	unsigned int real;+	unsigned int max;+	unsigned int height;+	int pull;++	/* find the distance to the bottom of the MPLS stack */+	pull = mpls_find_payload(skb);+	if (pull < 0)+		goto error_0;++	if (!skb_pull(skb, pull))+		goto error_0;++	height = skb->data - MPLSCB(skb)->top_of_stack;++	/* now where at the payload, for now we're+	 * assuming this is IPv4+	 */+	skb->nh.raw = skb->data;++	/* buid a new skb, that will be big enough to hold+	 * a maximum of 576 bytes (RFC792)+	 */+	if ((skb->len + skb_tailroom(skb)) < 576) {+		nskb = skb_copy_expand(skb, skb_headroom(skb),+			(576 + 16) - skb->len, GFP_ATOMIC);+	} else {+		nskb = skb_copy(skb, GFP_ATOMIC);+	}++	if (!nskb)+		goto error_0;++	/* I don't handle IP options */+	if (nskb->nh.iph->ihl > 5) {+		printk("Options!!!!\n");+		goto error_1;+	}++	memset(buf, 0, sizeof(buf));++	/* point to the buf, we'll build our ICMP message there+	 * then copy to nskb when we're done+	 */+	iph = (struct iphdr*)&buf[len];+	iph->version = 4;+	iph->ihl = 5;+	iph->tos = nskb->nh.iph->tos;+	iph->tot_len = 0;+	iph->id = 0;+	iph->frag_off = 0;+	iph->ttl = 255;+	iph->protocol = IPPROTO_ICMP;+	iph->check = 0;+	iph->saddr = nskb->nh.iph->daddr;+	iph->daddr = nskb->nh.iph->saddr;+	len += sizeof(struct iphdr);++	icmp_start = len;+ 	icmph = (struct icmphdr*)&buf[len];+	icmph->checksum = 0;+	icmph->un.gateway = icmp_data;++	switch (type) {+		case ICMP_TIME_EXCEEDED:+			icmph->type = ICMP_TIME_EXCEEDED;+			icmph->code = ICMP_EXC_TTL;+			break;+		case ICMP_DEST_UNREACH:+			icmph->type = ICMP_DEST_UNREACH;+			icmph->code = ICMP_FRAG_NEEDED;+			break;+		default:+			BUG_ON(1);+			break;+	}+	len += sizeof(struct icmphdr);++ 	data = &buf[len];+	if (mpls) {+		max = 128;+	} else {+		max = 576 - len;+	}+	real = (nskb->len > max) ? max : skb->len;+	memcpy(data, nskb->data, real);++	if (!mpls) {+		len += real;+	} else {+		struct mpls_icmp_common *common;+		struct mpls_icmp_object *object;+		unsigned char *mpls_data = NULL;+		unsigned int obj_start = 0;+		unsigned int mpls_start = 0;++		len += 128;++		mpls_start = len;+		common = (struct mpls_icmp_common*)&buf[len];+		common->version = 2;+		common->res1 = 0;+		common->res2 = 0;+		common->check = 0;+		len += sizeof(struct mpls_icmp_common);++		obj_start = len;+		object = (struct mpls_icmp_object*)&buf[len];+		object->length = 0;+		object->class = 1;+		object->type = 1;+		len += sizeof(struct mpls_icmp_object);++		mpls_data = &buf[len];+		memcpy(mpls_data, MPLSCB(skb)->top_of_stack, height);+		len += height;++		object->length = htons(len - obj_start);+		common->check = csum_fold (csum_partial ((char*)common,+			len - mpls_start, 0));+	}++	iph->tot_len = htons(len);+	ip_send_check(iph);+	icmph->checksum = csum_fold (csum_partial ((char*)icmph,+		len - icmp_start, 0));++	nskb->len = len;+	memcpy(nskb->data, buf, nskb->len);+	nskb->tail = nskb->data + nskb->len;++	nskb->ip_summed = CHECKSUM_NONE;+	nskb->csum = 0;++	{+		struct flowi fl = {+			.nl_u = { .ip4_u = {+					.daddr = iph->daddr,+					.saddr = iph->saddr,+					.tos = RT_TOS(iph->tos) } },+			.proto = IPPROTO_ICMP };++		if (ip_route_output_key(&rt, &fl))+			goto error_1;+	}++	if (nskb->dst)+		dst_release(nskb->dst);++	nskb->dst = &rt->u.dst;++	return nskb;++error_1:+	kfree_skb(nskb);+error_0:+	return NULL;+}++/* Policy decision, several options:+ *+ * 1) Silently discard+ * 2) Pops all MPLS headers, use resulting upper-layer+ *    protocol packet to generate ICMP.+ * 3) Walk down MPLS headers to upper-layer header,+ *    generate ICMP using that and then prepend+ *    IDENTICAL MPLS header stack to ICMP packet.+ *+ * Problem with #2 is that there may be no route to+ * upper-level packet source for us to use.  (f.e. we+ * are switching VPN packets that we have no routes to).+ *+ * Option #3 should work even in those cases, because it+ * is more likely that egress of this MPLS path knows how+ * to route such packets back to source.  It should also+ * not be susceptible to loops in MPLS fabric, since one+ * never responds to ICMP with ICMP.  It is deliberate+ * assumption made about upper-layer protocol.+ */+static int mpls4_ttl_expired(struct sk_buff **skb)+{+	struct sk_buff *nskb;++	if ((nskb = mpls4_build_icmp(*skb, ICMP_TIME_EXCEEDED, 0, 1)))+		if (dst_output(nskb))+			kfree_skb(nskb);++	/* make sure the MPLS stack frees the original skb! */+	return NET_RX_DROP;+}++static int mpls4_mtu_exceeded(struct sk_buff **skb, int mtu)+{+	struct sk_buff *nskb;++	if ((nskb = mpls4_build_icmp(*skb, ICMP_DEST_UNREACH, htonl(mtu), 0)))+		if (dst_output(nskb))+			kfree_skb(nskb);++	/* make sure the MPLS stack frees the original skb! */+	return MPLS_RESULT_DROP;+}++static int mpls4_local_deliver(struct sk_buff *skb)+{+	skb->protocol = htons(ETH_P_IP);+	memset(skb->cb, 0, sizeof(skb->cb));+	dst_release(skb->dst);+	skb->dst = NULL;+	return ip_rcv(skb, skb->dev, NULL);+}++static int mpls4_nexthop_resolve(struct neighbour **np, struct sockaddr *sock_addr, struct net_device *dev)+{+	struct sockaddr_in *addr = (struct sockaddr_in *) sock_addr;+	u32 saddr = addr->sin_addr.s_addr;+	struct flowi fl = { .oif = dev->ifindex,+	                    .nl_u = { .ip4_u = { .daddr = saddr } } };+	struct rtable *rp;+	int err;++	if (addr->sin_family != AF_INET)+	        return -EINVAL;++	if (inet_addr_type(saddr) != RTN_UNICAST)+	        return -EINVAL;++	err = __ip_route_output_key(&rp, &fl);+	if (err)+	        return err;++	/* If routing cache stops to automatically bind output routes+	 * to ARP cache, we will have to make arp_bind_neighbour() ourselves.+	 */+	if (!rp->u.dst.neighbour)+	        BUG();++	*np = neigh_clone(rp->u.dst.neighbour);+	ip_rt_put(rp);++	return err;+}++static struct mpls_prot_driver mpls4_driver = {+	.prot_num               =       AF_INET,+	.cache_flush            =       mpls4_cache_flush,+	.set_ttl                =       mpls4_set_ttl,+	.get_ttl                =       mpls4_get_ttl,+	.change_dsfield         =       mpls4_change_dsfield,+	.get_dsfield            =       mpls4_get_dsfield,+	.ttl_expired            =       mpls4_ttl_expired,+	.mtu_exceeded		=	mpls4_mtu_exceeded,+	.local_deliver		=	mpls4_local_deliver,+	.nexthop_resolve        =       mpls4_nexthop_resolve,+	.owner                  =       THIS_MODULE,+};++static int __init mpls4_init(void)+{+	struct mpls_instr_elem instr[2];+	struct mpls_label ml;+	struct mpls_ilm *ilm;+	int result = mpls_register_prot(&mpls4_driver);++	if (result)+		return result;++	ml.ml_type = MPLS_LABEL_GEN;+	ml.u.ml_gen = MPLS_IPV4_EXPLICIT_NULL;++	instr[0].mir_direction = MPLS_IN;+	instr[0].mir_opcode    = MPLS_OP_POP;+	instr[1].mir_direction = MPLS_IN;+	instr[1].mir_opcode    = MPLS_OP_DLV;++	ilm = mpls_ilm_dst_alloc(0, &ml, AF_INET, instr, 2);+	if (!ilm)+		return -ENOMEM;++	result = mpls_add_reserved_label(MPLS_IPV4_EXPLICIT_NULL, ilm);+	if (result) {+		ilm->u.dst.obsolete = 1;+		dst_free(&ilm->u.dst);+		return result;+	}++	return 0;+}++static void __exit mpls4_fini(void)+{+	struct mpls_ilm *ilm = mpls_del_reserved_label(MPLS_IPV4_EXPLICIT_NULL);+	mpls_unregister_prot(&mpls4_driver);++	if (ilm) {+		mpls_ilm_release(ilm);+		ilm->u.dst.obsolete = 1;+		call_rcu(&ilm->u.dst.rcu_head, dst_rcu_free);+	}+}++module_init(mpls4_init);+module_exit(mpls4_fini);diff -uNr linux-kernel/net/ipv4/netfilter/ipt_spec_nh.c mpls-kernel-1/net/ipv4/netfilter/ipt_spec_nh.c--- linux-kernel/net/ipv4/netfilter/ipt_spec_nh.c	1969-12-31 18:00:00.000000000 -0600+++ mpls-kernel-1/net/ipv4/netfilter/ipt_spec_nh.c	2005-01-05 01:10:18.000000000 -0600@@ -0,0 +1,73 @@+/* This is a module which is used for setting up a SKB to use a spec_nh. */+#include <linux/module.h>+#include <linux/skbuff.h>+#include <linux/ip.h>+#include <net/checksum.h>+#include <net/spec_nh.h>+#include <net/mpls.h>++#include <linux/netfilter_ipv4/ip_tables.h>+#include <linux/netfilter_ipv4/ipt_spec_nh.h>++MODULE_LICENSE("GPL");+MODULE_AUTHOR("James R. Leu <jle@mindspring.com>");+MODULE_DESCRIPTION("iptables spec_nh module");++static unsigned int+target(struct sk_buff **pskb,+       const struct net_device *in,+       const struct net_device *out,+       unsigned int hooknum,+       const void *targinfo,+       void *userinfo)+{+	const struct ipt_spec_nh_target_info *spec_nh_info = targinfo;+	struct spec_nh *spec_nh;++	spec_nh = spec_nh_find(spec_nh_info->proto);++	if (spec_nh)+		spec_nh->func((*pskb)->dst, spec_nh_info->data, spec_nh);++	return IPT_CONTINUE;+}++static int+checkentry(const char *tablename,+	   const struct ipt_entry *e,+           void *targinfo,+           unsigned int targinfosize,+           unsigned int hook_mask)+{+	if (targinfosize != IPT_ALIGN(sizeof(struct ipt_spec_nh_target_info))) {+		printk(KERN_WARNING "spec_nh: targinfosize %u != %Zu\n",+		       targinfosize,+		       IPT_ALIGN(sizeof(struct ipt_spec_nh_target_info)));+		return 0;+	}++	return 1;+}++static struct ipt_target ipt_spec_nh_reg = {+	.name           = "spec_nh",+	.target         = target,+	.checkentry     = checkentry,+	.me             = THIS_MODULE,+};++static int __init init(void)+{+	if (ipt_register_target(&ipt_spec_nh_reg))+		return -EINVAL;++	return 0;+}++static void __exit fini(void)+{+	ipt_unregister_target(&ipt_spec_nh_reg);+}++module_init(init);+module_exit(fini);diff -uNr linux-kernel/net/ipv4/netfilter/Kconfig mpls-kernel-1/net/ipv4/netfilter/Kconfig--- linux-kernel/net/ipv4/netfilter/Kconfig	2004-10-22 13:40:46.000000000 -0500+++ mpls-kernel-1/net/ipv4/netfilter/Kconfig	2005-01-05 01:10:14.000000000 -0600@@ -585,6 +585,15 @@  	  To compile it as a module, choose M here.  If unsure, say N. +config IP_NF_TARGET_SPEC_NH+	tristate "spec_nh target support"+	depends on IP_NF_IPTABLES+	help+	  This option adds a `spec_nh' target, which allows you to set+	  special nexthops.++	  To compile it as a module, choose M here.  If unsure, say N.+ config IP_NF_TARGET_CLASSIFY 	tristate "CLASSIFY target support" 	depends on IP_NF_MANGLEdiff -uNr linux-kernel/net/ipv4/netfilter/Makefile mpls-kernel-1/net/ipv4/netfilter/Makefile--- linux-kernel/net/ipv4/netfilter/Makefile	2004-10-22 13:40:46.000000000 -0500+++ mpls-kernel-1/net/ipv4/netfilter/Makefile	2005-01-05 01:10:14.000000000 -0600@@ -74,6 +74,7 @@ obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_DSCP.o obj-$(CONFIG_IP_NF_TARGET_MARK) += ipt_MARK.o+obj-$(CONFIG_IP_NF_TARGET_SPEC_NH) += ipt_spec_nh.o obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.odiff -uNr linux-kernel/net/ipv4/route.c mpls-kernel-1/net/ipv4/route.c--- linux-kernel/net/ipv4/route.c	2004-10-22 13:40:48.000000000 -0500+++ mpls-kernel-1/net/ipv4/route.c	2005-01-05 01:10:18.000000000 -0600@@ -103,6 +103,7 @@ #ifdef CONFIG_SYSCTL #include <linux/sysctl.h> #endif+#include <net/spec_nh.h>  #define IP_MAX_MTU	0xFFF0 @@ -1416,6 +1417,7 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) { 	struct fib_info *fi = res->fi;+	struct spec_nh *spec_nh;  	if (fi) { 		if (FIB_RES_GW(*res) &&@@ -1423,7 +1425,13 @@ 			rt->rt_gateway = FIB_RES_GW(*res); 		memcpy(rt->u.dst.metrics, fi->fib_metrics, 		  

⌨️ 快捷键说明

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