Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ifconfig parse logic failing on some tunnels #2635

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 20 additions & 13 deletions lib/facter/resolvers/networking.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,28 +80,35 @@ def extract_dhcp(interface_name, raw_data, parsed_interface_data)
end

def extract_ip_data(raw_data, parsed_interface_data)
ip = extract_values(raw_data, /inet (\S+)/)
mask = extract_values(raw_data, /netmask (\S+)/).map { |val| val.hex.to_s(2).count('1') }
inets = extract_values(raw_data, /inet (\S+).+netmask (\S+)/, :extract_ip4_data)
bindings = create_bindings(inets)
parsed_interface_data[:bindings] = bindings unless bindings.empty?

ip6 = extract_values(raw_data, /inet6 (\S+)/).map { |val| val.gsub(/%.+/, '') }
mask6 = extract_values(raw_data, /prefixlen (\S+)/)

parsed_interface_data[:bindings] = create_bindings(ip, mask) unless ip.empty?
parsed_interface_data[:bindings6] = create_bindings(ip6, mask6) unless ip6.empty?
inets = extract_values(raw_data, /inet6 (\S+).+prefixlen (\S+)/, :extract_ip6_data)
bindings = create_bindings(inets)
parsed_interface_data[:bindings6] = bindings unless bindings.empty?
end

def extract_values(data, regex)
def extract_values(data, regex, ip_func)
results = []
data.scan(regex).flatten.each do |val|
results << val
data.scan(regex).flatten.each_slice(2) do |val|
results << method(ip_func).call(val)
end
results
end

def create_bindings(ips, masks)
def extract_ip4_data(inet)
[inet[0], inet[1].hex.to_s(2).count('1')]
end

def extract_ip6_data(inet)
[inet[0].gsub(/%.+/, ''), inet[1]]
end

def create_bindings(inets)
bindings = []
ips.zip(masks).each do |ip, mask|
bindings << Facter::Util::Resolvers::Networking.build_binding(ip, mask)
inets.each do |inet|
bindings << Facter::Util::Resolvers::Networking.build_binding(inet[0], inet[1])
end
bindings
end
Expand Down
17 changes: 16 additions & 1 deletion spec/facter/resolvers/networking_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
describe Facter::Resolvers::Networking do
subject(:networking) { Facter::Resolvers::Networking }

let(:log_spy) { instance_spy(Facter::Log) }

describe '#resolve' do
before do
allow(Facter::Util::Resolvers::Networking::PrimaryInterface)
Expand Down Expand Up @@ -37,7 +39,7 @@
end

it 'detects all interfaces' do
expected = %w[lo0 gif0 stf0 en0 en0.1 en1 en2 bridge0 p2p0 awdl0 llw0 utun0 utun1 utun2 utun3 ib0 ib1]
expected = %w[lo0 gif0 stf0 en0 en0.1 en1 en2 bridge0 p2p0 awdl0 llw0 utun0 utun1 utun2 utun3 utun4 utun5 ib0 ib1]
expect(networking.resolve(:interfaces).keys).to match_array(expected)
end

Expand Down Expand Up @@ -135,6 +137,19 @@
expect(networking.resolve(:interfaces)['utun3']).to include(expected)
end

it 'checks interface utun4' do
expected = { bindings: [{ address: '192.0.2.100', netmask: '255.255.255.255', network: '192.0.2.100' }] }
expect(networking.resolve(:interfaces)['utun4']).to include(expected)
end

it 'checks interface utun5' do
expected = { bindings6: [
{ address: '2001:db8::1', netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
network: '2001:db8::1', scope6: 'global' }
] }
expect(networking.resolve(:interfaces)['utun5']).to include(expected)
end

