@@ -3,6 +3,7 @@ use std::{
3
3
os:: fd:: { AsFd , AsRawFd , BorrowedFd } ,
4
4
} ;
5
5
6
+
6
7
use crate :: {
7
8
error:: { ErrorWrap , NetavarkError , NetavarkResult } ,
8
9
network:: constants,
@@ -612,3 +613,57 @@ pub fn parse_create_link_options(msg: &mut LinkMessage, options: CreateLinkOptio
612
613
. push ( LinkAttribute :: NetNsFd ( netns. as_raw_fd ( ) ) ) ;
613
614
}
614
615
}
616
+
617
+
618
+ use log:: { info, warn} ;
619
+ use rtnetlink:: { new_connection, Error } ;
620
+ use futures:: stream:: TryStreamExt ;
621
+
622
+
623
+ pub fn allow_dhcp_on_vlan ( bridge_name : & str , vlan_id : u16 ) -> Result < ( ) , Error > {
624
+ info ! (
625
+ "Applying DHCP allow rule on VLAN {} for bridge {}" ,
626
+ vlan_id, bridge_name
627
+ ) ;
628
+
629
+ // Build VLAN subinterface name (e.g., br0.100)
630
+ let vlan_iface = format ! ( "{}.{}" , bridge_name, vlan_id) ;
631
+
632
+ // Create netlink connection
633
+ let ( connection, handle, _) = new_connection ( ) ?;
634
+ tokio:: spawn ( connection) ;
635
+
636
+ // Lookup VLAN interface by name
637
+ let mut rt = tokio:: runtime:: Runtime :: new ( ) . unwrap ( ) ;
638
+ let mut links = rt. block_on (
639
+ handle
640
+ . link ( )
641
+ . get ( )
642
+ . match_name ( vlan_iface. clone ( ) )
643
+ . execute ( )
644
+ ) ;
645
+
646
+ match rt. block_on ( links. try_next ( ) ) {
647
+ Ok ( Some ( _link) ) => {
648
+ info ! (
649
+ "Found VLAN interface {}, would configure bridge VLAN filtering to allow DHCP (UDP 67/68)" ,
650
+ vlan_iface
651
+ ) ;
652
+ // TODO: implement actual VLAN filtering adjustment here
653
+ }
654
+ Ok ( None ) => {
655
+ warn ! (
656
+ "VLAN interface {} not found, skipping DHCP allow rule" ,
657
+ vlan_iface
658
+ ) ;
659
+ }
660
+ Err ( e) => {
661
+ warn ! (
662
+ "Error looking up VLAN interface {}: {}" ,
663
+ vlan_iface, e
664
+ ) ;
665
+ }
666
+ }
667
+
668
+ Ok ( ( ) )
669
+ }
0 commit comments