1919class IProute2 (InstanceModule ):
2020 """Test network configuration via iproute2 commands
2121
22- Optional arguments:
23- - family: force iproute2 tools to use a specific protocol family
24- - namespace: execute iproute2 tools inside the provided namespace
22+ Currently supported:
23+
24+ * ip-address
25+ * ip-link
26+ * ip-route
27+ * ip-rule
28+ * ip-vrf
29+ * ip-tunnel
30+ * ip-netns
31+ * bridge vlan
32+ * bridge link
33+ * bridge fdb
34+ * bridge mdb
35+
36+ Optional module-level arguments can also be provided to contro; execution:
37+
38+ * family: force iproute2 tools to use a specific protocol family
39+ >>> host.iproute2(family="inet").addresses()
40+
41+ * namespace: execute iproute2 tools inside the provided namespace
42+ >>> host.iproute2(namespace="test").addresses()
2543
2644 """
2745
@@ -42,17 +60,68 @@ def _ip(self):
4260 ip_cmd = f"{ ip_cmd } -f { self .family } "
4361 return ip_cmd
4462
63+ @functools .cached_property
64+ def _bridge (self ):
65+ bridge_cmd = self .find_command ("bridge" )
66+ if self .namespace is not None :
67+ bridge_cmd = f"{ bridge_cmd } -n { self .namespace } "
68+ return bridge_cmd
69+
4570 @property
4671 def exists (self ):
72+ """Returns True if ip -V succeeds
73+
74+ >>> host.iproute2.exists
75+ True
76+
77+ """
4778 return self .run_test ("{} -V" .format (self ._ip )).rc == 0
4879
49- def addresses (self , address = None , ifname = None , local = None ):
50- """Return the addresses associated with interfaces
80+ @property
81+ def bridge_exists (self ):
82+ """Returns True if bridge -V succeeds
83+
84+ >>> host.iproute2.bridge_exists
85+ True
5186
52- Optionally, results can be filtered by:
53- - address
54- - ifname
55- - local
87+ """
88+ return self .run_test ("{} -V" .format (self ._bridge )).rc == 0
89+
90+ def addresses (self , address = None , ifname = None , local = None ):
91+ """Returns the addresses associated with interfaces
92+
93+ >>> host.iproute2.addresses()
94+ [{'ifindex': 1,
95+ 'ifname': 'lo',
96+ 'flags': ['LOOPBACK', 'UP', 'LOWER_UP'],
97+ 'mtu': 65536,
98+ 'qdisc': 'noqueue',
99+ 'operstate': 'UNKNOWN',
100+ 'group': 'default',
101+ 'txqlen': 1000,
102+ 'link_type': 'loopback',
103+ 'address': '00:00:00:00:00:00',
104+ 'broadcast': '00:00:00:00:00:00',
105+ 'addr_info': [{'family': 'inet',
106+ 'local': '127.0.0.1',
107+ 'prefixlen': 8,
108+ 'scope': 'host',
109+ 'label': 'lo',
110+ 'valid_life_time': 4294967295,
111+ 'preferred_life_time': 4294967295},
112+ {'family': 'inet6',
113+ 'local': '::1',
114+ 'prefixlen': 128,
115+ 'scope': 'host',
116+ 'noprefixroute': True,
117+ 'valid_life_time': 4294967295,
118+ 'preferred_life_time': 4294967295}]}]
119+
120+ Optionally, results can be filtered with the following selectors:
121+
122+ * address
123+ * ifname
124+ * local
56125
57126 """
58127 cmd = f"{ self ._ip } --json address show"
@@ -74,26 +143,56 @@ def addresses(self, address=None, ifname=None, local=None):
74143 return o
75144
76145 def links (self ):
77- """Return links and their state"""
146+ """Returns links and their state.
147+
148+ >>> host.iproute2.links()
149+ [{'ifindex': 1,
150+ 'ifname': 'lo',
151+ 'flags': ['LOOPBACK', 'UP', 'LOWER_UP'],
152+ 'mtu': 65536,
153+ 'qdisc': 'noqueue',
154+ 'operstate': 'UNKNOWN',
155+ 'linkmode': 'DEFAULT',
156+ 'group': 'default',
157+ 'txqlen': 1000,
158+ 'link_type': 'loopback',
159+ 'address': '00:00:00:00:00:00',
160+ 'broadcast': '00:00:00:00:00:00'}]
161+
162+ """
78163 cmd = f"{ self ._ip } --json link show"
79164 out = self .check_output (cmd )
80165 return json .loads (out )
81166
82167 def routes (
83168 self , table = "all" , device = None , scope = None , proto = None , src = None , metric = None
84169 ):
85- """Returns the routes installed
86-
87- Optionally, routes returned can be filtered with the following
88- selectors. This can be useful in busy routing tables.
89-
90- Selectors:
91- - table
92- - device (maps to ip-route's 'dev' selector)
93- - scope
94- - proto
95- - src
96- - metric
170+ """Returns the routes installed in *all* routing tables.
171+
172+ >>> host.iproute2.routes()
173+ [{'dst': '169.254.0.0/16',
174+ 'dev': 'wlp4s0',
175+ 'scope': 'link',
176+ 'metric': 1000,
177+ 'flags': []},
178+ {'type': 'multicast',
179+ 'dst': 'ff00::/8',
180+ 'dev': 'wlp4s0',
181+ 'table': 'local',
182+ 'protocol': 'kernel',
183+ 'metric': 256,
184+ 'flags': [],
185+ 'pref': 'medium'}]
186+
187+ Optionally, routes returned can be filtered with the following
188+ selectors. This can be useful in busy routing tables.
189+
190+ * table
191+ * device (maps to ip-route's 'dev' selector)
192+ * scope
193+ * proto
194+ * src
195+ * metric
97196
98197 """
99198 cmd = f"{ self ._ip } --json route show "
@@ -129,23 +228,28 @@ def rules(
129228 sport = None ,
130229 dport = None ,
131230 ):
132- """Returns the rules our routing policy consists of
133-
134- Optionally, rules returned can be filtered with the following
135- selectors. This can be useful in busy rulesets.
136-
137- Selectors:
138- - src (maps to ip-rule's 'from' selector)
139- - to
140- - tos
141- - fwmark
142- - iif
143- - oif
144- - pref
145- - uidrange
146- - ipproto
147- - sport
148- - dport
231+ """Returns the rules our routing policy consists of.
232+
233+ >>> host.iproute2.rules()
234+ [{'priority': 0, 'src': 'all', 'table': 'local'},
235+ {'priority': 32765, 'src': '1.2.3.4', 'table': '123'},
236+ {'priority': 32766, 'src': 'all', 'table': 'main'},
237+ {'priority': 32767, 'src': 'all', 'table': 'default'}]
238+
239+ Optionally, rules returned can be filtered with the following
240+ selectors. This can be useful in busy rulesets.
241+
242+ * src (maps to ip-rule's 'from' selector)
243+ * to
244+ * tos
245+ * fwmark
246+ * iif
247+ * oif
248+ * pref
249+ * uidrange
250+ * ipproto
251+ * sport
252+ * dport
149253
150254 """
151255 cmd = f"{ self ._ip } --json rule show "
@@ -191,11 +295,16 @@ def rules(
191295 def tunnels (self , ifname = None ):
192296 """Returns all configured tunnels
193297
194- Optionally, tunnels returned can be filtered with the interface name.
195- This can be faster in busy tunnel installations.
298+ >>> host.iproute2.tunnels()
299+ [{'ifname': 'test1',
300+ 'mode': 'ip/ip',
301+ 'remote': '127.0.0.2',
302+ 'local': '0.0.0.0'}]
303+
304+ Optionally, tunnels returned can be filtered with the interface name.
305+ This can be faster in busy tunnel installations.
196306
197- Selectors:
198- - ifname
307+ * ifname
199308
200309 """
201310 cmd = f"{ self ._ip } --json tunnel show "
@@ -215,33 +324,62 @@ def vrfs(self):
215324 return json .loads (out )
216325
217326 def netns (self ):
218- """Returns all configured network namespaces"""
327+ """Returns all configured network namespaces
328+
329+ >>> host.iproute2.netns()
330+ [{'name': 'test'}]
331+ """
332+
219333 cmd = f"{ self ._ip } --json netns show"
220334 out = self .check_output (cmd )
221335 if not out : # ip netns returns null instead of [] in json mode
222336 return json .loads ("[]\n " )
223337 return json .loads (out )
224338
225339 def bridge_vlan (self ):
226- """Returns all configured vlans"""
340+ """Returns all configured vlans
341+
342+ >>> host.iproute2.bridge_vlan()
343+ []
344+ """
345+
227346 cmd = f"{ self ._bridge } -json vlan show"
228347 out = self .check_output (cmd )
229348 return json .loads (out )
230349
231350 def bridge_fdb (self ):
232- """Returns all configured fdb entries"""
351+ """Returns all configured fdb entries
352+
353+ >>> host.iproute2.bridge_fdb()
354+ [{'mac': '33:33:00:00:00:01',
355+ 'ifname': 'enp0s31f6',
356+ 'flags': ['self'],
357+ 'state': 'permanent'}]
358+ """
359+
233360 cmd = f"{ self ._bridge } -json fdb show"
234361 out = self .check_output (cmd )
235362 return json .loads (out )
236363
237364 def bridge_mdb (self ):
238- """Returns all configured mdb entries"""
365+ """Returns all configured mdb entries
366+
367+ >>> host.iproute2.bridge_mdb()
368+ [{'mdb': [], 'router': {}}]
369+
370+ """
371+
239372 cmd = f"{ self ._bridge } -json mdb show"
240373 out = self .check_output (cmd )
241374 return json .loads (out )
242375
243376 def bridge_link (self ):
244- """Returns all configured links"""
377+ """Returns all configured links
378+
379+ >>> host.iproute2.bridge_link()
380+ []
381+ """
382+
245383 cmd = f"{ self ._bridge } -json link show"
246384 out = self .check_output (cmd )
247385 return json .loads (out )
0 commit comments