summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--datapath/datapath.c1
-rw-r--r--datapath/flow_netlink.c7
-rw-r--r--datapath/linux/compat/include/net/ip_tunnels.h4
-rw-r--r--include/linux/openvswitch.h1
-rw-r--r--lib/flow.c2
-rw-r--r--lib/flow.h1
-rw-r--r--lib/odp-util.c10
-rw-r--r--lib/odp-util.h3
8 files changed, 27 insertions, 2 deletions
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.