tunnel: Add support for matching on OAM packets.
authorJesse Gross <jesse@nicira.com>
Wed, 28 May 2014 04:50:35 +0000 (21:50 -0700)
committerJesse Gross <jesse@nicira.com>
Fri, 20 Jun 2014 01:33:28 +0000 (18:33 -0700)
Some tunnel formats have mechanisms for indicating that packets are
OAM frames that should be handled specially (either as high priority or
not forwarded beyond an endpoint). This provides support for allowing
those types of packets to be matched.

Signed-off-by: Jesse Gross <jesse@nicira.com>
Acked-by: Thomas Graf <tgraf@suug.ch>
Acked-by: Pravin B Shelar <pshelar@nicira.com>
datapath/datapath.c
datapath/flow_netlink.c
datapath/linux/compat/include/net/ip_tunnels.h
include/linux/openvswitch.h
lib/flow.c
lib/flow.h
lib/odp-util.c
lib/odp-util.h

index 351a075..32a4683 100644 (file)
@@ -393,6 +393,7 @@ static size_t key_attr_size(void)
                  + nla_total_size(1)   /* OVS_TUNNEL_KEY_ATTR_TTL */
                  + nla_total_size(0)   /* OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT */
                  + nla_total_size(0)   /* OVS_TUNNEL_KEY_ATTR_CSUM */
+                 + nla_total_size(0)   /* OVS_TUNNEL_KEY_ATTR_OAM */
                + nla_total_size(4)   /* OVS_KEY_ATTR_IN_PORT */
                + nla_total_size(4)   /* OVS_KEY_ATTR_SKB_MARK */
                + nla_total_size(4)   /* OVS_KEY_ATTR_DP_HASH */
index 0048a6e..c5ca2f4 100644 (file)
@@ -347,6 +347,7 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr,
                        [OVS_TUNNEL_KEY_ATTR_TTL] = 1,
                        [OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT] = 0,
                        [OVS_TUNNEL_KEY_ATTR_CSUM] = 0,
+                       [OVS_TUNNEL_KEY_ATTR_OAM] = 0,
                };
 
                if (type > OVS_TUNNEL_KEY_ATTR_MAX) {
@@ -391,6 +392,9 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr,
                case OVS_TUNNEL_KEY_ATTR_CSUM:
                        tun_flags |= TUNNEL_CSUM;
                        break;
+               case OVS_TUNNEL_KEY_ATTR_OAM:
+                       tun_flags |= TUNNEL_OAM;
+                       break;
                default:
                        return -EINVAL;
                }
@@ -448,6 +452,9 @@ static int ipv4_tun_to_nlattr(struct sk_buff *skb,
        if ((output->tun_flags & TUNNEL_CSUM) &&
                nla_put_flag(skb, OVS_TUNNEL_KEY_ATTR_CSUM))
                return -EMSGSIZE;
+       if ((output->tun_flags & TUNNEL_OAM) &&
+               nla_put_flag(skb, OVS_TUNNEL_KEY_ATTR_OAM))
+               return -EMSGSIZE;
 
        nla_nest_end(skb, nla);
        return 0;
index e59f9f3..e2f3c30 100644 (file)
@@ -44,4 +44,8 @@ int iptunnel_xmit(struct rtable *rt,
 int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto);
 
 #endif
+
+/* Not yet upstream */
+#define TUNNEL_OAM     __cpu_to_be16(0x0200)
+
 #endif /* __NET_IP_TUNNELS_H */
index 33423ad..57d40e3 100644 (file)
@@ -340,6 +340,7 @@ enum ovs_tunnel_key_attr {
        OVS_TUNNEL_KEY_ATTR_TTL,                /* u8 Tunnel IP TTL. */
        OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT,      /* No argument, set DF. */
        OVS_TUNNEL_KEY_ATTR_CSUM,               /* No argument. CSUM packet. */
+       OVS_TUNNEL_KEY_ATTR_OAM,                /* No argument, OAM frame. */
        __OVS_TUNNEL_KEY_ATTR_MAX
 };
 
index 1f7f310..88c6ef1 100644 (file)
@@ -687,6 +687,8 @@ flow_tun_flag_to_string(uint32_t flags)
         return "csum";
     case FLOW_TNL_F_KEY:
         return "key";
+    case FLOW_TNL_F_OAM:
+        return "oam";
     default:
         return NULL;
     }
