Skip to content

Commit b48cd3d

Browse files
committed
networking.interfaces: Provide ifconfig(8) flags, rdomain, desription and groups
OpenBSD, FreeBSD and macOS all show interface flags the same way. OpenBSD and FreeBSD support descriptions and groups. OpenBSD has https://man.openbsd.org/rdomain.4 as well. If these properties are not set or ifconfig does not print them, they will simply not appear. This allows OpenVox to act upon such details without shelling out to custom scripts; without either of this there is currently no way to ensure (partial) interface state. Example from OpenBSD: ``` pair2: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> rdomain 46 mtu 1500 lladdr fe:e1:ba:d1:c3:a7 description: gelatod CLAT 464XLAT index 6 priority 0 llprio 3 patch: pair1 groups: pair media: Ethernet autoselect status: active inet 192.0.0.1 netmask 0xfffffff8 broadcast 192.0.0.7 ``` Result: ``` { bindings => [ { address => "192.0.0.1", netmask => "255.255.255.248", network => "192.0.0.0" } ], + description => "gelatod CLAT 464XLAT", + flags => [ + "UP", + "BROADCAST", + "RUNNING", + "SIMPLEX", + "MULTICAST" + ], + groups => [ + "pair" + ], ip => "192.0.0.1", mac => "fe:e1:ba:d1:c3:a7", mtu => 1500, netmask => "255.255.255.248", network => "192.0.0.0", + rdomain => 46 } ```
1 parent 5de5947 commit b48cd3d

3 files changed

Lines changed: 47 additions & 7 deletions

File tree

lib/facter/resolvers/networking.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,12 @@ def parse_interfaces_response(response)
4949
interfaces_data.each do |interface_name, raw_data|
5050
parsed_interface_data = {}
5151

52+
extract_flags(raw_data, parsed_interface_data)
53+
extract_rdomain(raw_data, parsed_interface_data)
5254
extract_mtu(raw_data, parsed_interface_data)
5355
extract_mac(raw_data, parsed_interface_data)
56+
extract_description(raw_data, parsed_interface_data)
57+
extract_groups(raw_data, parsed_interface_data)
5458
extract_dhcp(interface_name, raw_data, parsed_interface_data)
5559
extract_ip_data(raw_data, parsed_interface_data)
5660

@@ -59,11 +63,31 @@ def parse_interfaces_response(response)
5963
@fact_list[:interfaces] = parsed_interfaces_data unless parsed_interfaces_data.empty?
6064
end
6165

66+
def extract_flags(raw_data, parsed_interface_data)
67+
flags = raw_data.match(/flags=\d+<(.+)>/)&.captures&.first
68+
parsed_interface_data[:flags] = flags.split(',') unless flags.nil?
69+
end
70+
71+
def extract_rdomain(raw_data, parsed_interface_data)
72+
rdomain = raw_data.match(/rdomain\s+(\d+)/)&.captures&.first&.to_i
73+
parsed_interface_data[:rdomain] = rdomain unless rdomain.nil?
74+
end
75+
6276
def extract_mtu(raw_data, parsed_interface_data)
6377
mtu = raw_data.match(/mtu\s+(\d+)/)&.captures&.first&.to_i
6478
parsed_interface_data[:mtu] = mtu unless mtu.nil?
6579
end
6680

81+
def extract_description(raw_data, parsed_interface_data)
82+
description = raw_data.match(/description:\s+(.+)/)&.captures&.first
83+
parsed_interface_data[:description] = description unless description.nil?
84+
end
85+
86+
def extract_groups(raw_data, parsed_interface_data)
87+
groups = raw_data.match(/groups:\s+(.+)/)&.captures&.first
88+
parsed_interface_data[:groups] = groups.split("\s") unless groups.nil?
89+
end
90+
6791
def extract_mac(raw_data, parsed_interface_data)
6892
mac = raw_data.match(/(?:ether|lladdr)\s+((?:\w?\w:){5}\w?\w)|(?:infiniband)\s+((?:\w?\w:){19}\w?\w)/)
6993
&.captures&.compact&.first

spec/facter/resolvers/networking_spec.rb

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@
1818
.to receive(:execute).with('ipconfig getoption llw0 server_identifier', logger: an_instance_of(Facter::Log)).and_return('')
1919
allow(Facter::Core::Execution)
2020
.to receive(:execute).with('ipconfig getoption awdl0 server_identifier', logger: an_instance_of(Facter::Log)).and_return(dhcp)
21+
allow(Facter::Core::Execution)
22+
.to receive(:execute).with('ipconfig getoption pair2 server_identifier', logger: an_instance_of(Facter::Log)).and_return('')
2123
end
2224

