3
3
/// flower filter
4
4
use std:: net:: { Ipv4Addr , Ipv6Addr } ;
5
5
6
- use anyhow:: Context ;
6
+ use anyhow:: { Context , Error } ;
7
7
use byteorder:: { BigEndian , ByteOrder , NativeEndian } ;
8
8
use netlink_packet_utils:: nla:: { NlasIterator , NLA_F_NESTED } ;
9
9
use netlink_packet_utils:: parsers:: {
@@ -814,19 +814,28 @@ impl Nla for FlowerAction {
814
814
#[ derive( Debug , PartialEq , Eq , Clone ) ]
815
815
struct FlowerActionList ( Vec < FlowerAction > ) ;
816
816
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 (
821
829
actions
822
830
. iter ( )
823
831
. enumerate ( )
824
832
. 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 ,
826
835
data : a. clone ( ) ,
827
836
} )
828
837
. collect :: < Vec < _ > > ( ) ,
829
- )
838
+ ) )
830
839
}
831
840
}
832
841
@@ -964,7 +973,9 @@ impl Nla for TcFilterFlowerOption {
964
973
Self :: ClassId ( _) => 4 ,
965
974
Self :: Indev ( b) => b. len ( ) ,
966
975
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()
968
979
}
969
980
Self :: KeyEthDst ( k) => k. as_slice ( ) . len ( ) ,
970
981
Self :: KeyEthDstMask ( k) => k. as_slice ( ) . len ( ) ,
@@ -1198,7 +1209,7 @@ impl Nla for TcFilterFlowerOption {
1198
1209
Self :: Indev ( b) => buffer. copy_from_slice ( b. as_slice ( ) ) ,
1199
1210
Self :: ClassId ( i) => NativeEndian :: write_u32 ( buffer, ( * i) . into ( ) ) ,
1200
1211
Self :: Action ( acts) => {
1201
- FlowerActionList :: from ( acts) . 0 . as_slice ( ) . emit ( buffer) ;
1212
+ acts. as_slice ( ) . emit ( buffer) ;
1202
1213
}
1203
1214
Self :: KeyEthDst ( k) => buffer. copy_from_slice ( k. as_slice ( ) ) ,
1204
1215
Self :: KeyEthDstMask ( k) => buffer. copy_from_slice ( k. as_slice ( ) ) ,
@@ -1208,6 +1219,9 @@ impl Nla for TcFilterFlowerOption {
1208
1219
buffer. copy_from_slice ( eth_type. as_be_bytes ( ) . as_slice ( ) ) ;
1209
1220
}
1210
1221
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) ]
1211
1225
buffer. copy_from_slice ( & [ i32:: from ( * proto) as u8 ] ) ;
1212
1226
}
1213
1227
Self :: KeyIpv4Src ( ip) => buffer. copy_from_slice ( & ip. octets ( ) ) ,
@@ -1338,9 +1352,11 @@ impl Nla for TcFilterFlowerOption {
1338
1352
buffer. copy_from_slice ( label. to_ne_bytes ( ) . as_slice ( ) ) ;
1339
1353
}
1340
1354
Self :: KeyTcpFlags ( flags) => buffer. copy_from_slice (
1355
+ #[ allow( clippy:: cast_lossless) ]
1341
1356
( flags. bits ( ) as u16 ) . to_be_bytes ( ) . as_slice ( ) ,
1342
1357
) ,
1343
1358
Self :: KeyTcpFlagsMask ( flags) => {
1359
+ #[ allow( clippy:: cast_lossless) ]
1344
1360
buffer. copy_from_slice ( ( * flags as u16 ) . to_be_bytes ( ) . as_slice ( ) ) ;
1345
1361
}
1346
1362
Self :: KeyIpTos ( tos) => {
@@ -1497,10 +1513,8 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>>
1497
1513
Self :: KeyEthType ( EthType :: from ( eth_type) )
1498
1514
}
1499
1515
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 ) ;
1504
1518
Self :: KeyIpProto ( proto)
1505
1519
}
1506
1520
TCA_FLOWER_KEY_IPV4_SRC => {
0 commit comments