From 207c689f560de2963210d245ae718b1f09d9eaae Mon Sep 17 00:00:00 2001 From: Andre Fredette Date: Thu, 4 Aug 2022 10:23:04 -0400 Subject: [PATCH] Add support for setting priority for classifier programs Addresses issue #358 Signed-off-by: Andre Fredette --- aya/src/programs/tc.rs | 18 ++++++++++++------ aya/src/sys/netlink.rs | 16 ++++++++-------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/aya/src/programs/tc.rs b/aya/src/programs/tc.rs index a3f3eeb7..787d9ae8 100644 --- a/aya/src/programs/tc.rs +++ b/aya/src/programs/tc.rs @@ -64,7 +64,7 @@ pub enum TcAttachType { /// /// let prog: &mut SchedClassifier = bpf.program_mut("redirect_ingress").unwrap().try_into()?; /// prog.load()?; -/// prog.attach("eth0", TcAttachType::Ingress)?; +/// prog.attach("eth0", TcAttachType::Ingress, 0)?; /// /// # Ok::<(), Error>(()) /// ``` @@ -108,6 +108,10 @@ impl SchedClassifier { /// Attaches the program to the given `interface`. /// + /// Valid priority values range from 0 - 65535 with lower number = higher priority. + /// 0 means let the system choose the next highest priority, or 49152 if no filters exist yet. + /// All other values in the range are taken as an explicit priority setting (aka "preference"). + /// /// The returned value can be used to detach, see [SchedClassifier::detach]. /// /// # Errors @@ -120,13 +124,15 @@ impl SchedClassifier { &mut self, interface: &str, attach_type: TcAttachType, + priority: u16, ) -> Result { let prog_fd = self.data.fd_or_err()?; let if_index = ifindex_from_ifname(interface) .map_err(|io_error| TcError::NetlinkError { io_error })?; - let priority = - unsafe { netlink_qdisc_attach(if_index as i32, &attach_type, prog_fd, &self.name) } - .map_err(|io_error| TcError::NetlinkError { io_error })?; + let priority = unsafe { + netlink_qdisc_attach(if_index as i32, &attach_type, prog_fd, &self.name, priority) + } + .map_err(|io_error| TcError::NetlinkError { io_error })?; self.data.links.insert(SchedClassifierLink(TcLink { if_index: if_index as i32, @@ -155,13 +161,13 @@ impl SchedClassifier { } #[derive(Debug, Hash, Eq, PartialEq)] -pub(crate) struct TcLinkId(i32, TcAttachType, u32); +pub(crate) struct TcLinkId(i32, TcAttachType, u16); #[derive(Debug)] struct TcLink { if_index: i32, attach_type: TcAttachType, - priority: u32, + priority: u16, } impl Link for TcLink { diff --git a/aya/src/sys/netlink.rs b/aya/src/sys/netlink.rs index 028200a8..2f20aba3 100644 --- a/aya/src/sys/netlink.rs +++ b/aya/src/sys/netlink.rs @@ -103,9 +103,9 @@ pub(crate) unsafe fn netlink_qdisc_attach( attach_type: &TcAttachType, prog_fd: RawFd, prog_name: &CStr, -) -> Result { + priority: u16, +) -> Result { let sock = NetlinkSocket::open()?; - let priority = 0; let mut req = mem::zeroed::(); let nlmsg_len = mem::size_of::() + mem::size_of::(); @@ -120,7 +120,7 @@ pub(crate) unsafe fn netlink_qdisc_attach( req.tc_info.tcm_handle = 0; // auto-assigned, if not provided req.tc_info.tcm_ifindex = if_index; req.tc_info.tcm_parent = attach_type.parent(); - req.tc_info.tcm_info = tc_handler_make(priority << 16, htons(ETH_P_ALL as u16) as u32); + req.tc_info.tcm_info = tc_handler_make((priority as u32) << 16, htons(ETH_P_ALL as u16) as u32); let attrs_buf = request_attributes(&mut req, nlmsg_len); @@ -159,14 +159,14 @@ pub(crate) unsafe fn netlink_qdisc_attach( } }; - let priority = ((tc_info & TC_H_MAJ_MASK) >> 16) as u32; + let priority = ((tc_info & TC_H_MAJ_MASK) >> 16) as u16; Ok(priority) } pub(crate) unsafe fn netlink_qdisc_detach( if_index: i32, attach_type: &TcAttachType, - priority: u32, + priority: u16, ) -> Result<(), io::Error> { let sock = NetlinkSocket::open()?; let mut req = mem::zeroed::(); @@ -181,7 +181,7 @@ pub(crate) unsafe fn netlink_qdisc_detach( req.tc_info.tcm_family = AF_UNSPEC as u8; req.tc_info.tcm_handle = 0; // auto-assigned, if not provided - req.tc_info.tcm_info = tc_handler_make(priority << 16, htons(ETH_P_ALL as u16) as u32); + req.tc_info.tcm_info = tc_handler_make((priority as u32) << 16, htons(ETH_P_ALL as u16) as u32); req.tc_info.tcm_parent = attach_type.parent(); req.tc_info.tcm_ifindex = if_index; @@ -196,7 +196,7 @@ pub(crate) unsafe fn netlink_find_filter_with_name( if_index: i32, attach_type: TcAttachType, name: &CStr, -) -> Result, io::Error> { +) -> Result, io::Error> { let mut req = mem::zeroed::(); let nlmsg_len = mem::size_of::() + mem::size_of::(); @@ -222,7 +222,7 @@ pub(crate) unsafe fn netlink_find_filter_with_name( } let tc_msg = ptr::read_unaligned(msg.data.as_ptr() as *const tcmsg); - let priority = tc_msg.tcm_info >> 16; + let priority = (tc_msg.tcm_info >> 16) as u16; let attrs = parse_attrs(&msg.data[mem::size_of::()..])?; if let Some(opts) = attrs.get(&(TCA_OPTIONS as u16)) {