2325
after do
2426
networking.invalidate_cache
2527
end
2628

27-
let(:interfaces) { load_fixture('ifconfig_mac').read }
29+
let(:interfaces) { load_fixture('ifconfig').read }
2830
let(:dhcp) { '192.168.143.1' }
2931
let(:primary) { 'en0' }
3032

@@ -37,12 +39,12 @@
3739
end
3840

3941
it 'detects all interfaces' do
40-
expected = %w[lo0 gif0 stf0 en0 en0.1 en1 en2 bridge0 p2p0 awdl0 llw0 utun0 utun1 utun2 utun3 ib0 ib1]
42+
expected = %w[lo0 gif0 stf0 en0 en0.1 en1 en2 bridge0 p2p0 awdl0 llw0 utun0 utun1 utun2 utun3 ib0 ib1 pair2]
4143
expect(networking.resolve(:interfaces).keys).to match_array(expected)
4244
end
4345

4446
it 'checks that interface lo0 has the expected keys' do
45-
expected = %i[mtu bindings6 bindings ip ip6 netmask netmask6 network network6 scope6]
47+
expected = %i[flags mtu bindings6 bindings ip ip6 netmask netmask6 network network6 scope6]
4648
expect(networking.resolve(:interfaces)['lo0'].keys).to match_array(expected)
4749
end
4850

@@ -68,17 +70,17 @@
6870
end
6971

7072
it 'detects interface en1' do
71-
expected = { mtu: 1500, mac: '82:17:0e:93:9d:00' }
73+
expected = { flags: %w[UP BROADCAST SMART RUNNING PROMISC SIMPLEX MULTICAST], mtu: 1500, mac: '82:17:0e:93:9d:00' }
7274
expect(networking.resolve(:interfaces)['en1']).to eq(expected)
7375
end
7476

7577
it 'detects interface gif0' do
76-
expected = { mtu: 1280 }
78+
expected = { flags: %w[POINTOPOINT MULTICAST], mtu: 1280 }
7779
expect(networking.resolve(:interfaces)['gif0']).to eq(expected)
7880
end
7981

8082
it 'checks that interface en0 has the expected keys' do
81-
expected = %i[mtu mac bindings ip netmask network dhcp]
83+
expected = %i[flags mtu mac bindings ip netmask network dhcp]
8284
expect(networking.resolve(:interfaces)['en0'].keys).to match_array(expected)
8385
end
8486

@@ -113,7 +115,7 @@
113115
end
114116

115117
it 'checks that interface awdl0 has the expected keys' do
116-
expected = %i[mtu mac bindings6 ip6 netmask6 network6 scope6 dhcp]
118+
expected = %i[flags mtu mac bindings6 ip6 netmask6 network6 scope6 dhcp]
117119
expect(networking.resolve(:interfaces)['awdl0'].keys).to match_array(expected)
118120
end
119121

@@ -135,6 +137,11 @@
135137
expect(networking.resolve(:interfaces)['utun3']).to include(expected)
136138
end
137139

140+
it 'checks that interface pair2 has description, rdomain and groups' do
141+
expected = { rdomain: 46, description: 'gelatod CLAT 464XLAT', groups: %w[pair] }
142+
expect(networking.resolve(:interfaces)['pair2']).to include(expected)
143+
end
144+
138145
it 'checks interface ib0 has the expected mac' do
139146
expected = { mac: '80:00:02:08:FA:81:00:00:00:00:00:00:00:00:00:00:00:00:00:00' }
140147
expect(networking.resolve(:interfaces)['ib0']).to include(expected)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,12 @@ ib1: flags=4099<UP,BROADCAST,MULTICAST> mtu 4092
8888
TX packets 0 bytes 0 (0.0 B)
8989
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
9090

91+
pair2: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> rdomain 46 mtu 1500
92+
lladdr fe:e1:ba:d1:c3:a7
93+
description: gelatod CLAT 464XLAT
94+
index 6 priority 0 llprio 3
95+
patch: pair1
96+
groups: pair
97+
media: Ethernet autoselect
98+
status: active
99+
inet 192.0.0.1 netmask 0xfffffff8 broadcast 192.0.0.7

0 commit comments

Comments
 (0)