aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch
diff options
context:
space:
mode:
Diffstat (limited to 'net/openvswitch')
-rw-r--r--net/openvswitch/Kconfig1
-rw-r--r--net/openvswitch/actions.c116
-rw-r--r--net/openvswitch/flow.c51
-rw-r--r--net/openvswitch/flow.h7
-rw-r--r--net/openvswitch/flow_netlink.c343
-rw-r--r--net/openvswitch/flow_netlink.h5
6 files changed, 521 insertions, 2 deletions
diff --git a/net/openvswitch/Kconfig b/net/openvswitch/Kconfig
index ce947292ae77..2650205cdaf9 100644
--- a/net/openvswitch/Kconfig
+++ b/net/openvswitch/Kconfig
@@ -14,6 +14,7 @@ config OPENVSWITCH
14 select MPLS 14 select MPLS
15 select NET_MPLS_GSO 15 select NET_MPLS_GSO
16 select DST_CACHE 16 select DST_CACHE
17 select NET_NSH
17 ---help--- 18 ---help---
18 Open vSwitch is a multilayer Ethernet switch targeted at virtualized 19 Open vSwitch is a multilayer Ethernet switch targeted at virtualized
19 environments. In addition to supporting a variety of features 20 environments. In addition to supporting a variety of features
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index a551232daf61..9a6a6d51e421 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -43,6 +43,7 @@
43#include "flow.h" 43#include "flow.h"
44#include "conntrack.h" 44#include "conntrack.h"
45#include "vport.h" 45#include "vport.h"
46#include "flow_netlink.h"
46 47
47struct deferred_action { 48struct deferred_action {
48 struct sk_buff *skb; 49 struct sk_buff *skb;
@@ -380,6 +381,38 @@ static int push_eth(struct sk_buff *skb, struct sw_flow_key *key,
380 return 0; 381 return 0;
381} 382}
382 383
384static int push_nsh(struct sk_buff *skb, struct sw_flow_key *key,
385 const struct nshhdr *nh)
386{
387 int err;
388
389 err = nsh_push(skb, nh);
390 if (err)
391 return err;
392
393 /* safe right before invalidate_flow_key */
394 key->mac_proto = MAC_PROTO_NONE;
395 invalidate_flow_key(key);
396 return 0;
397}
398
399static int pop_nsh(struct sk_buff *skb, struct sw_flow_key *key)
400{
401 int err;
402
403 err = nsh_pop(skb);
404 if (err)
405 return err;
406
407 /* safe right before invalidate_flow_key */
408 if (skb->protocol == htons(ETH_P_TEB))
409 key->mac_proto = MAC_PROTO_ETHERNET;
410 else
411 key->mac_proto = MAC_PROTO_NONE;
412 invalidate_flow_key(key);
413 return 0;
414}
415
383static void update_ip_l4_checksum(struct sk_buff *skb, struct iphdr *nh, 416static void update_ip_l4_checksum(struct sk_buff *skb, struct iphdr *nh,
384 __be32 addr, __be32 new_addr) 417 __be32 addr, __be32 new_addr)
385{ 418{
@@ -602,6 +635,69 @@ static int set_ipv6(struct sk_buff *skb, struct sw_flow_key *flow_key,
602 return 0; 635 return 0;
603} 636}
604 637
638static int set_nsh(struct sk_buff *skb, struct sw_flow_key *flow_key,
639 const struct nlattr *a)
640{
641 struct nshhdr *nh;
642 size_t length;
643 int err;
644 u8 flags;
645 u8 ttl;
646 int i;
647
648 struct ovs_key_nsh key;
649 struct ovs_key_nsh mask;
650
651 err = nsh_key_from_nlattr(a, &key, &mask);
652 if (err)
653 return err;
654
655 /* Make sure the NSH base header is there */
656 if (!pskb_may_pull(skb, skb_network_offset(skb) + NSH_BASE_HDR_LEN))
657 return -ENOMEM;
658
659 nh = nsh_hdr(skb);
660 length = nsh_hdr_len(nh);
661
662 /* Make sure the whole NSH header is there */
663 err = skb_ensure_writable(skb, skb_network_offset(skb) +
664 length);
665 if (unlikely(err))
666 return err;
667
668 nh = nsh_hdr(skb);
669 skb_postpull_rcsum(skb, nh, length);
670 flags = nsh_get_flags(nh);
671 flags = OVS_MASKED(flags, key.base.flags, mask.base.flags);
672 flow_key->nsh.base.flags = flags;
673 ttl = nsh_get_ttl(nh);
674 ttl = OVS_MASKED(ttl, key.base.ttl, mask.base.ttl);
675 flow_key->nsh.base.ttl = ttl;
676 nsh_set_flags_and_ttl(nh, flags, ttl);
677 nh->path_hdr = OVS_MASKED(nh->path_hdr, key.base.path_hdr,
678 mask.base.path_hdr);
679 flow_key->nsh.base.path_hdr = nh->path_hdr;
680 switch (nh->mdtype) {
681 case NSH_M_TYPE1:
682 for (i = 0; i < NSH_MD1_CONTEXT_SIZE; i++) {
683 nh->md1.context[i] =
684 OVS_MASKED(nh->md1.context[i], key.context[i],
685 mask.context[i]);
686 }
687 memcpy(flow_key->nsh.context, nh->md1.context,
688 sizeof(nh->md1.context));
689 break;
690 case NSH_M_TYPE2:
691 memset(flow_key->nsh.context, 0,
692 sizeof(flow_key->nsh.context));
693 break;
694 default:
695 return -EINVAL;
696 }
697 skb_postpush_rcsum(skb, nh, length);
698 return 0;
699}
700
605/* Must follow skb_ensure_writable() since that can move the skb data. */ 701/* Must follow skb_ensure_writable() since that can move the skb data. */
606static void set_tp_port(struct sk_buff *skb, __be16 *port, 702static void set_tp_port(struct sk_buff *skb, __be16 *port,
607 __be16 new_port, __sum16 *check) 703 __be16 new_port, __sum16 *check)
@@ -1024,6 +1120,10 @@ static int execute_masked_set_action(struct sk_buff *skb,
1024 get_mask(a, struct ovs_key_ethernet *)); 1120 get_mask(a, struct ovs_key_ethernet *));
1025 break; 1121 break;
1026 1122
1123 case OVS_KEY_ATTR_NSH:
1124 err = set_nsh(skb, flow_key, a);
1125 break;
1126
1027 case OVS_KEY_ATTR_IPV4: 1127 case OVS_KEY_ATTR_IPV4:
1028 err = set_ipv4(skb, flow_key, nla_data(a), 1128 err = set_ipv4(skb, flow_key, nla_data(a),
1029 get_mask(a, struct ovs_key_ipv4 *)); 1129 get_mask(a, struct ovs_key_ipv4 *));
@@ -1214,6 +1314,22 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
1214 case OVS_ACTION_ATTR_POP_ETH: 1314 case OVS_ACTION_ATTR_POP_ETH:
1215 err = pop_eth(skb, key); 1315 err = pop_eth(skb, key);
1216 break; 1316 break;
1317
1318 case OVS_ACTION_ATTR_PUSH_NSH: {
1319 u8 buffer[NSH_HDR_MAX_LEN];
1320 struct nshhdr *nh = (struct nshhdr *)buffer;
1321
1322 err = nsh_hdr_from_nlattr(nla_data(a), nh,
1323 NSH_HDR_MAX_LEN);
1324 if (unlikely(err))
1325 break;
1326 err = push_nsh(skb, key, nh);
1327 break;
1328 }
1329
1330 case OVS_ACTION_ATTR_POP_NSH:
1331 err = pop_nsh(skb, key);
1332 break;
1217 } 1333 }
1218 1334
1219 if (unlikely(err)) { 1335 if (unlikely(err)) {
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index 8c94cef25a72..864ddb1e3642 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -46,6 +46,7 @@
46#include <net/ipv6.h> 46#include <net/ipv6.h>
47#include <net/mpls.h> 47#include <net/mpls.h>
48#include <net/ndisc.h> 48#include <net/ndisc.h>
49#include <net/nsh.h>
49 50
50#include "conntrack.h" 51#include "conntrack.h"
51#include "datapath.h" 52#include "datapath.h"
@@ -490,6 +491,52 @@ invalid:
490 return 0; 491 return 0;
491} 492}
492 493
494static int parse_nsh(struct sk_buff *skb, struct sw_flow_key *key)
495{
496 struct nshhdr *nh;
497 unsigned int nh_ofs = skb_network_offset(skb);
498 u8 version, length;
499 int err;
500
501 err = check_header(skb, nh_ofs + NSH_BASE_HDR_LEN);
502 if (unlikely(err))
503 return err;
504
505 nh = nsh_hdr(skb);
506 version = nsh_get_ver(nh);
507 length = nsh_hdr_len(nh);
508
509 if (version != 0)
510 return -EINVAL;
511
512 err = check_header(skb, nh_ofs + length);
513 if (unlikely(err))
514 return err;
515
516 nh = nsh_hdr(skb);
517 key->nsh.base.flags = nsh_get_flags(nh);
518 key->nsh.base.ttl = nsh_get_ttl(nh);
519 key->nsh.base.mdtype = nh->mdtype;
520 key->nsh.base.np = nh->np;
521 key->nsh.base.path_hdr = nh->path_hdr;
522 switch (key->nsh.base.mdtype) {
523 case NSH_M_TYPE1:
524 if (length != NSH_M_TYPE1_LEN)
525 return -EINVAL;
526 memcpy(key->nsh.context, nh->md1.context,
527 sizeof(nh->md1));
528 break;
529 case NSH_M_TYPE2:
530 memset(key->nsh.context, 0,
531 sizeof(nh->md1));
532 break;
533 default:
534 return -EINVAL;
535 }
536
537 return 0;
538}
539
493/** 540/**
494 * key_extract - extracts a flow key from an Ethernet frame. 541 * key_extract - extracts a flow key from an Ethernet frame.
495 * @skb: sk_buff that contains the frame, with skb->data pointing to the 542 * @skb: sk_buff that contains the frame, with skb->data pointing to the
@@ -735,6 +782,10 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
735 memset(&key->tp, 0, sizeof(key->tp)); 782 memset(&key->tp, 0, sizeof(key->tp));
736 } 783 }
737 } 784 }
785 } else if (key->eth.type == htons(ETH_P_NSH)) {
786 error = parse_nsh(skb, key);
787 if (error)
788 return error;
738 } 789 }
739 return 0; 790 return 0;
740} 791}
diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h
index 1875bba4f865..c670dd24b8b7 100644
--- a/net/openvswitch/flow.h
+++ b/net/openvswitch/flow.h
@@ -35,6 +35,7 @@
35#include <net/inet_ecn.h> 35#include <net/inet_ecn.h>
36#include <net/ip_tunnels.h> 36#include <net/ip_tunnels.h>
37#include <net/dst_metadata.h> 37#include <net/dst_metadata.h>
38#include <net/nsh.h>
38 39
39struct sk_buff; 40struct sk_buff;
40 41
@@ -66,6 +67,11 @@ struct vlan_head {
66 (offsetof(struct sw_flow_key, recirc_id) + \ 67 (offsetof(struct sw_flow_key, recirc_id) + \
67 FIELD_SIZEOF(struct sw_flow_key, recirc_id)) 68 FIELD_SIZEOF(struct sw_flow_key, recirc_id))
68 69
70struct ovs_key_nsh {
71 struct ovs_nsh_key_base base;
72 __be32 context[NSH_MD1_CONTEXT_SIZE];
73};
74
69struct sw_flow_key { 75struct sw_flow_key {
70 u8 tun_opts[IP_TUNNEL_OPTS_MAX]; 76 u8 tun_opts[IP_TUNNEL_OPTS_MAX];
71 u8 tun_opts_len; 77 u8 tun_opts_len;
@@ -143,6 +149,7 @@ struct sw_flow_key {
143 } nd; 149 } nd;
144 }; 150 };
145 } ipv6; 151 } ipv6;
152 struct ovs_key_nsh nsh; /* network service header */
146 }; 153 };
147 struct { 154 struct {
148 /* Connection tracking fields not packed above. */ 155 /* Connection tracking fields not packed above. */
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index dc0d79092e74..4201f9293af3 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -48,6 +48,7 @@
48#include <net/ndisc.h> 48#include <net/ndisc.h>
49#include <net/mpls.h> 49#include <net/mpls.h>
50#include <net/vxlan.h> 50#include <net/vxlan.h>
51#include <net/tun_proto.h>
51#include <net/erspan.h> 52#include <net/erspan.h>
52 53
53#include "flow_netlink.h" 54#include "flow_netlink.h"
@@ -80,9 +81,11 @@ static bool actions_may_change_flow(const struct nlattr *actions)
80 case OVS_ACTION_ATTR_HASH: 81 case OVS_ACTION_ATTR_HASH:
81 case OVS_ACTION_ATTR_POP_ETH: 82 case OVS_ACTION_ATTR_POP_ETH:
82 case OVS_ACTION_ATTR_POP_MPLS: 83 case OVS_ACTION_ATTR_POP_MPLS:
84 case OVS_ACTION_ATTR_POP_NSH:
83 case OVS_ACTION_ATTR_POP_VLAN: 85 case OVS_ACTION_ATTR_POP_VLAN:
84 case OVS_ACTION_ATTR_PUSH_ETH: 86 case OVS_ACTION_ATTR_PUSH_ETH:
85 case OVS_ACTION_ATTR_PUSH_MPLS: 87 case OVS_ACTION_ATTR_PUSH_MPLS:
88 case OVS_ACTION_ATTR_PUSH_NSH:
86 case OVS_ACTION_ATTR_PUSH_VLAN: 89 case OVS_ACTION_ATTR_PUSH_VLAN:
87 case OVS_ACTION_ATTR_SAMPLE: 90 case OVS_ACTION_ATTR_SAMPLE:
88 case OVS_ACTION_ATTR_SET: 91 case OVS_ACTION_ATTR_SET:
@@ -175,7 +178,8 @@ static bool match_validate(const struct sw_flow_match *match,
175 | (1 << OVS_KEY_ATTR_ICMPV6) 178 | (1 << OVS_KEY_ATTR_ICMPV6)
176 | (1 << OVS_KEY_ATTR_ARP) 179 | (1 << OVS_KEY_ATTR_ARP)
177 | (1 << OVS_KEY_ATTR_ND) 180 | (1 << OVS_KEY_ATTR_ND)
178 | (1 << OVS_KEY_ATTR_MPLS)); 181 | (1 << OVS_KEY_ATTR_MPLS)
182 | (1 << OVS_KEY_ATTR_NSH));
179 183
180 /* Always allowed mask fields. */ 184 /* Always allowed mask fields. */
181 mask_allowed |= ((1 << OVS_KEY_ATTR_TUNNEL) 185 mask_allowed |= ((1 << OVS_KEY_ATTR_TUNNEL)
@@ -284,6 +288,14 @@ static bool match_validate(const struct sw_flow_match *match,
284 } 288 }
285 } 289 }
286 290
291 if (match->key->eth.type == htons(ETH_P_NSH)) {
292 key_expected |= 1 << OVS_KEY_ATTR_NSH;
293 if (match->mask &&
294 match->mask->key.eth.type == htons(0xffff)) {
295 mask_allowed |= 1 << OVS_KEY_ATTR_NSH;
296 }
297 }
298
287 if ((key_attrs & key_expected) != key_expected) { 299 if ((key_attrs & key_expected) != key_expected) {
288 /* Key attributes check failed. */ 300 /* Key attributes check failed. */
289 OVS_NLERR(log, "Missing key (keys=%llx, expected=%llx)", 301 OVS_NLERR(log, "Missing key (keys=%llx, expected=%llx)",
@@ -325,12 +337,25 @@ size_t ovs_tun_key_attr_size(void)
325 + nla_total_size(4); /* OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS */ 337 + nla_total_size(4); /* OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS */
326} 338}
327 339
340size_t ovs_nsh_key_attr_size(void)
341{
342 /* Whenever adding new OVS_NSH_KEY_ FIELDS, we should consider
343 * updating this function.
344 */
345 return nla_total_size(NSH_BASE_HDR_LEN) /* OVS_NSH_KEY_ATTR_BASE */
346 /* OVS_NSH_KEY_ATTR_MD1 and OVS_NSH_KEY_ATTR_MD2 are
347 * mutually exclusive, so the bigger one can cover
348 * the small one.
349 */
350 + nla_total_size(NSH_CTX_HDRS_MAX_LEN);
351}
352
328size_t ovs_key_attr_size(void) 353size_t ovs_key_attr_size(void)
329{ 354{
330 /* Whenever adding new OVS_KEY_ FIELDS, we should consider 355 /* Whenever adding new OVS_KEY_ FIELDS, we should consider
331 * updating this function. 356 * updating this function.
332 */ 357 */
333 BUILD_BUG_ON(OVS_KEY_ATTR_TUNNEL_INFO != 28); 358 BUILD_BUG_ON(OVS_KEY_ATTR_TUNNEL_INFO != 29);
334 359
335 return nla_total_size(4) /* OVS_KEY_ATTR_PRIORITY */ 360 return nla_total_size(4) /* OVS_KEY_ATTR_PRIORITY */
336 + nla_total_size(0) /* OVS_KEY_ATTR_TUNNEL */ 361 + nla_total_size(0) /* OVS_KEY_ATTR_TUNNEL */
@@ -344,6 +369,8 @@ size_t ovs_key_attr_size(void)
344 + nla_total_size(4) /* OVS_KEY_ATTR_CT_MARK */ 369 + nla_total_size(4) /* OVS_KEY_ATTR_CT_MARK */
345 + nla_total_size(16) /* OVS_KEY_ATTR_CT_LABELS */ 370 + nla_total_size(16) /* OVS_KEY_ATTR_CT_LABELS */
346 + nla_total_size(40) /* OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6 */ 371 + nla_total_size(40) /* OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6 */
372 + nla_total_size(0) /* OVS_KEY_ATTR_NSH */
373 + ovs_nsh_key_attr_size()
347 + nla_total_size(12) /* OVS_KEY_ATTR_ETHERNET */ 374 + nla_total_size(12) /* OVS_KEY_ATTR_ETHERNET */
348 + nla_total_size(2) /* OVS_KEY_ATTR_ETHERTYPE */ 375 + nla_total_size(2) /* OVS_KEY_ATTR_ETHERTYPE */
349 + nla_total_size(4) /* OVS_KEY_ATTR_VLAN */ 376 + nla_total_size(4) /* OVS_KEY_ATTR_VLAN */
@@ -377,6 +404,13 @@ static const struct ovs_len_tbl ovs_tunnel_key_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1]
377 [OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS] = { .len = sizeof(u32) }, 404 [OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS] = { .len = sizeof(u32) },
378}; 405};
379 406
407static const struct ovs_len_tbl
408ovs_nsh_key_attr_lens[OVS_NSH_KEY_ATTR_MAX + 1] = {
409 [OVS_NSH_KEY_ATTR_BASE] = { .len = sizeof(struct ovs_nsh_key_base) },
410 [OVS_NSH_KEY_ATTR_MD1] = { .len = sizeof(struct ovs_nsh_key_md1) },
411 [OVS_NSH_KEY_ATTR_MD2] = { .len = OVS_ATTR_VARIABLE },
412};
413
380/* The size of the argument for each %OVS_KEY_ATTR_* Netlink attribute. */ 414/* The size of the argument for each %OVS_KEY_ATTR_* Netlink attribute. */
381static const struct ovs_len_tbl ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = { 415static const struct ovs_len_tbl ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
382 [OVS_KEY_ATTR_ENCAP] = { .len = OVS_ATTR_NESTED }, 416 [OVS_KEY_ATTR_ENCAP] = { .len = OVS_ATTR_NESTED },
@@ -409,6 +443,8 @@ static const struct ovs_len_tbl ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
409 .len = sizeof(struct ovs_key_ct_tuple_ipv4) }, 443 .len = sizeof(struct ovs_key_ct_tuple_ipv4) },
410 [OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6] = { 444 [OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6] = {
411 .len = sizeof(struct ovs_key_ct_tuple_ipv6) }, 445 .len = sizeof(struct ovs_key_ct_tuple_ipv6) },
446 [OVS_KEY_ATTR_NSH] = { .len = OVS_ATTR_NESTED,
447 .next = ovs_nsh_key_attr_lens, },
412}; 448};
413 449
414static bool check_attr_len(unsigned int attr_len, unsigned int expected_len) 450static bool check_attr_len(unsigned int attr_len, unsigned int expected_len)
@@ -1227,6 +1263,221 @@ static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
1227 return 0; 1263 return 0;
1228} 1264}
1229 1265
1266int nsh_hdr_from_nlattr(const struct nlattr *attr,
1267 struct nshhdr *nh, size_t size)
1268{
1269 struct nlattr *a;
1270 int rem;
1271 u8 flags = 0;
1272 u8 ttl = 0;
1273 int mdlen = 0;
1274
1275 /* validate_nsh has check this, so we needn't do duplicate check here
1276 */
1277 if (size < NSH_BASE_HDR_LEN)
1278 return -ENOBUFS;
1279
1280 nla_for_each_nested(a, attr, rem) {
1281 int type = nla_type(a);
1282
1283 switch (type) {
1284 case OVS_NSH_KEY_ATTR_BASE: {
1285 const struct ovs_nsh_key_base *base = nla_data(a);
1286
1287 flags = base->flags;
1288 ttl = base->ttl;
1289 nh->np = base->np;
1290 nh->mdtype = base->mdtype;
1291 nh->path_hdr = base->path_hdr;
1292 break;
1293 }
1294 case OVS_NSH_KEY_ATTR_MD1:
1295 mdlen = nla_len(a);
1296 if (mdlen > size - NSH_BASE_HDR_LEN)
1297 return -ENOBUFS;
1298 memcpy(&nh->md1, nla_data(a), mdlen);
1299 break;
1300
1301 case OVS_NSH_KEY_ATTR_MD2:
1302 mdlen = nla_len(a);
1303 if (mdlen > size - NSH_BASE_HDR_LEN)
1304 return -ENOBUFS;
1305 memcpy(&nh->md2, nla_data(a), mdlen);
1306 break;
1307
1308 default:
1309 return -EINVAL;
1310 }
1311 }
1312
1313 /* nsh header length = NSH_BASE_HDR_LEN + mdlen */
1314 nh->ver_flags_ttl_len = 0;
1315 nsh_set_flags_ttl_len(nh, flags, ttl, NSH_BASE_HDR_LEN + mdlen);
1316
1317 return 0;
1318}
1319
1320int nsh_key_from_nlattr(const struct nlattr *attr,
1321 struct ovs_key_nsh *nsh, struct ovs_key_nsh *nsh_mask)
1322{
1323 struct nlattr *a;
1324 int rem;
1325
1326 /* validate_nsh has check this, so we needn't do duplicate check here
1327 */
1328 nla_for_each_nested(a, attr, rem) {
1329 int type = nla_type(a);
1330
1331 switch (type) {
1332 case OVS_NSH_KEY_ATTR_BASE: {
1333 const struct ovs_nsh_key_base *base = nla_data(a);
1334 const struct ovs_nsh_key_base *base_mask = base + 1;
1335
1336 nsh->base = *base;
1337 nsh_mask->base = *base_mask;
1338 break;
1339 }
1340 case OVS_NSH_KEY_ATTR_MD1: {
1341 const struct ovs_nsh_key_md1 *md1 = nla_data(a);
1342 const struct ovs_nsh_key_md1 *md1_mask = md1 + 1;
1343
1344 memcpy(nsh->context, md1->context, sizeof(*md1));
1345 memcpy(nsh_mask->context, md1_mask->context,
1346 sizeof(*md1_mask));
1347 break;
1348 }
1349 case OVS_NSH_KEY_ATTR_MD2:
1350 /* Not supported yet */
1351 return -ENOTSUPP;
1352 default:
1353 return -EINVAL;
1354 }
1355 }
1356
1357 return 0;
1358}
1359
1360static int nsh_key_put_from_nlattr(const struct nlattr *attr,
1361 struct sw_flow_match *match, bool is_mask,
1362 bool is_push_nsh, bool log)
1363{
1364 struct nlattr *a;
1365 int rem;
1366 bool has_base = false;
1367 bool has_md1 = false;
1368 bool has_md2 = false;
1369 u8 mdtype = 0;
1370 int mdlen = 0;
1371
1372 if (WARN_ON(is_push_nsh && is_mask))
1373 return -EINVAL;
1374
1375 nla_for_each_nested(a, attr, rem) {
1376 int type = nla_type(a);
1377 int i;
1378
1379 if (type > OVS_NSH_KEY_ATTR_MAX) {
1380 OVS_NLERR(log, "nsh attr %d is out of range max %d",
1381 type, OVS_NSH_KEY_ATTR_MAX);
1382 return -EINVAL;
1383 }
1384
1385 if (!check_attr_len(nla_len(a),
1386 ovs_nsh_key_attr_lens[type].len)) {
1387 OVS_NLERR(
1388 log,
1389 "nsh attr %d has unexpected len %d expected %d",
1390 type,
1391 nla_len(a),
1392 ovs_nsh_key_attr_lens[type].len
1393 );
1394 return -EINVAL;
1395 }
1396
1397 switch (type) {
1398 case OVS_NSH_KEY_ATTR_BASE: {
1399 const struct ovs_nsh_key_base *base = nla_data(a);
1400
1401 has_base = true;
1402 mdtype = base->mdtype;
1403 SW_FLOW_KEY_PUT(match, nsh.base.flags,
1404 base->flags, is_mask);
1405 SW_FLOW_KEY_PUT(match, nsh.base.ttl,
1406 base->ttl, is_mask);
1407 SW_FLOW_KEY_PUT(match, nsh.base.mdtype,
1408 base->mdtype, is_mask);
1409 SW_FLOW_KEY_PUT(match, nsh.base.np,
1410 base->np, is_mask);
1411 SW_FLOW_KEY_PUT(match, nsh.base.path_hdr,
1412 base->path_hdr, is_mask);
1413 break;
1414 }
1415 case OVS_NSH_KEY_ATTR_MD1: {
1416 const struct ovs_nsh_key_md1 *md1 = nla_data(a);
1417
1418 has_md1 = true;
1419 for (i = 0; i < NSH_MD1_CONTEXT_SIZE; i++)
1420 SW_FLOW_KEY_PUT(match, nsh.context[i],
1421 md1->context[i], is_mask);
1422 break;
1423 }
1424 case OVS_NSH_KEY_ATTR_MD2:
1425 if (!is_push_nsh) /* Not supported MD type 2 yet */
1426 return -ENOTSUPP;
1427
1428 has_md2 = true;
1429 mdlen = nla_len(a);
1430 if (mdlen > NSH_CTX_HDRS_MAX_LEN || mdlen <= 0) {
1431 OVS_NLERR(
1432 log,
1433 "Invalid MD length %d for MD type %d",
1434 mdlen,
1435 mdtype
1436 );
1437 return -EINVAL;
1438 }
1439 break;
1440 default:
1441 OVS_NLERR(log, "Unknown nsh attribute %d",
1442 type);
1443 return -EINVAL;
1444 }
1445 }
1446
1447 if (rem > 0) {
1448 OVS_NLERR(log, "nsh attribute has %d unknown bytes.", rem);
1449 return -EINVAL;
1450 }
1451
1452 if (has_md1 && has_md2) {
1453 OVS_NLERR(
1454 1,
1455 "invalid nsh attribute: md1 and md2 are exclusive."
1456 );
1457 return -EINVAL;
1458 }
1459
1460 if (!is_mask) {
1461 if ((has_md1 && mdtype != NSH_M_TYPE1) ||
1462 (has_md2 && mdtype != NSH_M_TYPE2)) {
1463 OVS_NLERR(1, "nsh attribute has unmatched MD type %d.",
1464 mdtype);
1465 return -EINVAL;
1466 }
1467
1468 if (is_push_nsh &&
1469 (!has_base || (!has_md1 && !has_md2))) {
1470 OVS_NLERR(
1471 1,
1472 "push_nsh: missing base or metadata attributes"
1473 );
1474 return -EINVAL;
1475 }
1476 }
1477
1478 return 0;
1479}
1480
1230static int ovs_key_from_nlattrs(struct net *net, struct sw_flow_match *match, 1481static int ovs_key_from_nlattrs(struct net *net, struct sw_flow_match *match,
1231 u64 attrs, const struct nlattr **a, 1482 u64 attrs, const struct nlattr **a,
1232 bool is_mask, bool log) 1483 bool is_mask, bool log)
@@ -1354,6 +1605,13 @@ static int ovs_key_from_nlattrs(struct net *net, struct sw_flow_match *match,
1354 attrs &= ~(1 << OVS_KEY_ATTR_ARP); 1605 attrs &= ~(1 << OVS_KEY_ATTR_ARP);
1355 } 1606 }
1356 1607
1608 if (attrs & (1 << OVS_KEY_ATTR_NSH)) {
1609 if (nsh_key_put_from_nlattr(a[OVS_KEY_ATTR_NSH], match,
1610 is_mask, false, log) < 0)
1611 return -EINVAL;
1612 attrs &= ~(1 << OVS_KEY_ATTR_NSH);
1613 }
1614
1357 if (attrs & (1 << OVS_KEY_ATTR_MPLS)) { 1615 if (attrs & (1 << OVS_KEY_ATTR_MPLS)) {
1358 const struct ovs_key_mpls *mpls_key; 1616 const struct ovs_key_mpls *mpls_key;
1359 1617
@@ -1670,6 +1928,34 @@ static int ovs_nla_put_vlan(struct sk_buff *skb, const struct vlan_head *vh,
1670 return 0; 1928 return 0;
1671} 1929}
1672 1930
1931static int nsh_key_to_nlattr(const struct ovs_key_nsh *nsh, bool is_mask,
1932 struct sk_buff *skb)
1933{
1934 struct nlattr *start;
1935
1936 start = nla_nest_start(skb, OVS_KEY_ATTR_NSH);
1937 if (!start)
1938 return -EMSGSIZE;
1939
1940 if (nla_put(skb, OVS_NSH_KEY_ATTR_BASE, sizeof(nsh->base), &nsh->base))
1941 goto nla_put_failure;
1942
1943 if (is_mask || nsh->base.mdtype == NSH_M_TYPE1) {
1944 if (nla_put(skb, OVS_NSH_KEY_ATTR_MD1,
1945 sizeof(nsh->context), nsh->context))
1946 goto nla_put_failure;
1947 }
1948
1949 /* Don't support MD type 2 yet */
1950
1951 nla_nest_end(skb, start);
1952
1953 return 0;
1954
1955nla_put_failure:
1956 return -EMSGSIZE;
1957}
1958
1673static int __ovs_nla_put_key(const struct sw_flow_key *swkey, 1959static int __ovs_nla_put_key(const struct sw_flow_key *swkey,
1674 const struct sw_flow_key *output, bool is_mask, 1960 const struct sw_flow_key *output, bool is_mask,
1675 struct sk_buff *skb) 1961 struct sk_buff *skb)
@@ -1798,6 +2084,9 @@ static int __ovs_nla_put_key(const struct sw_flow_key *swkey,
1798 ipv6_key->ipv6_tclass = output->ip.tos; 2084 ipv6_key->ipv6_tclass = output->ip.tos;
1799 ipv6_key->ipv6_hlimit = output->ip.ttl; 2085 ipv6_key->ipv6_hlimit = output->ip.ttl;
1800 ipv6_key->ipv6_frag = output->ip.frag; 2086 ipv6_key->ipv6_frag = output->ip.frag;
2087 } else if (swkey->eth.type == htons(ETH_P_NSH)) {
2088 if (nsh_key_to_nlattr(&output->nsh, is_mask, skb))
2089 goto nla_put_failure;
1801 } else if (swkey->eth.type == htons(ETH_P_ARP) || 2090 } else if (swkey->eth.type == htons(ETH_P_ARP) ||
1802 swkey->eth.type == htons(ETH_P_RARP)) { 2091 swkey->eth.type == htons(ETH_P_RARP)) {
1803 struct ovs_key_arp *arp_key; 2092 struct ovs_key_arp *arp_key;
@@ -2292,6 +2581,19 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
2292 return err; 2581 return err;
2293} 2582}
2294 2583
2584static bool validate_nsh(const struct nlattr *attr, bool is_mask,
2585 bool is_push_nsh, bool log)
2586{
2587 struct sw_flow_match match;
2588 struct sw_flow_key key;
2589 int ret = 0;
2590
2591 ovs_match_init(&match, &key, true, NULL);
2592 ret = nsh_key_put_from_nlattr(attr, &match, is_mask,
2593 is_push_nsh, log);
2594 return !ret;
2595}
2596
2295/* Return false if there are any non-masked bits set. 2597/* Return false if there are any non-masked bits set.
2296 * Mask follows data immediately, before any netlink padding. 2598 * Mask follows data immediately, before any netlink padding.
2297 */ 2599 */
@@ -2434,6 +2736,13 @@ static int validate_set(const struct nlattr *a,
2434 2736
2435 break; 2737 break;
2436 2738
2739 case OVS_KEY_ATTR_NSH:
2740 if (eth_type != htons(ETH_P_NSH))
2741 return -EINVAL;
2742 if (!validate_nsh(nla_data(a), masked, false, log))
2743 return -EINVAL;
2744 break;
2745
2437 default: 2746 default:
2438 return -EINVAL; 2747 return -EINVAL;
2439 } 2748 }
@@ -2533,6 +2842,8 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
2533 [OVS_ACTION_ATTR_TRUNC] = sizeof(struct ovs_action_trunc), 2842 [OVS_ACTION_ATTR_TRUNC] = sizeof(struct ovs_action_trunc),
2534 [OVS_ACTION_ATTR_PUSH_ETH] = sizeof(struct ovs_action_push_eth), 2843 [OVS_ACTION_ATTR_PUSH_ETH] = sizeof(struct ovs_action_push_eth),
2535 [OVS_ACTION_ATTR_POP_ETH] = 0, 2844 [OVS_ACTION_ATTR_POP_ETH] = 0,
2845 [OVS_ACTION_ATTR_PUSH_NSH] = (u32)-1,
2846 [OVS_ACTION_ATTR_POP_NSH] = 0,
2536 }; 2847 };
2537 const struct ovs_action_push_vlan *vlan; 2848 const struct ovs_action_push_vlan *vlan;
2538 int type = nla_type(a); 2849 int type = nla_type(a);
@@ -2690,6 +3001,34 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
2690 mac_proto = MAC_PROTO_ETHERNET; 3001 mac_proto = MAC_PROTO_ETHERNET;
2691 break; 3002 break;
2692 3003
3004 case OVS_ACTION_ATTR_PUSH_NSH:
3005 if (mac_proto != MAC_PROTO_ETHERNET) {
3006 u8 next_proto;
3007
3008 next_proto = tun_p_from_eth_p(eth_type);
3009 if (!next_proto)
3010 return -EINVAL;
3011 }
3012 mac_proto = MAC_PROTO_NONE;
3013 if (!validate_nsh(nla_data(a), false, true, true))
3014 return -EINVAL;
3015 break;
3016
3017 case OVS_ACTION_ATTR_POP_NSH: {
3018 __be16 inner_proto;
3019
3020 if (eth_type != htons(ETH_P_NSH))
3021 return -EINVAL;
3022 inner_proto = tun_p_to_eth_p(key->nsh.base.np);
3023 if (!inner_proto)
3024 return -EINVAL;
3025 if (key->nsh.base.np == TUN_P_ETHERNET)
3026 mac_proto = MAC_PROTO_ETHERNET;
3027 else
3028 mac_proto = MAC_PROTO_NONE;
3029 break;
3030 }
3031
2693 default: 3032 default:
2694 OVS_NLERR(log, "Unknown Action type %d", type); 3033 OVS_NLERR(log, "Unknown Action type %d", type);
2695 return -EINVAL; 3034 return -EINVAL;
diff --git a/net/openvswitch/flow_netlink.h b/net/openvswitch/flow_netlink.h
index 929c665ac3aa..6657606b2b47 100644
--- a/net/openvswitch/flow_netlink.h
+++ b/net/openvswitch/flow_netlink.h
@@ -79,4 +79,9 @@ int ovs_nla_put_actions(const struct nlattr *attr,
79void ovs_nla_free_flow_actions(struct sw_flow_actions *); 79void ovs_nla_free_flow_actions(struct sw_flow_actions *);
80void ovs_nla_free_flow_actions_rcu(struct sw_flow_actions *); 80void ovs_nla_free_flow_actions_rcu(struct sw_flow_actions *);
81 81
82int nsh_key_from_nlattr(const struct nlattr *attr, struct ovs_key_nsh *nsh,
83 struct ovs_key_nsh *nsh_mask);
84int nsh_hdr_from_nlattr(const struct nlattr *attr, struct nshhdr *nh,
85 size_t size);
86
82#endif /* flow_netlink.h */ 87#endif /* flow_netlink.h */