49
49
#include <net/mpls.h>
50
50
51
51
#include "flow_netlink.h"
52
+ #include "vport-vxlan.h"
52
53
53
54
struct ovs_len_tbl {
54
55
int len ;
@@ -268,6 +269,9 @@ size_t ovs_tun_key_attr_size(void)
268
269
+ nla_total_size (0 ) /* OVS_TUNNEL_KEY_ATTR_CSUM */
269
270
+ nla_total_size (0 ) /* OVS_TUNNEL_KEY_ATTR_OAM */
270
271
+ nla_total_size (256 ) /* OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS */
272
+ /* OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS is mutually exclusive with
273
+ * OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS and covered by it.
274
+ */
271
275
+ nla_total_size (2 ) /* OVS_TUNNEL_KEY_ATTR_TP_SRC */
272
276
+ nla_total_size (2 ); /* OVS_TUNNEL_KEY_ATTR_TP_DST */
273
277
}
@@ -308,6 +312,7 @@ static const struct ovs_len_tbl ovs_tunnel_key_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1]
308
312
[OVS_TUNNEL_KEY_ATTR_TP_DST ] = { .len = sizeof (u16 ) },
309
313
[OVS_TUNNEL_KEY_ATTR_OAM ] = { .len = 0 },
310
314
[OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS ] = { .len = OVS_ATTR_NESTED },
315
+ [OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS ] = { .len = OVS_ATTR_NESTED },
311
316
};
312
317
313
318
/* The size of the argument for each %OVS_KEY_ATTR_* Netlink attribute. */
@@ -460,6 +465,41 @@ static int genev_tun_opt_from_nlattr(const struct nlattr *a,
460
465
return 0 ;
461
466
}
462
467
468
+ static const struct nla_policy vxlan_opt_policy [OVS_VXLAN_EXT_MAX + 1 ] = {
469
+ [OVS_VXLAN_EXT_GBP ] = { .type = NLA_U32 },
470
+ };
471
+
472
+ static int vxlan_tun_opt_from_nlattr (const struct nlattr * a ,
473
+ struct sw_flow_match * match , bool is_mask ,
474
+ bool log )
475
+ {
476
+ struct nlattr * tb [OVS_VXLAN_EXT_MAX + 1 ];
477
+ unsigned long opt_key_offset ;
478
+ struct ovs_vxlan_opts opts ;
479
+ int err ;
480
+
481
+ BUILD_BUG_ON (sizeof (opts ) > sizeof (match -> key -> tun_opts ));
482
+
483
+ err = nla_parse_nested (tb , OVS_VXLAN_EXT_MAX , a , vxlan_opt_policy );
484
+ if (err < 0 )
485
+ return err ;
486
+
487
+ memset (& opts , 0 , sizeof (opts ));
488
+
489
+ if (tb [OVS_VXLAN_EXT_GBP ])
490
+ opts .gbp = nla_get_u32 (tb [OVS_VXLAN_EXT_GBP ]);
491
+
492
+ if (!is_mask )
493
+ SW_FLOW_KEY_PUT (match , tun_opts_len , sizeof (opts ), false);
494
+ else
495
+ SW_FLOW_KEY_PUT (match , tun_opts_len , 0xff , true);
496
+
497
+ opt_key_offset = TUN_METADATA_OFFSET (sizeof (opts ));
498
+ SW_FLOW_KEY_MEMCPY_OFFSET (match , opt_key_offset , & opts , sizeof (opts ),
499
+ is_mask );
500
+ return 0 ;
501
+ }
502
+
463
503
static int ipv4_tun_from_nlattr (const struct nlattr * attr ,
464
504
struct sw_flow_match * match , bool is_mask ,
465
505
bool log )
@@ -468,6 +508,7 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr,
468
508
int rem ;
469
509
bool ttl = false;
470
510
__be16 tun_flags = 0 ;
511
+ int opts_type = 0 ;
471
512
472
513
nla_for_each_nested (a , attr , rem ) {
473
514
int type = nla_type (a );
@@ -527,11 +568,30 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr,
527
568
tun_flags |= TUNNEL_OAM ;
528
569
break ;
529
570
case OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS :
571
+ if (opts_type ) {
572
+ OVS_NLERR (log , "Multiple metadata blocks provided" );
573
+ return - EINVAL ;
574
+ }
575
+
530
576
err = genev_tun_opt_from_nlattr (a , match , is_mask , log );
531
577
if (err )
532
578
return err ;
533
579
534
- tun_flags |= TUNNEL_OPTIONS_PRESENT ;
580
+ tun_flags |= TUNNEL_GENEVE_OPT ;
581
+ opts_type = type ;
582
+ break ;
583
+ case OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS :
584
+ if (opts_type ) {
585
+ OVS_NLERR (log , "Multiple metadata blocks provided" );
586
+ return - EINVAL ;
587
+ }
588
+
589
+ err = vxlan_tun_opt_from_nlattr (a , match , is_mask , log );
590
+ if (err )
591
+ return err ;
592
+
593
+ tun_flags |= TUNNEL_VXLAN_OPT ;
594
+ opts_type = type ;
535
595
break ;
536
596
default :
537
597
OVS_NLERR (log , "Unknown IPv4 tunnel attribute %d" ,
@@ -560,6 +620,23 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr,
560
620
}
561
621
}
562
622
623
+ return opts_type ;
624
+ }
625
+
626
+ static int vxlan_opt_to_nlattr (struct sk_buff * skb ,
627
+ const void * tun_opts , int swkey_tun_opts_len )
628
+ {
629
+ const struct ovs_vxlan_opts * opts = tun_opts ;
630
+ struct nlattr * nla ;
631
+
632
+ nla = nla_nest_start (skb , OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS );
633
+ if (!nla )
634
+ return - EMSGSIZE ;
635
+
636
+ if (nla_put_u32 (skb , OVS_VXLAN_EXT_GBP , opts -> gbp ) < 0 )
637
+ return - EMSGSIZE ;
638
+
639
+ nla_nest_end (skb , nla );
563
640
return 0 ;
564
641
}
565
642
@@ -596,10 +673,15 @@ static int __ipv4_tun_to_nlattr(struct sk_buff *skb,
596
673
if ((output -> tun_flags & TUNNEL_OAM ) &&
597
674
nla_put_flag (skb , OVS_TUNNEL_KEY_ATTR_OAM ))
598
675
return - EMSGSIZE ;
599
- if (tun_opts &&
600
- nla_put (skb , OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS ,
601
- swkey_tun_opts_len , tun_opts ))
602
- return - EMSGSIZE ;
676
+ if (tun_opts ) {
677
+ if (output -> tun_flags & TUNNEL_GENEVE_OPT &&
678
+ nla_put (skb , OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS ,
679
+ swkey_tun_opts_len , tun_opts ))
680
+ return - EMSGSIZE ;
681
+ else if (output -> tun_flags & TUNNEL_VXLAN_OPT &&
682
+ vxlan_opt_to_nlattr (skb , tun_opts , swkey_tun_opts_len ))
683
+ return - EMSGSIZE ;
684
+ }
603
685
604
686
return 0 ;
605
687
}
@@ -680,7 +762,7 @@ static int metadata_from_nlattrs(struct sw_flow_match *match, u64 *attrs,
680
762
}
681
763
if (* attrs & (1 << OVS_KEY_ATTR_TUNNEL )) {
682
764
if (ipv4_tun_from_nlattr (a [OVS_KEY_ATTR_TUNNEL ], match ,
683
- is_mask , log ))
765
+ is_mask , log ) < 0 )
684
766
return - EINVAL ;
685
767
* attrs &= ~(1 << OVS_KEY_ATTR_TUNNEL );
686
768
}
@@ -1578,17 +1660,23 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
1578
1660
struct sw_flow_key key ;
1579
1661
struct ovs_tunnel_info * tun_info ;
1580
1662
struct nlattr * a ;
1581
- int err , start ;
1663
+ int err , start , opts_type ;
1582
1664
1583
1665
ovs_match_init (& match , & key , NULL );
1584
- err = ipv4_tun_from_nlattr (nla_data (attr ), & match , false, log );
1585
- if (err )
1586
- return err ;
1666
+ opts_type = ipv4_tun_from_nlattr (nla_data (attr ), & match , false, log );
1667
+ if (opts_type < 0 )
1668
+ return opts_type ;
1587
1669
1588
1670
if (key .tun_opts_len ) {
1589
- err = validate_geneve_opts (& key );
1590
- if (err < 0 )
1591
- return err ;
1671
+ switch (opts_type ) {
1672
+ case OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS :
1673
+ err = validate_geneve_opts (& key );
1674
+ if (err < 0 )
1675
+ return err ;
1676
+ break ;
1677
+ case OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS :
1678
+ break ;
1679
+ }
1592
1680
};
1593
1681
1594
1682
start = add_nested_action_start (sfa , OVS_ACTION_ATTR_SET , log );
0 commit comments