33/// flower filter
44use std:: net:: { Ipv4Addr , Ipv6Addr } ;
55
6- use anyhow:: Context ;
6+ use anyhow:: { Context , Error } ;
77use byteorder:: { BigEndian , ByteOrder , NativeEndian } ;
88use netlink_packet_utils:: nla:: { NlasIterator , NLA_F_NESTED } ;
99use netlink_packet_utils:: parsers:: {
@@ -814,19 +814,28 @@ impl Nla for FlowerAction {
814814#[ derive( Debug , PartialEq , Eq , Clone ) ]
815815struct FlowerActionList ( Vec < FlowerAction > ) ;
816816
817- impl From < & Vec < TcAction > > for FlowerActionList {
818- fn from ( actions : & Vec < TcAction > ) -> Self {
819- Self (
820- actions
817+ impl TryFrom < & Vec < TcAction > > for FlowerActionList {
818+ type Error = Error ;
819+
820+ /// # Errors
821+ /// Returns an error if the number of actions is greater than `u16::MAX - 1`.
822+ fn try_from ( actions : & Vec < TcAction > ) -> Result < Self , Self :: Error > {
823+ if actions. len ( ) > ( u16:: MAX - 1 ) as usize {
824+ return Err ( Error :: msg (
825+ "Too many actions for flower filter" ,
826+ ) ) ;
827+ } ;
828+ Ok ( Self (
821829 actions
822830 . iter ( )
823831 . enumerate ( )
824832 . map ( |( i, a) | FlowerAction {
825- index : ( i as u16 ) + 1 ,
833+ #[ allow( clippy:: cast_possible_truncation) ]
834+ index : ( ( i & ( u16:: MAX as usize ) ) as u16 ) + 1 ,
826835 data : a. clone ( ) ,
827836 } )
828837 . collect :: < Vec < _ > > ( ) ,
829- )
838+ ) )
830839 }
831840}
832841
@@ -964,7 +973,9 @@ impl Nla for TcFilterFlowerOption {
964973 Self :: ClassId ( _) => 4 ,
965974 Self :: Indev ( b) => b. len ( ) ,
966975 Self :: Action ( acts) => {
967- FlowerActionList :: from ( acts) . 0 . as_slice ( ) . buffer_len ( )
976+ acts. as_slice ( ) . buffer_len ( )
977+ // TODO: I despise this unwrap.
978+ // FlowerActionList::try_from(acts).unwrap().0.as_slice().buffer_len()
968979 }
969980 Self :: KeyEthDst ( k) => k. as_slice ( ) . len ( ) ,
970981 Self :: KeyEthDstMask ( k) => k. as_slice ( ) . len ( ) ,
@@ -1198,7 +1209,7 @@ impl Nla for TcFilterFlowerOption {
11981209 Self :: Indev ( b) => buffer. copy_from_slice ( b. as_slice ( ) ) ,
11991210 Self :: ClassId ( i) => NativeEndian :: write_u32 ( buffer, ( * i) . into ( ) ) ,
12001211 Self :: Action ( acts) => {
1201- FlowerActionList :: from ( acts) . 0 . as_slice ( ) . emit ( buffer) ;
1212+ acts. as_slice ( ) . emit ( buffer) ;
12021213 }
12031214 Self :: KeyEthDst ( k) => buffer. copy_from_slice ( k. as_slice ( ) ) ,
12041215 Self :: KeyEthDstMask ( k) => buffer. copy_from_slice ( k. as_slice ( ) ) ,
@@ -1208,6 +1219,9 @@ impl Nla for TcFilterFlowerOption {
12081219 buffer. copy_from_slice ( eth_type. as_be_bytes ( ) . as_slice ( ) ) ;
12091220 }
12101221 Self :: KeyIpProto ( proto) => {
1222+ // TODO: find a way to make clippy happy with this.
1223+ // I think this is safe but that should be explained.
1224+ #[ allow( clippy:: cast_sign_loss, clippy:: cast_possible_truncation) ]
12111225 buffer. copy_from_slice ( & [ i32:: from ( * proto) as u8 ] ) ;
12121226 }
12131227 Self :: KeyIpv4Src ( ip) => buffer. copy_from_slice ( & ip. octets ( ) ) ,
@@ -1338,9 +1352,11 @@ impl Nla for TcFilterFlowerOption {
13381352 buffer. copy_from_slice ( label. to_ne_bytes ( ) . as_slice ( ) ) ;
13391353 }
13401354 Self :: KeyTcpFlags ( flags) => buffer. copy_from_slice (
1355+ #[ allow( clippy:: cast_lossless) ]
13411356 ( flags. bits ( ) as u16 ) . to_be_bytes ( ) . as_slice ( ) ,
13421357 ) ,
13431358 Self :: KeyTcpFlagsMask ( flags) => {
1359+ #[ allow( clippy:: cast_lossless) ]
13441360 buffer. copy_from_slice ( ( * flags as u16 ) . to_be_bytes ( ) . as_slice ( ) ) ;
13451361 }
13461362 Self :: KeyIpTos ( tos) => {
@@ -1497,10 +1513,8 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>>
14971513 Self :: KeyEthType ( EthType :: from ( eth_type) )
14981514 }
14991515 TCA_FLOWER_KEY_IP_PROTO => {
1500- if payload. len ( ) != 1 {
1501- return Err ( DecodeError :: from ( "invalid ip proto length" ) ) ;
1502- }
1503- let proto = IpProtocol :: from ( payload[ 0 ] as i32 ) ;
1516+ #[ allow( clippy:: cast_lossless) ]
1517+ let proto = IpProtocol :: from ( parse_u8 ( payload) ? as i32 ) ;
15041518 Self :: KeyIpProto ( proto)
15051519 }
15061520 TCA_FLOWER_KEY_IPV4_SRC => {
0 commit comments