@@ -273,6 +273,10 @@ enum {
* TCA_TUNNEL_KEY_ENC_OPTS_GENEVE
* attributes
*/
+ TCA_FLOWER_KEY_ENC_OPTS_VXLAN, /* Nested
+ * TCA_TUNNEL_KEY_ENC_OPTS_VXLAN
+ * attributes
+ */
__TCA_FLOWER_KEY_ENC_OPTS_MAX,
};
@@ -290,6 +294,15 @@ enum {
#define TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX \
(__TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX - 1)
+enum {
+ TCA_FLOWER_KEY_ENC_OPT_VXLAN_UNSPEC,
+ TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP, /* u32 */
+ __TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX,
+};
+
+#define TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX \
+ (__TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX - 1)
+
enum {
TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0),
TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST = (1 << 1),
@@ -1234,6 +1234,15 @@ parse_tc_flower_to_match(const struct netdev *netdev,
match_set_tun_tp_dst_masked(match, flower->key.tunnel.tp_dst,
flower->mask.tunnel.tp_dst);
}
+ if (flower->mask.tunnel.gbp.id) {
+ match_set_tun_gbp_id_masked(match, flower->key.tunnel.gbp.id,
+ flower->mask.tunnel.gbp.id);
+ }
+ if (flower->mask.tunnel.gbp.flags) {
+ match_set_tun_gbp_flags_masked(match,
+ flower->key.tunnel.gbp.flags,
+ flower->mask.tunnel.gbp.flags);
+ }
if (!strcmp(netdev_get_type(netdev), "geneve")) {
flower_tun_opt_to_match(match, flower);
@@ -2193,6 +2202,9 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
flower.key.tunnel.ttl = tnl->ip_ttl;
flower.key.tunnel.tp_src = tnl->tp_src;
flower.key.tunnel.tp_dst = tnl->tp_dst;
+ flower.key.tunnel.gbp.id = tnl->gbp_id;
+ flower.key.tunnel.gbp.flags = tnl->gbp_flags;
+ flower.key.tunnel.gbp.id_present = !!tnl_mask->gbp_id;
flower.mask.tunnel.ipv4.ipv4_src = tnl_mask->ip_src;
flower.mask.tunnel.ipv4.ipv4_dst = tnl_mask->ip_dst;
@@ -2207,6 +2219,9 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
* Degrading the flow down to exact match for now as a workaround. */
flower.mask.tunnel.tp_dst = OVS_BE16_MAX;
flower.mask.tunnel.id = (tnl->flags & FLOW_TNL_F_KEY) ? tnl_mask->tun_id : 0;
+ flower.mask.tunnel.gbp.id = tnl_mask->gbp_id;
+ flower.mask.tunnel.gbp.flags = tnl_mask->gbp_flags;
+ flower.mask.tunnel.gbp.id_present = !!tnl_mask->gbp_id;
memset(&tnl_mask->ip_src, 0, sizeof tnl_mask->ip_src);
memset(&tnl_mask->ip_dst, 0, sizeof tnl_mask->ip_dst);
@@ -2218,6 +2233,8 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
memset(&tnl_mask->tp_dst, 0, sizeof tnl_mask->tp_dst);
memset(&tnl_mask->tun_id, 0, sizeof tnl_mask->tun_id);
+ memset(&tnl_mask->gbp_id, 0, sizeof tnl_mask->gbp_id);
+ memset(&tnl_mask->gbp_flags, 0, sizeof tnl_mask->gbp_flags);
tnl_mask->flags &= ~FLOW_TNL_F_KEY;
/* XXX: This is wrong! We're ignoring DF and CSUM flags configuration
@@ -39,6 +39,7 @@
#include "coverage.h"
#include "netlink-socket.h"
#include "netlink.h"
+#include "odp-util.h"
#include "openvswitch/ofpbuf.h"
#include "openvswitch/util.h"
#include "openvswitch/vlog.h"
@@ -699,6 +700,38 @@ nl_parse_geneve_key(const struct nlattr *in_nlattr,
return 0;
}
+static int
+nl_parse_vxlan_key(const struct nlattr *in_nlattr,
+ struct tc_flower_tunnel *tunnel)
+{
+ const struct ofpbuf *msg;
+ struct nlattr *nla;
+ struct ofpbuf buf;
+ uint32_t gbp_raw;
+ size_t left;
+
+ nl_attr_get_nested(in_nlattr, &buf);
+ msg = &buf;
+
+ NL_ATTR_FOR_EACH (nla, left, ofpbuf_at(msg, 0, 0), msg->size) {
+ uint16_t type = nl_attr_type(nla);
+
+ switch (type) {
+ case TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP:
+ gbp_raw = nl_attr_get_u32(nla);
+ odp_decode_gbp_raw(gbp_raw, &tunnel->gbp.id,
+ &tunnel->gbp.flags);
+ tunnel->gbp.id_present = true;
+ break;
+ default:
+ VLOG_WARN_RL(&error_rl, "failed to parse vxlan tun options");
+ return EINVAL;
+ }
+ }
+
+ return 0;
+}
+
static int
nl_parse_flower_tunnel_opts(struct nlattr *options,
struct tc_flower_tunnel *tunnel)
@@ -721,6 +754,13 @@ nl_parse_flower_tunnel_opts(struct nlattr *options,
return err;
}
+ break;
+ case TCA_FLOWER_KEY_ENC_OPTS_VXLAN:
+ err = nl_parse_vxlan_key(nla, tunnel);
+ if (err) {
+ return err;
+ }
+
break;
}
}
@@ -3445,23 +3485,18 @@ nl_msg_put_masked_value(struct ofpbuf *request, uint16_t type,
}
static void
-nl_msg_put_flower_tunnel_opts(struct ofpbuf *request, uint16_t type,
- struct tc_flower_tunnel *tunnel)
+nl_msg_put_flower_geneve(struct ofpbuf *request,
+ const struct tc_flower_tunnel *tunnel)
{
- struct tun_metadata *metadata = &tunnel->metadata;
- struct geneve_opt *opt;
- size_t outer, inner;
+ const struct tun_metadata *metadata = &tunnel->metadata;
+ const struct geneve_opt *opt;
int len, cnt = 0;
+ size_t offset;
len = metadata->present.len;
- if (!len) {
- return;
- }
-
- outer = nl_msg_start_nested(request, type);
while (len) {
opt = &metadata->opts.gnv[cnt];
- inner = nl_msg_start_nested(request, TCA_FLOWER_KEY_ENC_OPTS_GENEVE);
+ offset = nl_msg_start_nested(request, TCA_FLOWER_KEY_ENC_OPTS_GENEVE);
nl_msg_put_be16(request, TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS,
opt->opt_class);
@@ -3472,8 +3507,41 @@ nl_msg_put_flower_tunnel_opts(struct ofpbuf *request, uint16_t type,
cnt += sizeof(struct geneve_opt) / 4 + opt->length;
len -= sizeof(struct geneve_opt) + opt->length * 4;
- nl_msg_end_nested(request, inner);
+ nl_msg_end_nested(request, offset);
}
+}
+
+static void
+nl_msg_put_flower_vxlan_tun_opts(struct ofpbuf *request,
+ const struct tc_flower_tunnel *tunnel)
+{
+ uint32_t gbp_raw;
+ size_t offset;
+
+ if (!tunnel->gbp.id_present) {
+ return;
+ }
+
+ gbp_raw = odp_encode_gbp_raw(tunnel->gbp.flags, tunnel->gbp.id);
+ offset = nl_msg_start_nested_with_flag(request,
+ TCA_FLOWER_KEY_ENC_OPTS_VXLAN);
+ nl_msg_put_u32(request, TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP, gbp_raw);
+ nl_msg_end_nested(request, offset);
+}
+
+static void
+nl_msg_put_flower_tunnel_opts(struct ofpbuf *request, uint16_t type,
+ struct tc_flower_tunnel *tunnel)
+{
+ size_t outer;
+
+ if (!tunnel->metadata.present.len && !tunnel->gbp.id_present) {
+ return;
+ }
+
+ outer = nl_msg_start_nested(request, type);
+ nl_msg_put_flower_geneve(request, tunnel);
+ nl_msg_put_flower_vxlan_tun_opts(request, tunnel);
nl_msg_end_nested(request, outer);
}
@@ -105,6 +105,12 @@ struct tc_cookie {
size_t len;
};
+struct tc_tunnel_gbp {
+ ovs_be16 id;
+ uint8_t flags;
+ bool id_present;
+};
+
struct tc_flower_tunnel {
struct {
ovs_be32 ipv4_src;
@@ -118,6 +124,7 @@ struct tc_flower_tunnel {
uint8_t ttl;
ovs_be16 tp_src;
ovs_be16 tp_dst;
+ struct tc_tunnel_gbp gbp;
ovs_be64 id;
struct tun_metadata metadata;
};