Re: [IPSEC] Progagating ECN based on per-SA flag

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jul 22, 2003 at 11:44:08PM -0700, David S. Miller wrote:
> 
> So the new bits should mean "disable ECN forwarding".
> 
> Ok?

That's fine by me.  Here is the patch which does that.
-- 
Debian GNU/Linux 3.0 is out! ( http://www.debian.org/ )
Email:  Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Index: kernel-source-2.5/include/linux/pfkeyv2.h
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/include/linux/pfkeyv2.h,v
retrieving revision 1.2
diff -u -r1.2 pfkeyv2.h
--- kernel-source-2.5/include/linux/pfkeyv2.h	22 Jul 2003 09:13:59 -0000	1.2
+++ kernel-source-2.5/include/linux/pfkeyv2.h	23 Jul 2003 06:55:12 -0000
@@ -245,6 +245,7 @@
 
 /* Security Association flags */
 #define SADB_SAFLAGS_PFS	1
+#define SADB_SAFLAGS_NOECN	0x80000000
 
 /* Security Association states */
 #define SADB_SASTATE_LARVAL	0
Index: kernel-source-2.5/include/linux/xfrm.h
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/include/linux/xfrm.h,v
retrieving revision 1.5
diff -u -r1.5 xfrm.h
--- kernel-source-2.5/include/linux/xfrm.h	22 Jul 2003 09:13:59 -0000	1.5
+++ kernel-source-2.5/include/linux/xfrm.h	23 Jul 2003 06:55:23 -0000
@@ -166,6 +166,8 @@
 	__u16				family;
 	__u8				mode; /* 0=transport,1=tunnel */
 	__u8				replay_window;
+	__u8				flags;
+#define XFRM_STATE_NOECN	1
 };
 
 struct xfrm_usersa_id {
Index: kernel-source-2.5/include/net/inet_ecn.h
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/include/net/inet_ecn.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 inet_ecn.h
--- kernel-source-2.5/include/net/inet_ecn.h	19 Oct 2002 04:02:29 -0000	1.1.1.1
+++ kernel-source-2.5/include/net/inet_ecn.h	22 Jul 2003 10:47:31 -0000
@@ -1,6 +1,8 @@
 #ifndef _INET_ECN_H_
 #define _INET_ECN_H_
 
+#include <linux/ip.h>
+
 static inline int INET_ECN_is_ce(__u8 dsfield)
 {
 	return (dsfield&3) == 3;
@@ -44,11 +46,21 @@
 	iph->tos |= 1;
 }
 
+static inline void IP_ECN_clear(struct iphdr *iph)
+{
+	iph->tos &= ~3;
+}
+
 struct ipv6hdr;
 
 static inline void IP6_ECN_set_ce(struct ipv6hdr *iph)
 {
 	*(u32*)iph |= htonl(1<<20);
+}
+
+static inline void IP6_ECN_clear(struct ipv6hdr *iph)
+{
+	*(u32*)iph &= ~htonl(3<<20);
 }
 
 #define ip6_get_dsfield(iph) ((ntohs(*(u16*)(iph)) >> 4) & 0xFF)
Index: kernel-source-2.5/include/net/xfrm.h
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/include/net/xfrm.h,v
retrieving revision 1.13
diff -u -r1.13 xfrm.h
--- kernel-source-2.5/include/net/xfrm.h	22 Jul 2003 09:13:59 -0000	1.13
+++ kernel-source-2.5/include/net/xfrm.h	22 Jul 2003 09:14:50 -0000
@@ -108,6 +108,7 @@
 		u8		mode;
 		u8		replay_window;
 		u8		aalgo, ealgo, calgo;
+		u8		flags;
 		u16		family;
 		xfrm_address_t	saddr;
 		int		header_len;
Index: kernel-source-2.5/net/ipv4/ah4.c
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/ipv4/ah4.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ah4.c
--- kernel-source-2.5/net/ipv4/ah4.c	17 Jun 2003 04:20:22 -0000	1.1.1.1
+++ kernel-source-2.5/net/ipv4/ah4.c	23 Jul 2003 06:56:53 -0000
@@ -1,5 +1,6 @@
 #include <linux/config.h>
 #include <linux/module.h>
+#include <net/inet_ecn.h>
 #include <net/ip.h>
 #include <net/xfrm.h>
 #include <net/ah.h>
@@ -123,6 +124,8 @@
 	top_iph->tos = iph->tos;
 	top_iph->ttl = iph->ttl;
 	if (x->props.mode) {
+		if (x->props.flags & XFRM_STATE_NOECN)
+			IP_ECN_clear(top_iph);
 		top_iph->frag_off = iph->frag_off&~htons(IP_MF|IP_OFFSET);
 		memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
 	} else {
Index: kernel-source-2.5/net/ipv4/esp4.c
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/ipv4/esp4.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 esp4.c
--- kernel-source-2.5/net/ipv4/esp4.c	17 Jun 2003 04:20:05 -0000	1.1.1.1
+++ kernel-source-2.5/net/ipv4/esp4.c	23 Jul 2003 06:57:01 -0000
@@ -1,5 +1,6 @@
 #include <linux/config.h>
 #include <linux/module.h>
+#include <net/inet_ecn.h>
 #include <net/ip.h>
 #include <net/xfrm.h>
 #include <net/esp.h>
@@ -109,6 +110,8 @@
 		top_iph->ihl = 5;
 		top_iph->version = 4;
 		top_iph->tos = iph->tos;	/* DS disclosed */
+		if (x->props.flags & XFRM_STATE_NOECN)
+			IP_ECN_clear(top_iph);
 		top_iph->tot_len = htons(skb->len + alen);
 		top_iph->frag_off = iph->frag_off&htons(IP_DF);
 		if (!(top_iph->frag_off))
Index: kernel-source-2.5/net/ipv4/ipcomp.c
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/ipv4/ipcomp.c,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 ipcomp.c
--- kernel-source-2.5/net/ipv4/ipcomp.c	17 Jun 2003 04:20:21 -0000	1.1.1.3
+++ kernel-source-2.5/net/ipv4/ipcomp.c	23 Jul 2003 06:57:18 -0000
@@ -18,6 +18,7 @@
 #include <asm/scatterlist.h>
 #include <linux/crypto.h>
 #include <linux/pfkeyv2.h>
+#include <net/inet_ecn.h>
 #include <net/ip.h>
 #include <net/xfrm.h>
 #include <net/icmp.h>
@@ -210,6 +211,8 @@
 	top_iph = (struct iphdr *)skb_push(skb, sizeof(struct ip_comp_hdr));
 	memcpy(top_iph, &tmp_iph, iph->ihl * 4);
 	iph = top_iph;
+	if (x->props.mode && (x->props.flags & XFRM_STATE_NOECN))
+		IP_ECN_clear(iph);
 	iph->tot_len = htons(skb->len);
 	iph->protocol = IPPROTO_COMP;
 	iph->check = 0;
Index: kernel-source-2.5/net/ipv4/xfrm4_input.c
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/ipv4/xfrm4_input.c,v
retrieving revision 1.2
diff -u -r1.2 xfrm4_input.c
--- kernel-source-2.5/net/ipv4/xfrm4_input.c	2 Jun 2003 10:55:50 -0000	1.2
+++ kernel-source-2.5/net/ipv4/xfrm4_input.c	23 Jul 2003 06:57:35 -0000
@@ -10,6 +10,7 @@
  */
 
 #include <linux/slab.h>
+#include <net/inet_ecn.h>
 #include <net/ip.h>
 #include <net/xfrm.h>
 
@@ -20,6 +21,15 @@
 	return xfrm4_rcv_encap(skb, 0);
 }
 
+static inline void ipip_ecn_decapsulate(struct iphdr *outer_iph, struct sk_buff *skb)
+{
+	struct iphdr *inner_iph = skb->nh.iph;
+
+	if (INET_ECN_is_ce(outer_iph->tos) &&
+	    INET_ECN_is_not_ce(inner_iph->tos))
+		IP_ECN_set_ce(inner_iph);
+}
+
 int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
 {
 	int err;
@@ -75,6 +85,8 @@
 			if (iph->protocol != IPPROTO_IPIP)
 				goto drop;
 			skb->nh.raw = skb->data;
+			if (!(x->props.flags & XFRM_STATE_NOECN))
+				ipip_ecn_decapsulate(iph, skb);
 			iph = skb->nh.iph;
 			memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
 			decaps = 1;
Index: kernel-source-2.5/net/ipv6/ah6.c
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/ipv6/ah6.c,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 ah6.c
--- kernel-source-2.5/net/ipv6/ah6.c	17 Jun 2003 04:20:07 -0000	1.1.1.5
+++ kernel-source-2.5/net/ipv6/ah6.c	23 Jul 2003 06:58:45 -0000
@@ -26,6 +26,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <net/inet_ecn.h>
 #include <net/ip.h>
 #include <net/xfrm.h>
 #include <net/ah.h>
@@ -220,6 +221,8 @@
 		skb->nh.ipv6h->flow_lbl[0] = iph->flow_lbl[0];
 		skb->nh.ipv6h->flow_lbl[1] = iph->flow_lbl[1];
 		skb->nh.ipv6h->flow_lbl[2] = iph->flow_lbl[2];
+		if (x->props.flags & XFRM_STATE_NOECN)
+			IP6_ECN_clear(skb->nh.ipv6h);
 	} else {
 		memcpy(skb->nh.ipv6h, iph, hdr_len);
 		skb->nh.raw[nh_offset] = IPPROTO_AH;
Index: kernel-source-2.5/net/ipv6/esp6.c
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/ipv6/esp6.c,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 esp6.c
--- kernel-source-2.5/net/ipv6/esp6.c	17 Jun 2003 04:20:06 -0000	1.1.1.5
+++ kernel-source-2.5/net/ipv6/esp6.c	23 Jul 2003 07:11:28 -0000
@@ -26,6 +26,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <net/inet_ecn.h>
 #include <net/ip.h>
 #include <net/xfrm.h>
 #include <net/esp.h>
@@ -121,6 +122,8 @@
 		top_iph->flow_lbl[0] = iph->flow_lbl[0];
 		top_iph->flow_lbl[1] = iph->flow_lbl[1];
 		top_iph->flow_lbl[2] = iph->flow_lbl[2];
+		if (x->props.flags & XFRM_STATE_NOECN)
+			IP6_ECN_clear(top_iph);
 		top_iph->nexthdr = IPPROTO_ESP;
 		top_iph->payload_len = htons(skb->len + alen - sizeof(struct ipv6hdr));
 		top_iph->hop_limit = iph->hop_limit;
Index: kernel-source-2.5/net/ipv6/ipcomp6.c
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/ipv6/ipcomp6.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 ipcomp6.c
--- kernel-source-2.5/net/ipv6/ipcomp6.c	17 Jun 2003 04:20:01 -0000	1.1.1.2
+++ kernel-source-2.5/net/ipv6/ipcomp6.c	23 Jul 2003 07:11:34 -0000
@@ -32,6 +32,7 @@
  */
 #include <linux/config.h>
 #include <linux/module.h>
+#include <net/inet_ecn.h>
 #include <net/ip.h>
 #include <net/xfrm.h>
 #include <net/ipcomp.h>
@@ -201,6 +202,8 @@
 	memcpy(top_iph, tmp_iph, hdr_len);
 	kfree(tmp_iph);
 
+	if (x->props.mode && (x->props.flags & XFRM_STATE_NOECN))
+		IP6_ECN_clear(top_iph);
 	top_iph->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
 	skb->nh.raw = skb->data; /* top_iph */
 	ip6_find_1stfragopt(skb, &prevhdr); 
Index: kernel-source-2.5/net/ipv6/xfrm6_input.c
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/ipv6/xfrm6_input.c,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 xfrm6_input.c
--- kernel-source-2.5/net/ipv6/xfrm6_input.c	2 Jul 2003 20:58:14 -0000	1.1.1.5
+++ kernel-source-2.5/net/ipv6/xfrm6_input.c	23 Jul 2003 07:11:04 -0000
@@ -9,12 +9,21 @@
  *		IPv6 support
  */
 
+#include <net/inet_ecn.h>
 #include <net/ip.h>
 #include <net/ipv6.h>
 #include <net/xfrm.h>
 
 static kmem_cache_t *secpath_cachep;
 
+static inline void ipip6_ecn_decapsulate(struct ipv6hdr *iph,
+					 struct sk_buff *skb)
+{
+	if (INET_ECN_is_ce(ip6_get_dsfield(iph)) &&
+	    INET_ECN_is_not_ce(ip6_get_dsfield(skb->nh.ipv6h)))
+		IP6_ECN_set_ce(skb->nh.ipv6h);
+}
+
 int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
 {
 	struct sk_buff *skb = *pskb;
@@ -71,6 +80,8 @@
 			if (nexthdr != IPPROTO_IPV6)
 				goto drop;
 			skb->nh.raw = skb->data;
+			if (!(x->props.flags & XFRM_STATE_NOECN))
+				ipip6_ecn_decapsulate(iph, skb);
 			iph = skb->nh.ipv6h;
 			decaps = 1;
 			break;
Index: kernel-source-2.5/net/key/af_key.c
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/key/af_key.c,v
retrieving revision 1.11
diff -u -r1.11 af_key.c
--- kernel-source-2.5/net/key/af_key.c	22 Jul 2003 09:13:59 -0000	1.11
+++ kernel-source-2.5/net/key/af_key.c	23 Jul 2003 06:55:40 -0000
@@ -681,6 +681,8 @@
 	}
 
 	sa->sadb_sa_flags = 0;
+	if (x->props.flags & XFRM_STATE_NOECN)
+		sa->sadb_sa_flags |= SADB_SAFLAGS_NOECN;
 
 	/* hard time */
 	if (hsc & 2) {
@@ -957,6 +959,8 @@
 	x->id.proto = proto;
 	x->id.spi = sa->sadb_sa_spi;
 	x->props.replay_window = sa->sadb_sa_replay;
+	if (sa->sadb_sa_flags & SADB_SAFLAGS_NOECN)
+		x->props.flags |= XFRM_STATE_NOECN;
 
 	lifetime = (struct sadb_lifetime*) ext_hdrs[SADB_EXT_LIFETIME_HARD-1];
 	if (lifetime != NULL) {
Index: kernel-source-2.5/net/xfrm/xfrm_user.c
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/xfrm/xfrm_user.c,v
retrieving revision 1.9
diff -u -r1.9 xfrm_user.c
--- kernel-source-2.5/net/xfrm/xfrm_user.c	5 Jul 2003 22:54:05 -0000	1.9
+++ kernel-source-2.5/net/xfrm/xfrm_user.c	22 Jul 2003 09:17:50 -0000
@@ -201,6 +201,7 @@
 	x->props.reqid = p->reqid;
 	x->props.family = p->family;
 	x->props.saddr = p->saddr;
+	x->props.flags = p->flags;
 }
 
 static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p,
@@ -305,6 +306,7 @@
 	p->replay_window = x->props.replay_window;
 	p->reqid = x->props.reqid;
 	p->family = x->props.family;
+	p->flags = x->props.flags;
 	p->seq = x->km.seq;
 }
 

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux