]> git.proxmox.com Git - mirror_ifupdown2.git/blob - ifupdown2/addons/vrrpd.py
Merge 'vlan filtering bridge + vxlan + mlag + vrr' support from internal
[mirror_ifupdown2.git] / ifupdown2 / addons / vrrpd.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 try:
8 from ipaddr import IPNetwork
9 from sets import Set
10 from ifupdown.iface import *
11 from ifupdownaddons.modulebase import moduleBase
12 from ifupdownaddons.iproute2 import iproute2
13 import os
14 import glob
15 import logging
16 import signal
17 import subprocess
18 import re
19 except ImportError, e:
20 raise ImportError (str(e) + "- required module not found")
21
22 class vrrpd(moduleBase):
23 """ ifupdown2 addon module to configure vrrpd attributes """
24
25 _modinfo = {'mhelp' : 'ethtool configuration module for interfaces',
26 'attrs': {
27 'vrrp-id' :
28 {'help' : 'vrrp instance id',
29 'example' : ['vrrp-id 1']},
30 'vrrp-priority' :
31 {'help': 'set vrrp priority',
32 'example' : ['vrrp-priority 20']},
33 'vrrp-virtual-ip' :
34 {'help': 'set vrrp virtual ip',
35 'example' : ['vrrp-virtual-ip 10.0.1.254']}}}
36
37 def __init__(self, *args, **kargs):
38 moduleBase.__init__(self, *args, **kargs)
39 self.ipcmd = None
40
41 def _check_if_process_is_running(self, cmdname, cmdline):
42 targetpids = []
43 pidstr = ''
44 try:
45 pidstr = subprocess.check_output(['/bin/pidof',
46 '%s' %cmdname]).strip('\n')
47 except:
48 pass
49 if not pidstr:
50 return []
51
52 pids = pidstr.split()
53 if not pids:
54 return targetpids
55 for pid in pids:
56 tmpcmdline = cmdline.replace(' ', '')
57 try:
58 pcmdline = self.read_file_oneline('/proc/%s/cmdline' %pid)
59 pcmdline = re.sub(r'\\(.)', r'\1', pcmdline)
60 self.logger.info('(%s)' %(pcmdline))
61 self.logger.info('(%s)' %(tmpcmdline))
62 self.logger.info('(%d) (%d)' %(len(pcmdline), len(tmpcmdline)))
63 if pcmdline and pcmdline == tmpcmdline:
64 targetpids.append(pid)
65 except:
66 pass
67 return targetpids
68
69 def _up(self, ifaceobj):
70 """ up vrrpd -n -D -i $IFACE -v 1 -p 20 10.0.1.254
71 up ifplugd -i $IFACE -b -f -u0 -d1 -I -p -q """
72
73 if (not self.DRYRUN and
74 not os.path.exists('/sys/class/net/%s' %ifaceobj.name)):
75 return
76
77 cmd = ''
78 attrval = ifaceobj.get_attr_value_first('vrrp-id')
79 if attrval:
80 cmd += ' -v %s' %attrval
81 else:
82 return
83 attrval = ifaceobj.get_attr_value_first('vrrp-priority')
84 if attrval:
85 cmd += ' -p %s' %attrval
86 else:
87 self.logger.warn('%s: incomplete vrrp parameters ' %ifaceobj.name,
88 '(priority not found)')
89 attrval = ifaceobj.get_attr_value_first('vrrp-virtual-ip')
90 if attrval:
91 cmd += ' %s' %attrval
92 else:
93 self.logger.warn('%s: incomplete vrrp arguments ' %ifaceobj.name,
94 '(virtual ip not found)')
95 return
96 cmd = '/usr/sbin/vrrpd -n -D -i %s %s' %(ifaceobj.name, cmd)
97 self.exec_command(cmd)
98
99 cmd = '/usr/sbin/ifplugd -i %s -b -f -u0 -d1 -I -p -q' %ifaceobj.name
100 if self._check_if_process_is_running('/usr/sbin/ifplugd', cmd):
101 self.logger.info('%s: ifplugd already running' %ifaceobj.name)
102 return
103 self.exec_command(cmd)
104
105 def _kill_pid_from_file(self, pidfilename):
106 if os.path.exists(pidfilename):
107 pid = self.read_file_oneline(pidfilename)
108 if os.path.exists('/proc/%s' %pid):
109 os.kill(int(pid), signal.SIGTERM)
110
111 def _down(self, ifaceobj):
112 """ down ifplugd -k -i $IFACE
113 down kill $(cat /var/run/vrrpd_$IFACE_*.pid) """
114 attrval = ifaceobj.get_attr_value_first('vrrp-id')
115 if not attrval:
116 return
117 try:
118 self.exec_command('/usr/sbin/ifplugd -k -i %s' %ifaceobj.name)
119 except Exception, e:
120 self.logger.debug('%s: ifplugd down error (%s)'
121 %(ifaceobj.name, str(e)))
122 pass
123
124 for pidfile in glob.glob('/var/run/vrrpd_%s_*.pid' %ifaceobj.name):
125 try:
126 self._kill_pid_from_file(pidfile)
127 except Exception, e:
128 self.logger.debug('%s: vrrpd down error (%s)'
129 %(ifaceobj.name, str(e)))
130 pass
131
132 def _query_check(self, ifaceobj, ifaceobjcurr):
133 # XXX
134 return
135
136
137 _run_ops = {'post-up' : _up,
138 'pre-down' : _down}
139
140 def get_ops(self):
141 """ returns list of ops supported by this module """
142 return self._run_ops.keys()
143
144 def run(self, ifaceobj, operation, query_ifaceobj=None, **extra_args):
145 """ run ethtool configuration on the interface object passed as
146 argument
147
148 Args:
149 **ifaceobj** (object): iface object
150
151 **operation** (str): any of 'post-up', 'query-checkcurr',
152 'query-running'
153 Kwargs:
154 **query_ifaceobj** (object): query check ifaceobject. This is only
155 valid when op is 'query-checkcurr'. It is an object same as
156 ifaceobj, but contains running attribute values and its config
157 status. The modules can use it to return queried running state
158 of interfaces. status is success if the running state is same
159 as user required state in ifaceobj. error otherwise.
160 """
161 op_handler = self._run_ops.get(operation)
162 if not op_handler:
163 return
164 if operation == 'query-checkcurr':
165 op_handler(self, ifaceobj, query_ifaceobj)
166 else:
167 op_handler(self, ifaceobj)