Transformation mode is used as either IPsec transport or tunnel.
It is required to add two more items, route-optimization and inbound trigger
by Mobile IPv6.
Based on MIPL2 kernel patch.
---
 include/linux/xfrm.h    |    9 ++++++++-
 include/net/xfrm.h      |    2 +-
 net/ipv4/ah4.c          |    2 +-
 net/ipv4/esp4.c         |    6 +++---
 net/ipv4/ipcomp.c       |    8 ++++----
 net/ipv4/xfrm4_input.c  |    2 +-
 net/ipv4/xfrm4_output.c |    6 +++---
 net/ipv4/xfrm4_policy.c |    2 +-
 net/ipv4/xfrm4_state.c  |    2 +-
 net/ipv4/xfrm4_tunnel.c |    2 +-
 net/ipv6/ah6.c          |    2 +-
 net/ipv6/esp6.c         |    4 ++--
 net/ipv6/ipcomp6.c      |    6 +++---
 net/ipv6/xfrm6_input.c  |    2 +-
 net/ipv6/xfrm6_output.c |    6 +++---
 net/ipv6/xfrm6_policy.c |    2 +-
 net/ipv6/xfrm6_state.c  |    2 +-
 net/ipv6/xfrm6_tunnel.c |    2 +-
 net/key/af_key.c        |    6 +++---
 net/xfrm/xfrm_policy.c  |   11 ++++++-----
 net/xfrm/xfrm_user.c    |    4 ++--
 21 files changed, 48 insertions(+), 40 deletions(-)

diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index 6b42cc4..7dff1c8 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -178,6 +178,13 @@ struct xfrm_user_sec_ctx {
        __u16                   ctx_len;
 };
 
