3 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
4 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
6 # This should be pretty simple and might not really even need to exist.
7 # The key is that we need to call link_create with a type of "dummy"
8 # since that will translate to 'ip link add loopbackX type dummy'
9 # The config file should probably just indicate that the type is
13 from ifupdown2
.lib
.addon
import Addon
14 from ifupdown2
.ifupdown
.iface
import ifaceLinkKind
, ifaceLinkPrivFlags
, ifaceStatus
15 from ifupdown2
.ifupdown
.utils
import utils
17 from ifupdown2
.ifupdownaddons
.modulebase
import moduleBase
19 import ifupdown2
.ifupdown
.ifupdownflags
as ifupdownflags
20 import ifupdown2
.ifupdown
.policymanager
as policymanager
21 except (ImportError, ModuleNotFoundError
):
22 from lib
.addon
import Addon
23 from ifupdown
.iface
import ifaceLinkKind
, ifaceLinkPrivFlags
, ifaceStatus
24 from ifupdown
.utils
import utils
26 from ifupdownaddons
.modulebase
import moduleBase
28 import ifupdown
.ifupdownflags
as ifupdownflags
29 import ifupdown
.policymanager
as policymanager
32 class link(Addon
, moduleBase
):
34 "mhelp": "create/configure link types. similar to ip-link",
37 "help": "type of link as in 'ip link' command.",
38 "validvals": ["dummy", "veth"],
39 "example": ["link-type <dummy|veth>"]
42 "help": "keep link down",
43 "example": ["link-down yes/no"],
45 "validvals": ["yes", "no"]
48 "help": "Name of the veth peer interface.",
49 "validvals": "<interface>",
50 "example": ["veth-peer-name veth_ext2int"]
55 def __init__(self
, *args
, **kargs
):
57 moduleBase
.__init
__(self
, *args
, **kargs
)
59 self
.check_physical_port_existance
= utils
.get_boolean_from_string(
60 policymanager
.policymanager_api
.get_module_globals(
61 self
.__class
__.__name
__,
62 'warn_on_physdev_not_present'
66 def syntax_check(self
, ifaceobj
, ifaceobj_getfunc
):
67 if self
.check_physical_port_existance
:
68 if not ifaceobj
.link_kind
and not self
.cache
.link_exists(ifaceobj
.name
):
69 self
.logger
.warning('%s: interface does not exist' % ifaceobj
.name
)
74 def _is_my_interface(ifaceobj
):
75 return ifaceobj
.get_attr_value_first('link-type') or ifaceobj
.get_attr_value_first('link-down')
77 def get_dependent_ifacenames(self
, ifaceobj
, ifacenames_all
=None, old_ifaceobjs
=False):
78 if ifaceobj
.get_attr_value_first('link-down') == 'yes':
79 ifaceobj
.link_privflags |
= ifaceLinkPrivFlags
.KEEP_LINK_DOWN
80 if ifaceobj
.get_attr_value_first('link-type'):
81 ifaceobj
.link_kind
= ifaceLinkKind
.OTHER
83 link_type
= ifaceobj
.get_attr_value_first("link-type")
84 # If this interface is one side of a veth link pair and a name for
85 # the peer interface if given, pass it to the link_create call.
86 if link_type
== "veth" and ifaceobj
.get_attr_value_first("veth-peer-name"):
87 return [ifaceobj
.get_attr_value_first("veth-peer-name")]
91 def _up(self
, ifaceobj
):
92 link_type
= ifaceobj
.get_attr_value_first("link-type")
94 # If this interface is one side of a veth link pair and a name for
95 # the peer interface if given, pass it to the link_create call.
96 if link_type
== "veth":
97 peer_name
= ifaceobj
.get_attr_value_first("veth-peer-name")
99 if peer_name
and not self
.cache
.link_exists(ifaceobj
.name
):
100 self
.iproute2
.link_add_veth(ifaceobj
.name
, peer_name
)
103 self
.netlink
.link_add(ifname
=ifaceobj
.name
, kind
=link_type
)
105 def _down(self
, ifaceobj
):
106 if not ifaceobj
.get_attr_value_first('link-type'):
108 if not ifupdownflags
.flags
.PERFMODE
and not self
.cache
.link_exists(ifaceobj
.name
):
111 self
.netlink
.link_del(ifaceobj
.name
)
112 except Exception as e
:
113 self
.log_warn(str(e
))
115 def _query_check(self
, ifaceobj
, ifaceobjcurr
):
116 if ifaceobj
.get_attr_value('link-type'):
117 if not self
.cache
.link_exists(ifaceobj
.name
):
118 ifaceobjcurr
.update_config_with_status('link-type', 'None', 1)
120 link_type
= ifaceobj
.get_attr_value_first('link-type')
121 if self
.cache
.get_link_kind(ifaceobj
.name
) == link_type
:
122 ifaceobjcurr
.update_config_with_status('link-type', link_type
, 0)
124 ifaceobjcurr
.update_config_with_status('link-type', link_type
, 1)
126 self
._query
_check
_link
_down
(ifaceobj
, ifaceobjcurr
)
128 def _query_check_link_down(self
, ifaceobj
, ifaceobjcurr
):
129 link_down
= ifaceobj
.get_attr_value_first('link-down')
132 link_should_be_down
= utils
.get_boolean_from_string(link_down
)
134 link_should_be_down
= False
136 link_up
= self
.cache
.link_is_up(ifaceobj
.name
)
138 if not link_up
and not link_should_be_down
and not link_down
:
139 ifaceobjcurr
.status_str
= 'link is down'
140 ifaceobjcurr
.status
= ifaceStatus
.ERROR
142 if link_should_be_down
and link_up
:
145 elif link_should_be_down
and not link_up
:
147 elif not link_should_be_down
and link_up
:
152 ifaceobjcurr
.update_config_with_status('link-down', link_down
, status
)
157 "query-checkcurr": _query_check
161 return list(self
._run
_ops
.keys())
163 def run(self
, ifaceobj
, operation
, query_ifaceobj
=None, **extra_args
):
164 op_handler
= self
._run
_ops
.get(operation
)
167 if (operation
!= 'query-running' and operation
!= 'query-checkcurr' and
168 not self
._is
_my
_interface
(ifaceobj
)):
170 if operation
== 'query-checkcurr':
171 op_handler(self
, ifaceobj
, query_ifaceobj
)
173 op_handler(self
, ifaceobj
)