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 <je...@nicira.com> --- datapath/flow_netlink.c | 7 +++++++ datapath/linux/compat/include/net/ip_tunnels.h | 4 ++++ include/linux/openvswitch.h | 1 + lib/flow.c | 2 ++ lib/flow.h | 1 + lib/odp-util.c | 10 +++++++++- 6 files changed, 24 insertions(+), 1 deletion(-) diff --git a/datapath/flow_netlink.c b/datapath/flow_netlink.c index 0048a6e..c5ca2f4 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 e59f9f3..e2f3c30 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 33423ad..57d40e3 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 1f7f310..88c6ef1 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 139e7f6..7675084 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 3c69ada..8f71c7c 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, -- 1.9.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev