1 # Copyright (C) 2013 Nippon Telegraph and Telephone Corporation.
2 # Copyright (C) 2013 Isaku Yamahata <yamahata at valinux co jp>
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 from __future__ import print_function
22 from ryu.base import app_manager
23 from ryu.lib import hub
24 from ryu.lib import mac as lib_mac
25 from ryu.lib.packet import vrrp
26 from ryu.services.protocols.vrrp import api as vrrp_api
27 from ryu.services.protocols.vrrp import event as vrrp_event
31 _PRIMARY_IP_ADDRESS0 = '10.0.0.2'
32 _PRIMARY_IP_ADDRESS1 = '10.0.0.3'
35 class VRRPCommon(app_manager.RyuApp):
39 def __init__(self, *args, **kwargs):
40 super(VRRPCommon, self).__init__(*args, **kwargs)
43 self._main_version(vrrp.VRRP_VERSION_V3)
44 self._main_version(vrrp.VRRP_VERSION_V2)
47 def _main_version(self, vrrp_version):
48 self._main_version_priority(vrrp_version,
49 vrrp.VRRP_PRIORITY_ADDRESS_OWNER)
50 self._main_version_priority(vrrp_version,
51 vrrp.VRRP_PRIORITY_BACKUP_MAX)
52 self._main_version_priority(vrrp_version,
53 vrrp.VRRP_PRIORITY_BACKUP_DEFAULT)
54 self._main_version_priority(vrrp_version,
55 vrrp.VRRP_PRIORITY_BACKUP_MIN)
57 def _main_version_priority(self, vrrp_version, priority):
58 self._main_version_priority_sleep(vrrp_version, priority, False)
59 self._main_version_priority_sleep(vrrp_version, priority, True)
61 def _check(self, vrrp_api, instances):
64 rep = vrrp_api.vrrp_list(self)
65 if len(rep.instance_list) >= len(instances) * 2:
66 if any(i.state == vrrp_event.VRRP_STATE_INITIALIZE
67 for i in rep.instance_list):
70 print('%s / %s' % (len(rep.instance_list), len(instances) * 2))
73 # for i in rep.instance_list:
74 # print('%s %s %s %s %s' % (i.instance_name,
79 assert len(rep.instance_list) == len(instances) * 2
81 d = dict(((i.instance_name, i) for i in rep.instance_list))
83 for i in rep.instance_list:
84 assert i.state in (vrrp_event.VRRP_STATE_MASTER,
85 vrrp_event.VRRP_STATE_BACKUP)
86 if i.state == vrrp_event.VRRP_STATE_MASTER:
89 vr = instances[i.config.vrid]
90 if (vr[0].config.priority > vr[1].config.priority and
91 i.instance_name == vr[1].instance_name) or \
92 (vr[0].config.priority < vr[1].config.priority and
93 i.instance_name == vr[0].instance_name):
94 if i.state == vrrp_event.VRRP_STATE_MASTER:
96 print('%s %s' % (d[vr[0].instance_name].state,
97 d[vr[0].instance_name].config.priority))
98 print('%s %s' % (d[vr[1].instance_name].state,
99 d[vr[1].instance_name].config.priority))
101 # assert i.state != vrrp_event.VRRP_STATE_MASTER
103 # this could be a transient state
104 print("%s bad masters" % bad)
107 if num_of_master >= len(instances):
108 assert num_of_master == len(instances)
110 print('%s / %s' % (num_of_master, len(instances)))
114 def _main_version_priority_sleep(self, vrrp_version, priority, do_sleep):
115 app_mgr = app_manager.AppManager.get_instance()
116 self.logger.debug('%s', app_mgr.applications)
117 vrrp_mgr = app_mgr.applications['VRRPManager']
121 for vrid in range(1, 256, step):
124 print("vrid %s" % vrid)
126 prio = max(vrrp.VRRP_PRIORITY_BACKUP_MIN,
127 min(vrrp.VRRP_PRIORITY_BACKUP_MAX, vrid))
128 rep0 = self._configure_vrrp_router(vrrp_version,
130 _PRIMARY_IP_ADDRESS0,
133 assert rep0.instance_name is not None
135 prio = max(vrrp.VRRP_PRIORITY_BACKUP_MIN,
136 min(vrrp.VRRP_PRIORITY_BACKUP_MAX, 256 - vrid))
137 rep1 = self._configure_vrrp_router(vrrp_version,
139 _PRIMARY_IP_ADDRESS1,
142 assert rep1.instance_name is not None
146 print("vrid %s" % _VRID)
148 rep0 = self._configure_vrrp_router(vrrp_version, priority,
149 _PRIMARY_IP_ADDRESS0,
150 self._IFNAME0, _VRID)
151 assert rep0.instance_name is not None
153 rep1 = self._configure_vrrp_router(
154 vrrp_version, vrrp.VRRP_PRIORITY_BACKUP_DEFAULT,
155 _PRIMARY_IP_ADDRESS1, self._IFNAME1, _VRID)
156 assert rep1.instance_name is not None
160 self.logger.debug('%s', vrrp_mgr._instances)
163 print("priority %s" % priority)
164 print("waiting for instances starting")
166 self._check(vrrp_api, instances)
168 for vrid in instances.keys():
172 new_priority = int(random.uniform(vrrp.VRRP_PRIORITY_BACKUP_MIN,
173 vrrp.VRRP_PRIORITY_BACKUP_MAX))
174 i = instances[vrid][which]
175 vrrp_api.vrrp_config_change(self, i.instance_name,
176 priority=new_priority)
177 i.config.priority = new_priority
180 print("priority shuffled")
182 self._check(vrrp_api, instances)
184 for vrid in instances.keys():
188 vrrp_api.vrrp_shutdown(self, instances[vrid][which].instance_name)
189 vrrp_api.vrrp_shutdown(self, instances[_VRID][0].instance_name)
192 print("shutting down instances")
194 rep = vrrp_api.vrrp_list(self)
195 if len(rep.instance_list) <= len(instances):
197 print("left %s" % len(rep.instance_list))
199 assert len(rep.instance_list) == len(instances)
200 print("waiting for the rest becoming master")
202 rep = vrrp_api.vrrp_list(self)
203 if all(i.state == vrrp_event.VRRP_STATE_MASTER
204 for i in rep.instance_list):
208 vrrp_api.vrrp_shutdown(self, instances[_VRID][1].instance_name)
209 for vrid in instances.keys():
212 which = 1 - (vrid & 1)
213 vrrp_api.vrrp_shutdown(self, instances[vrid][which].instance_name)
215 print("waiting for instances shutting down")
217 rep = vrrp_api.vrrp_list(self)
218 if not rep.instance_list:
220 print("left %s" % len(rep.instance_list))