it 'checks interface ib0 has the expected mac' do
expected = { mac: '80:00:02:08:FA:81:00:00:00:00:00:00:00:00:00:00:00:00:00:00' }
expect(networking.resolve(:interfaces)['ib0']).to include(expected)
Expand Down
37 changes: 21 additions & 16 deletions spec/fixtures/ifconfig_mac
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP>
inet 127.0.0.1 netmask 0xff000000
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
inet 127.0.0.1 netmask 0xff000000
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
nd6 options=201<PERFORMNUD,DAD>
gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280
stf0: flags=0<> mtu 1280
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
options=400<CHANNEL_IO>
ether 64:5a:ed:ea:5c:81
ether 64:5a:ed:ea:5c:81
inet 192.168.143.212 netmask 0xffffff00 broadcast 192.168.143.255
media: autoselect
status: active
Expand All @@ -23,17 +23,17 @@ en0.1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
en1: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
options=460<TSO4,TSO6,CHANNEL_IO>
ether 82:17:0e:93:9d:00
ether 82:17:0e:93:9d:00
media: autoselect <full-duplex>
status: inactive
en2: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
options=460<TSO4,TSO6,CHANNEL_IO>
ether 82:17:0e:93:9d:01
ether 82:17:0e:93:9d:01
media: autoselect <full-duplex>
status: inactive
bridge0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
options=63<RXCSUM,TXCSUM,TSO4,TSO6>
ether 82:17:0e:93:9d:00
ether 82:17:0e:93:9d:00
Configuration:
id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0
maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200
Expand All @@ -47,33 +47,39 @@ bridge0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
status: inactive
p2p0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 2304
options=400<CHANNEL_IO>
ether 06:5a:ed:ea:5c:81
ether 06:5a:ed:ea:5c:81
media: autoselect
status: inactive
awdl0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1484
options=400<CHANNEL_IO>
ether 2e:ba:e4:83:4b:b7
inet6 fe80::2cba:e4ff:fe83:4bb7%awdl0 prefixlen 64 scopeid 0x9
ether 2e:ba:e4:83:4b:b7
inet6 fe80::2cba:e4ff:fe83:4bb7%awdl0 prefixlen 64 scopeid 0x9
nd6 options=201<PERFORMNUD,DAD>
media: autoselect
status: active
llw0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
options=400<CHANNEL_IO>
ether 2e:ba:e4:83:4b:b7
inet6 fe80::2cba:e4ff:fe83:4bb7%llw0 prefixlen 64 scopeid 0xa
ether 2e:ba:e4:83:4b:b7
inet6 fe80::2cba:e4ff:fe83:4bb7%llw0 prefixlen 64 scopeid 0xa
nd6 options=201<PERFORMNUD,DAD>
media: aumm,l.j hn toselect
status: active
utun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1380
inet6 fe80::ba29:a797:6aa:9eb%utun0 prefixlen 64 scopeid 0xb
inet6 fe80::ba29:a797:6aa:9eb%utun0 prefixlen 64 scopeid 0xb
nd6 options=201<PERFORMNUD,DAD>
utun1: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 2000
inet6 fe80::64c6:1885:bec0:c316%utun1 prefixlen 64 scopeid 0xc
inet6 fe80::64c6:1885:bec0:c316%utun1 prefixlen 64 scopeid 0xc
nd6 options=201<PERFORMNUD,DAD>
utun2: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
inet 10.16.132.213 --> 10.16.132.213 netmask 0xfffffe00
inet 10.16.132.213 --> 10.16.132.213 netmask 0xfffffe00
utun3: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
inet6 2001:db8:cafe::132:213 --> 2001:db8:cafe::132:213 prefixlen 128
utun4: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1380
tunnel inet 192.0.2.1 --> 192.0.2.2
inet 192.0.2.100 --> 192.0.2.101 netmask 0xffffffff
utun5: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1380
tunnel inet 192.0.2.1 --> 192.0.2.2
inet6 2001:db8::1 --> 2001:db8::2 prefixlen 128
ib0: flags=4099<UP,BROADCAST,MULTICAST> mtu 4092
infiniband 80:00:02:08:FA:81:00:00:00:00:00:00:00:00:00:00:00:00:00:00 txqueuelen 256 (InfiniBand)
RX packets 0 bytes 0 (0.0 B)
Expand All @@ -87,4 +93,3 @@ ib1: flags=4099<UP,BROADCAST,MULTICAST> mtu 4092
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0