import nispor-1.1.0-2.el8
This commit is contained in:
parent
b4b0764fab
commit
83c7df05f4
375
SOURCES/0001-npc-Show-brief-network-state-when-no-argument.patch
Normal file
375
SOURCES/0001-npc-Show-brief-network-state-when-no-argument.patch
Normal file
@ -0,0 +1,375 @@
|
||||
From 69cc9aaf259d4c55b74d7b75037992431136ba42 Mon Sep 17 00:00:00 2001
|
||||
From: Gris Ge <fge@redhat.com>
|
||||
Date: Fri, 28 May 2021 18:18:13 +0800
|
||||
Subject: [PATCH 1/3] npc: Show brief network state when no argument
|
||||
|
||||
When running `npc` without any argument, instead of dumping all
|
||||
information, this patch changed to show brief network status.
|
||||
|
||||
Added new sub command `iface` to `npc` for old behaviour:
|
||||
|
||||
* `npc eth1` -- show eth1 interface info.
|
||||
* `npc iface eth1` -- the same as `npc eth1`.
|
||||
* `npc iface` -- show full information in yaml format.
|
||||
* `npc` -- show brief network state.
|
||||
* `npc --json` -- show brief network state in json format.
|
||||
|
||||
Example on running `npc` without argument:
|
||||
|
||||
```
|
||||
1: lo: <LOOPBACK,LOWERUP,RUNNING,UP> state unknown mtu 65536
|
||||
mac 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8
|
||||
ipv6 ::1/128
|
||||
2: eth1: <BROADCAST,LOWERUP,MULTICAST,RUNNING,UP> state up mtu 1500
|
||||
mac 00:01:02:03:04:05
|
||||
ipv4 192.0.2.6/24 gw4 192.0.2.1
|
||||
ipv6 2001:db8::6/64 fe80::6/64 gw6 fe80::1
|
||||
```
|
||||
|
||||
This patch contains many memory copy done by `to_string()`, `clone()`,
|
||||
`to_vec()`. We can improve it in future if that cause any problem.
|
||||
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
---
|
||||
src/cli/npc.rs | 232 +++++++++++++++++++++++++++++++++++++---
|
||||
src/lib/ifaces/iface.rs | 17 +++
|
||||
2 files changed, 237 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/src/cli/npc.rs b/src/cli/npc.rs
|
||||
index b7171bb..41ddbd8 100644
|
||||
--- a/src/cli/npc.rs
|
||||
+++ b/src/cli/npc.rs
|
||||
@@ -13,19 +13,188 @@
|
||||
// limitations under the License.
|
||||
|
||||
use clap::{clap_app, crate_authors, crate_version};
|
||||
-use nispor::{Iface, NetConf, NetState, NisporError, Route, RouteRule};
|
||||
+use nispor::{
|
||||
+ Iface, IfaceState, NetConf, NetState, NisporError, Route, RouteRule,
|
||||
+};
|
||||
use serde_derive::Serialize;
|
||||
use serde_json;
|
||||
use serde_yaml;
|
||||
+use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::io::{stderr, stdout, Write};
|
||||
use std::process;
|
||||
|
||||
-#[derive(Serialize)]
|
||||
+const INDENT: &str = " ";
|
||||
+
|
||||
+#[derive(Serialize, Debug)]
|
||||
pub struct CliError {
|
||||
pub msg: String,
|
||||
}
|
||||
|
||||
+#[derive(Serialize, Default)]
|
||||
+struct CliIfaceBrief {
|
||||
+ index: u32,
|
||||
+ name: String,
|
||||
+ state: IfaceState,
|
||||
+ flags: Vec<String>,
|
||||
+ mac: String,
|
||||
+ permanent_mac: String,
|
||||
+ mtu: i64,
|
||||
+ ipv4: Vec<String>,
|
||||
+ ipv6: Vec<String>,
|
||||
+ gw4: Vec<String>,
|
||||
+ gw6: Vec<String>,
|
||||
+}
|
||||
+
|
||||
+impl CliIfaceBrief {
|
||||
+ fn to_string(briefs: &[CliIfaceBrief]) -> String {
|
||||
+ let mut ret = Vec::new();
|
||||
+ for brief in briefs {
|
||||
+ ret.push(format!(
|
||||
+ "{}: {}: <{}> state {} mtu {}",
|
||||
+ brief.index,
|
||||
+ brief.name,
|
||||
+ brief.flags.join(","),
|
||||
+ brief.state,
|
||||
+ brief.mtu,
|
||||
+ ));
|
||||
+ if &brief.mac != "" {
|
||||
+ ret.push(format!(
|
||||
+ "{}mac {}{}",
|
||||
+ INDENT,
|
||||
+ brief.mac,
|
||||
+ if &brief.permanent_mac != ""
|
||||
+ && &brief.permanent_mac != &brief.mac
|
||||
+ {
|
||||
+ format!(" permanent_mac: {}", brief.permanent_mac)
|
||||
+ } else {
|
||||
+ "".into()
|
||||
+ }
|
||||
+ ));
|
||||
+ }
|
||||
+ if brief.ipv4.len() > 0 {
|
||||
+ ret.push(format!(
|
||||
+ "{}ipv4 {}{}",
|
||||
+ INDENT,
|
||||
+ brief.ipv4.join(" "),
|
||||
+ if brief.gw4.len() > 0 {
|
||||
+ format!(" gw4 {}", brief.gw4.join(" "))
|
||||
+ } else {
|
||||
+ "".into()
|
||||
+ },
|
||||
+ ));
|
||||
+ }
|
||||
+ if brief.ipv6.len() > 0 {
|
||||
+ ret.push(format!(
|
||||
+ "{}ipv6 {}{}",
|
||||
+ INDENT,
|
||||
+ brief.ipv6.join(" "),
|
||||
+ if brief.gw6.len() > 0 {
|
||||
+ format!(" gw6 {}", brief.gw6.join(" "))
|
||||
+ } else {
|
||||
+ "".into()
|
||||
+ }
|
||||
+ ));
|
||||
+ }
|
||||
+ }
|
||||
+ ret.join("\n")
|
||||
+ }
|
||||
+
|
||||
+ fn from_net_state(netstate: &NetState) -> Vec<Self> {
|
||||
+ let mut ret = Vec::new();
|
||||
+ let mut iface_to_gw4: HashMap<String, Vec<String>> = HashMap::new();
|
||||
+ let mut iface_to_gw6: HashMap<String, Vec<String>> = HashMap::new();
|
||||
+
|
||||
+ for route in &netstate.routes {
|
||||
+ if let Route {
|
||||
+ dst: None,
|
||||
+ gateway: Some(gw),
|
||||
+ oif: Some(iface_name),
|
||||
+ ..
|
||||
+ } = route
|
||||
+ {
|
||||
+ if gw.contains(":") {
|
||||
+ match iface_to_gw6.get_mut(iface_name) {
|
||||
+ Some(gateways) => {
|
||||
+ gateways.push(gw.to_string());
|
||||
+ }
|
||||
+ None => {
|
||||
+ iface_to_gw6.insert(
|
||||
+ iface_name.to_string(),
|
||||
+ vec![gw.to_string()],
|
||||
+ );
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ match iface_to_gw4.get_mut(iface_name) {
|
||||
+ Some(gateways) => {
|
||||
+ gateways.push(gw.to_string());
|
||||
+ }
|
||||
+ None => {
|
||||
+ iface_to_gw4.insert(
|
||||
+ iface_name.to_string(),
|
||||
+ vec![gw.to_string()],
|
||||
+ );
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ for iface in netstate.ifaces.values() {
|
||||
+ ret.push(CliIfaceBrief {
|
||||
+ index: iface.index,
|
||||
+ name: iface.name.clone(),
|
||||
+ flags: (&iface.flags)
|
||||
+ .into_iter()
|
||||
+ .map(|flag| format!("{:?}", flag).to_uppercase())
|
||||
+ .collect(),
|
||||
+ state: iface.state.clone(),
|
||||
+ mac: iface.mac_address.clone(),
|
||||
+ permanent_mac: iface.permanent_mac_address.clone(),
|
||||
+ mtu: iface.mtu,
|
||||
+ ipv4: match &iface.ipv4 {
|
||||
+ Some(ip_info) => {
|
||||
+ let mut addr_strs = Vec::new();
|
||||
+ for addr in &ip_info.addresses {
|
||||
+ addr_strs.push(format!(
|
||||
+ "{}/{}",
|
||||
+ addr.address, addr.prefix_len
|
||||
+ ));
|
||||
+ }
|
||||
+ addr_strs
|
||||
+ }
|
||||
+ None => Vec::new(),
|
||||
+ },
|
||||
+ ipv6: match &iface.ipv6 {
|
||||
+ Some(ip_info) => {
|
||||
+ let mut addr_strs = Vec::new();
|
||||
+ for addr in &ip_info.addresses {
|
||||
+ addr_strs.push(format!(
|
||||
+ "{}/{}",
|
||||
+ addr.address, addr.prefix_len
|
||||
+ ));
|
||||
+ }
|
||||
+ addr_strs
|
||||
+ }
|
||||
+ None => Vec::new(),
|
||||
+ },
|
||||
+ gw4: match &iface_to_gw4.get(&iface.name) {
|
||||
+ Some(gws) => gws.to_vec(),
|
||||
+ None => Vec::new(),
|
||||
+ },
|
||||
+ gw6: match &iface_to_gw6.get(&iface.name) {
|
||||
+ Some(gws) => gws.to_vec(),
|
||||
+ None => Vec::new(),
|
||||
+ },
|
||||
+ ..Default::default()
|
||||
+ })
|
||||
+ }
|
||||
+ ret.sort_by(|a, b| a.index.cmp(&b.index));
|
||||
+ ret
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
impl fmt::Display for CliError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.msg)
|
||||
@@ -34,6 +203,7 @@ impl fmt::Display for CliError {
|
||||
|
||||
enum CliResult {
|
||||
Pass,
|
||||
+ Brief(Vec<CliIfaceBrief>),
|
||||
Full(NetState),
|
||||
Ifaces(Vec<Iface>),
|
||||
Routes(Vec<Route>),
|
||||
@@ -42,6 +212,7 @@ enum CliResult {
|
||||
NisporError(NisporError),
|
||||
}
|
||||
|
||||
+#[derive(PartialEq)]
|
||||
enum CliOutputType {
|
||||
Json,
|
||||
Yaml,
|
||||
@@ -53,6 +224,7 @@ macro_rules! npc_print {
|
||||
CliResult::Pass => {
|
||||
process::exit(0);
|
||||
}
|
||||
+ CliResult::Brief(_) => unreachable!(),
|
||||
CliResult::Full(netstate) => {
|
||||
writeln!(stdout(), "{}", $display_func(&netstate).unwrap())
|
||||
.ok();
|
||||
@@ -83,9 +255,24 @@ macro_rules! npc_print {
|
||||
}
|
||||
|
||||
fn print_result(result: &CliResult, output_type: CliOutputType) {
|
||||
- match output_type {
|
||||
- CliOutputType::Json => npc_print!(serde_json::to_string_pretty, result),
|
||||
- CliOutputType::Yaml => npc_print!(serde_yaml::to_string, result),
|
||||
+ if let CliResult::Brief(briefs) = result {
|
||||
+ if output_type == CliOutputType::Json {
|
||||
+ writeln!(
|
||||
+ stdout(),
|
||||
+ "{}",
|
||||
+ serde_json::to_string_pretty(&briefs).unwrap()
|
||||
+ )
|
||||
+ .ok();
|
||||
+ } else {
|
||||
+ writeln!(stdout(), "{}", CliIfaceBrief::to_string(&briefs)).ok();
|
||||
+ }
|
||||
+ } else {
|
||||
+ match output_type {
|
||||
+ CliOutputType::Json => {
|
||||
+ npc_print!(serde_json::to_string_pretty, result)
|
||||
+ }
|
||||
+ CliOutputType::Yaml => npc_print!(serde_yaml::to_string, result),
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,6 +320,11 @@ fn main() {
|
||||
(about: "Nispor CLI")
|
||||
(@arg ifname: [INTERFACE_NAME] "interface name")
|
||||
(@arg json: -j --json "Show in json format")
|
||||
+ (@subcommand iface =>
|
||||
+ (@arg json: -j --json "Show in json format")
|
||||
+ (@arg ifname: [INTERFACE_NAME] "Show only specified interface")
|
||||
+ (about: "Show interface")
|
||||
+ )
|
||||
(@subcommand route =>
|
||||
(@arg json: -j --json "Show in json format")
|
||||
(@arg dev: -d --dev [OIF] "Show only route entries with output to the specified interface")
|
||||
@@ -162,13 +354,21 @@ fn main() {
|
||||
} else {
|
||||
let result = match NetState::retrieve() {
|
||||
Ok(mut state) => {
|
||||
- if let Some(ifname) = matches.value_of("ifname") {
|
||||
- if let Some(iface) = state.ifaces.remove(ifname) {
|
||||
- CliResult::Ifaces(vec![iface])
|
||||
+ if let Some(m) = matches.subcommand_matches("iface") {
|
||||
+ output_format = parse_arg_output_format(m);
|
||||
+ if let Some(ifname) = m.value_of("ifname") {
|
||||
+ if let Some(iface) = state.ifaces.remove(ifname) {
|
||||
+ CliResult::Ifaces(vec![iface])
|
||||
+ } else {
|
||||
+ CliResult::CliError(CliError {
|
||||
+ msg: format!(
|
||||
+ "Interface '{}' not found",
|
||||
+ ifname
|
||||
+ ),
|
||||
+ })
|
||||
+ }
|
||||
} else {
|
||||
- CliResult::CliError(CliError {
|
||||
- msg: format!("Interface '{}' not found", ifname),
|
||||
- })
|
||||
+ CliResult::Full(state)
|
||||
}
|
||||
} else if let Some(m) = matches.subcommand_matches("route") {
|
||||
output_format = parse_arg_output_format(m);
|
||||
@@ -176,9 +376,17 @@ fn main() {
|
||||
} else if let Some(m) = matches.subcommand_matches("rule") {
|
||||
output_format = parse_arg_output_format(m);
|
||||
CliResult::RouteRules(state.rules)
|
||||
+ } else if let Some(ifname) = matches.value_of("ifname") {
|
||||
+ if let Some(iface) = state.ifaces.remove(ifname) {
|
||||
+ CliResult::Ifaces(vec![iface])
|
||||
+ } else {
|
||||
+ CliResult::CliError(CliError {
|
||||
+ msg: format!("Interface '{}' not found", ifname),
|
||||
+ })
|
||||
+ }
|
||||
} else {
|
||||
/* Show everything if no cmdline arg has been supplied */
|
||||
- CliResult::Full(state)
|
||||
+ CliResult::Brief(CliIfaceBrief::from_net_state(&state))
|
||||
}
|
||||
}
|
||||
Err(e) => CliResult::NisporError(e),
|
||||
diff --git a/src/lib/ifaces/iface.rs b/src/lib/ifaces/iface.rs
|
||||
index ee71b0f..60afacd 100644
|
||||
--- a/src/lib/ifaces/iface.rs
|
||||
+++ b/src/lib/ifaces/iface.rs
|
||||
@@ -102,6 +102,23 @@ impl Default for IfaceState {
|
||||
}
|
||||
}
|
||||
|
||||
+impl std::fmt::Display for IfaceState {
|
||||
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
+ write!(
|
||||
+ f,
|
||||
+ "{}",
|
||||
+ match self {
|
||||
+ Self::Up => "up",
|
||||
+ Self::Dormant => "dormant",
|
||||
+ Self::Down => "down",
|
||||
+ Self::LowerLayerDown => "lower_layer_down",
|
||||
+ Self::Other(s) => s.as_str(),
|
||||
+ Self::Unknown => "unknown",
|
||||
+ }
|
||||
+ )
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum IfaceFlags {
|
||||
--
|
||||
2.32.0
|
||||
|
152
SOURCES/0002-ethtool-feature-tx-lockless-is-not-changeable.patch
Normal file
152
SOURCES/0002-ethtool-feature-tx-lockless-is-not-changeable.patch
Normal file
@ -0,0 +1,152 @@
|
||||
From 235458b72fe54feb97349db4b139babc80821e58 Mon Sep 17 00:00:00 2001
|
||||
From: Gris Ge <fge@redhat.com>
|
||||
Date: Fri, 4 Jun 2021 06:23:47 +0800
|
||||
Subject: [PATCH 2/3] ethtool feature: tx-lockless is not changeable
|
||||
|
||||
Currently, the `tx-lockless` is shown as changeable, but it actually is
|
||||
hard coded as not changeable by `NETIF_F_NEVER_CHANGE` in kernel.
|
||||
|
||||
The kernel netlink use `ETHTOOL_A_FEATURES_NOCHANGE` for hard coded
|
||||
non-changeable features, it take priority over `ETHTOOL_A_FEATURES_HW`.
|
||||
|
||||
Integration test case included, but disable in CI as CI has no ethtool
|
||||
netlink interface in kernel.
|
||||
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
---
|
||||
src/lib/ifaces/ethtool.rs | 19 +++++++++-
|
||||
src/lib/tests/dummy.rs | 74 +++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 92 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/lib/ifaces/ethtool.rs b/src/lib/ifaces/ethtool.rs
|
||||
index 7a5c08a..0697ad5 100644
|
||||
--- a/src/lib/ifaces/ethtool.rs
|
||||
+++ b/src/lib/ifaces/ethtool.rs
|
||||
@@ -313,6 +313,14 @@ async fn dump_feature_infos(
|
||||
let mut fixed_features = HashMap::new();
|
||||
let mut changeable_features = HashMap::new();
|
||||
|
||||
+ for nla in &nlas {
|
||||
+ if let FeatureAttr::NoChange(feature_bits) = nla {
|
||||
+ for FeatureBit { name, .. } in feature_bits {
|
||||
+ fixed_features.insert(name.to_string(), false);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
for nla in nlas {
|
||||
if let FeatureAttr::Header(hdrs) = nla {
|
||||
iface_name = get_iface_name_from_header(&hdrs);
|
||||
@@ -324,7 +332,16 @@ async fn dump_feature_infos(
|
||||
name,
|
||||
value: true,
|
||||
} => {
|
||||
- changeable_features.insert(name, false);
|
||||
+ // Dummy interface show `tx-lockless` is
|
||||
+ // changeable, but FeatureAttr::NoChange() says
|
||||
+ // otherwise. The kernel code
|
||||
+ // `NETIF_F_NEVER_CHANGE` shows `tx-lockless`
|
||||
+ // should never been changeable.
|
||||
+ if fixed_features.contains_key(&name) {
|
||||
+ fixed_features.insert(name, false);
|
||||
+ } else {
|
||||
+ changeable_features.insert(name, false);
|
||||
+ }
|
||||
}
|
||||
FeatureBit {
|
||||
index: _,
|
||||
diff --git a/src/lib/tests/dummy.rs b/src/lib/tests/dummy.rs
|
||||
index a0feed3..aab9ffd 100644
|
||||
--- a/src/lib/tests/dummy.rs
|
||||
+++ b/src/lib/tests/dummy.rs
|
||||
@@ -40,6 +40,66 @@ const EXPECTED_IFACE_STATE: &str = r#"---
|
||||
preferred_lft: forever
|
||||
mac_address: "00:23:45:67:89:1a""#;
|
||||
|
||||
+const EXPECTED_ETHTOOL_FEATURE: &str = r#"---
|
||||
+fixed:
|
||||
+ esp-hw-offload: false
|
||||
+ esp-tx-csum-hw-offload: false
|
||||
+ fcoe-mtu: false
|
||||
+ hw-tc-offload: false
|
||||
+ l2-fwd-offload: false
|
||||
+ loopback: false
|
||||
+ macsec-hw-offload: false
|
||||
+ netns-local: false
|
||||
+ rx-all: false
|
||||
+ rx-checksum: false
|
||||
+ rx-fcs: false
|
||||
+ rx-gro-hw: false
|
||||
+ rx-hashing: false
|
||||
+ rx-lro: false
|
||||
+ rx-ntuple-filter: false
|
||||
+ rx-udp_tunnel-port-offload: false
|
||||
+ rx-vlan-filter: false
|
||||
+ rx-vlan-hw-parse: false
|
||||
+ rx-vlan-stag-filter: false
|
||||
+ rx-vlan-stag-hw-parse: false
|
||||
+ tls-hw-record: false
|
||||
+ tls-hw-rx-offload: false
|
||||
+ tls-hw-tx-offload: false
|
||||
+ tx-checksum-fcoe-crc: false
|
||||
+ tx-checksum-ipv4: false
|
||||
+ tx-checksum-ipv6: false
|
||||
+ tx-checksum-sctp: false
|
||||
+ tx-esp-segmentation: false
|
||||
+ tx-fcoe-segmentation: false
|
||||
+ tx-gso-list: false
|
||||
+ tx-gso-partial: false
|
||||
+ tx-gso-robust: false
|
||||
+ tx-lockless: true
|
||||
+ tx-sctp-segmentation: false
|
||||
+ tx-tunnel-remcsum-segmentation: false
|
||||
+ tx-udp-segmentation: false
|
||||
+ tx-vlan-hw-insert: false
|
||||
+ tx-vlan-stag-hw-insert: false
|
||||
+ vlan-challenged: false
|
||||
+changeable:
|
||||
+ highdma: true
|
||||
+ rx-gro: true
|
||||
+ rx-gro-list: false
|
||||
+ tx-checksum-ip-generic: true
|
||||
+ tx-generic-segmentation: true
|
||||
+ tx-gre-csum-segmentation: true
|
||||
+ tx-gre-segmentation: true
|
||||
+ tx-ipxip4-segmentation: true
|
||||
+ tx-ipxip6-segmentation: true
|
||||
+ tx-nocache-copy: false
|
||||
+ tx-scatter-gather-fraglist: true
|
||||
+ tx-tcp-ecn-segmentation: true
|
||||
+ tx-tcp-mangleid-segmentation: true
|
||||
+ tx-tcp-segmentation: true
|
||||
+ tx-tcp6-segmentation: true
|
||||
+ tx-udp_tnl-csum-segmentation: true
|
||||
+ tx-udp_tnl-segmentation: true"#;
|
||||
+
|
||||
#[test]
|
||||
fn test_get_iface_dummy_yaml() {
|
||||
with_dummy_iface(|| {
|
||||
@@ -54,6 +114,20 @@ fn test_get_iface_dummy_yaml() {
|
||||
});
|
||||
}
|
||||
|
||||
+#[test]
|
||||
+#[ignore] // CI does not have ethtool_netlink kernel module yet
|
||||
+fn test_get_iface_dummy_ethtool_feature() {
|
||||
+ with_dummy_iface(|| {
|
||||
+ let state = NetState::retrieve().unwrap();
|
||||
+ let iface = &state.ifaces[IFACE_NAME];
|
||||
+ assert_eq!(
|
||||
+ serde_yaml::to_string(&iface.ethtool.as_ref().unwrap().features)
|
||||
+ .unwrap(),
|
||||
+ EXPECTED_ETHTOOL_FEATURE
|
||||
+ );
|
||||
+ });
|
||||
+}
|
||||
+
|
||||
fn with_dummy_iface<T>(test: T) -> ()
|
||||
where
|
||||
T: FnOnce() -> () + panic::UnwindSafe,
|
||||
--
|
||||
2.32.0
|
||||
|
61
SOURCES/0003-loopback-Fix-interface-type-of-loopback.patch
Normal file
61
SOURCES/0003-loopback-Fix-interface-type-of-loopback.patch
Normal file
@ -0,0 +1,61 @@
|
||||
From 7ef2df7e8849f7f674c14190fb997fc3f0e7ba67 Mon Sep 17 00:00:00 2001
|
||||
From: Gris Ge <fge@redhat.com>
|
||||
Date: Tue, 8 Jun 2021 16:59:31 +0800
|
||||
Subject: [PATCH 3/3] loopback: Fix interface type of loopback
|
||||
|
||||
Using `IFF_LOOPBACK` interface flag to determine whether a interface is
|
||||
loopback or not is incorrect as other type interface would also hold
|
||||
this flag.
|
||||
|
||||
Fixed to use `ARPHRD_LOOPBACK` from link_layer_type.
|
||||
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
---
|
||||
src/lib/ifaces/iface.rs | 17 ++++++++---------
|
||||
1 file changed, 8 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/lib/ifaces/iface.rs b/src/lib/ifaces/iface.rs
|
||||
index 60afacd..25ba558 100644
|
||||
--- a/src/lib/ifaces/iface.rs
|
||||
+++ b/src/lib/ifaces/iface.rs
|
||||
@@ -48,10 +48,10 @@ use crate::NisporError;
|
||||
use netlink_packet_route::rtnl::link::nlas;
|
||||
use netlink_packet_route::rtnl::LinkMessage;
|
||||
use netlink_packet_route::rtnl::{
|
||||
- ARPHRD_ETHER, IFF_ALLMULTI, IFF_AUTOMEDIA, IFF_BROADCAST, IFF_DEBUG,
|
||||
- IFF_DORMANT, IFF_LOOPBACK, IFF_LOWER_UP, IFF_MASTER, IFF_MULTICAST,
|
||||
- IFF_NOARP, IFF_POINTOPOINT, IFF_PORTSEL, IFF_PROMISC, IFF_RUNNING,
|
||||
- IFF_SLAVE, IFF_UP,
|
||||
+ ARPHRD_ETHER, ARPHRD_LOOPBACK, IFF_ALLMULTI, IFF_AUTOMEDIA, IFF_BROADCAST,
|
||||
+ IFF_DEBUG, IFF_DORMANT, IFF_LOOPBACK, IFF_LOWER_UP, IFF_MASTER,
|
||||
+ IFF_MULTICAST, IFF_NOARP, IFF_POINTOPOINT, IFF_PORTSEL, IFF_PROMISC,
|
||||
+ IFF_RUNNING, IFF_SLAVE, IFF_UP,
|
||||
};
|
||||
use rtnetlink::new_connection;
|
||||
|
||||
@@ -247,8 +247,10 @@ pub(crate) fn parse_nl_msg_to_iface(
|
||||
name: name.clone(),
|
||||
..Default::default()
|
||||
};
|
||||
- if nl_msg.header.link_layer_type == ARPHRD_ETHER {
|
||||
- iface_state.iface_type = IfaceType::Ethernet
|
||||
+ match nl_msg.header.link_layer_type {
|
||||
+ ARPHRD_ETHER => iface_state.iface_type = IfaceType::Ethernet,
|
||||
+ ARPHRD_LOOPBACK => iface_state.iface_type = IfaceType::Loopback,
|
||||
+ _ => (),
|
||||
}
|
||||
iface_state.index = nl_msg.header.index;
|
||||
let mut link: Option<u32> = None;
|
||||
@@ -392,9 +394,6 @@ pub(crate) fn parse_nl_msg_to_iface(
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
- if (nl_msg.header.flags & IFF_LOOPBACK) > 0 {
|
||||
- iface_state.iface_type = IfaceType::Loopback;
|
||||
- }
|
||||
iface_state.flags = _parse_iface_flags(nl_msg.header.flags);
|
||||
Ok(Some(iface_state))
|
||||
}
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,11 +1,14 @@
|
||||
Name: nispor
|
||||
Version: 1.1.0
|
||||
Release: 1%{?dist}
|
||||
Release: 2%{?dist}
|
||||
Summary: API for network status querying
|
||||
License: ASL 2.0
|
||||
URL: https://github.com/nispor/nispor
|
||||
Source: https://github.com/nispor/nispor/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
|
||||
Source1: %{name}-%{version}-vendor.tar.xz
|
||||
Patch1: 0001-npc-Show-brief-network-state-when-no-argument.patch
|
||||
Patch2: 0002-ethtool-feature-tx-lockless-is-not-changeable.patch
|
||||
Patch3: 0003-loopback-Fix-interface-type-of-loopback.patch
|
||||
BuildRequires: pkg-config
|
||||
BuildRequires: python3-devel
|
||||
BuildRequires: rust-toolset
|
||||
@ -81,6 +84,9 @@ popd
|
||||
%{_libdir}/pkgconfig/nispor.pc
|
||||
|
||||
%changelog
|
||||
* Tue Jun 08 2021 Gris Ge <fge@redhat.com> - 1.1.0-2
|
||||
- Fix cli output, loopback interface and ethtool features.
|
||||
|
||||
* Tue May 25 2021 Wen Liang <wenliang@redhat.com> - 1.1.0-1
|
||||
- Upgrade to 1.1.0. RHBZ#1942459
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user