From: Jesse Gross Date: Wed, 28 May 2014 04:50:35 +0000 (-0700) Subject: tunnel: Add support for matching on OAM packets. X-Git-Tag: v2.4.0~1954 X-Git-Url: http://git.cascardo.eti.br/?a=commitdiff_plain;h=94872594b79d1a4a6cfb9434b1c1d1d506b3c57d;p=cascardo%2Fovs.git tunnel: Add support for matching on OAM packets. 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 Acked-by: Thomas Graf Acked-by: Pravin B Shelar --- diff --git a/datapath/datapath.c b/datapath/datapath.c index 351a07563..32a46836d 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -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 */ diff --git a/datapath/flow_netlink.c b/datapath/flow_netlink.c index 0048a6e90..c5ca2f490 100644 --- a/datapath/flow_netlink.c +++ b/datapath/flow_netlink.c @@ -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; diff --git a/datapath/linux/compat/include/net/ip_tunnels.h b/datapath/linux/compat/include/net/ip_tunnels.h index e59f9f356..e2f3c30f4 100644 --- a/datapath/linux/compat/include/net/ip_tunnels.h +++ b/datapath/linux/compat/include/net/ip_tunnels.h @@ -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 */ diff --git a/include/linux/openvswitch.h b/include/linux/openvswitch.h index 33423add1..57d40e383 100644 --- a/include/linux/openvswitch.h +++ b/include/linux/openvswitch.h @@ -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 }; diff --git a/lib/flow.c b/lib/flow.c index 1f7f3100a..88c6ef122 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -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; } diff --git a/lib/flow.h b/lib/flow.h index 139e7f68b..76750843b 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -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); diff --git a/lib/odp-util.c b/lib/odp-util.c index 3c69adaf4..8f71c7c8f 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -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, diff --git a/lib/odp-util.h b/lib/odp-util.h index aad3098cd..0e912a4ad 100644 --- a/lib/odp-util.h +++ b/lib/odp-util.h @@ -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.