@@ -3,6 +3,7 @@ use std::{
33 os:: fd:: { AsFd , AsRawFd , BorrowedFd } ,
44} ;
55
6+
67use crate :: {
78 error:: { ErrorWrap , NetavarkError , NetavarkResult } ,
89 network:: constants,
@@ -612,3 +613,57 @@ pub fn parse_create_link_options(msg: &mut LinkMessage, options: CreateLinkOptio
612613 . push ( LinkAttribute :: NetNsFd ( netns. as_raw_fd ( ) ) ) ;
613614 }
614615}
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