From 9f7148f9dc03053a4a3231a7cf819c447a178a17 Mon Sep 17 00:00:00 2001 From: Yi Yang Date: Fri, 11 Nov 2016 11:13:18 +0800 Subject: [PATCH 1/8] Enable current VxLAN-gpe work and meet NSH requirements Signed-off-by: Yi Yang --- datapath/flow_netlink.c | 8 +- datapath/linux/compat/include/linux/openvswitch.h | 1 + datapath/linux/compat/include/net/vxlan.h | 1 + datapath/linux/compat/vxlan.c | 4 +- datapath/vport-netdev.c | 3 +- datapath/vport-vxlan.c | 15 ++++ include/openvswitch/match.h | 4 + include/openvswitch/meta-flow.h | 28 +++++++ include/openvswitch/packets.h | 4 +- lib/flow.c | 8 ++ lib/match.c | 34 +++++++++ lib/meta-flow.c | 36 +++++++++ lib/netdev-vport.c | 2 + lib/nx-match.c | 4 + lib/odp-util.c | 89 ++++++++++++++++++++++- tests/ofproto.at | 4 +- tests/ovs-ofctl.at | 4 + 17 files changed, 241 insertions(+), 8 deletions(-) diff --git a/datapath/flow_netlink.c b/datapath/flow_netlink.c index 0f32664..2dcae07 100644 --- a/datapath/flow_netlink.c +++ b/datapath/flow_netlink.c @@ -309,6 +309,7 @@ size_t ovs_key_attr_size(void) static const struct ovs_len_tbl ovs_vxlan_ext_key_lens[OVS_VXLAN_EXT_MAX + 1] = { [OVS_VXLAN_EXT_GBP] = { .len = sizeof(u32) }, + [OVS_VXLAN_EXT_GPE] = { .len = sizeof(u32) }, }; static const struct ovs_len_tbl ovs_tunnel_key_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1] = { @@ -523,6 +524,9 @@ static int vxlan_tun_opt_from_nlattr(const struct nlattr *attr, case OVS_VXLAN_EXT_GBP: opts.gbp = nla_get_u32(a); break; + case OVS_VXLAN_EXT_GPE: + opts.gpe = nla_get_u32(a); + break; default: OVS_NLERR(log, "Unknown VXLAN extension attribute %d", type); @@ -709,7 +713,9 @@ static int vxlan_opt_to_nlattr(struct sk_buff *skb, if (!nla) return -EMSGSIZE; - if (nla_put_u32(skb, OVS_VXLAN_EXT_GBP, opts->gbp) < 0) + if (opts->gbp && nla_put_u32(skb, OVS_VXLAN_EXT_GBP, opts->gbp) < 0) + return -EMSGSIZE; + else if (opts->gpe && nla_put_u32(skb, OVS_VXLAN_EXT_GPE, opts->gpe) < 0) return -EMSGSIZE; nla_nest_end(skb, nla); diff --git a/datapath/linux/compat/include/linux/openvswitch.h b/datapath/linux/compat/include/linux/openvswitch.h index 12260d8..44b7ce4 100644 --- a/datapath/linux/compat/include/linux/openvswitch.h +++ b/datapath/linux/compat/include/linux/openvswitch.h @@ -291,6 +291,7 @@ enum ovs_vport_attr { enum { OVS_VXLAN_EXT_UNSPEC, OVS_VXLAN_EXT_GBP, /* Flag or __u32 */ + OVS_VXLAN_EXT_GPE, __OVS_VXLAN_EXT_MAX, }; diff --git a/datapath/linux/compat/include/net/vxlan.h b/datapath/linux/compat/include/net/vxlan.h index 5bc8969..5a994b2 100644 --- a/datapath/linux/compat/include/net/vxlan.h +++ b/datapath/linux/compat/include/net/vxlan.h @@ -201,6 +201,7 @@ reserved_flags2:2; struct vxlan_metadata { u32 gbp; + u32 gpe; }; /* per UDP socket information */ diff --git a/datapath/linux/compat/vxlan.c b/datapath/linux/compat/vxlan.c index d5dbe8d..a80610b 100644 --- a/datapath/linux/compat/vxlan.c +++ b/datapath/linux/compat/vxlan.c @@ -705,7 +705,6 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb) if (vs->flags & VXLAN_F_GPE) { if (!vxlan_parse_gpe_hdr(&unparsed, &protocol, skb, vs->flags)) goto drop; - raw_proto = true; } if (__iptunnel_pull_header(skb, VXLAN_HLEN, protocol, raw_proto, @@ -896,10 +895,9 @@ static int vxlan_build_skb(struct sk_buff *skb, struct dst_entry *dst, if (vxflags & VXLAN_F_GBP) vxlan_build_gbp_hdr(vxh, vxflags, md); if (vxflags & VXLAN_F_GPE) { - err = vxlan_build_gpe_hdr(vxh, vxflags, skb->protocol); + err = vxlan_build_gpe_hdr(vxh, vxflags, inner_protocol); if (err < 0) goto out_free; - inner_protocol = skb->protocol; } ovs_skb_set_inner_protocol(skb, inner_protocol); diff --git a/datapath/vport-netdev.c b/datapath/vport-netdev.c index 970f7d3..0ee076b 100644 --- a/datapath/vport-netdev.c +++ b/datapath/vport-netdev.c @@ -102,7 +102,8 @@ struct vport *ovs_netdev_link(struct vport *vport, const char *name) } if (vport->dev->flags & IFF_LOOPBACK || - vport->dev->type != ARPHRD_ETHER || + (vport->dev->type != ARPHRD_ETHER && + vport->dev->type != ARPHRD_NONE) || ovs_is_internal_dev(vport->dev)) { err = -EINVAL; goto error_put; diff --git a/datapath/vport-vxlan.c b/datapath/vport-vxlan.c index 11965c0..e32c970 100644 --- a/datapath/vport-vxlan.c +++ b/datapath/vport-vxlan.c @@ -52,6 +52,18 @@ static int vxlan_get_options(const struct vport *vport, struct sk_buff *skb) return -EMSGSIZE; nla_nest_end(skb, exts); + } else if (vxlan->flags & VXLAN_F_GPE) { + struct nlattr *exts; + + exts = nla_nest_start(skb, OVS_TUNNEL_ATTR_EXTENSION); + if (!exts) + return -EMSGSIZE; + + if (vxlan->flags & VXLAN_F_GPE && + nla_put_flag(skb, OVS_VXLAN_EXT_GPE)) + return -EMSGSIZE; + + nla_nest_end(skb, exts); } return 0; @@ -59,6 +71,7 @@ static int vxlan_get_options(const struct vport *vport, struct sk_buff *skb) static const struct nla_policy exts_policy[OVS_VXLAN_EXT_MAX + 1] = { [OVS_VXLAN_EXT_GBP] = { .type = NLA_FLAG, }, + [OVS_VXLAN_EXT_GPE] = { .type = NLA_FLAG, }, }; static int vxlan_configure_exts(struct vport *vport, struct nlattr *attr, @@ -76,6 +89,8 @@ static int vxlan_configure_exts(struct vport *vport, struct nlattr *attr, if (exts[OVS_VXLAN_EXT_GBP]) conf->flags |= VXLAN_F_GBP; + else if (exts[OVS_VXLAN_EXT_GPE]) + conf->flags |= VXLAN_F_GPE; return 0; } diff --git a/include/openvswitch/match.h b/include/openvswitch/match.h index 3b7f32f..93af1b8 100644 --- a/include/openvswitch/match.h +++ b/include/openvswitch/match.h @@ -89,6 +89,10 @@ void match_set_tun_gbp_id_masked(struct match *match, ovs_be16 gbp_id, ovs_be16 void match_set_tun_gbp_id(struct match *match, ovs_be16 gbp_id); void match_set_tun_gbp_flags_masked(struct match *match, uint8_t flags, uint8_t mask); void match_set_tun_gbp_flags(struct match *match, uint8_t flags); +void match_set_tun_gpe_np_masked(struct match *match, uint8_t gpe_np, uint8_t mask); +void match_set_tun_gpe_np(struct match *match, uint8_t gpe_np); +void match_set_tun_gpe_flags_masked(struct match *match, uint8_t flags, uint8_t mask); +void match_set_tun_gpe_flags(struct match *match, uint8_t flags); void match_set_in_port(struct match *, ofp_port_t ofp_port); void match_set_pkt_mark(struct match *, uint32_t pkt_mark); void match_set_pkt_mark_masked(struct match *, uint32_t pkt_mark, uint32_t mask); diff --git a/include/openvswitch/meta-flow.h b/include/openvswitch/meta-flow.h index b091c1b..9e569ef 100644 --- a/include/openvswitch/meta-flow.h +++ b/include/openvswitch/meta-flow.h @@ -493,6 +493,34 @@ enum OVS_PACKED_ENUM mf_field_id { */ MFF_TUN_GBP_FLAGS, + /* "tun_gpe_np". + * + * VXLAN Generic Protocol Extension next_proto + * + * Type: u8. + * Maskable: bitwise. + * Formatting: hexadecimal. + * Prerequisites: none. + * Access: read/write. + * NXM: NXM_NX_TUN_GPE_NP(200) since v2.4. + * OXM: none. + */ + MFF_TUN_GPE_NP, + + /* "tun_gpe_flags". + * + * VXLAN Generic Protocol Extension flag + * + * Type: u8. + * Maskable: bitwise. + * Formatting: hexadecimal. + * Prerequisites: none. + * Access: read/write. + * NXM: NXM_NX_TUN_GPE_FLAGS(201) since v2.4. + * OXM: none. + */ + MFF_TUN_GPE_FLAGS, + #if TUN_METADATA_NUM_OPTS == 64 /* "tun_metadata". * diff --git a/include/openvswitch/packets.h b/include/openvswitch/packets.h index 5d97309..1e82df0 100644 --- a/include/openvswitch/packets.h +++ b/include/openvswitch/packets.h @@ -34,7 +34,9 @@ struct flow_tnl { ovs_be16 tp_dst; ovs_be16 gbp_id; uint8_t gbp_flags; - uint8_t pad1[5]; /* Pad to 64 bits. */ + uint8_t gpe_np; + uint8_t gpe_flags; + uint8_t pad1[3]; /* Pad to 64 bits. */ struct tun_metadata metadata; }; diff --git a/lib/flow.c b/lib/flow.c index ba4f8c7..375979b 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -897,6 +897,12 @@ flow_get_metadata(const struct flow *flow, struct match *flow_metadata) if (flow->tunnel.gbp_flags) { match_set_tun_gbp_flags(flow_metadata, flow->tunnel.gbp_flags); } + if (flow->tunnel.gpe_np != htons(0)) { + match_set_tun_gpe_np(flow_metadata, flow->tunnel.gpe_np); + } + if (flow->tunnel.gpe_flags) { + match_set_tun_gpe_flags(flow_metadata, flow->tunnel.gpe_flags); + } tun_metadata_get_fmd(&flow->tunnel, flow_metadata); if (flow->metadata != htonll(0)) { match_set_metadata(flow_metadata, flow->metadata); @@ -1292,6 +1298,8 @@ void flow_wildcards_init_for_packet(struct flow_wildcards *wc, WC_MASK_FIELD(wc, tunnel.tp_dst); WC_MASK_FIELD(wc, tunnel.gbp_id); WC_MASK_FIELD(wc, tunnel.gbp_flags); + WC_MASK_FIELD(wc, tunnel.gpe_np); + WC_MASK_FIELD(wc, tunnel.gpe_flags); if (!(flow->tunnel.flags & FLOW_TNL_F_UDPIF)) { if (flow->tunnel.metadata.present.map) { diff --git a/lib/match.c b/lib/match.c index d78e6a1..f19648d 100644 --- a/lib/match.c +++ b/lib/match.c @@ -305,6 +305,32 @@ match_set_tun_gbp_flags(struct match *match, uint8_t flags) } void +match_set_tun_gpe_np_masked(struct match *match, uint8_t np, uint8_t mask) +{ + match->wc.masks.tunnel.gpe_np = mask; + match->flow.tunnel.gpe_np = np & mask; +} + +void +match_set_tun_gpe_np(struct match *match, uint8_t np) +{ + match_set_tun_gpe_np_masked(match, np, UINT8_MAX); +} + +void +match_set_tun_gpe_flags_masked(struct match *match, uint8_t flags, uint8_t mask) +{ + match->wc.masks.tunnel.gpe_flags = mask; + match->flow.tunnel.gpe_flags = flags & mask; +} + +void +match_set_tun_gpe_flags(struct match *match, uint8_t flags) +{ + match_set_tun_gpe_flags_masked(match, flags, UINT8_MAX); +} + +void match_set_in_port(struct match *match, ofp_port_t ofp_port) { match->wc.masks.in_port.ofp_port = u16_to_ofp(UINT16_MAX); @@ -1029,6 +1055,14 @@ format_flow_tunnel(struct ds *s, const struct match *match) ds_put_format(s, "tun_gbp_flags=%#"PRIx8",", tnl->gbp_flags); } + if (wc->masks.tunnel.gpe_np) { + ds_put_format(s, "tun_gpe_np=%#"PRIx8",", tnl->gpe_np); + } + + if (wc->masks.tunnel.gpe_flags) { + ds_put_format(s, "tun_gpe_flags=%#"PRIx8",", tnl->gpe_flags); + } + if (wc->masks.tunnel.ip_tos) { ds_put_format(s, "tun_tos=%"PRIx8",", tnl->ip_tos); } diff --git a/lib/meta-flow.c b/lib/meta-flow.c index d07f927..5d0721f 100644 --- a/lib/meta-flow.c +++ b/lib/meta-flow.c @@ -213,6 +213,10 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc) return !wc->masks.tunnel.gbp_id; case MFF_TUN_GBP_FLAGS: return !wc->masks.tunnel.gbp_flags; + case MFF_TUN_GPE_NP: + return !wc->masks.tunnel.gpe_np; + case MFF_TUN_GPE_FLAGS: + return !wc->masks.tunnel.gpe_flags; CASE_MFF_TUN_METADATA: return !ULLONG_GET(wc->masks.tunnel.metadata.present.map, mf->id - MFF_TUN_METADATA0); @@ -434,6 +438,8 @@ mf_is_value_valid(const struct mf_field *mf, const union mf_value *value) case MFF_TUN_TTL: case MFF_TUN_GBP_ID: case MFF_TUN_GBP_FLAGS: + case MFF_TUN_GPE_NP: + case MFF_TUN_GPE_FLAGS: CASE_MFF_TUN_METADATA: case MFF_METADATA: case MFF_IN_PORT: @@ -568,6 +574,12 @@ mf_get_value(const struct mf_field *mf, const struct flow *flow, case MFF_TUN_GBP_FLAGS: value->u8 = flow->tunnel.gbp_flags; break; + case MFF_TUN_GPE_NP: + value->u8 = flow->tunnel.gpe_np; + break; + case MFF_TUN_GPE_FLAGS: + value->u8 = flow->tunnel.gpe_flags; + break; case MFF_TUN_TTL: value->u8 = flow->tunnel.ip_ttl; break; @@ -823,6 +835,12 @@ mf_set_value(const struct mf_field *mf, case MFF_TUN_GBP_FLAGS: match_set_tun_gbp_flags(match, value->u8); break; + case MFF_TUN_GPE_NP: + match_set_tun_gpe_np(match, value->u8); + break; + case MFF_TUN_GPE_FLAGS: + match_set_tun_gpe_flags(match, value->u8); + break; case MFF_TUN_TOS: match_set_tun_tos(match, value->u8); break; @@ -1161,6 +1179,12 @@ mf_set_flow_value(const struct mf_field *mf, case MFF_TUN_GBP_FLAGS: flow->tunnel.gbp_flags = value->u8; break; + case MFF_TUN_GPE_NP: + flow->tunnel.gpe_np= value->u8; + break; + case MFF_TUN_GPE_FLAGS: + flow->tunnel.gpe_flags= value->u8; + break; case MFF_TUN_TOS: flow->tunnel.ip_tos = value->u8; break; @@ -1484,6 +1508,12 @@ mf_set_wild(const struct mf_field *mf, struct match *match, char **err_str) case MFF_TUN_GBP_FLAGS: match_set_tun_gbp_flags_masked(match, 0, 0); break; + case MFF_TUN_GPE_NP: + match_set_tun_gpe_np_masked(match, 0, 0); + break; + case MFF_TUN_GPE_FLAGS: + match_set_tun_gpe_flags_masked(match, 0, 0); + break; case MFF_TUN_TOS: match_set_tun_tos_masked(match, 0, 0); break; @@ -1793,6 +1823,12 @@ mf_set(const struct mf_field *mf, case MFF_TUN_GBP_FLAGS: match_set_tun_gbp_flags_masked(match, value->u8, mask->u8); break; + case MFF_TUN_GPE_NP: + match_set_tun_gpe_np_masked(match, value->u8, mask->u8); + break; + case MFF_TUN_GPE_FLAGS: + match_set_tun_gpe_flags_masked(match, value->u8, mask->u8); + break; case MFF_TUN_TTL: match_set_tun_ttl_masked(match, value->u8, mask->u8); break; diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c index ac31da6..cff0f5c 100644 --- a/lib/netdev-vport.c +++ b/lib/netdev-vport.c @@ -526,6 +526,8 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args) while (ext) { if (!strcmp(type, "vxlan") && !strcmp(ext, "gbp")) { tnl_cfg.exts |= (1 << OVS_VXLAN_EXT_GBP); + } else if (!strcmp(type, "vxlan") && !strcmp(ext, "gpe")) { + tnl_cfg.exts |= (1 << OVS_VXLAN_EXT_GPE); } else { VLOG_WARN("%s: unknown extension '%s'", name, ext); } diff --git a/lib/nx-match.c b/lib/nx-match.c index b03ccf2..65d7ee3 100644 --- a/lib/nx-match.c +++ b/lib/nx-match.c @@ -1036,6 +1036,10 @@ nx_put_raw(struct ofpbuf *b, enum ofp_version oxm, const struct match *match, flow->tunnel.gbp_id, match->wc.masks.tunnel.gbp_id); nxm_put_8m(b, MFF_TUN_GBP_FLAGS, oxm, flow->tunnel.gbp_flags, match->wc.masks.tunnel.gbp_flags); + nxm_put_8m(b, MFF_TUN_GPE_NP, oxm, + flow->tunnel.gpe_np, match->wc.masks.tunnel.gpe_np); + nxm_put_8m(b, MFF_TUN_GPE_FLAGS, oxm, + flow->tunnel.gpe_flags, match->wc.masks.tunnel.gpe_flags); tun_metadata_to_nx_match(b, oxm, match); /* Registers. */ diff --git a/lib/odp-util.c b/lib/odp-util.c index 6d29b67..b9e8aa7 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -1755,6 +1755,7 @@ odp_actions_from_string(const char *s, const struct simap *port_names, static const struct attr_len_tbl ovs_vxlan_ext_attr_lens[OVS_VXLAN_EXT_MAX + 1] = { [OVS_VXLAN_EXT_GBP] = { .len = 4 }, + [OVS_VXLAN_EXT_GPE] = { .len = 4 }, }; static const struct attr_len_tbl ovs_tun_key_attr_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1] = { @@ -1916,7 +1917,10 @@ odp_tun_key_from_attr__(const struct nlattr *attr, break; case OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS: { static const struct nl_policy vxlan_opts_policy[] = { - [OVS_VXLAN_EXT_GBP] = { .type = NL_A_U32 }, + [OVS_VXLAN_EXT_GBP] = { .type = NL_A_U32 , + .optional = true }, + [OVS_VXLAN_EXT_GPE] = { .type = NL_A_U32 , + .optional = true }, }; struct nlattr *ext[ARRAY_SIZE(vxlan_opts_policy)]; @@ -1930,6 +1934,12 @@ odp_tun_key_from_attr__(const struct nlattr *attr, tun->gbp_id = htons(gbp & 0xFFFF); tun->gbp_flags = (gbp >> 16) & 0xFF; } + if (ext[OVS_VXLAN_EXT_GPE]) { + uint32_t gpe = nl_attr_get_u32(ext[OVS_VXLAN_EXT_GPE]); + + tun->gpe_np = gpe & 0xFF; + tun->gpe_flags = gpe >> 24; + } break; } @@ -2016,6 +2026,13 @@ tun_key_to_attr(struct ofpbuf *a, const struct flow_tnl *tun_key, nl_msg_put_u32(a, OVS_VXLAN_EXT_GBP, (tun_key->gbp_flags << 16) | ntohs(tun_key->gbp_id)); nl_msg_end_nested(a, vxlan_opts_ofs); + } else if (tun_key->gpe_flags || tun_key->gpe_np) { + size_t vxlan_opts_ofs; + + vxlan_opts_ofs = nl_msg_start_nested(a, OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS); + nl_msg_put_u32(a, OVS_VXLAN_EXT_GPE, + (tun_key->gpe_flags << 24) | (tun_key->gpe_np)); + nl_msg_end_nested(a, vxlan_opts_ofs); } tun_metadata_to_geneve_nlattr(tun_key, tun_flow_key, key_buf, a); @@ -2410,6 +2427,26 @@ format_odp_tun_vxlan_opt(const struct nlattr *attr, ds_put_cstr(ds, "),"); break; } + case OVS_VXLAN_EXT_GPE: { + uint32_t key = nl_attr_get_u32(a); + uint8_t np, np_mask; + uint8_t flags, flags_mask; + + np = key & 0xFF; + flags = (key >> 24) & 0xFF; + if (ma) { + uint32_t mask = nl_attr_get_u32(ma); + np_mask = mask & 0xFF; + flags_mask = (mask >> 24) & 0xFF; + } + + ds_put_cstr(ds, "gpe("); + format_u8x(ds, "np", np, ma ? &np_mask : NULL, verbose); + format_u8x(ds, "flags", flags, ma ? &flags_mask : NULL, verbose); + ds_chomp(ds, ','); + ds_put_cstr(ds, "),"); + break; + } default: format_unknown_key(ds, a, ma); @@ -3705,6 +3742,40 @@ scan_vxlan_gbp(const char *s, uint32_t *key, uint32_t *mask) } static int +scan_vxlan_gpe(const char *s, uint32_t *key, uint32_t *mask) +{ + const char *s_base = s; + uint8_t np = 0, np_mask = 0; + uint8_t flags = 0, flags_mask = 0; + + if (!strncmp(s, "np=", 3)) { + s += 3; + s += scan_u8(s, &np, mask ? &np_mask : NULL); + } + + if (s[0] == ',') { + s++; + } + if (!strncmp(s, "flags=", 6)) { + s += 6; + s += scan_u8(s, &flags, mask ? &flags_mask : NULL); + } + + if (!strncmp(s, "))", 2)) { + s += 2; + + *key = (flags << 24) | np; + if (mask) { + *mask = (flags_mask << 24) | np_mask; + } + + return s - s_base; + } + + return 0; +} + +static int scan_geneve(const char *s, struct geneve_scan *key, struct geneve_scan *mask) { const char *s_base = s; @@ -3831,6 +3902,21 @@ vxlan_gbp_to_attr(struct ofpbuf *a, const void *data_) } static void +vxlan_gpe_to_attr(struct ofpbuf *a, const void *data_) +{ + const uint32_t *gpe = data_; + + if (*gpe) { + size_t vxlan_opts_ofs; + + vxlan_opts_ofs = nl_msg_start_nested(a, OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS); + nl_msg_put_u32(a, OVS_VXLAN_EXT_GPE, *gpe); + nl_msg_end_nested(a, vxlan_opts_ofs); + } +} + + +static void geneve_to_attr(struct ofpbuf *a, const void *data_) { const struct geneve_scan *geneve = data_; @@ -4066,6 +4152,7 @@ parse_odp_key_mask_attr(const char *s, const struct simap *port_names, SCAN_FIELD_NESTED("tp_src=", ovs_be16, be16, OVS_TUNNEL_KEY_ATTR_TP_SRC); SCAN_FIELD_NESTED("tp_dst=", ovs_be16, be16, OVS_TUNNEL_KEY_ATTR_TP_DST); SCAN_FIELD_NESTED_FUNC("vxlan(gbp(", uint32_t, vxlan_gbp, vxlan_gbp_to_attr); + SCAN_FIELD_NESTED_FUNC("vxlan(gpe(", uint32_t, vxlan_gpe, vxlan_gpe_to_attr); SCAN_FIELD_NESTED_FUNC("geneve(", struct geneve_scan, geneve, geneve_to_attr); SCAN_FIELD_NESTED_FUNC("flags(", uint16_t, tun_flags, tun_flags_to_attr); diff --git a/tests/ofproto.at b/tests/ofproto.at index 6e55270..7b7f02b 100644 --- a/tests/ofproto.at +++ b/tests/ofproto.at @@ -2190,7 +2190,7 @@ head_table () { instructions: meter,apply_actions,clear_actions,write_actions,write_metadata,goto_table Write-Actions and Apply-Actions features: actions: output group set_field strip_vlan push_vlan mod_nw_ttl dec_ttl set_mpls_ttl dec_mpls_ttl push_mpls pop_mpls set_queue - supported on Set-Field: tun_id tun_src tun_dst tun_ipv6_src tun_ipv6_dst tun_flags tun_gbp_id tun_gbp_flags tun_metadata0 dnl + supported on Set-Field: tun_id tun_src tun_dst tun_ipv6_src tun_ipv6_dst tun_flags tun_gbp_id tun_gbp_flags tun_gpe_np tun_gpe_flags tun_metadata0 dnl tun_metadata1 tun_metadata2 tun_metadata3 tun_metadata4 tun_metadata5 tun_metadata6 tun_metadata7 tun_metadata8 tun_metadata9 tun_metadata10 tun_metadata11 tun_metadata12 tun_metadata13 tun_metadata14 tun_metadata15 tun_metadata16 tun_metadata17 tun_metadata18 tun_metadata19 tun_metadata20 tun_metadata21 tun_metadata22 tun_metadata23 tun_metadata24 tun_metadata25 tun_metadata26 tun_metadata27 tun_metadata28 tun_metadata29 tun_metadata30 tun_metadata31 tun_metadata32 tun_metadata33 tun_metadata34 tun_metadata35 tun_metadata36 tun_metadata37 tun_metadata38 tun_metadata39 tun_metadata40 tun_metadata41 tun_metadata42 tun_metadata43 tun_metadata44 tun_metadata45 tun_metadata46 tun_metadata47 tun_metadata48 tun_metadata49 tun_metadata50 tun_metadata51 tun_metadata52 tun_metadata53 tun_metadata54 tun_metadata55 tun_metadata56 tun_metadata57 tun_metadata58 tun_metadata59 tun_metadata60 tun_metadata61 tun_metadata62 tun_metadata63 dnl metadata in_port in_port_oxm pkt_mark ct_mark ct_label reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 reg10 reg11 reg12 reg13 reg14 reg15 xreg0 xreg1 xreg2 xreg3 xreg4 xreg5 xreg6 xreg7 xxreg0 xxreg1 xxreg2 xxreg3 eth_src eth_dst vlan_tci vlan_vid vlan_pcp mpls_label mpls_tc mpls_ttl ip_src ip_dst ipv6_src ipv6_dst ipv6_label nw_tos ip_dscp nw_ecn nw_ttl arp_op arp_spa arp_tpa arp_sha arp_tha tcp_src tcp_dst udp_src udp_dst sctp_src sctp_dst icmp_type icmp_code icmpv6_type icmpv6_code nd_target nd_sll nd_tll matching: @@ -2205,6 +2205,8 @@ metadata in_port in_port_oxm pkt_mark ct_mark ct_label reg0 reg1 reg2 reg3 reg4 tun_flags: arbitrary mask tun_gbp_id: arbitrary mask tun_gbp_flags: arbitrary mask + tun_gpe_np: arbitrary mask + tun_gpe_flags: arbitrary mask tun_metadata0: arbitrary mask tun_metadata1: arbitrary mask tun_metadata2: arbitrary mask diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at index cbb818e..2267be0 100644 --- a/tests/ovs-ofctl.at +++ b/tests/ovs-ofctl.at @@ -17,6 +17,10 @@ for test_case in \ 'tun_gbp_id=0/0x1 NXM,OXM' \ 'tun_gbp_flags=0 NXM,OXM' \ 'tun_gbp_flags=0/0x1 NXM,OXM' \ + 'tun_gpe_np=0 NXM,OXM' \ + 'tun_gpe_np=0/0x1 NXM,OXM' \ + 'tun_gpe_flags=0 NXM,OXM' \ + 'tun_gpe_flags=0/0x1 NXM,OXM' \ 'tun_metadata0=0 NXM,OXM' \ 'tun_metadata0=0/0x1 NXM,OXM' \ 'tun_metadata0 NXM,OXM' \ -- 2.1.0