mirror of
https://github.com/CumulusNetworks/ifupdown2.git
synced 2024-05-06 15:54:50 +00:00
174 lines
6.5 KiB
Python
174 lines
6.5 KiB
Python
#!/usr/bin/env python3
|
|
#
|
|
# Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
|
|
# Author: Roopa Prabhu, roopa@cumulusnetworks.com
|
|
#
|
|
# This should be pretty simple and might not really even need to exist.
|
|
# The key is that we need to call link_create with a type of "dummy"
|
|
# since that will translate to 'ip link add loopbackX type dummy'
|
|
# The config file should probably just indicate that the type is
|
|
# loopback or dummy.
|
|
|
|
try:
|
|
from ifupdown2.lib.addon import Addon
|
|
from ifupdown2.ifupdown.iface import ifaceLinkKind, ifaceLinkPrivFlags, ifaceStatus
|
|
from ifupdown2.ifupdown.utils import utils
|
|
|
|
from ifupdown2.ifupdownaddons.modulebase import moduleBase
|
|
|
|
import ifupdown2.ifupdown.ifupdownflags as ifupdownflags
|
|
import ifupdown2.ifupdown.policymanager as policymanager
|
|
except (ImportError, ModuleNotFoundError):
|
|
from lib.addon import Addon
|
|
from ifupdown.iface import ifaceLinkKind, ifaceLinkPrivFlags, ifaceStatus
|
|
from ifupdown.utils import utils
|
|
|
|
from ifupdownaddons.modulebase import moduleBase
|
|
|
|
import ifupdown.ifupdownflags as ifupdownflags
|
|
import ifupdown.policymanager as policymanager
|
|
|
|
|
|
class link(Addon, moduleBase):
|
|
_modinfo = {
|
|
"mhelp": "create/configure link types. similar to ip-link",
|
|
"attrs": {
|
|
"link-type": {
|
|
"help": "type of link as in 'ip link' command.",
|
|
"validvals": ["dummy", "veth"],
|
|
"example": ["link-type <dummy|veth>"]
|
|
},
|
|
"link-down": {
|
|
"help": "keep link down",
|
|
"example": ["link-down yes/no"],
|
|
"default": "no",
|
|
"validvals": ["yes", "no"]
|
|
},
|
|
"veth-peer-name": {
|
|
"help": "Name of the veth peer interface.",
|
|
"validvals": "<interface>",
|
|
"example": ["veth-peer-name veth_ext2int"]
|
|
}
|
|
}
|
|
}
|
|
|
|
def __init__(self, *args, **kargs):
|
|
Addon.__init__(self)
|
|
moduleBase.__init__(self, *args, **kargs)
|
|
|
|
self.check_physical_port_existance = utils.get_boolean_from_string(
|
|
policymanager.policymanager_api.get_module_globals(
|
|
self.__class__.__name__,
|
|
'warn_on_physdev_not_present'
|
|
)
|
|
)
|
|
|
|
def syntax_check(self, ifaceobj, ifaceobj_getfunc):
|
|
if self.check_physical_port_existance:
|
|
if not ifaceobj.link_kind and not self.cache.link_exists(ifaceobj.name):
|
|
self.logger.warning('%s: interface does not exist' % ifaceobj.name)
|
|
return False
|
|
return True
|
|
|
|
@staticmethod
|
|
def _is_my_interface(ifaceobj):
|
|
return ifaceobj.get_attr_value_first('link-type') or ifaceobj.get_attr_value_first('link-down')
|
|
|
|
def get_dependent_ifacenames(self, ifaceobj, ifacenames_all=None, old_ifaceobjs=False):
|
|
if ifaceobj.get_attr_value_first('link-down') == 'yes':
|
|
ifaceobj.link_privflags |= ifaceLinkPrivFlags.KEEP_LINK_DOWN
|
|
if ifaceobj.get_attr_value_first('link-type'):
|
|
ifaceobj.link_kind = ifaceLinkKind.OTHER
|
|
|
|
link_type = ifaceobj.get_attr_value_first("link-type")
|
|
# If this interface is one side of a veth link pair and a name for
|
|
# the peer interface if given, pass it to the link_create call.
|
|
if link_type == "veth" and ifaceobj.get_attr_value_first("veth-peer-name"):
|
|
return [ifaceobj.get_attr_value_first("veth-peer-name")]
|
|
|
|
return None
|
|
|
|
def _up(self, ifaceobj):
|
|
link_type = ifaceobj.get_attr_value_first("link-type")
|
|
|
|
# If this interface is one side of a veth link pair and a name for
|
|
# the peer interface if given, pass it to the link_create call.
|
|
if link_type == "veth":
|
|
peer_name = ifaceobj.get_attr_value_first("veth-peer-name")
|
|
|
|
if peer_name and not self.cache.link_exists(ifaceobj.name):
|
|
self.iproute2.link_add_veth(ifaceobj.name, peer_name)
|
|
|
|
elif link_type:
|
|
self.netlink.link_add(ifname=ifaceobj.name, kind=link_type)
|
|
|
|
def _down(self, ifaceobj):
|
|
if not ifaceobj.get_attr_value_first('link-type'):
|
|
return
|
|
if not ifupdownflags.flags.PERFMODE and not self.cache.link_exists(ifaceobj.name):
|
|
return
|
|
try:
|
|
self.netlink.link_del(ifaceobj.name)
|
|
except Exception as e:
|
|
self.log_warn(str(e))
|
|
|
|
def _query_check(self, ifaceobj, ifaceobjcurr):
|
|
if ifaceobj.get_attr_value('link-type'):
|
|
if not self.cache.link_exists(ifaceobj.name):
|
|
ifaceobjcurr.update_config_with_status('link-type', 'None', 1)
|
|
else:
|
|
link_type = ifaceobj.get_attr_value_first('link-type')
|
|
if self.cache.get_link_kind(ifaceobj.name) == link_type:
|
|
ifaceobjcurr.update_config_with_status('link-type', link_type, 0)
|
|
else:
|
|
ifaceobjcurr.update_config_with_status('link-type', link_type, 1)
|
|
|
|
self._query_check_link_down(ifaceobj, ifaceobjcurr)
|
|
|
|
def _query_check_link_down(self, ifaceobj, ifaceobjcurr):
|
|
link_down = ifaceobj.get_attr_value_first('link-down')
|
|
|
|
if link_down:
|
|
link_should_be_down = utils.get_boolean_from_string(link_down)
|
|
else:
|
|
link_should_be_down = False
|
|
|
|
link_up = self.cache.link_is_up(ifaceobj.name)
|
|
|
|
if not link_up and not link_should_be_down and not link_down:
|
|
ifaceobjcurr.status_str = 'link is down'
|
|
ifaceobjcurr.status = ifaceStatus.ERROR
|
|
elif link_down:
|
|
if link_should_be_down and link_up:
|
|
status = 1
|
|
link_down = 'no'
|
|
elif link_should_be_down and not link_up:
|
|
status = 0
|
|
elif not link_should_be_down and link_up:
|
|
status = 0
|
|
else:
|
|
status = 1
|
|
|
|
ifaceobjcurr.update_config_with_status('link-down', link_down, status)
|
|
|
|
_run_ops = {
|
|
"pre-up": _up,
|
|
"post-down": _down,
|
|
"query-checkcurr": _query_check
|
|
}
|
|
|
|
def get_ops(self):
|
|
return list(self._run_ops.keys())
|
|
|
|
def run(self, ifaceobj, operation, query_ifaceobj=None, **extra_args):
|
|
op_handler = self._run_ops.get(operation)
|
|
if not op_handler:
|
|
return
|
|
if (operation != 'query-running' and operation != 'query-checkcurr' and
|
|
not self._is_my_interface(ifaceobj)):
|
|
return
|
|
if operation == 'query-checkcurr':
|
|
op_handler(self, ifaceobj, query_ifaceobj)
|
|
else:
|
|
op_handler(self, ifaceobj)
|