Fuel plugin to deploy OVS with NSH and DPDK
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

0001-Enable-current-VxLAN-gpe-work-and-meet-NSH-requireme.patch 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. From 9f7148f9dc03053a4a3231a7cf819c447a178a17 Mon Sep 17 00:00:00 2001
  2. From: Yi Yang <yi.y.yang@intel.com>
  3. Date: Fri, 11 Nov 2016 11:13:18 +0800
  4. Subject: [PATCH 1/8] Enable current VxLAN-gpe work and meet NSH requirements
  5. Signed-off-by: Yi Yang <yi.y.yang@intel.com>
  6. ---
  7. datapath/flow_netlink.c | 8 +-
  8. datapath/linux/compat/include/linux/openvswitch.h | 1 +
  9. datapath/linux/compat/include/net/vxlan.h | 1 +
  10. datapath/linux/compat/vxlan.c | 4 +-
  11. datapath/vport-netdev.c | 3 +-
  12. datapath/vport-vxlan.c | 15 ++++
  13. include/openvswitch/match.h | 4 +
  14. include/openvswitch/meta-flow.h | 28 +++++++
  15. include/openvswitch/packets.h | 4 +-
  16. lib/flow.c | 8 ++
  17. lib/match.c | 34 +++++++++
  18. lib/meta-flow.c | 36 +++++++++
  19. lib/netdev-vport.c | 2 +
  20. lib/nx-match.c | 4 +
  21. lib/odp-util.c | 89 ++++++++++++++++++++++-
  22. tests/ofproto.at | 4 +-
  23. tests/ovs-ofctl.at | 4 +
  24. 17 files changed, 241 insertions(+), 8 deletions(-)
  25. diff --git a/datapath/flow_netlink.c b/datapath/flow_netlink.c
  26. index 0f32664..2dcae07 100644
  27. --- a/datapath/flow_netlink.c
  28. +++ b/datapath/flow_netlink.c
  29. @@ -309,6 +309,7 @@ size_t ovs_key_attr_size(void)
  30. static const struct ovs_len_tbl ovs_vxlan_ext_key_lens[OVS_VXLAN_EXT_MAX + 1] = {
  31. [OVS_VXLAN_EXT_GBP] = { .len = sizeof(u32) },
  32. + [OVS_VXLAN_EXT_GPE] = { .len = sizeof(u32) },
  33. };
  34. static const struct ovs_len_tbl ovs_tunnel_key_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1] = {
  35. @@ -523,6 +524,9 @@ static int vxlan_tun_opt_from_nlattr(const struct nlattr *attr,
  36. case OVS_VXLAN_EXT_GBP:
  37. opts.gbp = nla_get_u32(a);
  38. break;
  39. + case OVS_VXLAN_EXT_GPE:
  40. + opts.gpe = nla_get_u32(a);
  41. + break;
  42. default:
  43. OVS_NLERR(log, "Unknown VXLAN extension attribute %d",
  44. type);
  45. @@ -709,7 +713,9 @@ static int vxlan_opt_to_nlattr(struct sk_buff *skb,
  46. if (!nla)
  47. return -EMSGSIZE;
  48. - if (nla_put_u32(skb, OVS_VXLAN_EXT_GBP, opts->gbp) < 0)
  49. + if (opts->gbp && nla_put_u32(skb, OVS_VXLAN_EXT_GBP, opts->gbp) < 0)
  50. + return -EMSGSIZE;
  51. + else if (opts->gpe && nla_put_u32(skb, OVS_VXLAN_EXT_GPE, opts->gpe) < 0)
  52. return -EMSGSIZE;
  53. nla_nest_end(skb, nla);
  54. diff --git a/datapath/linux/compat/include/linux/openvswitch.h b/datapath/linux/compat/include/linux/openvswitch.h
  55. index 12260d8..44b7ce4 100644
  56. --- a/datapath/linux/compat/include/linux/openvswitch.h
  57. +++ b/datapath/linux/compat/include/linux/openvswitch.h
  58. @@ -291,6 +291,7 @@ enum ovs_vport_attr {
  59. enum {
  60. OVS_VXLAN_EXT_UNSPEC,
  61. OVS_VXLAN_EXT_GBP, /* Flag or __u32 */
  62. + OVS_VXLAN_EXT_GPE,
  63. __OVS_VXLAN_EXT_MAX,
  64. };
  65. diff --git a/datapath/linux/compat/include/net/vxlan.h b/datapath/linux/compat/include/net/vxlan.h
  66. index 5bc8969..5a994b2 100644
  67. --- a/datapath/linux/compat/include/net/vxlan.h
  68. +++ b/datapath/linux/compat/include/net/vxlan.h
  69. @@ -201,6 +201,7 @@ reserved_flags2:2;
  70. struct vxlan_metadata {
  71. u32 gbp;
  72. + u32 gpe;
  73. };
  74. /* per UDP socket information */
  75. diff --git a/datapath/linux/compat/vxlan.c b/datapath/linux/compat/vxlan.c
  76. index d5dbe8d..a80610b 100644
  77. --- a/datapath/linux/compat/vxlan.c
  78. +++ b/datapath/linux/compat/vxlan.c
  79. @@ -705,7 +705,6 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
  80. if (vs->flags & VXLAN_F_GPE) {
  81. if (!vxlan_parse_gpe_hdr(&unparsed, &protocol, skb, vs->flags))
  82. goto drop;
  83. - raw_proto = true;
  84. }
  85. if (__iptunnel_pull_header(skb, VXLAN_HLEN, protocol, raw_proto,
  86. @@ -896,10 +895,9 @@ static int vxlan_build_skb(struct sk_buff *skb, struct dst_entry *dst,
  87. if (vxflags & VXLAN_F_GBP)
  88. vxlan_build_gbp_hdr(vxh, vxflags, md);
  89. if (vxflags & VXLAN_F_GPE) {
  90. - err = vxlan_build_gpe_hdr(vxh, vxflags, skb->protocol);
  91. + err = vxlan_build_gpe_hdr(vxh, vxflags, inner_protocol);
  92. if (err < 0)
  93. goto out_free;
  94. - inner_protocol = skb->protocol;
  95. }
  96. ovs_skb_set_inner_protocol(skb, inner_protocol);
  97. diff --git a/datapath/vport-netdev.c b/datapath/vport-netdev.c
  98. index 970f7d3..0ee076b 100644
  99. --- a/datapath/vport-netdev.c
  100. +++ b/datapath/vport-netdev.c
  101. @@ -102,7 +102,8 @@ struct vport *ovs_netdev_link(struct vport *vport, const char *name)
  102. }
  103. if (vport->dev->flags & IFF_LOOPBACK ||
  104. - vport->dev->type != ARPHRD_ETHER ||
  105. + (vport->dev->type != ARPHRD_ETHER &&
  106. + vport->dev->type != ARPHRD_NONE) ||
  107. ovs_is_internal_dev(vport->dev)) {
  108. err = -EINVAL;
  109. goto error_put;
  110. diff --git a/datapath/vport-vxlan.c b/datapath/vport-vxlan.c
  111. index 11965c0..e32c970 100644
  112. --- a/datapath/vport-vxlan.c
  113. +++ b/datapath/vport-vxlan.c
  114. @@ -52,6 +52,18 @@ static int vxlan_get_options(const struct vport *vport, struct sk_buff *skb)
  115. return -EMSGSIZE;
  116. nla_nest_end(skb, exts);
  117. + } else if (vxlan->flags & VXLAN_F_GPE) {
  118. + struct nlattr *exts;
  119. +
  120. + exts = nla_nest_start(skb, OVS_TUNNEL_ATTR_EXTENSION);
  121. + if (!exts)
  122. + return -EMSGSIZE;
  123. +
  124. + if (vxlan->flags & VXLAN_F_GPE &&
  125. + nla_put_flag(skb, OVS_VXLAN_EXT_GPE))
  126. + return -EMSGSIZE;
  127. +
  128. + nla_nest_end(skb, exts);
  129. }
  130. return 0;
  131. @@ -59,6 +71,7 @@ static int vxlan_get_options(const struct vport *vport, struct sk_buff *skb)
  132. static const struct nla_policy exts_policy[OVS_VXLAN_EXT_MAX + 1] = {
  133. [OVS_VXLAN_EXT_GBP] = { .type = NLA_FLAG, },
  134. + [OVS_VXLAN_EXT_GPE] = { .type = NLA_FLAG, },
  135. };
  136. static int vxlan_configure_exts(struct vport *vport, struct nlattr *attr,
  137. @@ -76,6 +89,8 @@ static int vxlan_configure_exts(struct vport *vport, struct nlattr *attr,
  138. if (exts[OVS_VXLAN_EXT_GBP])
  139. conf->flags |= VXLAN_F_GBP;
  140. + else if (exts[OVS_VXLAN_EXT_GPE])
  141. + conf->flags |= VXLAN_F_GPE;
  142. return 0;
  143. }
  144. diff --git a/include/openvswitch/match.h b/include/openvswitch/match.h
  145. index 3b7f32f..93af1b8 100644
  146. --- a/include/openvswitch/match.h
  147. +++ b/include/openvswitch/match.h
  148. @@ -89,6 +89,10 @@ void match_set_tun_gbp_id_masked(struct match *match, ovs_be16 gbp_id, ovs_be16
  149. void match_set_tun_gbp_id(struct match *match, ovs_be16 gbp_id);
  150. void match_set_tun_gbp_flags_masked(struct match *match, uint8_t flags, uint8_t mask);
  151. void match_set_tun_gbp_flags(struct match *match, uint8_t flags);
  152. +void match_set_tun_gpe_np_masked(struct match *match, uint8_t gpe_np, uint8_t mask);
  153. +void match_set_tun_gpe_np(struct match *match, uint8_t gpe_np);
  154. +void match_set_tun_gpe_flags_masked(struct match *match, uint8_t flags, uint8_t mask);
  155. +void match_set_tun_gpe_flags(struct match *match, uint8_t flags);
  156. void match_set_in_port(struct match *, ofp_port_t ofp_port);
  157. void match_set_pkt_mark(struct match *, uint32_t pkt_mark);
  158. void match_set_pkt_mark_masked(struct match *, uint32_t pkt_mark, uint32_t mask);
  159. diff --git a/include/openvswitch/meta-flow.h b/include/openvswitch/meta-flow.h
  160. index b091c1b..9e569ef 100644
  161. --- a/include/openvswitch/meta-flow.h
  162. +++ b/include/openvswitch/meta-flow.h
  163. @@ -493,6 +493,34 @@ enum OVS_PACKED_ENUM mf_field_id {
  164. */
  165. MFF_TUN_GBP_FLAGS,
  166. + /* "tun_gpe_np".
  167. + *
  168. + * VXLAN Generic Protocol Extension next_proto
  169. + *
  170. + * Type: u8.
  171. + * Maskable: bitwise.
  172. + * Formatting: hexadecimal.
  173. + * Prerequisites: none.
  174. + * Access: read/write.
  175. + * NXM: NXM_NX_TUN_GPE_NP(200) since v2.4.
  176. + * OXM: none.
  177. + */
  178. + MFF_TUN_GPE_NP,
  179. +
  180. + /* "tun_gpe_flags".
  181. + *
  182. + * VXLAN Generic Protocol Extension flag
  183. + *
  184. + * Type: u8.
  185. + * Maskable: bitwise.
  186. + * Formatting: hexadecimal.
  187. + * Prerequisites: none.
  188. + * Access: read/write.
  189. + * NXM: NXM_NX_TUN_GPE_FLAGS(201) since v2.4.
  190. + * OXM: none.
  191. + */
  192. + MFF_TUN_GPE_FLAGS,
  193. +
  194. #if TUN_METADATA_NUM_OPTS == 64
  195. /* "tun_metadata<N>".
  196. *
  197. diff --git a/include/openvswitch/packets.h b/include/openvswitch/packets.h
  198. index 5d97309..1e82df0 100644
  199. --- a/include/openvswitch/packets.h
  200. +++ b/include/openvswitch/packets.h
  201. @@ -34,7 +34,9 @@ struct flow_tnl {
  202. ovs_be16 tp_dst;
  203. ovs_be16 gbp_id;
  204. uint8_t gbp_flags;
  205. - uint8_t pad1[5]; /* Pad to 64 bits. */
  206. + uint8_t gpe_np;
  207. + uint8_t gpe_flags;
  208. + uint8_t pad1[3]; /* Pad to 64 bits. */
  209. struct tun_metadata metadata;
  210. };
  211. diff --git a/lib/flow.c b/lib/flow.c
  212. index ba4f8c7..375979b 100644
  213. --- a/lib/flow.c
  214. +++ b/lib/flow.c
  215. @@ -897,6 +897,12 @@ flow_get_metadata(const struct flow *flow, struct match *flow_metadata)
  216. if (flow->tunnel.gbp_flags) {
  217. match_set_tun_gbp_flags(flow_metadata, flow->tunnel.gbp_flags);
  218. }
  219. + if (flow->tunnel.gpe_np != htons(0)) {
  220. + match_set_tun_gpe_np(flow_metadata, flow->tunnel.gpe_np);
  221. + }
  222. + if (flow->tunnel.gpe_flags) {
  223. + match_set_tun_gpe_flags(flow_metadata, flow->tunnel.gpe_flags);
  224. + }
  225. tun_metadata_get_fmd(&flow->tunnel, flow_metadata);
  226. if (flow->metadata != htonll(0)) {
  227. match_set_metadata(flow_metadata, flow->metadata);
  228. @@ -1292,6 +1298,8 @@ void flow_wildcards_init_for_packet(struct flow_wildcards *wc,
  229. WC_MASK_FIELD(wc, tunnel.tp_dst);
  230. WC_MASK_FIELD(wc, tunnel.gbp_id);
  231. WC_MASK_FIELD(wc, tunnel.gbp_flags);
  232. + WC_MASK_FIELD(wc, tunnel.gpe_np);
  233. + WC_MASK_FIELD(wc, tunnel.gpe_flags);
  234. if (!(flow->tunnel.flags & FLOW_TNL_F_UDPIF)) {
  235. if (flow->tunnel.metadata.present.map) {
  236. diff --git a/lib/match.c b/lib/match.c
  237. index d78e6a1..f19648d 100644
  238. --- a/lib/match.c
  239. +++ b/lib/match.c
  240. @@ -305,6 +305,32 @@ match_set_tun_gbp_flags(struct match *match, uint8_t flags)
  241. }
  242. void
  243. +match_set_tun_gpe_np_masked(struct match *match, uint8_t np, uint8_t mask)
  244. +{
  245. + match->wc.masks.tunnel.gpe_np = mask;
  246. + match->flow.tunnel.gpe_np = np & mask;
  247. +}
  248. +
  249. +void
  250. +match_set_tun_gpe_np(struct match *match, uint8_t np)
  251. +{
  252. + match_set_tun_gpe_np_masked(match, np, UINT8_MAX);
  253. +}
  254. +
  255. +void
  256. +match_set_tun_gpe_flags_masked(struct match *match, uint8_t flags, uint8_t mask)
  257. +{
  258. + match->wc.masks.tunnel.gpe_flags = mask;
  259. + match->flow.tunnel.gpe_flags = flags & mask;
  260. +}
  261. +
  262. +void
  263. +match_set_tun_gpe_flags(struct match *match, uint8_t flags)
  264. +{
  265. + match_set_tun_gpe_flags_masked(match, flags, UINT8_MAX);
  266. +}
  267. +
  268. +void
  269. match_set_in_port(struct match *match, ofp_port_t ofp_port)
  270. {
  271. match->wc.masks.in_port.ofp_port = u16_to_ofp(UINT16_MAX);
  272. @@ -1029,6 +1055,14 @@ format_flow_tunnel(struct ds *s, const struct match *match)
  273. ds_put_format(s, "tun_gbp_flags=%#"PRIx8",", tnl->gbp_flags);
  274. }
  275. + if (wc->masks.tunnel.gpe_np) {
  276. + ds_put_format(s, "tun_gpe_np=%#"PRIx8",", tnl->gpe_np);
  277. + }
  278. +
  279. + if (wc->masks.tunnel.gpe_flags) {
  280. + ds_put_format(s, "tun_gpe_flags=%#"PRIx8",", tnl->gpe_flags);
  281. + }
  282. +
  283. if (wc->masks.tunnel.ip_tos) {
  284. ds_put_format(s, "tun_tos=%"PRIx8",", tnl->ip_tos);
  285. }
  286. diff --git a/lib/meta-flow.c b/lib/meta-flow.c
  287. index d07f927..5d0721f 100644
  288. --- a/lib/meta-flow.c
  289. +++ b/lib/meta-flow.c
  290. @@ -213,6 +213,10 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc)
  291. return !wc->masks.tunnel.gbp_id;
  292. case MFF_TUN_GBP_FLAGS:
  293. return !wc->masks.tunnel.gbp_flags;
  294. + case MFF_TUN_GPE_NP:
  295. + return !wc->masks.tunnel.gpe_np;
  296. + case MFF_TUN_GPE_FLAGS:
  297. + return !wc->masks.tunnel.gpe_flags;
  298. CASE_MFF_TUN_METADATA:
  299. return !ULLONG_GET(wc->masks.tunnel.metadata.present.map,
  300. mf->id - MFF_TUN_METADATA0);
  301. @@ -434,6 +438,8 @@ mf_is_value_valid(const struct mf_field *mf, const union mf_value *value)
  302. case MFF_TUN_TTL:
  303. case MFF_TUN_GBP_ID:
  304. case MFF_TUN_GBP_FLAGS:
  305. + case MFF_TUN_GPE_NP:
  306. + case MFF_TUN_GPE_FLAGS:
  307. CASE_MFF_TUN_METADATA:
  308. case MFF_METADATA:
  309. case MFF_IN_PORT:
  310. @@ -568,6 +574,12 @@ mf_get_value(const struct mf_field *mf, const struct flow *flow,
  311. case MFF_TUN_GBP_FLAGS:
  312. value->u8 = flow->tunnel.gbp_flags;
  313. break;
  314. + case MFF_TUN_GPE_NP:
  315. + value->u8 = flow->tunnel.gpe_np;
  316. + break;
  317. + case MFF_TUN_GPE_FLAGS:
  318. + value->u8 = flow->tunnel.gpe_flags;
  319. + break;
  320. case MFF_TUN_TTL:
  321. value->u8 = flow->tunnel.ip_ttl;
  322. break;
  323. @@ -823,6 +835,12 @@ mf_set_value(const struct mf_field *mf,
  324. case MFF_TUN_GBP_FLAGS:
  325. match_set_tun_gbp_flags(match, value->u8);
  326. break;
  327. + case MFF_TUN_GPE_NP:
  328. + match_set_tun_gpe_np(match, value->u8);
  329. + break;
  330. + case MFF_TUN_GPE_FLAGS:
  331. + match_set_tun_gpe_flags(match, value->u8);
  332. + break;
  333. case MFF_TUN_TOS:
  334. match_set_tun_tos(match, value->u8);
  335. break;
  336. @@ -1161,6 +1179,12 @@ mf_set_flow_value(const struct mf_field *mf,
  337. case MFF_TUN_GBP_FLAGS:
  338. flow->tunnel.gbp_flags = value->u8;
  339. break;
  340. + case MFF_TUN_GPE_NP:
  341. + flow->tunnel.gpe_np= value->u8;
  342. + break;
  343. + case MFF_TUN_GPE_FLAGS:
  344. + flow->tunnel.gpe_flags= value->u8;
  345. + break;
  346. case MFF_TUN_TOS:
  347. flow->tunnel.ip_tos = value->u8;
  348. break;
  349. @@ -1484,6 +1508,12 @@ mf_set_wild(const struct mf_field *mf, struct match *match, char **err_str)
  350. case MFF_TUN_GBP_FLAGS:
  351. match_set_tun_gbp_flags_masked(match, 0, 0);
  352. break;
  353. + case MFF_TUN_GPE_NP:
  354. + match_set_tun_gpe_np_masked(match, 0, 0);
  355. + break;
  356. + case MFF_TUN_GPE_FLAGS:
  357. + match_set_tun_gpe_flags_masked(match, 0, 0);
  358. + break;
  359. case MFF_TUN_TOS:
  360. match_set_tun_tos_masked(match, 0, 0);
  361. break;
  362. @@ -1793,6 +1823,12 @@ mf_set(const struct mf_field *mf,
  363. case MFF_TUN_GBP_FLAGS:
  364. match_set_tun_gbp_flags_masked(match, value->u8, mask->u8);
  365. break;
  366. + case MFF_TUN_GPE_NP:
  367. + match_set_tun_gpe_np_masked(match, value->u8, mask->u8);
  368. + break;
  369. + case MFF_TUN_GPE_FLAGS:
  370. + match_set_tun_gpe_flags_masked(match, value->u8, mask->u8);
  371. + break;
  372. case MFF_TUN_TTL:
  373. match_set_tun_ttl_masked(match, value->u8, mask->u8);
  374. break;
  375. diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
  376. index ac31da6..cff0f5c 100644
  377. --- a/lib/netdev-vport.c
  378. +++ b/lib/netdev-vport.c
  379. @@ -526,6 +526,8 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args)
  380. while (ext) {
  381. if (!strcmp(type, "vxlan") && !strcmp(ext, "gbp")) {
  382. tnl_cfg.exts |= (1 << OVS_VXLAN_EXT_GBP);
  383. + } else if (!strcmp(type, "vxlan") && !strcmp(ext, "gpe")) {
  384. + tnl_cfg.exts |= (1 << OVS_VXLAN_EXT_GPE);
  385. } else {
  386. VLOG_WARN("%s: unknown extension '%s'", name, ext);
  387. }
  388. diff --git a/lib/nx-match.c b/lib/nx-match.c
  389. index b03ccf2..65d7ee3 100644
  390. --- a/lib/nx-match.c
  391. +++ b/lib/nx-match.c
  392. @@ -1036,6 +1036,10 @@ nx_put_raw(struct ofpbuf *b, enum ofp_version oxm, const struct match *match,
  393. flow->tunnel.gbp_id, match->wc.masks.tunnel.gbp_id);
  394. nxm_put_8m(b, MFF_TUN_GBP_FLAGS, oxm,
  395. flow->tunnel.gbp_flags, match->wc.masks.tunnel.gbp_flags);
  396. + nxm_put_8m(b, MFF_TUN_GPE_NP, oxm,
  397. + flow->tunnel.gpe_np, match->wc.masks.tunnel.gpe_np);
  398. + nxm_put_8m(b, MFF_TUN_GPE_FLAGS, oxm,
  399. + flow->tunnel.gpe_flags, match->wc.masks.tunnel.gpe_flags);
  400. tun_metadata_to_nx_match(b, oxm, match);
  401. /* Registers. */
  402. diff --git a/lib/odp-util.c b/lib/odp-util.c
  403. index 6d29b67..b9e8aa7 100644
  404. --- a/lib/odp-util.c
  405. +++ b/lib/odp-util.c
  406. @@ -1755,6 +1755,7 @@ odp_actions_from_string(const char *s, const struct simap *port_names,
  407. static const struct attr_len_tbl ovs_vxlan_ext_attr_lens[OVS_VXLAN_EXT_MAX + 1] = {
  408. [OVS_VXLAN_EXT_GBP] = { .len = 4 },
  409. + [OVS_VXLAN_EXT_GPE] = { .len = 4 },
  410. };
  411. static const struct attr_len_tbl ovs_tun_key_attr_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1] = {
  412. @@ -1916,7 +1917,10 @@ odp_tun_key_from_attr__(const struct nlattr *attr,
  413. break;
  414. case OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS: {
  415. static const struct nl_policy vxlan_opts_policy[] = {
  416. - [OVS_VXLAN_EXT_GBP] = { .type = NL_A_U32 },
  417. + [OVS_VXLAN_EXT_GBP] = { .type = NL_A_U32 ,
  418. + .optional = true },
  419. + [OVS_VXLAN_EXT_GPE] = { .type = NL_A_U32 ,
  420. + .optional = true },
  421. };
  422. struct nlattr *ext[ARRAY_SIZE(vxlan_opts_policy)];
  423. @@ -1930,6 +1934,12 @@ odp_tun_key_from_attr__(const struct nlattr *attr,
  424. tun->gbp_id = htons(gbp & 0xFFFF);
  425. tun->gbp_flags = (gbp >> 16) & 0xFF;
  426. }
  427. + if (ext[OVS_VXLAN_EXT_GPE]) {
  428. + uint32_t gpe = nl_attr_get_u32(ext[OVS_VXLAN_EXT_GPE]);
  429. +
  430. + tun->gpe_np = gpe & 0xFF;
  431. + tun->gpe_flags = gpe >> 24;
  432. + }
  433. break;
  434. }
  435. @@ -2016,6 +2026,13 @@ tun_key_to_attr(struct ofpbuf *a, const struct flow_tnl *tun_key,
  436. nl_msg_put_u32(a, OVS_VXLAN_EXT_GBP,
  437. (tun_key->gbp_flags << 16) | ntohs(tun_key->gbp_id));
  438. nl_msg_end_nested(a, vxlan_opts_ofs);
  439. + } else if (tun_key->gpe_flags || tun_key->gpe_np) {
  440. + size_t vxlan_opts_ofs;
  441. +
  442. + vxlan_opts_ofs = nl_msg_start_nested(a, OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS);
  443. + nl_msg_put_u32(a, OVS_VXLAN_EXT_GPE,
  444. + (tun_key->gpe_flags << 24) | (tun_key->gpe_np));
  445. + nl_msg_end_nested(a, vxlan_opts_ofs);
  446. }
  447. tun_metadata_to_geneve_nlattr(tun_key, tun_flow_key, key_buf, a);
  448. @@ -2410,6 +2427,26 @@ format_odp_tun_vxlan_opt(const struct nlattr *attr,
  449. ds_put_cstr(ds, "),");
  450. break;
  451. }
  452. + case OVS_VXLAN_EXT_GPE: {
  453. + uint32_t key = nl_attr_get_u32(a);
  454. + uint8_t np, np_mask;
  455. + uint8_t flags, flags_mask;
  456. +
  457. + np = key & 0xFF;
  458. + flags = (key >> 24) & 0xFF;
  459. + if (ma) {
  460. + uint32_t mask = nl_attr_get_u32(ma);
  461. + np_mask = mask & 0xFF;
  462. + flags_mask = (mask >> 24) & 0xFF;
  463. + }
  464. +
  465. + ds_put_cstr(ds, "gpe(");
  466. + format_u8x(ds, "np", np, ma ? &np_mask : NULL, verbose);
  467. + format_u8x(ds, "flags", flags, ma ? &flags_mask : NULL, verbose);
  468. + ds_chomp(ds, ',');
  469. + ds_put_cstr(ds, "),");
  470. + break;
  471. + }
  472. default:
  473. format_unknown_key(ds, a, ma);
  474. @@ -3705,6 +3742,40 @@ scan_vxlan_gbp(const char *s, uint32_t *key, uint32_t *mask)
  475. }
  476. static int
  477. +scan_vxlan_gpe(const char *s, uint32_t *key, uint32_t *mask)
  478. +{
  479. + const char *s_base = s;
  480. + uint8_t np = 0, np_mask = 0;
  481. + uint8_t flags = 0, flags_mask = 0;
  482. +
  483. + if (!strncmp(s, "np=", 3)) {
  484. + s += 3;
  485. + s += scan_u8(s, &np, mask ? &np_mask : NULL);
  486. + }
  487. +
  488. + if (s[0] == ',') {
  489. + s++;
  490. + }
  491. + if (!strncmp(s, "flags=", 6)) {
  492. + s += 6;
  493. + s += scan_u8(s, &flags, mask ? &flags_mask : NULL);
  494. + }
  495. +
  496. + if (!strncmp(s, "))", 2)) {
  497. + s += 2;
  498. +
  499. + *key = (flags << 24) | np;
  500. + if (mask) {
  501. + *mask = (flags_mask << 24) | np_mask;
  502. + }
  503. +
  504. + return s - s_base;
  505. + }
  506. +
  507. + return 0;
  508. +}
  509. +
  510. +static int
  511. scan_geneve(const char *s, struct geneve_scan *key, struct geneve_scan *mask)
  512. {
  513. const char *s_base = s;
  514. @@ -3831,6 +3902,21 @@ vxlan_gbp_to_attr(struct ofpbuf *a, const void *data_)
  515. }
  516. static void
  517. +vxlan_gpe_to_attr(struct ofpbuf *a, const void *data_)
  518. +{
  519. + const uint32_t *gpe = data_;
  520. +
  521. + if (*gpe) {
  522. + size_t vxlan_opts_ofs;
  523. +
  524. + vxlan_opts_ofs = nl_msg_start_nested(a, OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS);
  525. + nl_msg_put_u32(a, OVS_VXLAN_EXT_GPE, *gpe);
  526. + nl_msg_end_nested(a, vxlan_opts_ofs);
  527. + }
  528. +}
  529. +
  530. +
  531. +static void
  532. geneve_to_attr(struct ofpbuf *a, const void *data_)
  533. {
  534. const struct geneve_scan *geneve = data_;
  535. @@ -4066,6 +4152,7 @@ parse_odp_key_mask_attr(const char *s, const struct simap *port_names,
  536. SCAN_FIELD_NESTED("tp_src=", ovs_be16, be16, OVS_TUNNEL_KEY_ATTR_TP_SRC);
  537. SCAN_FIELD_NESTED("tp_dst=", ovs_be16, be16, OVS_TUNNEL_KEY_ATTR_TP_DST);
  538. SCAN_FIELD_NESTED_FUNC("vxlan(gbp(", uint32_t, vxlan_gbp, vxlan_gbp_to_attr);
  539. + SCAN_FIELD_NESTED_FUNC("vxlan(gpe(", uint32_t, vxlan_gpe, vxlan_gpe_to_attr);
  540. SCAN_FIELD_NESTED_FUNC("geneve(", struct geneve_scan, geneve,
  541. geneve_to_attr);
  542. SCAN_FIELD_NESTED_FUNC("flags(", uint16_t, tun_flags, tun_flags_to_attr);
  543. diff --git a/tests/ofproto.at b/tests/ofproto.at
  544. index 6e55270..7b7f02b 100644
  545. --- a/tests/ofproto.at
  546. +++ b/tests/ofproto.at
  547. @@ -2190,7 +2190,7 @@ head_table () {
  548. instructions: meter,apply_actions,clear_actions,write_actions,write_metadata,goto_table
  549. Write-Actions and Apply-Actions features:
  550. 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
  551. - 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
  552. + 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
  553. 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
  554. 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
  555. matching:
  556. @@ -2205,6 +2205,8 @@ metadata in_port in_port_oxm pkt_mark ct_mark ct_label reg0 reg1 reg2 reg3 reg4
  557. tun_flags: arbitrary mask
  558. tun_gbp_id: arbitrary mask
  559. tun_gbp_flags: arbitrary mask
  560. + tun_gpe_np: arbitrary mask
  561. + tun_gpe_flags: arbitrary mask
  562. tun_metadata0: arbitrary mask
  563. tun_metadata1: arbitrary mask
  564. tun_metadata2: arbitrary mask
  565. diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at
  566. index cbb818e..2267be0 100644
  567. --- a/tests/ovs-ofctl.at
  568. +++ b/tests/ovs-ofctl.at
  569. @@ -17,6 +17,10 @@ for test_case in \
  570. 'tun_gbp_id=0/0x1 NXM,OXM' \
  571. 'tun_gbp_flags=0 NXM,OXM' \
  572. 'tun_gbp_flags=0/0x1 NXM,OXM' \
  573. + 'tun_gpe_np=0 NXM,OXM' \
  574. + 'tun_gpe_np=0/0x1 NXM,OXM' \
  575. + 'tun_gpe_flags=0 NXM,OXM' \
  576. + 'tun_gpe_flags=0/0x1 NXM,OXM' \
  577. 'tun_metadata0=0 NXM,OXM' \
  578. 'tun_metadata0=0/0x1 NXM,OXM' \
  579. 'tun_metadata0 NXM,OXM' \
  580. --
  581. 2.1.0