1 # Copyright (C) 2013 Nippon Telegraph and Telephone Corporation.
2 # Copyright (C) 2013 Isaku Yamahata <yamahata at private email ne 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.
21 from ryu.controller import handler
22 from ryu.controller import event
23 from ryu.lib import dpid as dpid_lib
24 from ryu.lib import mac as mac_lib
25 from ryu.lib.packet import vrrp
26 from ryu.lib import addrconv
29 # When an instance is created, state transition is None -> Initialize
30 VRRP_STATE_INITIALIZE = 'Initialize'
31 VRRP_STATE_MASTER = 'Master'
32 VRRP_STATE_BACKUP = 'Backup'
35 VRRP_MANAGER_NAME = 'VRRPManager'
38 class VRRPInterfaceBase(object):
40 interface on which VRRP router works
41 vlan_id = None means no vlan.
42 NOTE: multiple virtual router can be configured on single port
43 See RFC 5798 4.2 Sample Configuration 2
46 def __init__(self, mac_address, primary_ip_address, vlan_id=None):
47 super(VRRPInterfaceBase, self).__init__()
48 self.mac_address = mac_address
49 self.primary_ip_address = primary_ip_address
50 self.vlan_id = vlan_id
52 def __eq__(self, other):
53 return (self.__class__ == other.__class__ and
54 self.mac_address == other.mac_address and
55 self.primary_ip_address == other.primary_ip_address and
56 self.vlan_id == other.vlan_id)
60 addrconv.mac.text_to_bin(self.mac_address),
61 vrrp.ip_text_to_bin(self.primary_ip_address), self.vlan_id))
64 class VRRPInterfaceNetworkDevice(VRRPInterfaceBase):
65 def __init__(self, mac_address, primary_ip_address, vlan_id,
67 super(VRRPInterfaceNetworkDevice, self).__init__(
68 mac_address, primary_ip_address, vlan_id)
69 self.device_name = device_name
72 return '%s<%s, %s, %s, %s>' % (
73 self.__class__.__name__,
75 self.primary_ip_address, self.vlan_id,
78 def __eq__(self, other):
79 return (super(VRRPInterfaceNetworkDevice, self).__eq__(other) and
80 self.device_name == other.device_name)
84 addrconv.mac.text_to_bin(self.mac_address),
85 vrrp.ip_text_to_bin(self.primary_ip_address), self.vlan_id,
89 class VRRPInterfaceOpenFlow(VRRPInterfaceBase):
90 def __init__(self, mac_address, primary_ip_address, vlan_id,
92 super(VRRPInterfaceOpenFlow, self).__init__(
93 mac_address, primary_ip_address, vlan_id)
95 self.port_no = port_no
98 return '%s<%s, %s, %s, %s, %d>' % (
99 self.__class__.__name__,
101 self.primary_ip_address, self.vlan_id,
102 dpid_lib.dpid_to_str(self.dpid), self.port_no)
104 def __eq__(self, other):
105 return (super(VRRPInterfaceOpenFlow, self).__eq__(other) and
106 self.dpid == other.dpid and self.port_no == other.port_no)
110 addrconv.mac.text_to_bin(self.mac_address),
111 vrrp.ip_text_to_bin(self.primary_ip_address), self.vlan_id,
112 self.dpid, self.port_no))
115 class VRRPConfig(object):
117 advertmisement_interval is in seconds as float. (Not in centiseconds)
120 def __init__(self, version=vrrp.VRRP_VERSION_V3, vrid=None,
122 priority=vrrp.VRRP_PRIORITY_BACKUP_DEFAULT, ip_addresses=None,
123 advertisement_interval=vrrp.VRRP_MAX_ADVER_INT_DEFAULT_IN_SEC,
124 preempt_mode=True, preempt_delay=0, accept_mode=False,
125 statistics_interval=30, resource_id=None):
126 # To allow version and priority default
127 assert vrid is not None
128 assert ip_addresses is not None
129 super(VRRPConfig, self).__init__()
131 self.version = version
132 self.admin_state = admin_state
134 self.priority = priority
135 self.ip_addresses = ip_addresses
136 self.advertisement_interval = advertisement_interval
137 self.preempt_mode = preempt_mode
138 self.preempt_delay = preempt_delay
139 self.accept_mode = accept_mode
140 self.is_ipv6 = vrrp.is_ipv6(ip_addresses[0])
141 self.statistics_interval = statistics_interval
142 self.resource_id = resource_id
145 def address_owner(self):
146 return self.priority == vrrp.VRRP_PRIORITY_ADDRESS_OWNER
148 def __eq__(self, other):
149 return (self.version == other.version and
150 self.vrid == other.vrid and
151 self.priority == other.priority and
152 self.ip_addresses == other.ip_addresses and
153 self.advertisement_interval == other.advertisement_interval and
154 self.preempt_mode == other.preempt_mode and
155 self.preempt_delay == other.preempt_delay and
156 self.accept_mode == other.accept_mode and
157 self.is_ipv6 == other.is_ipv6)
160 hash((self.version, self.vrid, self.priority,
161 list(map(vrrp.ip_text_to_bin, self.ip_addresses)),
162 self.advertisement_interval, self.preempt_mode,
163 self.preempt_delay, self.accept_mode, self.is_ipv6))
166 class EventVRRPConfigRequest(event.EventRequestBase):
168 Request from management layer to VRRP manager to initialize VRRP Router.
171 def __init__(self, interface, config):
172 super(EventVRRPConfigRequest, self).__init__()
173 self.dst = VRRP_MANAGER_NAME
174 self.interface = interface
178 class EventVRRPConfigReply(event.EventReplyBase):
179 def __init__(self, instance_name, interface, config):
180 # dst = None. dst is filled by app_base.RyuApp#reply_to_request()
181 super(EventVRRPConfigReply, self).__init__(None)
182 self.instance_name = instance_name # None means failure
183 self.interface = interface
187 class EventVRRPShutdownRequest(event.EventRequestBase):
189 Request from management layer to VRRP to shutdown VRRP Router.
192 def __init__(self, instance_name):
193 super(EventVRRPShutdownRequest, self).__init__()
194 self.instance_name = instance_name
197 class EventVRRPStateChanged(event.EventBase):
199 Event that this VRRP Router changed its state.
202 def __init__(self, instance_name, monitor_name, interface, config,
203 old_state, new_state):
204 super(EventVRRPStateChanged, self).__init__()
205 self.instance_name = instance_name
206 self.monitor_name = monitor_name
207 self.interface = interface
209 self.old_state = old_state
210 self.new_state = new_state
213 class VRRPInstance(object):
214 def __init__(self, instance_name, monitor_name, config, interface, state):
215 super(VRRPInstance, self).__init__()
216 self.instance_name = instance_name
217 self.monitor_name = monitor_name
219 self.interface = interface
223 class EventVRRPListRequest(event.EventRequestBase):
225 Event that requests list of configured VRRP router
226 instance_name=None means all instances.
229 def __init__(self, instance_name=None):
230 super(EventVRRPListRequest, self).__init__()
231 self.instance_name = instance_name
234 class EventVRRPListReply(event.EventReplyBase):
235 def __init__(self, instance_list):
236 super(EventVRRPListReply, self).__init__(None)
237 self.instance_list = instance_list
240 class EventVRRPConfigChangeRequest(event.EventRequestBase):
242 Event that requests to change configuration of a given VRRP router.
243 None means no-change.
246 def __init__(self, instance_name, priority=None,
247 advertisement_interval=None, preempt_mode=None,
248 preempt_delay=None, accept_mode=None):
249 super(EventVRRPConfigChangeRequest, self).__init__()
250 self.instance_name = instance_name
251 self.priority = priority
252 self.advertisement_interval = advertisement_interval
253 self.preempt_mode = preempt_mode
254 self.preempt_delay = preempt_delay
255 self.accept_mode = accept_mode
258 # Following classes are internally used by VRRP
260 class EventVRRPReceived(event.EventBase):
262 Event that port manager received valid VRRP packet.
263 Usually handed by VRRP Router.
266 def __init__(self, interface, packet):
267 super(EventVRRPReceived, self).__init__()
268 self.interface = interface
272 class EventVRRPTransmitRequest(event.EventRequestBase):
274 Request from VRRP router to port manager to transmit VRRP packet.
277 def __init__(self, data):
278 super(EventVRRPTransmitRequest, self).__init__()
282 handler.register_service('ryu.services.protocols.vrrp.manager')