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);
 
                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;
                }
 
        .output = xfrm4_beet_output,
        .owner = THIS_MODULE,
        .encap = XFRM_MODE_BEET,
+       .flags = XFRM_MODE_FLAG_TUNNEL,
 };
 
 static int __init xfrm4_beet_init(void)
 
        .output = xfrm4_tunnel_output,
        .owner = THIS_MODULE,
        .encap = XFRM_MODE_TUNNEL,
+       .flags = XFRM_MODE_FLAG_TUNNEL,
 };
 
 static int __init xfrm4_tunnel_init(void)
 
        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;
 
                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:
 
                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;
                }
 
        .output = xfrm6_beet_output,
        .owner = THIS_MODULE,
        .encap = XFRM_MODE_BEET,
+       .flags = XFRM_MODE_FLAG_TUNNEL,
 };
 
 static int __init xfrm6_beet_init(void)
 
        .output = xfrm6_tunnel_output,
        .owner = THIS_MODULE,
        .encap = XFRM_MODE_TUNNEL,
+       .flags = XFRM_MODE_FLAG_TUNNEL,
 };
 
 static int __init xfrm6_tunnel_init(void)
 
        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;
 
                __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:
 
        /* 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;
                }
        /* 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;
                }
 
                }
                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;
 
 
                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;
 
                        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,