summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Phillips <mphillips81@bloomberg.net>2022-03-23 11:52:47 -0400
committerMatt Phillips <mphillips81@bloomberg.net>2022-05-16 17:03:51 -0400
commitc431f946585ea7ffddae2c7a1450667a0ffdfda8 (patch)
tree88495b15458148835d95e655123826487a1ff159
parent88484dd2a15d18150a520061b6a0e7de1c80370d (diff)
downloadohai-c431f946585ea7ffddae2c7a1450667a0ffdfda8.tar.gz
prefer route that explicitly define a device
in theory I don't this should occur in real life, as I'm pretty sure /usr/sbin/ip should always print the dev routes above non dev routes if the metric is the same, but it is a good case to cover in code. also removed the default metric 10 gateway route as it was spurious/irrelevant to the test. Signed-off-by: Matt Phillips <mphillips81@bloomberg.net>
-rw-r--r--lib/ohai/plugins/linux/network.rb8
-rw-r--r--spec/unit/plugins/linux/network_spec.rb21
2 files changed, 25 insertions, 4 deletions
diff --git a/lib/ohai/plugins/linux/network.rb b/lib/ohai/plugins/linux/network.rb
index cbecae86..eb83843c 100644
--- a/lib/ohai/plugins/linux/network.rb
+++ b/lib/ohai/plugins/linux/network.rb
@@ -103,16 +103,20 @@ Ohai.plugin(:Network) do
next
end
route_endings.each do |route_ending|
+ route_entry = Mash.new(destination: route_dest,
+ family: family[:name])
route_int = nil
if route_ending =~ /\bdev\s+([^\s]+)\b/
route_int = $1
end
# does any known interface own the src address?
+ # we try to infer the interface/device from its address if it isn't specified
# we want to override the interface set via nexthop but only if possible
if line =~ /\bsrc\s+([^\s]+)\b/ && (!route_int || line.include?("nexthop"))
# only clobber previously set route_int if we find a match
if (match = iface.select { |name, intf| intf.fetch("addresses", {}).any? { |addr, _| addr == $1 } }.keys.first)
route_int = match
+ route_entry[:inferred] = true
end
end
@@ -127,8 +131,6 @@ Ohai.plugin(:Network) do
next
end
- route_entry = Mash.new(destination: route_dest,
- family: family[:name])
%w{via scope metric proto src}.each do |k|
# http://rubular.com/r/pwTNp65VFf
route_entry[k] = $1 if route_ending =~ /\b#{k}\s+([^\s]+)/
@@ -656,10 +658,12 @@ Ohai.plugin(:Network) do
# sorting the selected routes:
# - getting default routes first
# - then sort by metric
+ # - then sort by if the device was inferred or not (preferring explicit to inferred)
# - then by prefixlen
[
r[:destination] == "default" ? 0 : 1,
r[:metric].nil? ? 0 : r[:metric].to_i,
+ r[:inferred] ? 1 : 0,
# for some reason IPAddress doesn't accept "::/0", it doesn't like prefix==0
# just a quick workaround: use 0 if IPAddress fails
begin
diff --git a/spec/unit/plugins/linux/network_spec.rb b/spec/unit/plugins/linux/network_spec.rb
index 0bb20597..f3928322 100644
--- a/spec/unit/plugins/linux/network_spec.rb
+++ b/spec/unit/plugins/linux/network_spec.rb
@@ -1339,7 +1339,6 @@ describe Ohai::System, "Linux Network Plugin" do
let(:linux_ip_route) do
<<~EOM
default proto bird src 172.16.19.39 metric 10 \\ nexthop via 10.1.81.1 dev eth0 weight 20
- default via 10.116.201.1 dev eth0 metric 10 src 10.116.201.1
10.116.201.0/24 dev eth0 proto kernel src 10.116.201.76
192.168.0.0/24 dev eth0 proto kernel src 192.168.0.2
default via 10.116.201.254 dev eth0 metric 20 src 10.116.201.74
@@ -1353,6 +1352,7 @@ describe Ohai::System, "Linux Network Plugin" do
end
end
+ # note: default via 10.116.201.1 discarded because src not on eth0
describe "when there's a source field in a local route entry but no dev with a higher priority default route" do
let(:linux_ip_route) do
<<~EOM
@@ -1365,7 +1365,24 @@ describe Ohai::System, "Linux Network Plugin" do
end
let(:linux_ip_route_inet6) { "" }
- it "maps the no-dev route and sets ipaddress" do
+ it "maps the dev route and sets ipaddress" do
+ plugin.run
+ expect(plugin["ipaddress"]).to eq("10.116.201.74")
+ end
+ end
+
+ describe "when there's a source field in a local route entry but no dev, but a dev route with the same metric" do
+ let(:linux_ip_route) do
+ <<~EOM
+ default proto bird src 172.16.19.39 metric 10 \\ nexthop via 10.1.81.1 dev eth0 weight 20
+ default via 10.116.201.254 dev eth0 metric 10 src 10.116.201.74
+ 10.116.201.0/24 dev eth0 proto kernel src 10.116.201.76
+ 192.168.0.0/24 dev eth0 proto kernel src 192.168.0.2
+ EOM
+ end
+ let(:linux_ip_route_inet6) { "" }
+
+ it "maps the dev route and sets ipaddress" do
plugin.run
expect(plugin["ipaddress"]).to eq("10.116.201.74")
end