+enum {
+       XFRM_MODE_TRANSPORT = 0,
+       XFRM_MODE_TUNNEL = 1,
+       XFRM_MODE_ROUTEOPTIMIZATION = 2,
+       XFRM_MODE_IN_TRIGGER = 3,
+};
+
 struct xfrm_user_tmpl {
        struct xfrm_id          id;
        __u16                   family;
@@ -243,7 +250,7 @@ struct xfrm_usersa_info {
        __u32                           seq;
        __u32                           reqid;
        __u16                           family;
-       __u8                            mode; /* 0=transport,1=tunnel */
+       __u8                            mode;           /* XFRM_MODE_xxx */
        __u8                            replay_window;
        __u8                            flags;
 #define XFRM_STATE_NOECN       1
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index afa508d..ddb153d 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -289,7 +289,7 @@ struct xfrm_tmpl
 
        __u32                   reqid;
 
-/* Mode: transport/tunnel */
+/* Mode: transport, tunnel etc. */
        __u8                    mode;
 
 /* Sharing mode: unique, this session only, this user only etc. */
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index e2e4771..fa16bc2 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -257,7 +257,7 @@ static int ah_init_state(struct xfrm_sta
                goto error;
        
        x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + 
ahp->icv_trunc_len);
-       if (x->props.mode)
+       if (x->props.mode == XFRM_MODE_TUNNEL)
                x->props.header_len += sizeof(struct iphdr);
        x->data = ahp;
 
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 9d1881c..dd4edd1 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -240,7 +240,7 @@ static int esp_input(struct xfrm_state *
                 *    as per draft-ietf-ipsec-udp-encaps-06,
                 *    section 3.1.2
                 */
-               if (!x->props.mode)
+               if (x->props.mode == XFRM_MODE_TRANSPORT)
                        skb->ip_summed = CHECKSUM_UNNECESSARY;
        }
 
@@ -263,7 +263,7 @@ static u32 esp4_get_max_size(struct xfrm
        struct esp_data *esp = x->data;
        u32 blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4);
 
-       if (x->props.mode) {
+       if (x->props.mode == XFRM_MODE_TUNNEL) {
                mtu = ALIGN(mtu + 2, blksize);
        } else {
                /* The worst case. */
@@ -377,7 +377,7 @@ static int esp_init_state(struct xfrm_st
        if (crypto_cipher_setkey(esp->conf.tfm, esp->conf.key, 
esp->conf.key_len))
                goto error;
        x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen;
-       if (x->props.mode)
+       if (x->props.mode == XFRM_MODE_TUNNEL)
                x->props.header_len += sizeof(struct iphdr);
        if (x->encap) {
                struct xfrm_encap_tmpl *encap = x->encap;
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index 95278b2..a4c35f7 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -194,7 +194,7 @@ static int ipcomp_output(struct xfrm_sta
        return 0;
 
 out_ok:
-       if (x->props.mode)
+       if (x->props.mode == XFRM_MODE_TUNNEL)
                ip_send_check(iph);
        return 0;
 }
@@ -234,7 +234,7 @@ static struct xfrm_state *ipcomp_tunnel_
        t->id.daddr.a4 = x->id.daddr.a4;
        memcpy(&t->sel, &x->sel, sizeof(t->sel));
        t->props.family = AF_INET;
-       t->props.mode = 1;
+       t->props.mode = XFRM_MODE_TUNNEL;
        t->props.saddr.a4 = x->props.saddr.a4;
        t->props.flags = x->props.flags;
 
@@ -434,7 +434,7 @@ static int ipcomp_init_state(struct xfrm
 
        memset(ipcd, 0, sizeof(*ipcd));
        x->props.header_len = 0;
-       if (x->props.mode)
+       if (x->props.mode == XFRM_MODE_TUNNEL)
                x->props.header_len += sizeof(struct iphdr);
 
        mutex_lock(&ipcomp_resource_mutex);
@@ -446,7 +446,7 @@ static int ipcomp_init_state(struct xfrm
                goto error;
        mutex_unlock(&ipcomp_resource_mutex);
 
-       if (x->props.mode) {
+       if (x->props.mode == XFRM_MODE_TUNNEL) {
                err = ipcomp_tunnel_attach(x);
                if (err)
                        goto error_tunnel;
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index 3e174c8..615e1ba 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -115,7 +115,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb,
 
                iph = skb->nh.iph;
 
-               if (x->props.mode) {
+               if (x->props.mode == XFRM_MODE_TUNNEL) {
                        if (iph->protocol != IPPROTO_IPIP)
                                goto drop;
                        if (!pskb_may_pull(skb, sizeof(struct iphdr)))
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index 4ef8efa..c7f6bc5 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -43,7 +43,7 @@ static void xfrm4_encap(struct sk_buff *
        skb->nh.raw = skb_push(skb, x->props.header_len);
        top_iph = skb->nh.iph;
 
-       if (!x->props.mode) {
+       if (x->props.mode == XFRM_MODE_TRANSPORT) {
                skb->h.raw += iph->ihl*4;
                memmove(top_iph, iph, iph->ihl*4);
                return;
@@ -109,7 +109,7 @@ static int xfrm4_output_one(struct sk_bu
                        goto error_nolock;
        }
 
-       if (x->props.mode) {
+       if (x->props.mode == XFRM_MODE_TUNNEL) {
                err = xfrm4_tunnel_check_size(skb);
                if (err)
                        goto error_nolock;
@@ -138,7 +138,7 @@ static int xfrm4_output_one(struct sk_bu
                }
                dst = skb->dst;
                x = dst->xfrm;
-       } while (x && !x->props.mode);
+       } while (x && (x->props.mode != XFRM_MODE_TUNNEL));
 
        IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
        err = 0;
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 8604c74..bf77489 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -99,7 +99,7 @@ __xfrm4_bundle_create(struct xfrm_policy
 
                dst1->next = dst_prev;
                dst_prev = dst1;
-               if (xfrm[i]->props.mode) {
+               if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
                        remote = xfrm[i]->id.daddr.a4;
                        local  = xfrm[i]->props.saddr.a4;
                        tunnel = 1;
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c
index dbabf81..171cdc5 100644
--- a/net/ipv4/xfrm4_state.c
+++ b/net/ipv4/xfrm4_state.c
@@ -42,7 +42,7 @@ __xfrm4_init_tempsel(struct xfrm_state *
        x->props.saddr = tmpl->saddr;
        if (x->props.saddr.a4 == 0)
                x->props.saddr.a4 = saddr->a4;
-       if (tmpl->mode && x->props.saddr.a4 == 0) {
+       if (tmpl->mode == XFRM_MODE_TUNNEL && x->props.saddr.a4 == 0) {
                struct rtable *rt;
                struct flowi fl_tunnel = {
                        .nl_u = {
diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c
index f8ceaa1..f110af5 100644
--- a/net/ipv4/xfrm4_tunnel.c
+++ b/net/ipv4/xfrm4_tunnel.c
@@ -28,7 +28,7 @@ static int ipip_xfrm_rcv(struct xfrm_sta
 
 static int ipip_init_state(struct xfrm_state *x)
 {
-       if (!x->props.mode)
+       if (x->props.mode != XFRM_MODE_TUNNEL)
                return -EINVAL;
 
        if (x->encap)
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 6778173..dcdd039 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -392,7 +392,7 @@ static int ah6_init_state(struct xfrm_st
                goto error;
        
        x->props.header_len = XFRM_ALIGN8(sizeof(struct ipv6_auth_hdr) + 
ahp->icv_trunc_len);
-       if (x->props.mode)
+       if (x->props.mode == XFRM_MODE_TUNNEL)
                x->props.header_len += sizeof(struct ipv6hdr);
        x->data = ahp;
 
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 22f0460..ad3b8a8 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -240,7 +240,7 @@ static u32 esp6_get_max_size(struct xfrm
        struct esp_data *esp = x->data;
        u32 blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4);
 
-       if (x->props.mode) {
+       if (x->props.mode == XFRM_MODE_TUNNEL) {
                mtu = ALIGN(mtu + 2, blksize);
        } else {
                /* The worst case. */
@@ -357,7 +357,7 @@ static int esp6_init_state(struct xfrm_s
        if (crypto_cipher_setkey(esp->conf.tfm, esp->conf.key, 
esp->conf.key_len))
                goto error;
        x->props.header_len = sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen;
-       if (x->props.mode)
+       if (x->props.mode == XFRM_MODE_TUNNEL)
                x->props.header_len += sizeof(struct ipv6hdr);
        x->data = esp;
        return 0;
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 4863643..94877f5 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -234,7 +234,7 @@ static struct xfrm_state *ipcomp6_tunnel
        memcpy(t->id.daddr.a6, x->id.daddr.a6, sizeof(struct in6_addr));
        memcpy(&t->sel, &x->sel, sizeof(t->sel));
        t->props.family = AF_INET6;
-       t->props.mode = 1;
+       t->props.mode = XFRM_MODE_TUNNEL;
        memcpy(t->props.saddr.a6, x->props.saddr.a6, sizeof(struct in6_addr));
 
        if (xfrm_init_state(t))
@@ -438,7 +438,7 @@ static int ipcomp6_init_state(struct xfr
                goto out;
 
        x->props.header_len = 0;
-       if (x->props.mode)
+       if (x->props.mode == XFRM_MODE_TUNNEL)
                x->props.header_len += sizeof(struct ipv6hdr);
        
        mutex_lock(&ipcomp6_resource_mutex);
@@ -450,7 +450,7 @@ static int ipcomp6_init_state(struct xfr
                goto error;
        mutex_unlock(&ipcomp6_resource_mutex);
 
-       if (x->props.mode) {
+       if (x->props.mode == XFRM_MODE_TUNNEL) {
                err = ipcomp6_tunnel_attach(x);
                if (err)
                        goto error_tunnel;
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 00cfdee..915e867 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -81,7 +81,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, u
 
                xfrm_vec[xfrm_nr++] = x;
 
-               if (x->props.mode) { /* XXX */
+               if (x->props.mode == XFRM_MODE_TUNNEL) { /* XXX */
                        if (nexthdr != IPPROTO_IPV6)
                                goto drop;
                        if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index 8024217..2736a54 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -44,7 +44,7 @@ static void xfrm6_encap(struct sk_buff *
        skb_push(skb, x->props.header_len);
        iph = skb->nh.ipv6h;
 
-       if (!x->props.mode) {
+       if (x->props.mode != XFRM_MODE_TUNNEL) {
                u8 *prevhdr;
                int hdr_len;
 
@@ -106,7 +106,7 @@ static int xfrm6_output_one(struct sk_bu
                        goto error_nolock;
        }
 
-       if (x->props.mode) {
+       if (x->props.mode == XFRM_MODE_TUNNEL) {
                err = xfrm6_tunnel_check_size(skb);
                if (err)
                        goto error_nolock;
@@ -137,7 +137,7 @@ static int xfrm6_output_one(struct sk_bu
                }
                dst = skb->dst;
                x = dst->xfrm;
-       } while (x && !x->props.mode);
+       } while (x && (x->props.mode != XFRM_MODE_TUNNEL));
 
        IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
        err = 0;
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 88c840f..1d8489b 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -117,7 +117,7 @@ __xfrm6_bundle_create(struct xfrm_policy
 
                dst1->next = dst_prev;
                dst_prev = dst1;
-               if (xfrm[i]->props.mode) {
+               if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
                        remote = (struct in6_addr*)&xfrm[i]->id.daddr;
                        local  = (struct in6_addr*)&xfrm[i]->props.saddr;
                        tunnel = 1;
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
index a572302..71c40bb 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -42,7 +42,7 @@ __xfrm6_init_tempsel(struct xfrm_state *
        memcpy(&x->props.saddr, &tmpl->saddr, sizeof(x->props.saddr));
        if (ipv6_addr_any((struct in6_addr*)&x->props.saddr))
                memcpy(&x->props.saddr, saddr, sizeof(x->props.saddr));
-       if (tmpl->mode && ipv6_addr_any((struct in6_addr*)&x->props.saddr)) {
+       if (tmpl->mode == XFRM_MODE_TUNNEL && ipv6_addr_any((struct 
in6_addr*)&x->props.saddr)) {
                struct rt6_info *rt;
                struct flowi fl_tunnel = {
                        .nl_u = {
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index d37768e..66fec6e 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -414,7 +414,7 @@ static int xfrm6_tunnel_err(struct sk_bu
 
 static int xfrm6_tunnel_init_state(struct xfrm_state *x)
 {
-       if (!x->props.mode)
+       if (x->props.mode != XFRM_MODE_TUNNEL)
                return -EINVAL;
 
        if (x->encap)
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 8595822..ed2d712 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1764,7 +1764,7 @@ #endif
        }
 
        /* addresses present only in tunnel mode */
-       if (t->mode) {
+       if (t->mode == XFRM_MODE_TUNNEL) {
                switch (xp->family) {
                case AF_INET:
                        sin = (void*)(rq+1);
@@ -1996,7 +1996,7 @@ #endif
                int req_size;
 
                req_size = sizeof(struct sadb_x_ipsecrequest);
-               if (t->mode)
+               if (t->mode == XFRM_MODE_TUNNEL)
                        req_size += 2*socklen;
                else
                        size -= 2*socklen;
@@ -2012,7 +2012,7 @@ #endif
                if (t->optional)
                        rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_USE;
                rq->sadb_x_ipsecrequest_reqid = t->reqid;
-               if (t->mode) {
+               if (t->mode == XFRM_MODE_TUNNEL) {
                        switch (xp->family) {
                        case AF_INET:
                                sin = (void*)(rq+1);
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index b469c8b..d143381 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -702,7 +702,7 @@ xfrm_tmpl_resolve(struct xfrm_policy *po
                xfrm_address_t *local  = saddr;
                struct xfrm_tmpl *tmpl = &policy->xfrm_vec[i];
 
-               if (tmpl->mode) {
+               if (tmpl->mode == XFRM_MODE_TUNNEL) {
                        remote = &tmpl->id.daddr;
                        local = &tmpl->saddr;
                }
@@ -928,7 +928,8 @@ xfrm_state_ok(struct xfrm_tmpl *tmpl, st
                (x->props.reqid == tmpl->reqid || !tmpl->reqid) &&
                x->props.mode == tmpl->mode &&
                (tmpl->aalgos & (1<<x->props.aalgo)) &&
-               !(x->props.mode && xfrm_state_addr_cmp(tmpl, x, family));
+               !(x->props.mode != XFRM_MODE_TRANSPORT &&
+                 xfrm_state_addr_cmp(tmpl, x, family));
 }
 
 static inline int
@@ -938,14 +939,14 @@ xfrm_policy_ok(struct xfrm_tmpl *tmpl, s
        int idx = start;
 
        if (tmpl->optional) {
-               if (!tmpl->mode)
+               if (tmpl->mode == XFRM_MODE_TRANSPORT)
                        return start;
        } else
                start = -1;
        for (; idx < sp->len; idx++) {
                if (xfrm_state_ok(tmpl, sp->xvec[idx], family))
                        return ++idx;
-               if (sp->xvec[idx]->props.mode)
+               if (sp->xvec[idx]->props.mode != XFRM_MODE_TRANSPORT)
                        break;
        }
        return start;
@@ -968,7 +969,7 @@ EXPORT_SYMBOL(xfrm_decode_session);
 static inline int secpath_has_tunnel(struct sec_path *sp, int k)
 {
        for (; k < sp->len; k++) {
-               if (sp->xvec[k]->props.mode)
+               if (sp->xvec[k]->props.mode != XFRM_MODE_TRANSPORT)
                        return 1;
        }
 
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 81d1005..9516da3 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -173,8 +173,8 @@ #endif
 
        err = -EINVAL;
        switch (p->mode) {
-       case 0:
-       case 1:
+       case XFRM_MODE_TRANSPORT:
+       case XFRM_MODE_TUNNEL:
                break;
 
        default:
-- 
1.4.1

-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to