]> git.proxmox.com Git - mirror_ifupdown2.git/blob - addons/addressvirtual.py
Move ifupdown2addons into ifupdown2 pacakge
[mirror_ifupdown2.git] / addons / addressvirtual.py
1 #!/usr/bin/python
2 #
3 # Copyright 2014 Cumulus Networks, Inc. All rights reserved.
4 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
5 #
6
7 from ifupdown.iface import *
8 from ifupdownaddons.modulebase import moduleBase
9 from ifupdownaddons.iproute2 import iproute2
10 import logging
11 import os
12 import glob
13
14 class addressvirtual(moduleBase):
15 """ ifupdown2 addon module to configure virtual addresses """
16
17 _modinfo = {'mhelp' : 'address module configures virtual addresses for ' +
18 'interfaces. It creates a macvlan interface for ' +
19 'every mac ip address-virtual line',
20 'attrs' : {
21 'address-virtual' :
22 { 'help' : 'bridge router virtual mac and ip',
23 'example' : ['address-virtual 00:11:22:33:44:01 11.0.1.254/24 11.0.1.254/24']}
24 }}
25
26 def __init__(self, *args, **kargs):
27 moduleBase.__init__(self, *args, **kargs)
28 self.ipcmd = None
29
30 def _is_supported(self, ifaceobj):
31 if ifaceobj.get_attr_value_first('address-virtual'):
32 return True
33 return False
34
35 def _apply_address_config(self, ifaceobj, realifacename, address_virtual_list):
36 purge_existing = False if self.PERFMODE else True
37
38 self.ipcmd.batch_start()
39 av_idx = 0
40 macvlan_prefix = '%s-virt' %ifaceobj.name.replace('.', '-')
41 for av in address_virtual_list:
42 av_attrs = av.split()
43 if len(av_attrs) < 2:
44 self.logger.warn("%s: incorrect address-virtual attrs '%s'"
45 %(ifaceobj.name, av))
46 av_idx += 1
47 continue
48
49 # Create a macvlan device on this device and set the virtual
50 # router mac and ip on it
51 macvlan_ifacename = '%s-%d' %(macvlan_prefix, av_idx)
52 self.ipcmd.link_create_macvlan(macvlan_ifacename, realifacename)
53 self.ipcmd.link_set_hwaddress(macvlan_ifacename, av_attrs[0])
54 self.ipcmd.addr_add_multiple(macvlan_ifacename, av_attrs[1:],
55 purge_existing)
56 av_idx += 1
57 self.ipcmd.batch_commit()
58
59 def _remove_address_config(self, ifaceobj, ifacename):
60 if not self.ipcmd.link_exists(ifacename):
61 return
62 self.ipcmd.batch_start()
63 macvlan_prefix = '%s-virt' %ifacename.replace('.', '-')
64 for macvlan_ifacename in glob.glob("/sys/class/net/%s-*" %macvlan_prefix):
65 self.ipcmd.link_delete(os.path.basename(macvlan_ifacename))
66 self.ipcmd.batch_commit()
67
68 def _get_real_ifacename(self, ifaceobj):
69 realifacename = ifaceobj.name
70 if ifaceobj.type == ifaceType.BRIDGE_VLAN:
71 bridgename = ifaceobj.get_attr_value_first('bridge')
72 if bridgename:
73 realifacename = '%s.%s' %(bridgename, ifaceobj.priv_data)
74 return realifacename
75
76 def _up(self, ifaceobj):
77 realifacename = self._get_real_ifacename(ifaceobj)
78 address_virtual_list = ifaceobj.get_attr_value('address-virtual')
79 if not address_virtual_list:
80 # XXX: address virtual is not present. In which case,
81 # delete stale any macvlan devices.
82 self._remove_address_config(ifaceobj, realifacename)
83 return
84
85 if not self.ipcmd.link_exists(realifacename):
86 self.log_warn('%s: target link %s does not exist'
87 %(ifaceobj.name, realifacename))
88 return
89 self._apply_address_config(ifaceobj, realifacename, address_virtual_list)
90
91 def _down(self, ifaceobj):
92 realifacename = self._get_real_ifacename(ifaceobj)
93 try:
94 self._remove_address_config(ifaceobj, realifacename)
95 except Exception, e:
96 self.log_warn(str(e))
97
98 def _query_check(self, ifaceobj, ifaceobjcurr):
99 address_virtual_list = ifaceobj.get_attr_value('address-virtual')
100 if not address_virtual_list:
101 return
102 realifacename = self._get_real_ifacename(ifaceobj)
103 av_idx = 0
104 macvlan_prefix = '%s-virt' %realifacename.replace('.', '-')
105 for address_virtual in address_virtual_list:
106 av_attrs = address_virtual.split()
107 if len(av_attrs) < 2:
108 self.logger.warn("%s: incorrect address-virtual attrs '%s'"
109 %(ifaceobj.name, address_virtual))
110 av_idx += 1
111 continue
112
113 # Check if the macvlan device on this interface
114 macvlan_ifacename = '%s-%d' %(macvlan_prefix, av_idx)
115 if self.ipcmd.link_exists(macvlan_ifacename):
116 # XXX Check mac and ip address
117 rhwaddress = self.ipcmd.link_get_hwaddress(macvlan_ifacename)
118 raddrs = self.ipcmd.addr_get(macvlan_ifacename)
119 if rhwaddress == av_attrs[0] and raddrs == av_attrs[1:]:
120 ifaceobjcurr.update_config_with_status('address-virtual',
121 address_virtual, 0)
122 else:
123 raddress_virtual = '%s %s' %(rhwaddress, ' '.join(raddrs))
124 ifaceobjcurr.update_config_with_status('address-virtual',
125 raddress_virtual, 1)
126 av_idx += 1
127 return
128
129 def _query_running(self, ifaceobjrunning):
130 # Not implemented
131 return
132
133 _run_ops = {'up' : _up,
134 'down' : _down,
135 'query-checkcurr' : _query_check,
136 'query-running' : _query_running}
137
138 def get_ops(self):
139 """ returns list of ops supported by this module """
140 return self._run_ops.keys()
141
142 def _init_command_handlers(self):
143 if not self.ipcmd:
144 self.ipcmd = iproute2(**self.get_flags())
145
146 def run(self, ifaceobj, operation, query_ifaceobj=None):
147 """ run vlan configuration on the interface object passed as argument
148
149 Args:
150 **ifaceobj** (object): iface object
151
152 **operation** (str): any of 'pre-up', 'post-down', 'query-checkcurr',
153 'query-running'
154 Kwargs:
155 **query_ifaceobj** (object): query check ifaceobject. This is only
156 valid when op is 'query-checkcurr'. It is an object same as
157 ifaceobj, but contains running attribute values and its config
158 status. The modules can use it to return queried running state
159 of interfaces. status is success if the running state is same
160 as user required state in ifaceobj. error otherwise.
161 """
162 op_handler = self._run_ops.get(operation)
163 if not op_handler:
164 return
165 self._init_command_handlers()
166 if operation == 'query-checkcurr':
167 op_handler(self, ifaceobj, query_ifaceobj)
168 else:
169 op_handler(self, ifaceobj)