]> git.hungrycats.org Git - linux/commitdiff
[IPSEC]: Implement DSCP decapsulation
authorHerbert Xu <herbert@gondor.apana.org.au>
Thu, 16 Sep 2004 06:12:04 +0000 (23:12 -0700)
committerDavid S. Miller <davem@nuts.davemloft.net>
Thu, 16 Sep 2004 06:12:04 +0000 (23:12 -0700)
This patch adds DSCP decapsulation for IPsec.  This is enabled by
a per-state flag which is off by default.  Leaving it off by default
maintains compatibility and is also good for performance reasons.

I decided to not implement a toggle on the output path since not
encapsulating the DSCP can and should be done by netfilter.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/pfkeyv2.h
include/linux/xfrm.h
include/net/inet_ecn.h
net/ipv4/xfrm4_input.c
net/ipv6/xfrm6_input.c
net/key/af_key.c

index a48a3ecc7c216dc41ccaa48c0288f79285ecc1dc..e6b5192202453edfc6fd7d1fac27d2d2fb5c2ef2 100644 (file)
@@ -245,6 +245,7 @@ struct sadb_x_nat_t_port {
 
 /* Security Association flags */
 #define SADB_SAFLAGS_PFS       1
+#define SADB_SAFLAGS_DECAP_DSCP        0x40000000
 #define SADB_SAFLAGS_NOECN     0x80000000
 
 /* Security Association states */
index 2e22a996f623f8da1ba1572d50b7f44ed206c1ca..f0df02ae68a4138152b5f278f9a1afaaf973554a 100644 (file)
@@ -190,6 +190,7 @@ struct xfrm_usersa_info {
        __u8                            replay_window;
        __u8                            flags;
 #define XFRM_STATE_NOECN       1
+#define XFRM_STATE_DECAP_DSCP  2
 };
 
 struct xfrm_usersa_id {
index 0bde1b6d5ced7f05c327da6d49efc6906bf39252..6e2ee16546ecc8ccd749d7ee3e63ca355476272f 100644 (file)
@@ -78,6 +78,12 @@ static inline void IP_ECN_clear(struct iphdr *iph)
        iph->tos &= ~INET_ECN_MASK;
 }
 
+static inline void ipv4_copy_dscp(struct iphdr *outer, struct iphdr *inner)
+{
+       u32 dscp = ipv4_get_dsfield(outer) & ~INET_ECN_MASK;
+       ipv4_change_dsfield(inner, INET_ECN_MASK, dscp);
+}
+
 struct ipv6hdr;
 
 static inline void IP6_ECN_set_ce(struct ipv6hdr *iph)
index f074d49306368f526e4475bb6d2109d826595872..47e54d4218df336b57b75b3bf8c962f38c8b7ea8 100644 (file)
@@ -101,6 +101,8 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
                        if (skb_cloned(skb) &&
                            pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
                                goto drop;
+                       if (x->props.flags & XFRM_STATE_DECAP_DSCP)
+                               ipv4_copy_dscp(iph, skb->h.ipiph);
                        if (!(x->props.flags & XFRM_STATE_NOECN))
                                ipip_ecn_decapsulate(skb);
                        skb->mac.raw = memmove(skb->data - skb->mac_len,
index 45702e4d429cf1794fdd4513e400c8db49073a4d..28c29d78338e3a84c259264182b6f5d322f71ac9 100644 (file)
@@ -88,6 +88,8 @@ int xfrm6_rcv_spi(struct sk_buff **pskb, unsigned int *nhoffp, u32 spi)
                        if (skb_cloned(skb) &&
                            pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
                                goto drop;
+                       if (x->props.flags & XFRM_STATE_DECAP_DSCP)
+                               ipv6_copy_dscp(skb->nh.ipv6h, skb->h.ipv6h);
                        if (!(x->props.flags & XFRM_STATE_NOECN))
                                ipip6_ecn_decapsulate(skb);
                        skb->mac.raw = memmove(skb->data - skb->mac_len,
index b059fa2931f0cd49b18d703f58eefc91145f9eb3..ed9d9bebdd353f449abbaebe143090afaf2e77b5 100644 (file)
@@ -683,6 +683,8 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
        sa->sadb_sa_flags = 0;
        if (x->props.flags & XFRM_STATE_NOECN)
                sa->sadb_sa_flags |= SADB_SAFLAGS_NOECN;
+       if (x->props.flags & XFRM_STATE_DECAP_DSCP)
+               sa->sadb_sa_flags |= SADB_SAFLAGS_DECAP_DSCP;
 
        /* hard time */
        if (hsc & 2) {
@@ -965,6 +967,8 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
        x->props.replay_window = sa->sadb_sa_replay;
        if (sa->sadb_sa_flags & SADB_SAFLAGS_NOECN)
                x->props.flags |= XFRM_STATE_NOECN;
+       if (sa->sadb_sa_flags & SADB_SAFLAGS_DECAP_DSCP)
+               x->props.flags |= XFRM_STATE_DECAP_DSCP;
 
        lifetime = (struct sadb_lifetime*) ext_hdrs[SADB_EXT_LIFETIME_HARD-1];
        if (lifetime != NULL) {