@@ -110,27 +110,32 @@ impl TrafficFilterNewRequest {
110110
111111 /// The 32bit filter allows to match arbitrary bitfields in the packet.
112112 /// Equivalent to `tc filter ... u32`.
113- pub fn u32 ( mut self , data : Vec < tc:: u32:: Nla > ) -> Self {
114- assert ! ( ! self
113+ pub fn u32 ( mut self , data : Vec < tc:: u32:: Nla > ) -> Result < Self , Error > {
114+ if self
115115 . message
116116 . nlas
117117 . iter ( )
118- . any( |nla| matches!( nla, tc:: Nla :: Kind ( _) ) ) ) ;
118+ . any ( |nla| matches ! ( nla, tc:: Nla :: Kind ( _) ) )
119+ {
120+ return Err ( Error :: InvalidNla (
121+ "message kind has already been set." . to_string ( ) ,
122+ ) ) ;
123+ }
119124 self . message
120125 . nlas
121126 . push ( tc:: Nla :: Kind ( tc:: u32:: KIND . to_string ( ) ) ) ;
122127 self . message . nlas . push ( tc:: Nla :: Options (
123128 data. into_iter ( ) . map ( tc:: TcOpt :: U32 ) . collect ( ) ,
124129 ) ) ;
125- self
130+ Ok ( self )
126131 }
127132
128133 /// Use u32 to implement traffic redirect.
129134 /// Equivalent to
130135 /// `tc filter add [dev source] [parent ffff:] [protocol all] u32 match u8 0
131136 /// 0 action mirred egress redirect dev dest` You need to set the
132137 /// `parent` and `protocol` before call redirect.
133- pub fn redirect ( self , dst_index : u32 ) -> Self {
138+ pub fn redirect ( self , dst_index : u32 ) -> Result < Self , Error > {
134139 let mut sel_na = tc:: u32:: Sel :: default ( ) ;
135140 sel_na. flags = TC_U32_TERMINAL ;
136141 sel_na. nkeys = 1 ;
@@ -267,10 +272,22 @@ mod test {
267272 . parent ( 0xffff0000 )
268273 . protocol ( 0x0003 )
269274 . redirect ( test2. header . index )
275+ . unwrap ( )
270276 . execute ( )
271277 . await
272278 . unwrap ( ) ;
273279
280+ // Verify that attempting to set 2 redirects causes and error
281+ assert ! ( handle
282+ . traffic_filter( test1. header. index as i32 )
283+ . add( )
284+ . parent( 0xffff0000 )
285+ . protocol( 0x0003 )
286+ . redirect( test2. header. index)
287+ . unwrap( )
288+ . redirect( test1. header. index)
289+ . is_err( ) ) ;
290+
274291 let mut filters_iter = handle
275292 . traffic_filter ( test1. header . index as i32 )
276293 . get ( )
0 commit comments