[IPSEC]: Add missing BEET checks
authorHerbert Xu <herbert@gondor.apana.org.au>
Thu, 18 Oct 2007 04:31:50 +0000 (21:31 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 18 Oct 2007 04:31:50 +0000 (21:31 -0700)
Currently BEET mode does not reinject the packet back into the stack
like tunnel mode does.  Since BEET should behave just like tunnel mode
this is incorrect.

This patch fixes this by introducing a flags field to xfrm_mode that
tells the IPsec code whether it should terminate and reinject the packet
back into the stack.

It then sets the flag for BEET and tunnel mode.

I've also added a number of missing BEET checks elsewhere where we check
whether a given mode is a tunnel or not.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
14 files changed:
include/net/xfrm.h
net/ipv4/xfrm4_input.c
net/ipv4/xfrm4_mode_beet.c
net/ipv4/xfrm4_mode_tunnel.c
net/ipv4/xfrm4_output.c
net/ipv4/xfrm4_policy.c
net/ipv6/xfrm6_input.c
net/ipv6/xfrm6_mode_beet.c
net/ipv6/xfrm6_mode_tunnel.c
net/ipv6/xfrm6_output.c
net/ipv6/xfrm6_policy.c
net/ipv6/xfrm6_state.c
net/xfrm/xfrm_output.c
net/xfrm/xfrm_policy.c

index 7f156a0b94c8d40e51ecbd3712bd09427f35ace0..2143f2911a21ac29cc33a382aedfa582c539e31c 100644 (file)
@@ -314,6 +314,12 @@ struct xfrm_mode {
 
        struct module *owner;
        unsigned int encap;
+       int flags;
+};
+
+/* Flags for xfrm_mode. */
+enum {
+       XFRM_MODE_FLAG_TUNNEL = 1,
 };
 
 extern int xfrm_register_mode(struct xfrm_mode *mode, int family);
index 5cb0b5995bc806a2b9e663d79cae17152de8c55c..bc5dc0747cd2eb6423ba460f3891d3303d0d844e 100644 (file)
@@ -94,7 +94,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
                if (x->mode->input(x, skb))
                        goto drop;
 
-               if (x->props.mode == XFRM_MODE_TUNNEL) {
+               if (x->mode->flags & XFRM_MODE_FLAG_TUNNEL) {
                        decaps = 1;
                        break;
                }
index 73d2338bec55f306985f82897b644b1f6f70df1a..e42e122414be1e461c01898aff091f405b48dfa2 100644 (file)
@@ -114,6 +114,7 @@ static struct xfrm_mode xfrm4_beet_mode = {
        .output = xfrm4_beet_output,
        .owner = THIS_MODULE,
        .encap = XFRM_MODE_BEET,
+       .flags = XFRM_MODE_FLAG_TUNNEL,
 };
 
 static int __init xfrm4_beet_init(void)
index 1ae9d32276f0a8daa13cf8abbf743b34c691f0f8..e4deecba6dd216d546706f57e3e557123af52c71 100644 (file)
@@ -139,6 +139,7 @@ static struct xfrm_mode xfrm4_tunnel_mode = {
        .output = xfrm4_tunnel_output,
        .owner = THIS_MODULE,
        .encap = XFRM_MODE_TUNNEL,
+       .flags = XFRM_MODE_FLAG_TUNNEL,
 };
 
 static int __init xfrm4_tunnel_init(void)
index a4edd666318b0f85bb9efb166df3512f78bce8d5..dcbc2743069c9d1c6f7d485d72b738ff90ee6a63 100644 (file)
@@ -47,7 +47,7 @@ static inline int xfrm4_output_one(struct sk_buff *skb)
        struct iphdr *iph;
        int err;
 
-       if (x->props.mode == XFRM_MODE_TUNNEL) {
+       if (x->mode->flags & XFRM_MODE_FLAG_TUNNEL) {
                err = xfrm4_tunnel_check_size(skb);
                if (err)
                        goto error_nolock;
index 329825ca68fe71730387583c9d96129ee3770db2..2373d673df60b799a32a20713e00b0c2f2e83905 100644 (file)
@@ -117,7 +117,7 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
                header_len += xfrm[i]->props.header_len;
                trailer_len += xfrm[i]->props.trailer_len;
 
-               if (xfrm[i]->props.mode == XFRM_MODE_TUNNEL) {
+               if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
                        unsigned short encap_family = xfrm[i]->props.family;
                        switch (encap_family) {
                        case AF_INET:
index b1201c33eb1203a295658c1743fa5b8571198db2..c6ee1a3ba19a4ed93c0b1e620efb749663631211 100644 (file)
@@ -71,7 +71,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
                if (x->mode->input(x, skb))
                        goto drop;
 
-               if (x->props.mode == XFRM_MODE_TUNNEL) { /* XXX */
+               if (x->mode->flags & XFRM_MODE_FLAG_TUNNEL) {
                        decaps = 1;
                        break;
                }
index 13bb1e85676467e8e3a03d19b38518736d44e2ce..2bfb4f05c14cdffec7f7c455e5ecf43f34acd4c9 100644 (file)
@@ -79,6 +79,7 @@ static struct xfrm_mode xfrm6_beet_mode = {
        .output = xfrm6_beet_output,
        .owner = THIS_MODULE,
        .encap = XFRM_MODE_BEET,
+       .flags = XFRM_MODE_FLAG_TUNNEL,
 };
 
 static int __init xfrm6_beet_init(void)
index ea22838791126f1df90aa82f43487ae121a6afc6..fd84e2217274a894ca69b1b7a23bfee81fab297f 100644 (file)
@@ -118,6 +118,7 @@ static struct xfrm_mode xfrm6_tunnel_mode = {
        .output = xfrm6_tunnel_output,
        .owner = THIS_MODULE,
        .encap = XFRM_MODE_TUNNEL,
+       .flags = XFRM_MODE_FLAG_TUNNEL,
 };
 
 static int __init xfrm6_tunnel_init(void)
index a5a32c17249ded0bc1211a3a2ff101c9898ed61e..c9f42d1c2dff9be5c1f291396e51e8e152d67c3e 100644 (file)
@@ -50,7 +50,7 @@ static inline int xfrm6_output_one(struct sk_buff *skb)
        struct ipv6hdr *iph;
        int err;
 
-       if (x->props.mode == XFRM_MODE_TUNNEL) {
+       if (x->mode->flags & XFRM_MODE_FLAG_TUNNEL) {
                err = xfrm6_tunnel_check_size(skb);
                if (err)
                        goto error_nolock;
index 15aa4c58c3159ef9ec2a844bcca0305c0b034ec8..dc4bdcb55cbe9a79171c2433f31227316a8b3c62 100644 (file)
@@ -178,8 +178,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
                __xfrm6_bundle_len_inc(&header_len, &nfheader_len, xfrm[i]);
                trailer_len += xfrm[i]->props.trailer_len;
 
-               if (xfrm[i]->props.mode == XFRM_MODE_TUNNEL ||
-                   xfrm[i]->props.mode == XFRM_MODE_ROUTEOPTIMIZATION) {
+               if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
                        unsigned short encap_family = xfrm[i]->props.family;
                        switch(encap_family) {
                        case AF_INET:
index cdadb4847469f21e52237c75d5f12abaac9a5ffb..e644c80515fc591d2c016b5ca796a736bf9567d1 100644 (file)
@@ -93,7 +93,8 @@ __xfrm6_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n)
        /* Rule 4: select IPsec tunnel */
        for (i = 0; i < n; i++) {
                if (src[i] &&
-                   src[i]->props.mode == XFRM_MODE_TUNNEL) {
+                   (src[i]->props.mode == XFRM_MODE_TUNNEL ||
+                    src[i]->props.mode == XFRM_MODE_BEET)) {
                        dst[j++] = src[i];
                        src[i] = NULL;
                }
@@ -146,7 +147,8 @@ __xfrm6_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n)
        /* Rule 3: select IPsec tunnel */
        for (i = 0; i < n; i++) {
                if (src[i] &&
-                   src[i]->mode == XFRM_MODE_TUNNEL) {
+                   (src[i]->mode == XFRM_MODE_TUNNEL ||
+                    src[i]->mode == XFRM_MODE_BEET)) {
                        dst[j++] = src[i];
                        src[i] = NULL;
                }
index 0eb3377602e9c3c9b413072f1db6f0b5a915b8e5..8bf71ba2345f36006b6745ab940e46e45ed3064f 100644 (file)
@@ -82,7 +82,7 @@ int xfrm_output(struct sk_buff *skb)
                }
                dst = skb->dst;
                x = dst->xfrm;
-       } while (x && (x->props.mode != XFRM_MODE_TUNNEL));
+       } while (x && !(x->mode->flags & XFRM_MODE_FLAG_TUNNEL));
 
        err = 0;
 
index ca24c90d37967cc44d542f9fafa2087949ecb837..1d66fb42c9cbe87f81b56fd5e5de06fbcd9c096e 100644 (file)
@@ -1940,7 +1940,8 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first,
                if (xdst->genid != dst->xfrm->genid)
                        return 0;
 
-               if (strict && fl && dst->xfrm->props.mode != XFRM_MODE_TUNNEL &&
+               if (strict && fl &&
+                   !(dst->xfrm->mode->flags & XFRM_MODE_FLAG_TUNNEL) &&
                    !xfrm_state_addr_flow_check(dst->xfrm, fl, family))
                        return 0;
 
@@ -2291,7 +2292,8 @@ static int xfrm_policy_migrate(struct xfrm_policy *pol,
                        if (!migrate_tmpl_match(mp, &pol->xfrm_vec[i]))
                                continue;
                        n++;
-                       if (pol->xfrm_vec[i].mode != XFRM_MODE_TUNNEL)
+                       if (pol->xfrm_vec[i].mode != XFRM_MODE_TUNNEL &&
+                           pol->xfrm_vec[i].mode != XFRM_MODE_BEET)
                                continue;
                        /* update endpoints */
                        memcpy(&pol->xfrm_vec[i].id.daddr, &mp->new_daddr,