3 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
4 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
9 from ipaddr
import IPNetwork
, IPv4Network
, IPv6Network
, _BaseV6
12 from ifupdown2
.ifupdown
.iface
import *
13 from ifupdown2
.ifupdown
.utils
import utils
14 from ifupdown2
.ifupdown
.netlink
import netlink
16 from ifupdown2
.ifupdownaddons
.dhclient
import dhclient
17 from ifupdown2
.ifupdownaddons
.LinkUtils
import LinkUtils
18 from ifupdown2
.ifupdownaddons
.modulebase
import moduleBase
20 import ifupdown2
.ifupdown
.statemanager
as statemanager
21 import ifupdown2
.ifupdown
.policymanager
as policymanager
22 import ifupdown2
.ifupdown
.ifupdownflags
as ifupdownflags
23 import ifupdown2
.ifupdown
.ifupdownconfig
as ifupdownconfig
25 from ifupdown
.iface
import *
26 from ifupdown
.utils
import utils
27 from ifupdown
.netlink
import netlink
29 from ifupdownaddons
.dhclient
import dhclient
30 from ifupdownaddons
.LinkUtils
import LinkUtils
31 from ifupdownaddons
.modulebase
import moduleBase
33 import ifupdown
.statemanager
as statemanager
34 import ifupdown
.policymanager
as policymanager
35 import ifupdown
.ifupdownflags
as ifupdownflags
36 import ifupdown
.ifupdownconfig
as ifupdownconfig
39 class address(moduleBase
):
40 """ ifupdown2 addon module to configure address, mtu, hwaddress, alias
41 (description) on an interface """
43 _modinfo
= {'mhelp' : 'address configuration module for interfaces',
46 {'help' : 'ipv4 or ipv6 addresses',
47 'validvals' : ['<ipv4/prefixlen>', '<ipv6/prefixlen>'],
49 'example' : ['address 10.0.12.3/24',
50 'address 2000:1000:1000:1000:3::5/128']},
53 'example' : ['netmask 255.255.255.0'],
56 {'help': 'broadcast address',
57 'validvals' : ['<ipv4>', ],
58 'example' : ['broadcast 10.0.1.255']},
61 'validvals' : ['universe', 'site', 'link', 'host', 'nowhere'],
62 'example' : ['scope host']},
63 'preferred-lifetime' :
64 {'help': 'preferred lifetime',
65 'validrange' : ['0', '65535'],
66 'example' : ['preferred-lifetime forever',
67 'preferred-lifetime 10']},
69 {'help': 'default gateway',
70 'validvals' : ['<ipv4>', '<ipv6>'],
72 'example' : ['gateway 255.255.255.0']},
74 { 'help': 'interface mtu',
75 'validrange' : ['552', '9216'],
76 'example' : ['mtu 1600'],
79 {'help' : 'hw address',
80 'validvals' : ['<mac>',],
81 'example': ['hwaddress 44:38:39:00:27:b8']},
83 { 'help': 'description/alias',
84 'example' : ['alias testnetwork']},
86 { 'help': 'purge existing addresses. By default ' +
87 'any existing ip addresses on an interface are ' +
88 'purged to match persistant addresses in the ' +
89 'interfaces file. Set this attribute to \'no\'' +
90 'if you want to preserve existing addresses',
91 'validvals' : ['yes', 'no'],
93 'example' : ['address-purge yes/no']},
94 'clagd-vxlan-anycast-ip' :
95 { 'help' : 'Anycast local IP address for ' +
96 'dual connected VxLANs',
97 'validvals' : ['<ipv4>', ],
98 'example' : ['clagd-vxlan-anycast-ip 36.0.0.11']},
100 { 'help': 'ip forwarding flag',
101 'validvals': ['on', 'off', 'yes', 'no', '0', '1'],
103 'example' : ['ip-forward off']},
105 { 'help': 'ipv6 forwarding flag',
106 'validvals': ['on', 'off', 'yes', 'no', '0', '1'],
108 'example' : ['ip6-forward off']},
110 { 'help': 'mpls enable flag',
111 'validvals': ['yes', 'no'],
113 'example' : ['mpls-enable yes']},
115 'help': 'enable disable ipv6 link addrgenmode',
116 'validvals': ['on', 'off'],
125 def __init__(self
, *args
, **kargs
):
126 moduleBase
.__init
__(self
, *args
, **kargs
)
128 self
._bridge
_fdb
_query
_cache
= {}
129 self
.default_mtu
= policymanager
.policymanager_api
.get_attr_default(module_name
=self
.__class
__.__name
__, attr
='mtu')
130 self
.max_mtu
= policymanager
.policymanager_api
.get_module_globals(module_name
=self
.__class
__.__name
__, attr
='max_mtu')
131 self
.ipforward
= policymanager
.policymanager_api
.get_attr_default(module_name
=self
.__class
__.__name
__, attr
='ip-forward')
132 self
.ip6forward
= policymanager
.policymanager_api
.get_attr_default(module_name
=self
.__class
__.__name
__, attr
='ip6-forward')
133 self
.ifaces_defaults
= policymanager
.policymanager_api
.get_iface_defaults(module_name
=self
.__class
__.__name
__)
134 self
.enable_l3_iface_forwarding_checks
= utils
.get_boolean_from_string(
135 policymanager
.policymanager_api
.get_module_globals(
136 self
.__class
__.__name
__,
137 'enable_l3_iface_forwarding_checks'
141 if not self
.default_mtu
:
142 self
.default_mtu
= '1500'
144 self
.logger
.info('address: using default mtu %s' %self
.default_mtu
)
147 self
.logger
.info('address: using max mtu %s' %self
.max_mtu
)
149 self
.lower_iface_mtu_checked_list
= list()
151 self
.l3_intf_arp_accept
= utils
.get_boolean_from_string(
152 policymanager
.policymanager_api
.get_module_globals(
153 module_name
=self
.__class
__.__name
__,
154 attr
='l3_intf_arp_accept'
159 def syntax_check(self
, ifaceobj
, ifaceobj_getfunc
=None):
160 return (self
.syntax_check_multiple_gateway(ifaceobj
)
161 and self
.syntax_check_addr_allowed_on(ifaceobj
, True)
162 and self
.syntax_check_mtu(ifaceobj
, ifaceobj_getfunc
)
163 and self
.syntax_check_sysctls(ifaceobj
)
164 and self
.syntax_check_enable_l3_iface_forwardings(ifaceobj
, ifaceobj_getfunc
, syntax_check
=True))
166 def syntax_check_enable_l3_iface_forwardings(self
, ifaceobj
, ifaceobj_getfunc
, syntax_check
=False):
167 if (self
.enable_l3_iface_forwarding_checks
168 and (ifaceobj
.link_kind
& ifaceLinkKind
.VLAN
169 or ifaceobj
.link_kind
& ifaceLinkKind
.BRIDGE
)
170 and not ifaceobj
.link_privflags
& ifaceLinkPrivFlags
.BRIDGE_PORT
):
172 ifname
= ifaceobj
.name
174 vlan_ipforward_off
= None
176 for obj
in ifaceobj_getfunc(ifname
) or [ifaceobj
]:
178 vlan_addr
= obj
.get_attr_value('address')
180 if not vlan_ipforward_off
:
181 ip_forward_value
= obj
.get_attr_value_first('ip-forward')
183 if ip_forward_value
and not utils
.get_boolean_from_string(ip_forward_value
):
184 vlan_ipforward_off
= True
186 if vlan_addr
and vlan_ipforward_off
:
189 'configuring ip-forward off and ip address(es) (%s) is not compatible'
190 % (', '.join(vlan_addr
))
194 '%s: configuring ip-forward off and ip address(es) (%s) is not compatible'
195 % (ifname
, ', '.join(vlan_addr
))
200 def syntax_check_sysctls(self
, ifaceobj
):
202 bridge_port
= (ifaceobj
.link_privflags
& ifaceLinkPrivFlags
.BRIDGE_PORT
)
203 ipforward
= ifaceobj
.get_attr_value_first('ip-forward')
204 if bridge_port
and ipforward
:
206 self
.log_error('%s: \'ip-forward\' is not supported for '
207 'bridge port' %ifaceobj
.name
)
208 ip6forward
= ifaceobj
.get_attr_value_first('ip6-forward')
209 if bridge_port
and ip6forward
:
211 self
.log_error('%s: \'ip6-forward\' is not supported for '
212 'bridge port' %ifaceobj
.name
)
215 def syntax_check_mtu(self
, ifaceobj
, ifaceobj_getfunc
):
216 mtu
= ifaceobj
.get_attr_value_first('mtu')
218 return self
._check
_mtu
_config
(ifaceobj
, mtu
, ifaceobj_getfunc
,
222 def syntax_check_addr_allowed_on(self
, ifaceobj
, syntax_check
=False):
223 if ifaceobj
.get_attr_value('address'):
224 return utils
.is_addr_ip_allowed_on(ifaceobj
, syntax_check
=syntax_check
)
227 def _syntax_check_multiple_gateway(self
, family
, found
, addr
, type_obj
):
228 if type(IPNetwork(addr
)) == type_obj
:
230 raise Exception('%s: multiple gateways for %s family'
235 def syntax_check_multiple_gateway(self
, ifaceobj
):
239 gateways
= ifaceobj
.get_attr_value('gateway')
240 for addr
in gateways
if gateways
else []:
242 if self
._syntax
_check
_multiple
_gateway
('inet', inet
, addr
,
245 if self
._syntax
_check
_multiple
_gateway
('inet6', inet6
, addr
,
248 except Exception as e
:
249 self
.logger
.warning('%s: address: %s' % (ifaceobj
.name
, str(e
)))
253 def _address_valid(self
, addrs
):
256 if any(map(lambda a
: True if a
[:7] != '0.0.0.0'
261 def _get_hwaddress(self
, ifaceobj
):
262 return utils
.strip_hwaddress(ifaceobj
.get_attr_value_first('hwaddress'))
264 def _process_bridge(self
, ifaceobj
, up
):
265 hwaddress
= self
._get
_hwaddress
(ifaceobj
)
266 addrs
= ifaceobj
.get_attr_value_first('address')
267 is_vlan_dev_on_vlan_aware_bridge
= False
268 is_bridge
= self
.ipcmd
.is_bridge(ifaceobj
.name
)
270 if ifaceobj
.link_kind
& ifaceLinkKind
.VLAN
:
271 bridgename
= ifaceobj
.lowerifaces
[0]
272 vlan
= self
._get
_vlan
_id
(ifaceobj
)
273 is_vlan_dev_on_vlan_aware_bridge
= self
.ipcmd
.bridge_is_vlan_aware(bridgename
)
274 if ((is_bridge
and not self
.ipcmd
.bridge_is_vlan_aware(ifaceobj
.name
))
275 or is_vlan_dev_on_vlan_aware_bridge
):
276 if self
._address
_valid
(addrs
):
277 if self
.l3_intf_arp_accept
:
279 self
.write_file('/proc/sys/net/ipv4/conf/%s' % ifaceobj
.name
+
282 self
.write_file('/proc/sys/net/ipv4/conf/%s' % ifaceobj
.name
+
285 self
.write_file('/proc/sys/net/ipv4/conf/%s/arp_accept' % ifaceobj
.name
, '0')
286 if hwaddress
and is_vlan_dev_on_vlan_aware_bridge
:
288 self
.ipcmd
.bridge_fdb_add(bridgename
, hwaddress
, vlan
)
290 self
.ipcmd
.bridge_fdb_del(bridgename
, hwaddress
, vlan
)
292 def _get_anycast_addr(self
, ifaceobjlist
):
293 for ifaceobj
in ifaceobjlist
:
294 anycast_addr
= ifaceobj
.get_attr_value_first('clagd-vxlan-anycast-ip')
296 anycast_addr
= anycast_addr
+'/32'
300 def _inet_address_convert_to_cidr(self
, ifaceobjlist
):
304 for ifaceobj
in ifaceobjlist
:
305 addrs
= ifaceobj
.get_attr_value('address')
309 if not self
.syntax_check_addr_allowed_on(ifaceobj
,
311 return (False, newaddrs
, newaddr_attrs
)
312 # If user address is not in CIDR notation, convert them to CIDR
313 for addr_index
in range(0, len(addrs
)):
314 addr
= addrs
[addr_index
]
317 newaddrs
.append(addr
)
319 netmask
= ifaceobj
.get_attr_value_n('netmask', addr_index
)
321 prefixlen
= IPNetwork('%s' %addr
+
322 '/%s' %netmask
).prefixlen
323 newaddr
= addr
+ '/%s' %prefixlen
325 # we are here because there is no slash (/xx) and no netmask
326 # just let IPNetwork handle the ipv4 or ipv6 address mask
327 prefixlen
= IPNetwork(addr
).prefixlen
328 newaddr
= addr
+ '/%s' %prefixlen
329 newaddrs
.append(newaddr
)
332 for a
in ['broadcast', 'pointopoint', 'scope',
333 'preferred-lifetime']:
334 aval
= ifaceobj
.get_attr_value_n(a
, addr_index
)
339 newaddr_attrs
[newaddr
]= attrs
340 return (True, newaddrs
, newaddr_attrs
)
342 def _inet_address_list_config(self
, ifaceobj
, newaddrs
, newaddr_attrs
):
343 for addr_index
in range(0, len(newaddrs
)):
346 self
.ipcmd
.addr_add(ifaceobj
.name
, newaddrs
[addr_index
],
347 newaddr_attrs
.get(newaddrs
[addr_index
],
348 {}).get('broadcast'),
349 newaddr_attrs
.get(newaddrs
[addr_index
],
350 {}).get('pointopoint'),
351 newaddr_attrs
.get(newaddrs
[addr_index
],
353 newaddr_attrs
.get(newaddrs
[addr_index
],
354 {}).get('preferred-lifetime'))
356 self
.ipcmd
.addr_add(ifaceobj
.name
, newaddrs
[addr_index
])
358 self
.log_error(str(e
), ifaceobj
)
360 def _inet_address_config(self
, ifaceobj
, ifaceobj_getfunc
=None,
361 force_reapply
=False):
362 squash_addr_config
= (True if \
363 ifupdownconfig
.config
.get('addr_config_squash', \
364 '0') == '1' else False)
366 if (squash_addr_config
and
367 not (ifaceobj
.flags
& ifaceobj
.YOUNGEST_SIBLING
)):
370 purge_addresses
= ifaceobj
.get_attr_value_first('address-purge')
371 if not purge_addresses
:
372 purge_addresses
= 'yes'
374 if squash_addr_config
and ifaceobj
.flags
& iface
.HAS_SIBLINGS
:
375 ifaceobjlist
= ifaceobj_getfunc(ifaceobj
.name
)
377 ifaceobjlist
= [ifaceobj
]
379 module_name
= self
.__class
__.__name
__
380 ifname
= ifaceobj
.name
382 (addr_supported
, newaddrs
, newaddr_attrs
) = self
._inet
_address
_convert
_to
_cidr
(ifaceobjlist
)
383 newaddrs
= utils
.get_ip_objs(module_name
, ifname
, newaddrs
)
385 if not addr_supported
:
387 if (not squash_addr_config
and (ifaceobj
.flags
& iface
.HAS_SIBLINGS
)):
388 # if youngest sibling and squash addr is not set
389 # print a warning that addresses will not be purged
390 if (ifaceobj
.flags
& iface
.YOUNGEST_SIBLING
):
391 self
.logger
.warn('%s: interface has multiple ' %ifaceobj
.name
+
392 'iface stanzas, skip purging existing addresses')
393 purge_addresses
= 'no'
395 if not ifupdownflags
.flags
.PERFMODE
and purge_addresses
== 'yes':
396 # if perfmode is not set and purge addresses is not set to 'no'
397 # lets purge addresses not in the config
398 runningaddrs
= self
.ipcmd
.get_running_addrs(ifaceobj
, details
=False)
400 # if anycast address is configured on 'lo' and is in running config
401 # add it to newaddrs so that ifreload doesn't wipe it out
402 anycast_addr
= utils
.get_normalized_ip_addr(ifaceobj
.name
, self
._get
_anycast
_addr
(ifaceobjlist
))
404 if runningaddrs
and anycast_addr
and anycast_addr
in runningaddrs
:
405 newaddrs
.append(anycast_addr
)
407 user_ip4
, user_ip6
, newaddrs
= self
.order_user_configured_addrs(newaddrs
)
409 if newaddrs
== runningaddrs
or self
.compare_running_ips_and_user_config(user_ip4
, user_ip6
, runningaddrs
):
411 self
._inet
_address
_list
_config
(ifaceobj
, newaddrs
, newaddr_attrs
)
414 # if primary address is not same, there is no need to keep any.
415 # reset all addresses
416 if newaddrs
and runningaddrs
and newaddrs
[0] != runningaddrs
[0]:
419 skip_addrs
= newaddrs
or []
420 for addr
in runningaddrs
or []:
421 if addr
in skip_addrs
:
423 self
.ipcmd
.addr_del(ifaceobj
.name
, addr
)
425 self
.log_warn(str(e
))
428 self
._inet
_address
_list
_config
(ifaceobj
, newaddrs
, newaddr_attrs
)
430 def compare_running_ips_and_user_config(self
, user_ip4
, user_ip6
, running_addrs
):
432 We need to compare the user config ips and the running ips.
433 ip4 ordering matters (primary etc) but ip6 order doesn't matter
435 this function replaces the strict comparison previously in place
436 if newaddrs == running_addrs ?
438 We will compare if the ip4 ordering is correct, then check if all
439 ip6 are present in the list (without checking the ordering)
441 if (user_ip4
or user_ip6
) and not running_addrs
:
443 elif running_addrs
and not user_ip4
and not user_ip6
:
445 elif not running_addrs
and not user_ip4
and not user_ip6
:
448 len_ip4
= len(user_ip4
)
449 len_running_addrs
= len(running_addrs
)
451 if len_ip4
> len_running_addrs
:
456 if user_ip4
[i
] != running_addrs
[i
]:
461 running_ip6
= running_addrs
[len_ip4
:]
463 running_ip6
= running_addrs
466 len_ip6
= len(user_ip6
)
468 for ip6
in running_ip6
:
469 if ip6
not in user_ip6
:
475 def order_user_configured_addrs(self
, user_config_addrs
):
479 for a
in user_config_addrs
:
480 if isinstance(a
, _BaseV6
):
485 return ip4
, ip6
, ip4
+ ip6
487 def _delete_gateway(self
, ifaceobj
, gateways
, vrf
, metric
):
488 for del_gw
in gateways
:
490 self
.ipcmd
.route_del_gateway(ifaceobj
.name
, del_gw
, vrf
, metric
)
491 except Exception as e
:
492 self
.logger
.debug('%s: %s' % (ifaceobj
.name
, str(e
)))
494 def _add_delete_gateway(self
, ifaceobj
, gateways
=[], prev_gw
=[]):
495 vrf
= ifaceobj
.get_attr_value_first('vrf')
496 metric
= ifaceobj
.get_attr_value_first('metric')
497 self
._delete
_gateway
(ifaceobj
, list(set(prev_gw
) - set(gateways
)),
499 for add_gw
in gateways
:
501 self
.ipcmd
.route_add_gateway(ifaceobj
.name
, add_gw
, vrf
, metric
)
502 except Exception as e
:
503 self
.log_error('%s: %s' % (ifaceobj
.name
, str(e
)))
505 def _get_prev_gateway(self
, ifaceobj
, gateways
):
507 saved_ifaceobjs
= statemanager
.statemanager_api
.get_ifaceobjs(ifaceobj
.name
)
508 if not saved_ifaceobjs
:
510 prev_gateways
= saved_ifaceobjs
[0].get_attr_value('gateway')
511 if not prev_gateways
:
515 def _check_mtu_config(self
, ifaceobj
, mtu
, ifaceobj_getfunc
, syntaxcheck
=False):
517 if (ifaceobj
.link_kind
& ifaceLinkKind
.BRIDGE
):
519 self
.logger
.warn('%s: bridge inherits mtu from its ports. There is no need to assign mtu on a bridge' %ifaceobj
.name
)
522 self
.logger
.info('%s: bridge inherits mtu from its ports. There is no need to assign mtu on a bridge' %ifaceobj
.name
)
523 elif ifaceobj_getfunc
:
524 if ((ifaceobj
.link_privflags
& ifaceLinkPrivFlags
.BOND_SLAVE
) and
525 ifaceobj
.upperifaces
):
526 masterobj
= ifaceobj_getfunc(ifaceobj
.upperifaces
[0])
528 master_mtu
= masterobj
[0].get_attr_value_first('mtu')
529 if master_mtu
and master_mtu
!= mtu
:
531 self
.logger
.warn('%s: bond slave mtu %s is different from bond master %s mtu %s. There is no need to configure mtu on a bond slave.' %(ifaceobj
.name
, mtu
, masterobj
[0].name
, master_mtu
))
534 self
.logger
.info('%s: bond slave mtu %s is different from bond master %s mtu %s. There is no need to configure mtu on a bond slave.' %(ifaceobj
.name
, mtu
, masterobj
[0].name
, master_mtu
))
535 elif ((ifaceobj
.link_kind
& ifaceLinkKind
.VLAN
) and
536 ifaceobj
.lowerifaces
):
537 lowerobj
= ifaceobj_getfunc(ifaceobj
.lowerifaces
[0])
540 lowerdev_mtu
= lowerobj
[0].get_attr_value_first('mtu')
542 lowerdev_mtu
= self
.ipcmd
.link_get_mtu_sysfs(lowerobj
[0].name
)
543 if lowerdev_mtu
and int(mtu
) > int(lowerdev_mtu
):
544 self
.logger
.warn('%s: vlan dev mtu %s is greater than lower realdev %s mtu %s'
545 %(ifaceobj
.name
, mtu
, lowerobj
[0].name
, lowerdev_mtu
))
547 elif (not lowerobj
[0].link_kind
and
548 not (lowerobj
[0].link_privflags
& ifaceLinkPrivFlags
.LOOPBACK
) and
549 not lowerdev_mtu
and self
.default_mtu
and
550 (int(mtu
) > int(self
.default_mtu
))):
551 # only check default mtu on lower device which is a physical interface
552 self
.logger
.warn('%s: vlan dev mtu %s is greater than lower realdev %s mtu %s'
553 %(ifaceobj
.name
, mtu
, lowerobj
[0].name
, self
.default_mtu
))
555 if self
.max_mtu
and mtu
> self
.max_mtu
:
556 self
.logger
.warn('%s: specified mtu %s is greater than max mtu %s'
557 %(ifaceobj
.name
, mtu
, self
.max_mtu
))
561 def _propagate_mtu_to_upper_devs(self
, ifaceobj
, mtu
, ifaceobj_getfunc
):
562 if (not ifaceobj
.upperifaces
or
563 (ifaceobj
.link_privflags
& ifaceLinkPrivFlags
.BOND_SLAVE
) or
564 (ifaceobj
.link_privflags
& ifaceLinkPrivFlags
.VRF_SLAVE
) or
565 (ifaceobj
.link_privflags
& ifaceLinkPrivFlags
.BRIDGE_PORT
)):
567 for u
in ifaceobj
.upperifaces
:
568 upperobjs
= ifaceobj_getfunc(u
)
570 not (upperobjs
[0].link_kind
& ifaceLinkKind
.VLAN
)):
572 # only adjust mtu for vlan devices on ifaceobj
573 umtu
= upperobjs
[0].get_attr_value_first('mtu')
575 running_mtu
= self
.ipcmd
.link_get_mtu(upperobjs
[0].name
)
576 if not running_mtu
or (running_mtu
!= mtu
):
577 self
.ipcmd
.link_set(u
, 'mtu', mtu
)
579 def _process_mtu_config(self
, ifaceobj
, ifaceobj_getfunc
, mtu
):
581 if not self
._check
_mtu
_config
(ifaceobj
, mtu
, ifaceobj_getfunc
):
583 cached_running_mtu
= self
.ipcmd
.link_get_mtu(ifaceobj
.name
)
584 running_mtu
= self
.ipcmd
.link_get_mtu_sysfs(ifaceobj
.name
)
585 if not running_mtu
or (running_mtu
and running_mtu
!= mtu
):
586 force
= cached_running_mtu
!= running_mtu
587 self
.ipcmd
.link_set(ifaceobj
.name
, 'mtu', mtu
, force
=force
)
588 if (not ifupdownflags
.flags
.ALL
and
589 not ifaceobj
.link_kind
and
590 ifupdownconfig
.config
.get('adjust_logical_dev_mtu', '1') != '0'):
591 # This is additional cost to us, so do it only when
592 # ifupdown2 is called on a particular interface and
593 # it is a physical interface
594 self
._propagate
_mtu
_to
_upper
_devs
(ifaceobj
, mtu
, ifaceobj_getfunc
)
597 if ifaceobj
.link_kind
:
598 # bonds and vxlan devices need an explicit set of mtu.
599 # bridges don't need mtu set
600 if (ifaceobj
.link_kind
& ifaceLinkKind
.BOND
or
601 ifaceobj
.link_kind
& ifaceLinkKind
.VXLAN
):
602 running_mtu
= self
.ipcmd
.link_get_mtu(ifaceobj
.name
)
603 if (self
.default_mtu
and running_mtu
!= self
.default_mtu
):
604 self
.ipcmd
.link_set(ifaceobj
.name
, 'mtu', self
.default_mtu
)
606 if (ifupdownconfig
.config
.get('adjust_logical_dev_mtu', '1') != '0'
607 and ifaceobj
.lowerifaces
):
608 # set vlan interface mtu to lower device mtu
609 if (ifaceobj
.link_kind
& ifaceLinkKind
.VLAN
):
610 lower_iface
= ifaceobj
.lowerifaces
[0]
611 if lower_iface
not in self
.lower_iface_mtu_checked_list
:
612 lower_iface_mtu
= self
.ipcmd
.link_get_mtu_sysfs(lower_iface
)
613 self
.ipcmd
.cache_update([lower_iface
, 'mtu'], lower_iface_mtu
)
614 self
.lower_iface_mtu_checked_list
.append(lower_iface
)
616 lower_iface_mtu
= self
.ipcmd
.link_get_mtu(lower_iface
)
618 if lower_iface_mtu
!= self
.ipcmd
.link_get_mtu_sysfs(ifaceobj
.name
):
619 self
.ipcmd
.link_set_mtu(ifaceobj
.name
, lower_iface_mtu
)
621 elif (not (ifaceobj
.name
== 'lo') and not ifaceobj
.link_kind
and
622 not (ifaceobj
.link_privflags
& ifaceLinkPrivFlags
.BOND_SLAVE
) and
624 # logical devices like bridges and vlan devices rely on mtu
625 # from their lower devices. ie mtu travels from
626 # lower devices to upper devices. For bonds mtu travels from
627 # upper to lower devices. running mtu depends on upper and
628 # lower device mtu. With all this implicit mtu
629 # config by the kernel in play, we try to be cautious here
630 # on which devices we want to reset mtu to default.
631 # essentially only physical interfaces which are not bond slaves
632 running_mtu
= self
.ipcmd
.link_get_mtu(ifaceobj
.name
)
633 if running_mtu
!= self
.default_mtu
:
634 self
.ipcmd
.link_set(ifaceobj
.name
, 'mtu', self
.default_mtu
)
636 def _set_bridge_forwarding(self
, ifaceobj
):
637 """ set ip forwarding to 0 if bridge interface does not have a
639 if not ifaceobj
.upperifaces
and not ifaceobj
.get_attr_value('address'):
641 if self
.sysctl_get('net.ipv4.conf.%s.forwarding' %ifaceobj
.name
) == '1':
642 self
.sysctl_set('net.ipv4.conf.%s.forwarding' %ifaceobj
.name
, 0)
643 if self
.sysctl_get('net.ipv6.conf.%s.forwarding' %ifaceobj
.name
) == '1':
644 self
.sysctl_set('net.ipv6.conf.%s.forwarding' %ifaceobj
.name
, 0)
646 if self
.sysctl_get('net.ipv4.conf.%s.forwarding' %ifaceobj
.name
) == '0':
647 self
.sysctl_set('net.ipv4.conf.%s.forwarding' %ifaceobj
.name
, 1)
648 if self
.sysctl_get('net.ipv6.conf.%s.forwarding' %ifaceobj
.name
) == '0':
649 self
.sysctl_set('net.ipv6.conf.%s.forwarding' %ifaceobj
.name
, 1)
651 def _sysctl_config(self
, ifaceobj
):
652 setting_default_value
= False
653 mpls_enable
= ifaceobj
.get_attr_value_first('mpls-enable');
655 setting_default_value
= True
656 mpls_enable
= self
.get_mod_subattr('mpls-enable', 'default')
657 mpls_enable
= utils
.boolean_support_binary(mpls_enable
)
658 # File read has been used for better performance
659 # instead of using sysctl command
660 if ifupdownflags
.flags
.PERFMODE
:
661 running_mpls_enable
= '0'
663 running_mpls_enable
= self
.read_file_oneline(
664 '/proc/sys/net/mpls/conf/%s/input'
668 if mpls_enable
!= running_mpls_enable
:
670 self
.sysctl_set('net.mpls.conf.%s.input'
671 %('/'.join(ifaceobj
.name
.split("."))),
673 except Exception as e
:
674 if not setting_default_value
:
675 ifaceobj
.status
= ifaceStatus
.ERROR
676 self
.logger
.error('%s: %s' %(ifaceobj
.name
, str(e
)))
678 if (ifaceobj
.link_kind
& ifaceLinkKind
.BRIDGE
):
679 self
._set
_bridge
_forwarding
(ifaceobj
)
681 if not self
.syntax_check_sysctls(ifaceobj
):
683 ipforward
= ifaceobj
.get_attr_value_first('ip-forward')
684 ip6forward
= ifaceobj
.get_attr_value_first('ip6-forward')
685 if ifupdownflags
.flags
.PERFMODE
:
687 self
.sysctl_set('net.ipv4.conf.%s.forwarding'
688 %('/'.join(ifaceobj
.name
.split("."))),
689 utils
.boolean_support_binary(ipforward
))
691 self
.sysctl_set('net.ipv6.conf.%s.forwarding'
692 %('/'.join(ifaceobj
.name
.split("."))),
693 utils
.boolean_support_binary(ip6forward
))
695 bridge_port
= ifaceobj
.link_privflags
& ifaceLinkPrivFlags
.BRIDGE_PORT
698 self
.log_error('%s: \'ip-forward\' is not supported for '
699 'bridge port' %ifaceobj
.name
)
701 self
.log_error('%s: \'ip6-forward\' is not supported for '
702 'bridge port' %ifaceobj
.name
)
704 setting_default_value
= False
706 setting_default_value
= True
707 ipforward
= (self
.ipforward
or
708 self
.get_mod_subattr('ip-forward', 'default'))
709 ipforward
= utils
.boolean_support_binary(ipforward
)
710 # File read has been used for better performance
711 # instead of using sysctl command
712 running_ipforward
= self
.read_file_oneline(
713 '/proc/sys/net/ipv4/conf/%s/forwarding'
715 if ipforward
!= running_ipforward
:
717 self
.sysctl_set('net.ipv4.conf.%s.forwarding'
718 %('/'.join(ifaceobj
.name
.split("."))),
720 except Exception as e
:
721 if not setting_default_value
:
722 ifaceobj
.status
= ifaceStatus
.ERROR
723 self
.logger
.error('%s: %s' %(ifaceobj
.name
, str(e
)))
725 setting_default_value
= False
727 setting_default_value
= True
728 ip6forward
= (self
.ip6forward
or
729 self
.get_mod_subattr('ip6-forward', 'default'))
730 ip6forward
= utils
.boolean_support_binary(ip6forward
)
731 # File read has been used for better performance
732 # instead of using sysctl command
733 running_ip6forward
= self
.read_file_oneline(
734 '/proc/sys/net/ipv6/conf/%s/forwarding'
736 if ip6forward
!= running_ip6forward
:
738 self
.sysctl_set('net.ipv6.conf.%s.forwarding'
739 %('/'.join(ifaceobj
.name
.split("."))),
741 except Exception as e
:
742 # There is chance of ipv6 being removed because of,
743 # for example, setting mtu < 1280
744 # In such cases, log error only if user has configured
746 if not setting_default_value
:
747 ifaceobj
.status
= ifaceStatus
.ERROR
748 self
.logger
.error('%s: %s' %(ifaceobj
.name
, str(e
)))
750 def process_mtu(self
, ifaceobj
, ifaceobj_getfunc
):
751 mtu
= ifaceobj
.get_attr_value_first('mtu')
754 default_iface_mtu
= self
.ifaces_defaults
.get(ifaceobj
.name
, {}).get('mtu')
756 if default_iface_mtu
:
758 mtu
= default_iface_mtu
759 int(default_iface_mtu
)
760 except Exception as e
:
761 self
.logger
.warning('%s: MTU value from policy file: %s' % (ifaceobj
.name
, str(e
)))
764 self
._process
_mtu
_config
(ifaceobj
, ifaceobj_getfunc
, mtu
)
766 def up_ipv6_addrgen(self
, ifaceobj
):
767 user_configured_ipv6_addrgen
= ifaceobj
.get_attr_value_first('ipv6-addrgen')
769 if not user_configured_ipv6_addrgen
and ifupdownflags
.flags
.PERFMODE
:
770 # no need to go further during perfmode (boot)
773 if not user_configured_ipv6_addrgen
:
774 # if user didn't configure ipv6-addrgen, should we reset to default?
775 user_configured_ipv6_addrgen
= self
.get_attr_default_value('ipv6-addrgen')
784 }.get(user_configured_ipv6_addrgen
.lower(), None)
786 if ipv6_addrgen_nl
is not None:
787 self
.ipcmd
.ipv6_addrgen(ifaceobj
.name
, ipv6_addrgen_nl
, link_created
=True)
788 # link_create=False will flush the addr cache of that intf
790 self
.logger
.warning('%s: invalid value "%s" for attribute ipv6-addrgen' % (ifaceobj
.name
, user_configured_ipv6_addrgen
))
792 def _up(self
, ifaceobj
, ifaceobj_getfunc
=None):
793 if not self
.ipcmd
.link_exists(ifaceobj
.name
):
796 if not self
.syntax_check_enable_l3_iface_forwardings(ifaceobj
, ifaceobj_getfunc
):
799 alias
= ifaceobj
.get_attr_value_first('alias')
800 current_alias
= self
.ipcmd
.link_get_alias(ifaceobj
.name
)
801 if alias
and alias
!= current_alias
:
802 self
.ipcmd
.link_set_alias(ifaceobj
.name
, alias
)
803 elif not alias
and current_alias
:
804 self
.ipcmd
.link_set_alias(ifaceobj
.name
, '')
806 self
._sysctl
_config
(ifaceobj
)
808 addr_method
= ifaceobj
.addr_method
809 force_reapply
= False
811 # release any stale dhcp addresses if present
812 if (addr_method
not in ["dhcp", "ppp"] and not ifupdownflags
.flags
.PERFMODE
and
813 not (ifaceobj
.flags
& iface
.HAS_SIBLINGS
)):
814 # if not running in perf mode and ifaceobj does not have
815 # any sibling iface objects, kill any stale dhclient
817 dhclientcmd
= dhclient()
818 if dhclientcmd
.is_running(ifaceobj
.name
):
819 # release any dhcp leases
820 dhclientcmd
.release(ifaceobj
.name
)
822 elif dhclientcmd
.is_running6(ifaceobj
.name
):
823 dhclientcmd
.release6(ifaceobj
.name
)
828 self
.ipcmd
.batch_start()
829 self
.up_ipv6_addrgen(ifaceobj
)
831 if addr_method
not in ["dhcp", "ppp"]:
832 self
._inet
_address
_config
(ifaceobj
, ifaceobj_getfunc
,
835 self
.process_mtu(ifaceobj
, ifaceobj_getfunc
)
838 self
.ipcmd
.batch_commit()
839 except Exception as e
:
840 self
.log_error('%s: %s' % (ifaceobj
.name
, str(e
)), ifaceobj
, raise_error
=False)
843 hwaddress
= self
._get
_hwaddress
(ifaceobj
)
845 running_hwaddress
= None
846 if not ifupdownflags
.flags
.PERFMODE
: # system is clean
847 running_hwaddress
= self
.ipcmd
.link_get_hwaddress(ifaceobj
.name
)
848 if hwaddress
!= running_hwaddress
:
850 netlink
.link_set_updown(ifaceobj
.name
, "down")
851 if ifaceobj
.link_kind
& ifaceLinkKind
.BOND
:
852 # if bond, down all the slaves
853 if ifaceobj
.lowerifaces
:
854 for l
in ifaceobj
.lowerifaces
:
855 netlink
.link_set_updown(l
, "down")
858 self
.ipcmd
.link_set(ifaceobj
.name
, 'address', hwaddress
)
860 netlink
.link_set_updown(ifaceobj
.name
, "up")
862 for l
in ifaceobj
.lowerifaces
:
863 netlink
.link_set_updown(l
, "up")
865 # Handle special things on a bridge
866 self
._process
_bridge
(ifaceobj
, True)
868 self
.log_error('%s: %s' %(ifaceobj
.name
, str(e
)), ifaceobj
)
870 gateways
= ifaceobj
.get_attr_value('gateway')
873 prev_gw
= self
._get
_prev
_gateway
(ifaceobj
, gateways
)
874 self
._add
_delete
_gateway
(ifaceobj
, gateways
, prev_gw
)
876 def _down(self
, ifaceobj
, ifaceobj_getfunc
=None):
878 if not self
.ipcmd
.link_exists(ifaceobj
.name
):
880 addr_method
= ifaceobj
.addr_method
881 if addr_method
not in ["dhcp", "ppp"]:
882 if ifaceobj
.get_attr_value_first('address-purge')=='no':
883 addrlist
= ifaceobj
.get_attr_value('address')
884 for addr
in addrlist
:
885 self
.ipcmd
.addr_del(ifaceobj
.name
, addr
)
886 #self.ipcmd.addr_del(ifaceobj.name, ifaceobj.get_attr_value('address')[0])
887 elif not ifaceobj
.link_kind
:
888 # for logical interfaces we don't need to remove the ip addresses
889 # kernel will do it for us on 'ip link del'
890 self
.ipcmd
.del_addr_all(ifaceobj
.name
)
891 gateways
= ifaceobj
.get_attr_value('gateway')
893 self
._delete
_gateway
(ifaceobj
, gateways
,
894 ifaceobj
.get_attr_value_first('vrf'),
895 ifaceobj
.get_attr_value_first('metric'))
896 mtu
= ifaceobj
.get_attr_value_first('mtu')
897 if (not ifaceobj
.link_kind
and mtu
and
898 self
.default_mtu
and (mtu
!= self
.default_mtu
)):
899 self
.ipcmd
.link_set(ifaceobj
.name
, 'mtu', self
.default_mtu
)
900 alias
= ifaceobj
.get_attr_value_first('alias')
902 self
.write_file('/sys/class/net/%s/ifalias' % ifaceobj
.name
, '\n')
903 # XXX hwaddress reset cannot happen because we dont know last
906 # Handle special things on a bridge
907 self
._process
_bridge
(ifaceobj
, False)
909 self
.logger
.debug('%s : %s' %(ifaceobj
.name
, str(e
)))
912 def _get_iface_addresses(self
, ifaceobj
):
913 addrlist
= ifaceobj
.get_attr_value('address')
916 if not addrlist
: return None
917 for addrindex
in range(0, len(addrlist
)):
918 addr
= addrlist
[addrindex
]
919 netmask
= ifaceobj
.get_attr_value_n('netmask', addrindex
)
921 prefixlen
= IPNetwork('%s' %addr
+
922 '/%s' %netmask
).prefixlen
923 addr
= addr
+ '/%s' %prefixlen
924 outaddrlist
.append(addr
)
927 def _get_bridge_fdbs(self
, bridgename
, vlan
):
928 fdbs
= self
._bridge
_fdb
_query
_cache
.get(bridgename
)
930 fdbs
= self
.ipcmd
.bridge_fdb_show_dev(bridgename
)
933 self
._bridge
_fdb
_query
_cache
[bridgename
] = fdbs
934 return fdbs
.get(vlan
)
936 def _check_addresses_in_bridge(self
, ifaceobj
, hwaddress
):
937 """ If the device is a bridge, make sure the addresses
938 are in the bridge """
939 if ifaceobj
.link_kind
& ifaceLinkKind
.VLAN
:
940 bridgename
= ifaceobj
.lowerifaces
[0]
941 vlan
= self
._get
_vlan
_id
(ifaceobj
)
942 if self
.ipcmd
.bridge_is_vlan_aware(bridgename
):
943 fdb_addrs
= self
._get
_bridge
_fdbs
(bridgename
, str(vlan
))
944 if not fdb_addrs
or hwaddress
not in fdb_addrs
:
948 def _query_sysctl(self
, ifaceobj
, ifaceobjcurr
):
949 bridge_port
= ifaceobj
.link_privflags
& ifaceLinkPrivFlags
.BRIDGE_PORT
950 ipforward
= ifaceobj
.get_attr_value_first('ip-forward')
953 ifaceobjcurr
.status
= ifaceStatus
.ERROR
954 ifaceobjcurr
.status_str
= ('\'ip-forward\' not supported ' +
956 ifaceobjcurr
.update_config_with_status('ip-forward', 1, None)
958 running_ipforward
= self
.read_file_oneline(
959 '/proc/sys/net/ipv4/conf/%s/forwarding'
961 running_ipforward
= utils
.get_boolean_from_string(running_ipforward
)
962 config_ipforward
= utils
.get_boolean_from_string(ipforward
)
963 ifaceobjcurr
.update_config_with_status(
965 'on' if running_ipforward
else 'off',
966 running_ipforward
!= config_ipforward
969 ip6forward
= ifaceobj
.get_attr_value_first('ip6-forward')
972 ifaceobjcurr
.status
= ifaceStatus
.ERROR
973 ifaceobjcurr
.status_str
= ('\'ip6-forward\' not supported ' +
975 ifaceobjcurr
.update_config_with_status('ip6-forward', 1, None)
977 running_ip6forward
= self
.read_file_oneline(
978 '/proc/sys/net/ipv6/conf/%s/forwarding'
980 running_ip6forward
= utils
.get_boolean_from_string(running_ip6forward
)
981 config_ip6forward
= utils
.get_boolean_from_string(ip6forward
)
982 ifaceobjcurr
.update_config_with_status(
984 'on' if running_ip6forward
else 'off',
985 running_ip6forward
!= config_ip6forward
987 mpls_enable
= ifaceobj
.get_attr_value_first('mpls-enable');
989 running_mpls_enable
= self
.read_file_oneline(
990 '/proc/sys/net/mpls/conf/%s/input'
992 running_mpls_enable
= utils
.get_yesno_from_onezero(
994 ifaceobjcurr
.update_config_with_status('mpls-enable',
996 mpls_enable
!= running_mpls_enable
)
999 def query_check_ipv6_addrgen(self
, ifaceobj
, ifaceobjcurr
):
1000 ipv6_addrgen
= ifaceobj
.get_attr_value_first('ipv6-addrgen')
1002 if not ipv6_addrgen
:
1005 if ipv6_addrgen
in utils
._string
_values
:
1006 ifaceobjcurr
.update_config_with_status(
1009 utils
.get_boolean_from_string(ipv6_addrgen
) == self
.ipcmd
.get_ipv6_addrgen_mode(ifaceobj
.name
)
1012 ifaceobjcurr
.update_config_with_status('ipv6-addrgen', ipv6_addrgen
, 1)
1014 def _query_check(self
, ifaceobj
, ifaceobjcurr
, ifaceobj_getfunc
=None):
1015 runningaddrsdict
= None
1016 if not self
.ipcmd
.link_exists(ifaceobj
.name
):
1017 self
.logger
.debug('iface %s not found' %ifaceobj
.name
)
1020 self
.query_check_ipv6_addrgen(ifaceobj
, ifaceobjcurr
)
1022 addr_method
= ifaceobj
.addr_method
1023 self
.query_n_update_ifaceobjcurr_attr(ifaceobj
, ifaceobjcurr
,
1024 'mtu', self
.ipcmd
.link_get_mtu
)
1025 hwaddress
= self
._get
_hwaddress
(ifaceobj
)
1027 rhwaddress
= self
.ipcmd
.link_get_hwaddress(ifaceobj
.name
)
1028 if not rhwaddress
or rhwaddress
!= hwaddress
:
1029 ifaceobjcurr
.update_config_with_status('hwaddress', rhwaddress
,
1031 elif not self
._check
_addresses
_in
_bridge
(ifaceobj
, hwaddress
):
1032 # XXX: hw address is not in bridge
1033 ifaceobjcurr
.update_config_with_status('hwaddress', rhwaddress
,
1035 ifaceobjcurr
.status_str
= 'bridge fdb error'
1037 ifaceobjcurr
.update_config_with_status('hwaddress', rhwaddress
,
1039 self
.query_n_update_ifaceobjcurr_attr(ifaceobj
, ifaceobjcurr
,
1040 'alias', self
.ipcmd
.link_get_alias
)
1041 self
._query
_sysctl
(ifaceobj
, ifaceobjcurr
)
1043 if addr_method
in ["dhcp", "ppp"]:
1045 addrs
= utils
.get_normalized_ip_addr(ifaceobj
.name
,
1046 self
._get
_iface
_addresses
(ifaceobj
))
1047 runningaddrsdict
= self
.ipcmd
.get_running_addrs(ifaceobj
)
1048 # if anycast address is configured on 'lo' and is in running config
1049 # add it to addrs so that query_check doesn't fail
1050 anycast_addr
= utils
.get_normalized_ip_addr(ifaceobj
.name
, ifaceobj
.get_attr_value_first('clagd-vxlan-anycast-ip'))
1052 anycast_addr
= anycast_addr
+'/32'
1053 if runningaddrsdict
and anycast_addr
and runningaddrsdict
.get(anycast_addr
):
1054 addrs
.append(anycast_addr
)
1056 # Set ifaceobjcurr method and family
1057 ifaceobjcurr
.addr_method
= ifaceobj
.addr_method
1058 ifaceobjcurr
.addr_family
= ifaceobj
.addr_family
1059 if not runningaddrsdict
and not addrs
:
1061 runningaddrs
= runningaddrsdict
.keys() if runningaddrsdict
else []
1062 # Add /32 netmask to configured address without netmask.
1063 # This may happen on interfaces where pointopoint is used.
1064 runningaddrs
= [ addr
if '/' in addr
else addr
+ '/32' for addr
in runningaddrs
]
1065 if runningaddrs
!= addrs
:
1066 runningaddrsset
= set(runningaddrs
) if runningaddrs
else set([])
1067 addrsset
= set(addrs
) if addrs
else set([])
1068 if (ifaceobj
.flags
& iface
.HAS_SIBLINGS
):
1071 # only check for addresses present in running config
1072 addrsdiff
= addrsset
.difference(runningaddrsset
)
1074 if addr
in addrsdiff
:
1075 ifaceobjcurr
.update_config_with_status('address',
1078 ifaceobjcurr
.update_config_with_status('address',
1081 addrsdiff
= addrsset
.symmetric_difference(runningaddrsset
)
1082 for addr
in addrsset
.union(runningaddrsset
):
1083 if addr
in addrsdiff
:
1084 ifaceobjcurr
.update_config_with_status('address',
1087 ifaceobjcurr
.update_config_with_status('address',
1090 [ifaceobjcurr
.update_config_with_status('address',
1091 addr
, 0) for addr
in addrs
]
1092 #XXXX Check broadcast address, scope, etc
1095 def query_running_ipv6_addrgen(self
, ifaceobjrunning
):
1096 ipv6_addrgen
= self
.ipcmd
.get_ipv6_addrgen_mode(ifaceobjrunning
.name
)
1099 ifaceobjrunning
.update_config('ipv6-addrgen', 'off')
1101 def _query_running(self
, ifaceobjrunning
, ifaceobj_getfunc
=None):
1102 if not self
.ipcmd
.link_exists(ifaceobjrunning
.name
):
1103 self
.logger
.debug('iface %s not found' %ifaceobjrunning
.name
)
1106 self
.query_running_ipv6_addrgen(ifaceobjrunning
)
1108 dhclientcmd
= dhclient()
1109 if (dhclientcmd
.is_running(ifaceobjrunning
.name
) or
1110 dhclientcmd
.is_running6(ifaceobjrunning
.name
)):
1111 # If dhcp is configured on the interface, we skip it
1113 isloopback
= self
.ipcmd
.link_isloopback(ifaceobjrunning
.name
)
1115 default_addrs
= ['127.0.0.1/8', '::1/128']
1116 ifaceobjrunning
.addr_family
.append('inet')
1117 ifaceobjrunning
.addr_method
= 'loopback'
1120 runningaddrsdict
= self
.ipcmd
.get_running_addrs(ifaceobjrunning
)
1121 if runningaddrsdict
:
1122 [ifaceobjrunning
.update_config('address', addr
)
1123 for addr
, addrattrs
in runningaddrsdict
.items()
1124 if addr
not in default_addrs
]
1125 mtu
= self
.ipcmd
.link_get_mtu(ifaceobjrunning
.name
)
1127 (ifaceobjrunning
.name
== 'lo' and mtu
!= '16436') or
1128 (ifaceobjrunning
.name
!= 'lo' and
1129 mtu
!= self
.get_mod_subattr('mtu', 'default'))):
1130 ifaceobjrunning
.update_config('mtu', mtu
)
1131 alias
= self
.ipcmd
.link_get_alias(ifaceobjrunning
.name
)
1133 ifaceobjrunning
.update_config('alias', alias
)
1135 ipforward
= self
.read_file_oneline(
1136 '/proc/sys/net/ipv4/conf/%s/forwarding'
1137 %ifaceobjrunning
.name
)
1140 _run_ops
= {'up' : _up
,
1142 'query-checkcurr' : _query_check
,
1143 'query-running' : _query_running
}
1146 """ returns list of ops supported by this module """
1147 return self
._run
_ops
.keys()
1149 def _init_command_handlers(self
):
1151 self
.ipcmd
= LinkUtils()
1153 def run(self
, ifaceobj
, operation
, query_ifaceobj
=None, ifaceobj_getfunc
=None):
1154 """ run address configuration on the interface object passed as argument
1157 **ifaceobj** (object): iface object
1159 **operation** (str): any of 'up', 'down', 'query-checkcurr',
1162 query_ifaceobj (object): query check ifaceobject. This is only
1163 valid when op is 'query-checkcurr'. It is an object same as
1164 ifaceobj, but contains running attribute values and its config
1165 status. The modules can use it to return queried running state
1166 of interfaces. status is success if the running state is same
1167 as user required state in ifaceobj. error otherwise.
1169 if ifaceobj
.type == ifaceType
.BRIDGE_VLAN
:
1171 op_handler
= self
._run
_ops
.get(operation
)
1174 self
._init
_command
_handlers
()
1175 if operation
== 'query-checkcurr':
1176 op_handler(self
, ifaceobj
, query_ifaceobj
,
1177 ifaceobj_getfunc
=ifaceobj_getfunc
)
1179 op_handler(self
, ifaceobj
,
1180 ifaceobj_getfunc
=ifaceobj_getfunc
)