@@ -21,6 +21,9 @@ const ETH_P_IP: u16 = nix::libc::ETH_P_IP as u16;
2121/// EtherType for IPv6 packets (0x86DD).
2222const ETH_P_IPV6 : u16 = nix:: libc:: ETH_P_IPV6 as u16 ;
2323
24+ /// EtherType for matching all protocols supported by Ethernet.
25+ const ETH_P_ALL : u16 = nix:: libc:: ETH_P_ALL as u16 ;
26+
2427/// Compute an IPv4 netmask from a prefix length.
2528fn ipv4_mask ( prefix_len : u8 ) -> Ipv4Addr {
2629 if prefix_len == 0 {
@@ -82,9 +85,9 @@ pub struct FlowerFilterRequest {
8285}
8386
8487impl FlowerFilterRequest {
85- /// Create a new flower filter for the given destination IP.
88+ /// Create a new flower filter for the given destination IP
8689 ///
87- /// By default, uses /32 (exact match) for IPv4 or /128 for IPv6.
90+ /// By default, uses /32 (exact match) for IPv4 or /128 for IPv6 and root class id .
8891 pub fn new ( inner : QdiscRequestInner , destination : IpAddr ) -> Self {
8992 let default_mask = match destination {
9093 IpAddr :: V4 ( _) => 32 ,
@@ -95,7 +98,7 @@ impl FlowerFilterRequest {
9598 destination,
9699 mask : default_mask,
97100 // Default class ID will be set by caller
98- class_id : 0 ,
101+ class_id : u32 :: MAX , // Root class id
99102 }
100103 }
101104
@@ -213,6 +216,14 @@ struct TcU32Sel {
213216 // Followed by nkeys * tc_u32_key structures
214217}
215218
219+ impl TcU32Sel {
220+ /// Returns an instance of [`Self`] with all fields set to zero.
221+ #[ allow( dead_code) ]
222+ fn zero ( ) -> Self {
223+ Self { flags : 0 , offmask : 0 , offshift : 0 , nkeys : 0 , off : 0 , offoff : 0 , hoff : 0 , hmask : 0 }
224+ }
225+ }
226+
216227/// The kernel's `tc_u32_key` structure for u32 matching.
217228#[ derive( Debug , Clone , Copy , Default ) ]
218229struct TcU32Key {
@@ -226,6 +237,13 @@ struct TcU32Key {
226237 offmask : i32 ,
227238}
228239
240+ impl TcU32Key {
241+ /// Returns an instance of [`Self`] with all fields set to zero.
242+ fn zero ( ) -> Self {
243+ Self { mask : 0 , val : 0 , off : 0 , offmask : 0 }
244+ }
245+ }
246+
229247/// Builder for creating a u32 catch-all filter.
230248///
231249/// The u32 filter with `match u32 0 0` matches all packets. This is used as a catch-all
@@ -280,8 +298,8 @@ impl U32CatchallFilterRequest {
280298 pub fn new ( inner : QdiscRequestInner ) -> Self {
281299 Self {
282300 inner,
283- class_id : 0 ,
284- priority : 65535 , // Lowest priority = checked last
301+ class_id : u32 :: MAX , // Root class id.
302+ priority : 65535 , // Lowest priority = checked last
285303 }
286304 }
287305
@@ -304,10 +322,7 @@ impl U32CatchallFilterRequest {
304322 let mut tc_msg = TcMessage :: with_index ( self . inner . interface_index ) ;
305323 tc_msg. header . parent = self . inner . parent ;
306324 tc_msg. header . handle = TcHandle :: from ( 0u32 ) ;
307- // The info field contains the priority (in upper 16 bits) and protocol (in lower 16 bits)
308- // ETH_P_ALL (0x0003) matches all protocols
309- let eth_p_all: u16 = 0x0003 ;
310- tc_msg. header . info = ( ( self . priority as u32 ) << 16 ) | ( eth_p_all. to_be ( ) as u32 ) ;
325+ tc_msg. header . info = ( ( self . priority as u32 ) << 16 ) | ( ETH_P_ALL . to_be ( ) as u32 ) ;
311326
312327 tc_msg. attributes . push ( TcAttribute :: Kind ( "u32" . to_string ( ) ) ) ;
313328
@@ -320,7 +335,7 @@ impl U32CatchallFilterRequest {
320335
321336 // Mask of 0 means "don't care".
322337 // Value doesn't matter when mask is 0
323- let key = TcU32Key :: default ( ) ;
338+ let key = TcU32Key :: zero ( ) ;
324339
325340 // Serialize selector + key
326341 let mut sel_bytes = Vec :: with_capacity ( size_of :: < TcU32Sel > ( ) + size_of :: < TcU32Key > ( ) ) ;
0 commit comments