summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Matthews <glmatthe@cisco.com>2015-12-10 16:01:23 -0500
committerAdam Leff <adam@leff.co>2016-02-18 13:56:33 -0500
commit09645d6fb7940f40113eab22f1e66b92af7e508d (patch)
treedc4703bf7982ce1ee9f550d9c6bafc2a8f7e517d
parent8710640580950d52791678a4862e54dbaf225193 (diff)
downloadohai-09645d6fb7940f40113eab22f1e66b92af7e508d.tar.gz
Report an ipaddress in a Linux corner case observed on Cisco IOS XR
- we have a default route to an interface - the route has a configured src - the src address is not configured on the default interface, but the default interface has no address at all In this case we will choose the src as the ipaddress to report.
-rw-r--r--lib/ohai/plugins/linux/network.rb38
-rw-r--r--spec/unit/plugins/linux/network_spec.rb66
2 files changed, 94 insertions, 10 deletions
diff --git a/lib/ohai/plugins/linux/network.rb b/lib/ohai/plugins/linux/network.rb
index 32b77650..1244bcfd 100644
--- a/lib/ohai/plugins/linux/network.rb
+++ b/lib/ohai/plugins/linux/network.rb
@@ -113,7 +113,15 @@ Ohai.plugin(:Network) do
# a sanity check, especially for Linux-VServer, OpenVZ and LXC:
# don't report the route entry if the src address isn't set on the node
- next if route_entry[:src] and not iface[route_int][:addresses].has_key? route_entry[:src]
+ # unless the interface has no addresses of this type at all
+ if route_entry[:src]
+ addr = iface[route_int][:addresses]
+ unless addr.nil? || addr.has_key?(route_entry[:src]) ||
+ addr.values.all? { |a| a['family'] != family[:name] }
+ Ohai::Log.debug("Skipping route entry whose src does not match the interface IP")
+ next
+ end
+ end
iface[route_int][:routes] = Array.new unless iface[route_int][:routes]
iface[route_int][:routes] << route_entry
@@ -126,6 +134,7 @@ Ohai.plugin(:Network) do
# for information, default routes can be of this form :
# - default via 10.0.2.4 dev br0
# - default dev br0 scope link
+ # - default dev eth0 scope link src 1.1.1.1
# - default via 10.0.3.1 dev eth1 src 10.0.3.2 metric 10
# - default via 10.0.4.1 dev eth2 src 10.0.4.2 metric 20
@@ -310,7 +319,11 @@ Ohai.plugin(:Network) do
# returns the macaddress for interface from a hash of interfaces (iface elsewhere in this file)
def get_mac_for_interface(interfaces, interface)
+<<<<<<< ac9f5a2ae4ada9f2e6e821418ed3a9039bda9a91
interfaces[interface][:addresses].select { |k, v| v["family"] == "lladdr" }.first.first unless interfaces[interface][:flags].include? "NOARP"
+=======
+ interfaces[interface][:addresses].select{|k,v| v["family"]=="lladdr"}.first.first unless interfaces[interface][:addresses].nil? || interfaces[interface][:flags].include?("NOARP")
+>>>>>>> Report an ipaddress in a Linux corner case observed on Cisco IOS XR
end
# returns the default route with the lowest metric (unspecified metric is 0)
@@ -332,15 +345,22 @@ Ohai.plugin(:Network) do
# using the source field when it's specified :
# 1) in the default route
# 2) in the route entry used to reach the default gateway
- r[:src] and # it has a src field
- iface[r[:dev]] and # the iface exists
- iface[r[:dev]][:addresses].has_key? r[:src] and # the src ip is set on the node
- iface[r[:dev]][:addresses][r[:src]][:scope].downcase != "link" and # this isn't a link level addresse
- ( r[:destination] == "default" or
- ( default_route[:via] and # the default route has a gateway
- IPAddress(r[:destination]).include? IPAddress(default_route[:via]) # the route matches the gateway
- )
+ r[:src] && # it has a src field
+ iface[r[:dev]] && # the iface exists
+ (
+ iface[r[:dev]][:addresses].nil? || # this int has no addresses
+ iface[r[:dev]][:addresses].values.all? { |addr| addr['family'] != family[:name] } || # this int has no ip
+ (
+ iface[r[:dev]][:addresses].has_key?(r[:src]) && # the src ip is set on the node
+ iface[r[:dev]][:addresses][r[:src]][:scope].downcase != "link" # this isn't a link level address
+ )
+ ) && (
+ r[:destination] == "default" ||
+ (
+ default_route[:via] && # the default route has a gateway
+ IPAddress(r[:destination]).include?(IPAddress(default_route[:via])) # the route matches the gateway
)
+ )
elsif family[:name] == "inet6"
# selecting routes for ipv6
iface[r[:dev]] and # the iface exists
diff --git a/spec/unit/plugins/linux/network_spec.rb b/spec/unit/plugins/linux/network_spec.rb
index 213d0e2d..2ff39385 100644
--- a/spec/unit/plugins/linux/network_spec.rb
+++ b/spec/unit/plugins/linux/network_spec.rb
@@ -138,6 +138,14 @@ xapi1 Link encap:Ethernet HWaddr E8:39:35:C5:C8:50
TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:21515031 (20.5 MiB) TX bytes:2052 (2.0 KiB)
+
+fwdintf Link encap:Ethernet HWaddr 00:00:00:00:00:0a
+ inet6 addr: fe80::200:ff:fe00:a/64 Scope:Link
+ UP RUNNING NOARP MULTICAST MTU:1496 Metric:1
+ RX packets:0 errors:0 dropped:0 overruns:0 frame:0
+ TX packets:2 errors:0 dropped:1 overruns:0 carrier:0
+ collisions:0 txqueuelen:1000
+ RX bytes:0 (0.0 B) TX bytes:140 (140.0 B)
EOM
# Note that ifconfig shows foo:veth0@eth0 but fails to show any address information.
# This was not a mistake collecting the output and Apparently ifconfig is broken in this regard.
@@ -225,6 +233,8 @@ EOM
link/ether e8:39:35:c5:c8:50 brd ff:ff:ff:ff:ff:ff
inet 192.168.13.34/24 brd 192.168.13.255 scope global xapi1
valid_lft forever preferred_lft forever
+13: fwdintf: <MULTICAST,NOARP,UP,LOWER_UP> mtu 1496 qdisc pfifo_fast state UNKNOWN group default qlen 1000
+ link/ether 00:00:00:00:00:0a brd ff:ff:ff:ff:ff:ff
EOM
}
@@ -278,6 +288,12 @@ EOM
21468183 159866 0 0 0 0
TX: bytes packets errors dropped carrier collsns
2052 6 0 0 0 0
+13: fwdintf: <MULTICAST,NOARP,UP,LOWER_UP> mtu 1496 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 1000
+ link/ether 00:00:00:00:00:0a brd ff:ff:ff:ff:ff:ff promiscuity 0
+ RX: bytes packets errors dropped overrun mcast
+ 0 0 0 0 0 0
+ TX: bytes packets errors dropped carrier collsns
+ 140 2 0 1 0 0
EOM
}
@@ -374,7 +390,7 @@ EOM
end
it "detects the interfaces" do
- expect(plugin["network"]["interfaces"].keys.sort).to eq(["eth0", "eth0.11", "eth0.151", "eth0.152", "eth0.153", "eth0:5", "eth3", "foo:veth0@eth0", "lo", "ovs-system", "tun0", "venet0", "venet0:0", "xapi1"])
+ expect(plugin['network']['interfaces'].keys.sort).to eq(["eth0", "eth0.11", "eth0.151", "eth0.152", "eth0.153", "eth0:5", "eth3", "foo:veth0@eth0", "fwdintf", "lo", "ovs-system", "tun0", "venet0", "venet0:0", "xapi1"])
end
it "detects the layer one details of an ethernet interface" do
@@ -896,6 +912,54 @@ EOM
end
end
+ describe "with a link level default route to an unaddressed int" do
+ let(:linux_ip_route) {
+'default dev eth3 scope link
+'
+ }
+
+ before(:each) do
+ plugin.run
+ end
+
+ it "completes the run" do
+ expect(Ohai::Log).not_to receive(:debug).with(/Plugin linux::network threw exception/)
+ expect(plugin['network']).not_to be_nil
+ end
+
+ it "sets default_interface" do
+ expect(plugin['network']['default_interface']).to eq('eth3')
+ end
+
+ it "doesn't set ipaddress" do
+ expect(plugin['ipaddress']).to be_nil
+ end
+ end
+
+ describe "with a link level default route with a source" do
+ let(:linux_ip_route) {
+'default dev fwdintf scope link src 2.2.2.2
+'
+ }
+
+ before(:each) do
+ plugin.run
+ end
+
+ it "completes the run" do
+ expect(Ohai::Log).not_to receive(:debug).with(/Plugin linux::network threw exception/)
+ expect(plugin['network']).not_to be_nil
+ end
+
+ it "sets default_interface" do
+ expect(plugin['network']['default_interface']).to eq('fwdintf')
+ end
+
+ it "sets ipaddress" do
+ expect(plugin['ipaddress']).to eq('2.2.2.2')
+ end
+ end
+
describe "when not having a global scope ipv6 address" do
let(:linux_ip_route_inet6) { <<-EOM
fe80::/64 dev eth0 proto kernel metric 256