@@ -19,7 +19,7 @@ use super::{
1919 constants:: {
2020 ISOLATE_OPTION_FALSE , ISOLATE_OPTION_STRICT , ISOLATE_OPTION_TRUE ,
2121 NO_CONTAINER_INTERFACE_ERROR , OPTION_ISOLATE , OPTION_METRIC , OPTION_MTU ,
22- OPTION_NO_DEFAULT_ROUTE ,
22+ OPTION_NO_DEFAULT_ROUTE , OPTION_VRF ,
2323 } ,
2424 core_utils:: { self , get_ipam_addresses, join_netns, parse_option, CoreUtils } ,
2525 driver:: { self , DriverInfo } ,
@@ -50,6 +50,8 @@ struct InternalData {
5050 metric : Option < u32 > ,
5151 /// if set, no default gateway will be added
5252 no_default_route : bool ,
53+ /// sef vrf for bridge
54+ vrf : Option < String > ,
5355 // TODO: add vlan
5456}
5557
@@ -81,6 +83,7 @@ impl driver::NetworkDriver for Bridge<'_> {
8183 let metric: u32 = parse_option ( & self . info . network . options , OPTION_METRIC ) ?. unwrap_or ( 100 ) ;
8284 let no_default_route: bool =
8385 parse_option ( & self . info . network . options , OPTION_NO_DEFAULT_ROUTE ) ?. unwrap_or ( false ) ;
86+ let vrf: Option < String > = parse_option ( & self . info . network . options , OPTION_VRF ) ?;
8487
8588 let static_mac = match & self . info . per_network_opts . static_mac {
8689 Some ( mac) => Some ( CoreUtils :: decode_address_from_hex ( mac) ?) ,
@@ -96,6 +99,7 @@ impl driver::NetworkDriver for Bridge<'_> {
9699 isolate,
97100 metric : Some ( metric) ,
98101 no_default_route,
102+ vrf,
99103 } ) ;
100104 Ok ( ( ) )
101105 }
@@ -494,6 +498,15 @@ fn create_interfaces(
494498 InfoKind :: Bridge ,
495499 ) ;
496500 create_link_opts. mtu = data. mtu ;
501+
502+ if let Some ( vrf_name) = & data. vrf {
503+ let vrf = match host. get_link ( netlink:: LinkID :: Name ( vrf_name. to_string ( ) ) ) {
504+ Ok ( vrf) => check_link_is_vrf ( vrf, vrf_name) ?,
505+ Err ( err) => return Err ( err) . wrap ( "get vrf to set up bridge interface" ) ,
506+ } ;
507+ create_link_opts. primary_index = vrf. header . index ;
508+ }
509+
497510 host. create_link ( create_link_opts) . wrap ( "create bridge" ) ?;
498511
499512 if data. ipam . ipv6_enabled {
@@ -672,6 +685,30 @@ fn check_link_is_bridge(msg: LinkMessage, br_name: &str) -> NetavarkResult<LinkM
672685 ) ) )
673686}
674687
688+ /// make sure the LinkMessage is the kind VRF
689+ fn check_link_is_vrf ( msg : LinkMessage , vrf_name : & str ) -> NetavarkResult < LinkMessage > {
690+ for nla in msg. nlas . iter ( ) {
691+ if let Nla :: Info ( info) = nla {
692+ for inf in info. iter ( ) {
693+ if let Info :: Kind ( kind) = inf {
694+ if * kind == InfoKind :: Vrf {
695+ return Ok ( msg) ;
696+ } else {
697+ return Err ( NetavarkError :: Message ( format ! (
698+ "vrf {} already exists but is a {:?} interface" ,
699+ vrf_name, kind
700+ ) ) ) ;
701+ }
702+ }
703+ }
704+ }
705+ }
706+ Err ( NetavarkError :: Message ( format ! (
707+ "could not determine namespace link kind for vrf {}" ,
708+ vrf_name
709+ ) ) )
710+ }
711+
675712fn remove_link (
676713 host : & mut netlink:: Socket ,
677714 netns : & mut netlink:: Socket ,
0 commit comments