Add ability to resolve (and cache) multicast groups for a given family name#12
Add ability to resolve (and cache) multicast groups for a given family name#12Ragnt wants to merge 4 commits into
Conversation
|
|
||
| use crate::{error::GenetlinkError, GenetlinkHandle}; | ||
| use futures::{future::Either, StreamExt}; | ||
| use log::{error, trace, warn}; |
There was a problem hiding this comment.
I think adding
#[macro_use]
extern crate log;in lib.rs is acceptable.
Since it is widely used in many Rust project today.
There was a problem hiding this comment.
I hadn't realized I added the logging, obviously it was for debugging so it doesn't matter to me either way.
|
I found that I also don't have write access to this repository... |
Co-authored-by: Shao-Fu Chen <leo881003@gmail.com>
| trace!("Creating GenlMessage for CTRL_CMD_GETFAMILY"); | ||
| let mut genlmsg: GenlMessage<GenlCtrl> = GenlMessage::from_payload(GenlCtrl { | ||
| cmd: GenlCtrlCmd::GetFamily, | ||
| nlas: vec![GenlCtrlAttrs::FamilyId(family_id)], |
There was a problem hiding this comment.
This should also work with GenlCtrlAttrs::FamilyName so you don't have to resolve the family id here.
| } | ||
| } | ||
|
|
||
| pub fn query_family_multicast_groups( |
There was a problem hiding this comment.
This functions always sends out a netlink request compared to query_family_id. I don't have a preference, but wanted to point out this inconsistency.
| trace!("Processing InnerMessage: {:?}", genlmsg); | ||
| for nla in genlmsg.payload.nlas { | ||
| trace!("Processing NLA: {:?}", nla); | ||
| if let GenlCtrlAttrs::McastGroups(groups) = nla { | ||
| trace!("Found McastGroups: {:?}", groups); | ||
| for group in groups { | ||
| // 'group' is a Vec<McastGrpAttrs> | ||
| let mut group_name = None; | ||
| let mut group_id = None; | ||
|
|
||
| for group_attr in group { | ||
| trace!("Processing group_attr: {:?}", group_attr); | ||
| match group_attr { | ||
| McastGrpAttrs::Name(ref name) => { | ||
| group_name = Some(name.clone()); | ||
| trace!("Found group name: '{}'", name); | ||
| } | ||
| McastGrpAttrs::Id(id) => { | ||
| group_id = Some(id); | ||
| trace!("Found group id: {}", id); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if let (Some(name), Some(id)) = (group_name, group_id) { | ||
| mc_groups.insert(name.clone(), id); | ||
| trace!( | ||
| "Inserted group '{}' with id {} into mc_groups", | ||
| name, | ||
| id | ||
| ); | ||
| } | ||
| } | ||
| } else { | ||
| trace!("Unhandled NLA: {:?}", nla); | ||
| } | ||
| } |
There was a problem hiding this comment.
This could probably be written a little more concise:
| trace!("Processing InnerMessage: {:?}", genlmsg); | |
| for nla in genlmsg.payload.nlas { | |
| trace!("Processing NLA: {:?}", nla); | |
| if let GenlCtrlAttrs::McastGroups(groups) = nla { | |
| trace!("Found McastGroups: {:?}", groups); | |
| for group in groups { | |
| // 'group' is a Vec<McastGrpAttrs> | |
| let mut group_name = None; | |
| let mut group_id = None; | |
| for group_attr in group { | |
| trace!("Processing group_attr: {:?}", group_attr); | |
| match group_attr { | |
| McastGrpAttrs::Name(ref name) => { | |
| group_name = Some(name.clone()); | |
| trace!("Found group name: '{}'", name); | |
| } | |
| McastGrpAttrs::Id(id) => { | |
| group_id = Some(id); | |
| trace!("Found group id: {}", id); | |
| } | |
| } | |
| } | |
| if let (Some(name), Some(id)) = (group_name, group_id) { | |
| mc_groups.insert(name.clone(), id); | |
| trace!( | |
| "Inserted group '{}' with id {} into mc_groups", | |
| name, | |
| id | |
| ); | |
| } | |
| } | |
| } else { | |
| trace!("Unhandled NLA: {:?}", nla); | |
| } | |
| } | |
| // One specific family id was requested, it can be assumed, that the mcast | |
| // groups are part of that family. | |
| let Some(mcast_groups) = genlmsg | |
| .payload | |
| .nlas | |
| .into_iter() | |
| .filter_map(|attr| match attr { | |
| GenlCtrlAttrs::McastGroups(groups) => { | |
| Some(groups) | |
| } | |
| _ => None, | |
| }) | |
| .next() | |
| else { | |
| continue; | |
| }; | |
| for group in mcast_groups.into_iter().filter_map(|attrs| { | |
| match attrs.as_slice() { | |
| [McastGrpAttrs::Name(name), McastGrpAttrs::Id(i)] | | |
| [McastGrpAttrs::Id(i), McastGrpAttrs::Name(name)] => Some((name.clone(), *i)), | |
| _ => None | |
| } | |
| }) { | |
| mc_groups.insert(group.0, group.1); | |
| } |
|
|
||
| } | ||
|
|
||
| #[cfg(all(test, tokio_socket))] |
There was a problem hiding this comment.
The tests are actually never run and always disabled ...
| #[cfg(all(test, tokio_socket))] | |
| #[cfg(all(test, feature = "tokio_socket"))] |
|
It been a while. Any progress? |
flaviosousamato244-design
left a comment
There was a problem hiding this comment.
Hola seus exorcista
This was a quick add. I didn't want to disturb the existing function as it would break current implementations, but this adds the functionality without (hopefully) breaking anything.