]>
Commit | Line | Data |
---|---|---|
35681c06 | 1 | #!/usr/bin/env python3 |
d486dd0d JF |
2 | # |
3 | # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved. | |
4 | # Author: Roopa Prabhu, roopa@cumulusnetworks.com | |
5 | # | |
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 | |
10 | # loopback or dummy. | |
11 | ||
12 | try: | |
223ba5af | 13 | from ifupdown2.lib.addon import Addon |
d486dd0d JF |
14 | from ifupdown2.ifupdown.iface import * |
15 | from ifupdown2.ifupdown.utils import utils | |
16 | ||
d486dd0d JF |
17 | from ifupdown2.ifupdownaddons.modulebase import moduleBase |
18 | ||
19 | import ifupdown2.ifupdown.ifupdownflags as ifupdownflags | |
20 | import ifupdown2.ifupdown.policymanager as policymanager | |
bd441a51 | 21 | except (ImportError, ModuleNotFoundError): |
223ba5af | 22 | from lib.addon import Addon |
d486dd0d JF |
23 | from ifupdown.iface import * |
24 | from ifupdown.utils import utils | |
25 | ||
d486dd0d JF |
26 | from ifupdownaddons.modulebase import moduleBase |
27 | ||
28 | import ifupdown.ifupdownflags as ifupdownflags | |
29 | import ifupdown.policymanager as policymanager | |
30 | ||
31 | ||
223ba5af JF |
32 | class link(Addon, moduleBase): |
33 | _modinfo = { | |
34 | "mhelp": "create/configure link types. similar to ip-link", | |
35 | "attrs": { | |
36 | "link-type": { | |
37 | "help": "type of link as in 'ip link' command.", | |
38 | "validvals": ["dummy", "veth"], | |
39 | "example": ["link-type <dummy|veth>"] | |
40 | }, | |
41 | "link-down": { | |
42 | "help": "keep link down", | |
43 | "example": ["link-down yes/no"], | |
44 | "default": "no", | |
45 | "validvals": ["yes", "no"] | |
5890ab71 JF |
46 | }, |
47 | "veth-peer-name": { | |
48 | "help": "Name of the veth peer interface.", | |
49 | "validvals": "<interface>", | |
50 | "example": ["veth-peer-name veth_ext2int"] | |
223ba5af JF |
51 | } |
52 | } | |
53 | } | |
d486dd0d JF |
54 | |
55 | def __init__(self, *args, **kargs): | |
223ba5af | 56 | Addon.__init__(self) |
d486dd0d | 57 | moduleBase.__init__(self, *args, **kargs) |
d486dd0d | 58 | |
223ba5af JF |
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' | |
63 | ) | |
64 | ) | |
d486dd0d JF |
65 | |
66 | def syntax_check(self, ifaceobj, ifaceobj_getfunc): | |
67 | if self.check_physical_port_existance: | |
223ba5af | 68 | if not ifaceobj.link_kind and not self.cache.link_exists(ifaceobj.name): |
d486dd0d JF |
69 | self.logger.warning('%s: interface does not exist' % ifaceobj.name) |
70 | return False | |
71 | return True | |
72 | ||
223ba5af JF |
73 | @staticmethod |
74 | def _is_my_interface(ifaceobj): | |
75 | return ifaceobj.get_attr_value_first('link-type') or ifaceobj.get_attr_value_first('link-down') | |
d486dd0d JF |
76 | |
77 | def get_dependent_ifacenames(self, ifaceobj, ifacenames_all=None): | |
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 | |
82 | ||
5890ab71 JF |
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")] | |
88 | ||
89 | return None | |
90 | ||
d486dd0d | 91 | def _up(self, ifaceobj): |
5890ab71 JF |
92 | link_type = ifaceobj.get_attr_value_first("link-type") |
93 | ||
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") | |
98 | ||
99 | if peer_name and not self.cache.link_exists(ifaceobj.name): | |
100 | self.iproute2.link_add_veth(ifaceobj.name, peer_name) | |
101 | ||
102 | elif link_type: | |
223ba5af | 103 | self.netlink.link_add(ifname=ifaceobj.name, kind=link_type) |
d486dd0d JF |
104 | |
105 | def _down(self, ifaceobj): | |
106 | if not ifaceobj.get_attr_value_first('link-type'): | |
107 | return | |
223ba5af JF |
108 | if not ifupdownflags.flags.PERFMODE and not self.cache.link_exists(ifaceobj.name): |
109 | return | |
d486dd0d | 110 | try: |
223ba5af | 111 | self.netlink.link_del(ifaceobj.name) |
3b01ed76 | 112 | except Exception as e: |
d486dd0d JF |
113 | self.log_warn(str(e)) |
114 | ||
115 | def _query_check(self, ifaceobj, ifaceobjcurr): | |
116 | if ifaceobj.get_attr_value('link-type'): | |
223ba5af | 117 | if not self.cache.link_exists(ifaceobj.name): |
d486dd0d JF |
118 | ifaceobjcurr.update_config_with_status('link-type', 'None', 1) |
119 | else: | |
120 | link_type = ifaceobj.get_attr_value_first('link-type') | |
223ba5af JF |
121 | if self.cache.get_link_kind(ifaceobj.name) == link_type: |
122 | ifaceobjcurr.update_config_with_status('link-type', link_type, 0) | |
d486dd0d | 123 | else: |
223ba5af | 124 | ifaceobjcurr.update_config_with_status('link-type', link_type, 1) |
d486dd0d JF |
125 | |
126 | link_down = ifaceobj.get_attr_value_first('link-down') | |
127 | if link_down: | |
223ba5af | 128 | link_up = self.cache.link_is_up(ifaceobj.name) |
d486dd0d JF |
129 | link_should_be_down = utils.get_boolean_from_string(link_down) |
130 | ||
131 | if link_should_be_down and link_up: | |
132 | status = 1 | |
133 | link_down = 'no' | |
134 | elif link_should_be_down and not link_up: | |
135 | status = 0 | |
136 | elif not link_should_be_down and link_up: | |
137 | status = 0 | |
138 | else: | |
139 | status = 1 | |
140 | ||
141 | ifaceobjcurr.update_config_with_status('link-down', link_down, status) | |
142 | ||
223ba5af JF |
143 | _run_ops = { |
144 | "pre-up": _up, | |
145 | "post-down": _down, | |
146 | "query-checkcurr": _query_check | |
147 | } | |
d486dd0d JF |
148 | |
149 | def get_ops(self): | |
3b01ed76 | 150 | return list(self._run_ops.keys()) |
d486dd0d | 151 | |
d486dd0d JF |
152 | def run(self, ifaceobj, operation, query_ifaceobj=None, **extra_args): |
153 | op_handler = self._run_ops.get(operation) | |
154 | if not op_handler: | |
155 | return | |
156 | if (operation != 'query-running' and | |
157 | not self._is_my_interface(ifaceobj)): | |
158 | return | |
d486dd0d JF |
159 | if operation == 'query-checkcurr': |
160 | op_handler(self, ifaceobj, query_ifaceobj) | |
161 | else: | |
162 | op_handler(self, ifaceobj) |