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-ovs-vxlan-gpe-vxlan-extension-to-support-vxlan-gpe-t.patch 27KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  1. From 5d79831435ec4e5bea20cc36c3f83eacf6fd065c Mon Sep 17 00:00:00 2001
  2. From: Yi Yang <yi.y.yang@intel.com>
  3. Date: Mon, 11 Apr 2016 15:58:14 +0800
  4. Subject: [PATCH 1/6] ovs-vxlan-gpe: vxlan extension to support vxlan-gpe
  5. tunnel port
  6. Signed-off-by: Mengke Liu <mengke.liu@intel.com>
  7. Signed-off-by: Ricky Li <ricky.li@intel.com>
  8. Signed-off-by: Johnson Li <johnson.li@intel.com>
  9. Signed-off-by: Yi Yang <yi.y.yang@intel.com>
  10. ---
  11. datapath/flow_netlink.c | 8 +-
  12. datapath/linux/compat/include/linux/openvswitch.h | 1 +
  13. datapath/linux/compat/include/net/vxlan.h | 73 +++++++++++++++++++
  14. datapath/linux/compat/vxlan.c | 30 ++++++++
  15. datapath/vport-vxlan.c | 15 ++++
  16. lib/flow.c | 8 ++
  17. lib/match.c | 34 +++++++++
  18. lib/match.h | 4 +
  19. lib/meta-flow.c | 36 +++++++++
  20. lib/meta-flow.h | 28 +++++++
  21. lib/netdev-vport.c | 2 +
  22. lib/nx-match.c | 4 +
  23. lib/odp-util.c | 89 ++++++++++++++++++++++-
  24. lib/packets.h | 4 +-
  25. tests/ofproto.at | 4 +-
  26. tests/ovs-ofctl.at | 4 +
  27. 16 files changed, 340 insertions(+), 4 deletions(-)
  28. diff --git a/datapath/flow_netlink.c b/datapath/flow_netlink.c
  29. index 6ffcc53..351a504 100644
  30. --- a/datapath/flow_netlink.c
  31. +++ b/datapath/flow_netlink.c
  32. @@ -309,6 +309,7 @@ size_t ovs_key_attr_size(void)
  33. static const struct ovs_len_tbl ovs_vxlan_ext_key_lens[OVS_VXLAN_EXT_MAX + 1] = {
  34. [OVS_VXLAN_EXT_GBP] = { .len = sizeof(u32) },
  35. + [OVS_VXLAN_EXT_GPE] = { .len = sizeof(u32) },
  36. };
  37. static const struct ovs_len_tbl ovs_tunnel_key_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1] = {
  38. @@ -521,6 +522,9 @@ static int vxlan_tun_opt_from_nlattr(const struct nlattr *attr,
  39. case OVS_VXLAN_EXT_GBP:
  40. opts.gbp = nla_get_u32(a);
  41. break;
  42. + case OVS_VXLAN_EXT_GPE:
  43. + opts.gpe = nla_get_u32(a);
  44. + break;
  45. default:
  46. OVS_NLERR(log, "Unknown VXLAN extension attribute %d",
  47. type);
  48. @@ -677,7 +681,9 @@ static int vxlan_opt_to_nlattr(struct sk_buff *skb,
  49. if (!nla)
  50. return -EMSGSIZE;
  51. - if (nla_put_u32(skb, OVS_VXLAN_EXT_GBP, opts->gbp) < 0)
  52. + if (opts->gbp && nla_put_u32(skb, OVS_VXLAN_EXT_GBP, opts->gbp) < 0)
  53. + return -EMSGSIZE;
  54. + else if (opts->gpe && nla_put_u32(skb, OVS_VXLAN_EXT_GPE, opts->gpe) < 0)
  55. return -EMSGSIZE;
  56. nla_nest_end(skb, nla);
  57. diff --git a/datapath/linux/compat/include/linux/openvswitch.h b/datapath/linux/compat/include/linux/openvswitch.h
  58. index 3b39ebb..44adb81 100644
  59. --- a/datapath/linux/compat/include/linux/openvswitch.h
  60. +++ b/datapath/linux/compat/include/linux/openvswitch.h
  61. @@ -287,6 +287,7 @@ enum ovs_vport_attr {
  62. enum {
  63. OVS_VXLAN_EXT_UNSPEC,
  64. OVS_VXLAN_EXT_GBP, /* Flag or __u32 */
  65. + OVS_VXLAN_EXT_GPE,
  66. __OVS_VXLAN_EXT_MAX,
  67. };
  68. diff --git a/datapath/linux/compat/include/net/vxlan.h b/datapath/linux/compat/include/net/vxlan.h
  69. index 75a5a7a..2bfc3f8 100644
  70. --- a/datapath/linux/compat/include/net/vxlan.h
  71. +++ b/datapath/linux/compat/include/net/vxlan.h
  72. @@ -84,6 +84,75 @@ struct vxlanhdr_gbp {
  73. #define VXLAN_GBP_POLICY_APPLIED (BIT(3) << 16)
  74. #define VXLAN_GBP_ID_MASK (0xFFFF)
  75. +/*
  76. + * VXLAN Generic Protocol Extension Extension:
  77. + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  78. + * |R|R|Ver|I|P|R|O|R|R|R|R|R|R|R|R|R|R|R|R|R|R|R|R| Next Proto |
  79. + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  80. + * | VXLAN Network Identifier (VNI) | Reserved |
  81. + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  82. + * Ver = Version. Indicates VXLAN GPE protocol version. The initial
  83. + * version is 0. If a receiver does not support the version
  84. + * indicated it MUST drop the packet.
  85. + *
  86. + * I = Instance Bit. The I bit MUST be set to indicate a valid VNI.
  87. + *
  88. + * P = Next Protocol Bit. The P bit is set to indicate that the
  89. + * Next Protocol field is present.
  90. + *
  91. + * O = OAM Flag Bit. The O bit is set to indicate that the packet
  92. + * is an OAM packet.
  93. + *
  94. + * [1] https://www.ietf.org/id/draft-ietf-nvo3-vxlan-gpe-01.txt
  95. + */
  96. +
  97. +struct vxlanhdr_gpe {
  98. +#ifdef __LITTLE_ENDIAN_BITFIELD
  99. + uint8_t oam_flag:1;
  100. + uint8_t reserved_flags1:1;
  101. + uint8_t np_applied:1;
  102. + uint8_t instance_applied:1;
  103. + uint8_t gpe_version:2;
  104. + uint8_t reserved_flags2:2;
  105. +#elif defined(__BIG_ENDIAN_BITFIELD)
  106. + uint8_t reserved_flags2:2;
  107. + uint8_t gpe_version:2;
  108. + uint8_t instance_applied:1;
  109. + uint8_t np_applied:1;
  110. + uint8_t reserved_flags1:1;
  111. + uint8_t oam_flag:1;
  112. +#else
  113. +#error "Please fix <asm/byteorder.h>"
  114. +#endif
  115. + uint8_t reserved_flags3;
  116. + uint8_t reserved_flags4;
  117. + uint8_t next_proto;
  118. + __be32 vx_vni;
  119. +};
  120. +
  121. +/* VxLAN-GPE Header Next Protocol */
  122. +#define VXLAN_GPE_NP_IPV4 0x01
  123. +#define VXLAN_GPE_NP_IPV6 0x02
  124. +#define VXLAN_GPE_NP_ETHERNET 0x03
  125. +#define VXLAN_GPE_NP_NSH 0x04
  126. +
  127. +/* skb->mark mapping
  128. + *
  129. + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  130. + * |R|R|Ver|I|P|R|O|R|R|R|R|R|R|R|R|R|R|R|R|R|R|R|R| Next Proto |
  131. + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  132. + */
  133. +
  134. +#define VXLAN_GPE_OAM_FLAG (BIT(0) << 24)
  135. +#define VXLAN_GPE_NP_APPLIED (BIT(0) << 26)
  136. +#define VXLAN_GPE_INSTANCE_APPLIED (BIT(0) << 27)
  137. +#define VXLAN_GPE_VERSION ((BIT(0) << 28) | (BIT(0) << 29))
  138. +
  139. +#define VXLAN_GPE_NP_MASK (0xFF)
  140. +
  141. +#define VXLAN_GPE_USED_BITS (VXLAN_GPE_OAM_FLAG | VXLAN_GPE_NP_APPLIED \
  142. + | VXLAN_GPE_INSTANCE_APPLIED | VXLAN_GPE_VERSION | 0xFF)
  143. +
  144. /* VXLAN protocol header:
  145. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  146. * |G|R|R|R|I|R|R|C| Reserved |
  147. @@ -104,6 +173,7 @@ struct vxlanhdr {
  148. #define VXLAN_HF_RCO BIT(21)
  149. #define VXLAN_HF_VNI BIT(27)
  150. #define VXLAN_HF_GBP BIT(31)
  151. +#define VXLAN_HF_GPE BIT(26)
  152. /* Remote checksum offload header option */
  153. #define VXLAN_RCO_MASK 0x7f /* Last byte of vni field */
  154. @@ -120,6 +190,7 @@ struct vxlanhdr {
  155. struct vxlan_metadata {
  156. __be32 vni;
  157. u32 gbp;
  158. + u32 gpe;
  159. };
  160. #define VNI_HASH_BITS 10
  161. @@ -205,11 +276,13 @@ struct vxlan_dev {
  162. #define VXLAN_F_GBP 0x800
  163. #define VXLAN_F_REMCSUM_NOPARTIAL 0x1000
  164. #define VXLAN_F_COLLECT_METADATA 0x2000
  165. +#define VXLAN_F_GPE 0x4000
  166. /* Flags that are used in the receive path. These flags must match in
  167. * order for a socket to be shareable
  168. */
  169. #define VXLAN_F_RCV_FLAGS (VXLAN_F_GBP | \
  170. + VXLAN_F_GPE | \
  171. VXLAN_F_UDP_ZERO_CSUM6_RX | \
  172. VXLAN_F_REMCSUM_RX | \
  173. VXLAN_F_REMCSUM_NOPARTIAL | \
  174. diff --git a/datapath/linux/compat/vxlan.c b/datapath/linux/compat/vxlan.c
  175. index 4faa18f..7ef051c 100644
  176. --- a/datapath/linux/compat/vxlan.c
  177. +++ b/datapath/linux/compat/vxlan.c
  178. @@ -971,6 +971,18 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
  179. md->gbp |= VXLAN_GBP_POLICY_APPLIED;
  180. flags &= ~VXLAN_GBP_USED_BITS;
  181. + } else if ((flags & VXLAN_HF_GPE) && (vs->flags & VXLAN_F_GPE)) {
  182. + struct vxlanhdr_gpe *gpe;
  183. +
  184. + gpe = (struct vxlanhdr_gpe *)vxh;
  185. + md->gpe = ntohs(gpe->next_proto);
  186. +
  187. + buf.dst.u.tun_info.key.tun_flags |= TUNNEL_VXLAN_OPT;
  188. +
  189. + if (gpe->oam_flag)
  190. + md->gpe |= VXLAN_GPE_OAM_FLAG;
  191. +
  192. + flags &= ~VXLAN_GPE_USED_BITS;
  193. }
  194. if (flags || vni & ~VXLAN_VNI_MASK) {
  195. @@ -1023,6 +1035,22 @@ static void vxlan_build_gbp_hdr(struct vxlanhdr *vxh, u32 vxflags,
  196. gbp->policy_id = htons(md->gbp & VXLAN_GBP_ID_MASK);
  197. }
  198. +static void vxlan_build_gpe_hdr(struct vxlanhdr *vxh, u32 vxflags,
  199. + struct vxlan_metadata *md)
  200. +{
  201. + struct vxlanhdr_gpe *gpe;
  202. +
  203. + if (!md->gpe)
  204. + return;
  205. +
  206. + gpe = (struct vxlanhdr_gpe*)vxh;
  207. + vxh->vx_flags |= htonl(VXLAN_HF_GPE);
  208. +
  209. + if (md->gpe & VXLAN_GPE_OAM_FLAG)
  210. + gpe->oam_flag = 1;
  211. + gpe->next_proto = md->gpe & VXLAN_GPE_NP_MASK;
  212. +}
  213. +
  214. #if IS_ENABLED(CONFIG_IPV6)
  215. static int vxlan6_xmit_skb(struct dst_entry *dst, struct sock *sk,
  216. struct sk_buff *skb,
  217. @@ -1106,6 +1134,8 @@ static int vxlan6_xmit_skb(struct dst_entry *dst, struct sock *sk,
  218. if (vxflags & VXLAN_F_GBP)
  219. vxlan_build_gbp_hdr(vxh, vxflags, md);
  220. + else if (vxflags & VXLAN_F_GPE)
  221. + vxlan_build_gpe_hdr(vxh, vxflags, md);
  222. ovs_skb_set_inner_protocol(skb, htons(ETH_P_TEB));
  223. diff --git a/datapath/vport-vxlan.c b/datapath/vport-vxlan.c
  224. index c05f5d4..5d775cc 100644
  225. --- a/datapath/vport-vxlan.c
  226. +++ b/datapath/vport-vxlan.c
  227. @@ -52,6 +52,18 @@ static int vxlan_get_options(const struct vport *vport, struct sk_buff *skb)
  228. return -EMSGSIZE;
  229. nla_nest_end(skb, exts);
  230. + } else if (vxlan->flags & VXLAN_F_GPE) {
  231. + struct nlattr *exts;
  232. +
  233. + exts = nla_nest_start(skb, OVS_TUNNEL_ATTR_EXTENSION);
  234. + if (!exts)
  235. + return -EMSGSIZE;
  236. +
  237. + if (vxlan->flags & VXLAN_F_GPE &&
  238. + nla_put_flag(skb, OVS_VXLAN_EXT_GPE))
  239. + return -EMSGSIZE;
  240. +
  241. + nla_nest_end(skb, exts);
  242. }
  243. return 0;
  244. @@ -59,6 +71,7 @@ static int vxlan_get_options(const struct vport *vport, struct sk_buff *skb)
  245. static const struct nla_policy exts_policy[OVS_VXLAN_EXT_MAX + 1] = {
  246. [OVS_VXLAN_EXT_GBP] = { .type = NLA_FLAG, },
  247. + [OVS_VXLAN_EXT_GPE] = { .type = NLA_FLAG, },
  248. };
  249. static int vxlan_configure_exts(struct vport *vport, struct nlattr *attr,
  250. @@ -76,6 +89,8 @@ static int vxlan_configure_exts(struct vport *vport, struct nlattr *attr,
  251. if (exts[OVS_VXLAN_EXT_GBP])
  252. conf->flags |= VXLAN_F_GBP;
  253. + else if (exts[OVS_VXLAN_EXT_GPE])
  254. + conf->flags |= VXLAN_F_GPE;
  255. return 0;
  256. }
  257. diff --git a/lib/flow.c b/lib/flow.c
  258. index b9ce331..d24bdc9 100644
  259. --- a/lib/flow.c
  260. +++ b/lib/flow.c
  261. @@ -870,6 +870,12 @@ flow_get_metadata(const struct flow *flow, struct match *flow_metadata)
  262. if (flow->tunnel.gbp_flags) {
  263. match_set_tun_gbp_flags(flow_metadata, flow->tunnel.gbp_flags);
  264. }
  265. + if (flow->tunnel.gpe_np != htons(0)) {
  266. + match_set_tun_gpe_np(flow_metadata, flow->tunnel.gpe_np);
  267. + }
  268. + if (flow->tunnel.gpe_flags) {
  269. + match_set_tun_gpe_flags(flow_metadata, flow->tunnel.gpe_flags);
  270. + }
  271. tun_metadata_get_fmd(&flow->tunnel, flow_metadata);
  272. if (flow->metadata != htonll(0)) {
  273. match_set_metadata(flow_metadata, flow->metadata);
  274. @@ -1265,6 +1271,8 @@ void flow_wildcards_init_for_packet(struct flow_wildcards *wc,
  275. WC_MASK_FIELD(wc, tunnel.tp_dst);
  276. WC_MASK_FIELD(wc, tunnel.gbp_id);
  277. WC_MASK_FIELD(wc, tunnel.gbp_flags);
  278. + WC_MASK_FIELD(wc, tunnel.gpe_np);
  279. + WC_MASK_FIELD(wc, tunnel.gpe_flags);
  280. if (!(flow->tunnel.flags & FLOW_TNL_F_UDPIF)) {
  281. if (flow->tunnel.metadata.present.map) {
  282. diff --git a/lib/match.c b/lib/match.c
  283. index fd571d9..52437c9 100644
  284. --- a/lib/match.c
  285. +++ b/lib/match.c
  286. @@ -289,6 +289,32 @@ match_set_tun_gbp_flags(struct match *match, uint8_t flags)
  287. }
  288. void
  289. +match_set_tun_gpe_np_masked(struct match *match, uint8_t np, uint8_t mask)
  290. +{
  291. + match->wc.masks.tunnel.gpe_np = mask;
  292. + match->flow.tunnel.gpe_np = np & mask;
  293. +}
  294. +
  295. +void
  296. +match_set_tun_gpe_np(struct match *match, uint8_t np)
  297. +{
  298. + match_set_tun_gpe_np_masked(match, np, UINT8_MAX);
  299. +}
  300. +
  301. +void
  302. +match_set_tun_gpe_flags_masked(struct match *match, uint8_t flags, uint8_t mask)
  303. +{
  304. + match->wc.masks.tunnel.gpe_flags = mask;
  305. + match->flow.tunnel.gpe_flags = flags & mask;
  306. +}
  307. +
  308. +void
  309. +match_set_tun_gpe_flags(struct match *match, uint8_t flags)
  310. +{
  311. + match_set_tun_gpe_flags_masked(match, flags, UINT8_MAX);
  312. +}
  313. +
  314. +void
  315. match_set_in_port(struct match *match, ofp_port_t ofp_port)
  316. {
  317. match->wc.masks.in_port.ofp_port = u16_to_ofp(UINT16_MAX);
  318. @@ -1013,6 +1039,14 @@ format_flow_tunnel(struct ds *s, const struct match *match)
  319. ds_put_format(s, "tun_gbp_flags=%#"PRIx8",", tnl->gbp_flags);
  320. }
  321. + if (wc->masks.tunnel.gpe_np) {
  322. + ds_put_format(s, "tun_gpe_np=%#"PRIx8",", tnl->gpe_np);
  323. + }
  324. +
  325. + if (wc->masks.tunnel.gpe_flags) {
  326. + ds_put_format(s, "tun_gpe_flags=%#"PRIx8",", tnl->gpe_flags);
  327. + }
  328. +
  329. if (wc->masks.tunnel.ip_tos) {
  330. ds_put_format(s, "tun_tos=%"PRIx8",", tnl->ip_tos);
  331. }
  332. diff --git a/lib/match.h b/lib/match.h
  333. index 0a6ac29..48aa0b1 100644
  334. --- a/lib/match.h
  335. +++ b/lib/match.h
  336. @@ -86,6 +86,10 @@ void match_set_tun_gbp_id_masked(struct match *match, ovs_be16 gbp_id, ovs_be16
  337. void match_set_tun_gbp_id(struct match *match, ovs_be16 gbp_id);
  338. void match_set_tun_gbp_flags_masked(struct match *match, uint8_t flags, uint8_t mask);
  339. void match_set_tun_gbp_flags(struct match *match, uint8_t flags);
  340. +void match_set_tun_gpe_np_masked(struct match *match, uint8_t gpe_np, uint8_t mask);
  341. +void match_set_tun_gpe_np(struct match *match, uint8_t gpe_np);
  342. +void match_set_tun_gpe_flags_masked(struct match *match, uint8_t flags, uint8_t mask);
  343. +void match_set_tun_gpe_flags(struct match *match, uint8_t flags);
  344. void match_set_in_port(struct match *, ofp_port_t ofp_port);
  345. void match_set_pkt_mark(struct match *, uint32_t pkt_mark);
  346. void match_set_pkt_mark_masked(struct match *, uint32_t pkt_mark, uint32_t mask);
  347. diff --git a/lib/meta-flow.c b/lib/meta-flow.c
  348. index 721152c..ab77fca 100644
  349. --- a/lib/meta-flow.c
  350. +++ b/lib/meta-flow.c
  351. @@ -213,6 +213,10 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc)
  352. return !wc->masks.tunnel.gbp_id;
  353. case MFF_TUN_GBP_FLAGS:
  354. return !wc->masks.tunnel.gbp_flags;
  355. + case MFF_TUN_GPE_NP:
  356. + return !wc->masks.tunnel.gpe_np;
  357. + case MFF_TUN_GPE_FLAGS:
  358. + return !wc->masks.tunnel.gpe_flags;
  359. CASE_MFF_TUN_METADATA:
  360. return !ULLONG_GET(wc->masks.tunnel.metadata.present.map,
  361. mf->id - MFF_TUN_METADATA0);
  362. @@ -515,6 +519,8 @@ mf_is_value_valid(const struct mf_field *mf, const union mf_value *value)
  363. case MFF_TUN_TTL:
  364. case MFF_TUN_GBP_ID:
  365. case MFF_TUN_GBP_FLAGS:
  366. + case MFF_TUN_GPE_NP:
  367. + case MFF_TUN_GPE_FLAGS:
  368. CASE_MFF_TUN_METADATA:
  369. case MFF_METADATA:
  370. case MFF_IN_PORT:
  371. @@ -648,6 +654,12 @@ mf_get_value(const struct mf_field *mf, const struct flow *flow,
  372. case MFF_TUN_GBP_FLAGS:
  373. value->u8 = flow->tunnel.gbp_flags;
  374. break;
  375. + case MFF_TUN_GPE_NP:
  376. + value->u8 = flow->tunnel.gpe_np;
  377. + break;
  378. + case MFF_TUN_GPE_FLAGS:
  379. + value->u8 = flow->tunnel.gpe_flags;
  380. + break;
  381. case MFF_TUN_TTL:
  382. value->u8 = flow->tunnel.ip_ttl;
  383. break;
  384. @@ -899,6 +911,12 @@ mf_set_value(const struct mf_field *mf,
  385. case MFF_TUN_GBP_FLAGS:
  386. match_set_tun_gbp_flags(match, value->u8);
  387. break;
  388. + case MFF_TUN_GPE_NP:
  389. + match_set_tun_gpe_np(match, value->u8);
  390. + break;
  391. + case MFF_TUN_GPE_FLAGS:
  392. + match_set_tun_gpe_flags(match, value->u8);
  393. + break;
  394. case MFF_TUN_TOS:
  395. match_set_tun_tos(match, value->u8);
  396. break;
  397. @@ -1216,6 +1234,12 @@ mf_set_flow_value(const struct mf_field *mf,
  398. case MFF_TUN_GBP_FLAGS:
  399. flow->tunnel.gbp_flags = value->u8;
  400. break;
  401. + case MFF_TUN_GPE_NP:
  402. + flow->tunnel.gpe_np= value->u8;
  403. + break;
  404. + case MFF_TUN_GPE_FLAGS:
  405. + flow->tunnel.gpe_flags= value->u8;
  406. + break;
  407. case MFF_TUN_TOS:
  408. flow->tunnel.ip_tos = value->u8;
  409. break;
  410. @@ -1535,6 +1559,12 @@ mf_set_wild(const struct mf_field *mf, struct match *match, char **err_str)
  411. case MFF_TUN_GBP_FLAGS:
  412. match_set_tun_gbp_flags_masked(match, 0, 0);
  413. break;
  414. + case MFF_TUN_GPE_NP:
  415. + match_set_tun_gpe_np_masked(match, 0, 0);
  416. + break;
  417. + case MFF_TUN_GPE_FLAGS:
  418. + match_set_tun_gpe_flags_masked(match, 0, 0);
  419. + break;
  420. case MFF_TUN_TOS:
  421. match_set_tun_tos_masked(match, 0, 0);
  422. break;
  423. @@ -1838,6 +1868,12 @@ mf_set(const struct mf_field *mf,
  424. case MFF_TUN_GBP_FLAGS:
  425. match_set_tun_gbp_flags_masked(match, value->u8, mask->u8);
  426. break;
  427. + case MFF_TUN_GPE_NP:
  428. + match_set_tun_gpe_np_masked(match, value->u8, mask->u8);
  429. + break;
  430. + case MFF_TUN_GPE_FLAGS:
  431. + match_set_tun_gpe_flags_masked(match, value->u8, mask->u8);
  432. + break;
  433. case MFF_TUN_TTL:
  434. match_set_tun_ttl_masked(match, value->u8, mask->u8);
  435. break;
  436. diff --git a/lib/meta-flow.h b/lib/meta-flow.h
  437. index c73a1af..4bd9ff6 100644
  438. --- a/lib/meta-flow.h
  439. +++ b/lib/meta-flow.h
  440. @@ -491,6 +491,34 @@ enum OVS_PACKED_ENUM mf_field_id {
  441. */
  442. MFF_TUN_GBP_FLAGS,
  443. + /* "tun_gpe_np".
  444. + *
  445. + * VXLAN Generic Protocol Extension next_proto
  446. + *
  447. + * Type: u8.
  448. + * Maskable: bitwise.
  449. + * Formatting: hexadecimal.
  450. + * Prerequisites: none.
  451. + * Access: read/write.
  452. + * NXM: NXM_NX_TUN_GPE_NP(111) since v2.4.
  453. + * OXM: none.
  454. + */
  455. + MFF_TUN_GPE_NP,
  456. +
  457. + /* "tun_gpe_flags".
  458. + *
  459. + * VXLAN Generic Protocol Extension flag
  460. + *
  461. + * Type: u8.
  462. + * Maskable: bitwise.
  463. + * Formatting: hexadecimal.
  464. + * Prerequisites: none.
  465. + * Access: read/write.
  466. + * NXM: NXM_NX_TUN_GPE_FLAGS(112) since v2.4.
  467. + * OXM: none.
  468. + */
  469. + MFF_TUN_GPE_FLAGS,
  470. +
  471. #if TUN_METADATA_NUM_OPTS == 64
  472. /* "tun_metadata<N>".
  473. *
  474. diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
  475. index e398562..92ceec1 100644
  476. --- a/lib/netdev-vport.c
  477. +++ b/lib/netdev-vport.c
  478. @@ -583,6 +583,8 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args)
  479. while (ext) {
  480. if (!strcmp(type, "vxlan") && !strcmp(ext, "gbp")) {
  481. tnl_cfg.exts |= (1 << OVS_VXLAN_EXT_GBP);
  482. + } else if (!strcmp(type, "vxlan") && !strcmp(ext, "gpe")) {
  483. + tnl_cfg.exts |= (1 << OVS_VXLAN_EXT_GPE);
  484. } else {
  485. VLOG_WARN("%s: unknown extension '%s'", name, ext);
  486. }
  487. diff --git a/lib/nx-match.c b/lib/nx-match.c
  488. index 9f0f452..0eecac7 100644
  489. --- a/lib/nx-match.c
  490. +++ b/lib/nx-match.c
  491. @@ -1037,6 +1037,10 @@ nx_put_raw(struct ofpbuf *b, enum ofp_version oxm, const struct match *match,
  492. flow->tunnel.gbp_id, match->wc.masks.tunnel.gbp_id);
  493. nxm_put_8m(b, MFF_TUN_GBP_FLAGS, oxm,
  494. flow->tunnel.gbp_flags, match->wc.masks.tunnel.gbp_flags);
  495. + nxm_put_8m(b, MFF_TUN_GPE_NP, oxm,
  496. + flow->tunnel.gpe_np, match->wc.masks.tunnel.gpe_np);
  497. + nxm_put_8m(b, MFF_TUN_GPE_FLAGS, oxm,
  498. + flow->tunnel.gpe_flags, match->wc.masks.tunnel.gpe_flags);
  499. tun_metadata_to_nx_match(b, oxm, match);
  500. /* Registers. */
  501. diff --git a/lib/odp-util.c b/lib/odp-util.c
  502. index b4689cc..7983720 100644
  503. --- a/lib/odp-util.c
  504. +++ b/lib/odp-util.c
  505. @@ -1727,6 +1727,7 @@ odp_actions_from_string(const char *s, const struct simap *port_names,
  506. static const struct attr_len_tbl ovs_vxlan_ext_attr_lens[OVS_VXLAN_EXT_MAX + 1] = {
  507. [OVS_VXLAN_EXT_GBP] = { .len = 4 },
  508. + [OVS_VXLAN_EXT_GPE] = { .len = 4 },
  509. };
  510. static const struct attr_len_tbl ovs_tun_key_attr_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1] = {
  511. @@ -1888,7 +1889,10 @@ odp_tun_key_from_attr__(const struct nlattr *attr,
  512. break;
  513. case OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS: {
  514. static const struct nl_policy vxlan_opts_policy[] = {
  515. - [OVS_VXLAN_EXT_GBP] = { .type = NL_A_U32 },
  516. + [OVS_VXLAN_EXT_GBP] = { .type = NL_A_U32 ,
  517. + .optional = true },
  518. + [OVS_VXLAN_EXT_GPE] = { .type = NL_A_U32 ,
  519. + .optional = true },
  520. };
  521. struct nlattr *ext[ARRAY_SIZE(vxlan_opts_policy)];
  522. @@ -1902,6 +1906,12 @@ odp_tun_key_from_attr__(const struct nlattr *attr,
  523. tun->gbp_id = htons(gbp & 0xFFFF);
  524. tun->gbp_flags = (gbp >> 16) & 0xFF;
  525. }
  526. + if (ext[OVS_VXLAN_EXT_GPE]) {
  527. + uint32_t gpe = nl_attr_get_u32(ext[OVS_VXLAN_EXT_GPE]);
  528. +
  529. + tun->gpe_np = gpe & 0xFF;
  530. + tun->gpe_flags = gpe >> 24;
  531. + }
  532. break;
  533. }
  534. @@ -1988,6 +1998,13 @@ tun_key_to_attr(struct ofpbuf *a, const struct flow_tnl *tun_key,
  535. nl_msg_put_u32(a, OVS_VXLAN_EXT_GBP,
  536. (tun_key->gbp_flags << 16) | ntohs(tun_key->gbp_id));
  537. nl_msg_end_nested(a, vxlan_opts_ofs);
  538. + } else if (tun_key->gpe_flags || tun_key->gpe_np) {
  539. + size_t vxlan_opts_ofs;
  540. +
  541. + vxlan_opts_ofs = nl_msg_start_nested(a, OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS);
  542. + nl_msg_put_u32(a, OVS_VXLAN_EXT_GPE,
  543. + (tun_key->gpe_flags << 24) | (tun_key->gpe_np));
  544. + nl_msg_end_nested(a, vxlan_opts_ofs);
  545. }
  546. tun_metadata_to_geneve_nlattr(tun_key, tun_flow_key, key_buf, a);
  547. @@ -2383,6 +2400,26 @@ format_odp_tun_vxlan_opt(const struct nlattr *attr,
  548. ds_put_cstr(ds, "),");
  549. break;
  550. }
  551. + case OVS_VXLAN_EXT_GPE: {
  552. + uint32_t key = nl_attr_get_u32(a);
  553. + uint8_t np, np_mask;
  554. + uint8_t flags, flags_mask;
  555. +
  556. + np = key & 0xFF;
  557. + flags = (key >> 24) & 0xFF;
  558. + if (ma) {
  559. + uint32_t mask = nl_attr_get_u32(ma);
  560. + np_mask = mask & 0xFF;
  561. + flags_mask = (mask >> 24) & 0xFF;
  562. + }
  563. +
  564. + ds_put_cstr(ds, "gpe(");
  565. + format_u8x(ds, "np", np, ma ? &np_mask : NULL, verbose);
  566. + format_u8x(ds, "flags", flags, ma ? &flags_mask : NULL, verbose);
  567. + ds_chomp(ds, ',');
  568. + ds_put_cstr(ds, "),");
  569. + break;
  570. + }
  571. default:
  572. format_unknown_key(ds, a, ma);
  573. @@ -3670,6 +3707,40 @@ scan_vxlan_gbp(const char *s, uint32_t *key, uint32_t *mask)
  574. }
  575. static int
  576. +scan_vxlan_gpe(const char *s, uint32_t *key, uint32_t *mask)
  577. +{
  578. + const char *s_base = s;
  579. + uint8_t np = 0, np_mask = 0;
  580. + uint8_t flags = 0, flags_mask = 0;
  581. +
  582. + if (!strncmp(s, "np=", 3)) {
  583. + s += 3;
  584. + s += scan_u8(s, &np, mask ? &np_mask : NULL);
  585. + }
  586. +
  587. + if (s[0] == ',') {
  588. + s++;
  589. + }
  590. + if (!strncmp(s, "flags=", 6)) {
  591. + s += 6;
  592. + s += scan_u8(s, &flags, mask ? &flags_mask : NULL);
  593. + }
  594. +
  595. + if (!strncmp(s, "))", 2)) {
  596. + s += 2;
  597. +
  598. + *key = (flags << 24) | np;
  599. + if (mask) {
  600. + *mask = (flags_mask << 24) | np_mask;
  601. + }
  602. +
  603. + return s - s_base;
  604. + }
  605. +
  606. + return 0;
  607. +}
  608. +
  609. +static int
  610. scan_geneve(const char *s, struct geneve_scan *key, struct geneve_scan *mask)
  611. {
  612. const char *s_base = s;
  613. @@ -3796,6 +3867,21 @@ vxlan_gbp_to_attr(struct ofpbuf *a, const void *data_)
  614. }
  615. static void
  616. +vxlan_gpe_to_attr(struct ofpbuf *a, const void *data_)
  617. +{
  618. + const uint32_t *gpe = data_;
  619. +
  620. + if (*gpe) {
  621. + size_t vxlan_opts_ofs;
  622. +
  623. + vxlan_opts_ofs = nl_msg_start_nested(a, OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS);
  624. + nl_msg_put_u32(a, OVS_VXLAN_EXT_GPE, *gpe);
  625. + nl_msg_end_nested(a, vxlan_opts_ofs);
  626. + }
  627. +}
  628. +
  629. +
  630. +static void
  631. geneve_to_attr(struct ofpbuf *a, const void *data_)
  632. {
  633. const struct geneve_scan *geneve = data_;
  634. @@ -4031,6 +4117,7 @@ parse_odp_key_mask_attr(const char *s, const struct simap *port_names,
  635. SCAN_FIELD_NESTED("tp_src=", ovs_be16, be16, OVS_TUNNEL_KEY_ATTR_TP_SRC);
  636. SCAN_FIELD_NESTED("tp_dst=", ovs_be16, be16, OVS_TUNNEL_KEY_ATTR_TP_DST);
  637. SCAN_FIELD_NESTED_FUNC("vxlan(gbp(", uint32_t, vxlan_gbp, vxlan_gbp_to_attr);
  638. + SCAN_FIELD_NESTED_FUNC("vxlan(gpe(", uint32_t, vxlan_gpe, vxlan_gpe_to_attr);
  639. SCAN_FIELD_NESTED_FUNC("geneve(", struct geneve_scan, geneve,
  640. geneve_to_attr);
  641. SCAN_FIELD_NESTED_FUNC("flags(", uint16_t, tun_flags, tun_flags_to_attr);
  642. diff --git a/lib/packets.h b/lib/packets.h
  643. index a8ea24b..dc97333 100644
  644. --- a/lib/packets.h
  645. +++ b/lib/packets.h
  646. @@ -49,7 +49,9 @@ struct flow_tnl {
  647. ovs_be16 tp_dst;
  648. ovs_be16 gbp_id;
  649. uint8_t gbp_flags;
  650. - uint8_t pad1[5]; /* Pad to 64 bits. */
  651. + uint8_t gpe_np;
  652. + uint8_t gpe_flags;
  653. + uint8_t pad1[3]; /* Pad to 64 bits. */
  654. struct tun_metadata metadata;
  655. };
  656. diff --git a/tests/ofproto.at b/tests/ofproto.at
  657. index fbb6d71..6c7217d 100644
  658. --- a/tests/ofproto.at
  659. +++ b/tests/ofproto.at
  660. @@ -1775,7 +1775,7 @@ head_table () {
  661. instructions: meter,apply_actions,clear_actions,write_actions,write_metadata,goto_table
  662. Write-Actions and Apply-Actions features:
  663. 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
  664. - 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
  665. + 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
  666. 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
  667. metadata in_port in_port_oxm pkt_mark ct_mark ct_label reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 xreg0 xreg1 xreg2 xreg3 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
  668. matching:
  669. @@ -1790,6 +1790,8 @@ metadata in_port in_port_oxm pkt_mark ct_mark ct_label reg0 reg1 reg2 reg3 reg4
  670. tun_flags: arbitrary mask
  671. tun_gbp_id: arbitrary mask
  672. tun_gbp_flags: arbitrary mask
  673. + tun_gpe_np: arbitrary mask
  674. + tun_gpe_flags: arbitrary mask
  675. tun_metadata0: arbitrary mask
  676. tun_metadata1: arbitrary mask
  677. tun_metadata2: arbitrary mask
  678. diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at
  679. index f26f622..dde603d 100644
  680. --- a/tests/ovs-ofctl.at
  681. +++ b/tests/ovs-ofctl.at
  682. @@ -17,6 +17,10 @@ for test_case in \
  683. 'tun_gbp_id=0/0x1 NXM,OXM' \
  684. 'tun_gbp_flags=0 NXM,OXM' \
  685. 'tun_gbp_flags=0/0x1 NXM,OXM' \
  686. + 'tun_gpe_np=0 NXM,OXM' \
  687. + 'tun_gpe_np=0/0x1 NXM,OXM' \
  688. + 'tun_gpe_flags=0 NXM,OXM' \
  689. + 'tun_gpe_flags=0/0x1 NXM,OXM' \
  690. 'tun_metadata0=0 NXM,OXM' \
  691. 'tun_metadata0=0/0x1 NXM,OXM' \
  692. 'tun_metadata0 NXM,OXM' \
  693. --
  694. 1.9.3