index 139e7f6..7675084 100644 (file)
@@ -58,6 +58,7 @@ BUILD_ASSERT_DECL(FLOW_NW_FRAG_LATER == NX_IP_FRAG_LATER);
 #define FLOW_TNL_F_DONT_FRAGMENT (1 << 0)
 #define FLOW_TNL_F_CSUM (1 << 1)
 #define FLOW_TNL_F_KEY (1 << 2)
+#define FLOW_TNL_F_OAM (1 << 3)
 
 const char *flow_tun_flag_to_string(uint32_t flags);
 
index 3c69ada..8f71c7c 100644 (file)
@@ -832,6 +832,7 @@ tunnel_key_attr_len(int type)
     case OVS_TUNNEL_KEY_ATTR_TTL: return 1;
     case OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT: return 0;
     case OVS_TUNNEL_KEY_ATTR_CSUM: return 0;
+    case OVS_TUNNEL_KEY_ATTR_OAM: return 0;
     case __OVS_TUNNEL_KEY_ATTR_MAX:
         return -1;
     }
@@ -879,6 +880,9 @@ odp_tun_key_from_attr(const struct nlattr *attr, struct flow_tnl *tun)
         case OVS_TUNNEL_KEY_ATTR_CSUM:
             tun->flags |= FLOW_TNL_F_CSUM;
             break;
+        case OVS_TUNNEL_KEY_ATTR_OAM:
+            tun->flags |= FLOW_TNL_F_OAM;
+            break;
         default:
             /* Allow this to show up as unexpected, if there are unknown
              * tunnel attribute, eventually resulting in ODP_FIT_TOO_MUCH. */
@@ -923,6 +927,9 @@ tun_key_to_attr(struct ofpbuf *a, const struct flow_tnl *tun_key)
     if (tun_key->flags & FLOW_TNL_F_CSUM) {
         nl_msg_put_flag(a, OVS_TUNNEL_KEY_ATTR_CSUM);
     }
+    if (tun_key->flags & FLOW_TNL_F_OAM) {
+        nl_msg_put_flag(a, OVS_TUNNEL_KEY_ATTR_OAM);
+    }
 
     nl_msg_end_nested(a, tun_key_ofs);
 }
@@ -949,7 +956,8 @@ odp_mask_attr_is_exact(const struct nlattr *ma)
         odp_tun_key_from_attr(ma, &tun_mask);
         if (tun_mask.flags == (FLOW_TNL_F_KEY
                                | FLOW_TNL_F_DONT_FRAGMENT
-                               | FLOW_TNL_F_CSUM)) {
+                               | FLOW_TNL_F_CSUM
+                               | FLOW_TNL_F_OAM)) {
             /* The flags are exact match, check the remaining fields. */
             tun_mask.flags = 0xffff;
             is_exact = is_all_ones((uint8_t *)&tun_mask,
index aad3098..0e912a4 100644 (file)
@@ -104,6 +104,7 @@ void odp_portno_names_destroy(struct hmap *portno_names);
  *  - OVS_TUNNEL_KEY_ATTR_TTL            1    3      4      8
  *  - OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT  0    --     4      4
  *  - OVS_TUNNEL_KEY_ATTR_CSUM           0    --     4      4
+ *  - OVS_TUNNEL_KEY_ATTR_OAM            0    --     4      4
  *  OVS_KEY_ATTR_IN_PORT                 4    --     4      8
  *  OVS_KEY_ATTR_SKB_MARK                4    --     4      8
  *  OVS_KEY_ATTR_DP_HASH                 4    --     4      8
@@ -117,7 +118,7 @@ void odp_portno_names_destroy(struct hmap *portno_names);
  *  OVS_KEY_ATTR_ICMPV6                  2     2     4      8
  *  OVS_KEY_ATTR_ND                     28    --     4     32
  *  ----------------------------------------------------------
- *  total                                                 224
+ *  total                                                 228
  *
  * We include some slack space in case the calculation isn't quite right or we
  * add another field and forget to adjust this value.