backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / services / protocols / vrrp / monitor_openflow.py
1 # Copyright (C) 2013 Nippon Telegraph and Telephone Corporation.
2 # Copyright (C) 2013 Isaku Yamahata <yamahata at private email ne jp>
3 #
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
7 #
8 #    http://www.apache.org/licenses/LICENSE-2.0
9 #
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
13 # implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 from ryu.controller import handler
18 from ryu.controller import ofp_event
19 from ryu.lib import dpid as dpid_lib
20 from ryu.lib.packet import vrrp
21 from ryu.ofproto import ether
22 from ryu.ofproto import inet
23 from ryu.ofproto import ofproto_v1_2
24 from ryu.ofproto import ofproto_v1_3
25 from ryu.services.protocols.vrrp import monitor
26 from ryu.services.protocols.vrrp import event as vrrp_event
27 from ryu.services.protocols.vrrp import utils
28
29
30 @monitor.VRRPInterfaceMonitor.register(vrrp_event.VRRPInterfaceOpenFlow)
31 class VRRPInterfaceMonitorOpenFlow(monitor.VRRPInterfaceMonitor):
32     # OF1.2
33     OFP_VERSIONS = [ofproto_v1_2.OFP_VERSION,
34                     ofproto_v1_3.OFP_VERSION]   # probably work with OF1.3
35
36     _TABLE = 0          # generate packet-in in this table
37     _PRIORITY = 0x8000  # default priority
38
39     def __init__(self, *args, **kwargs):
40         super(VRRPInterfaceMonitorOpenFlow, self).__init__(*args, **kwargs)
41         table = kwargs.get('vrrp_imof_table', None)
42         if table is not None:
43             self._TABLE = int(table)
44         priority = kwargs.get('vrrp_imof_priority', None)
45         if priority is not None:
46             self._PRIORITY = int(priority)
47
48     @handler.set_ev_cls(ofp_event.EventOFPPacketIn, handler.MAIN_DISPATCHER)
49     def packet_in_handler(self, ev):
50         self.logger.debug('packet_in_handler')
51         msg = ev.msg
52         datapath = msg.datapath
53         ofproto = datapath.ofproto
54
55         # TODO: subscribe only the designated datapath
56         dpid = datapath.id
57         if dpid != self.interface.dpid:
58             self.logger.debug('packet_in_handler dpid %s %s',
59                               dpid_lib.dpid_to_str(dpid),
60                               dpid_lib.dpid_to_str(self.interface.dpid))
61             return
62
63         in_port = None
64         for field in msg.match.fields:
65             if field.header == ofproto.OXM_OF_IN_PORT:
66                 in_port = field.value
67                 break
68
69         if in_port != self.interface.port_no:
70             self.logger.debug('packet_in_handler in_port %s %s',
71                               in_port, self.interface.port_no)
72             return
73
74         self._send_vrrp_packet_received(msg.data)
75
76     def _get_dp(self):
77         return utils.get_dp(self, self.interface.dpid)
78
79     @handler.set_ev_handler(vrrp_event.EventVRRPTransmitRequest)
80     def vrrp_transmit_request_handler(self, ev):
81         dp = self._get_dp()
82         if not dp:
83             return
84         utils.dp_packet_out(dp, self.interface.port_no, ev.data)
85
86     def _ofp_match(self, ofproto_parser):
87         is_ipv6 = vrrp.is_ipv6(self.config.ip_addresses[0])
88         kwargs = {}
89         kwargs['in_port'] = self.interface.port_no
90         if is_ipv6:
91             kwargs['eth_dst'] = vrrp.VRRP_IPV6_DST_MAC_ADDRESS
92             kwargs['eth_src'] = \
93                 vrrp.vrrp_ipv6_src_mac_address(self.config.vrid)
94             kwargs['eth_type'] = ether.ETH_TYPE_IPV6
95             kwargs['ipv6_dst'] = vrrp.VRRP_IPV6_DST_ADDRESS
96         else:
97             kwargs['eth_dst'] = vrrp.VRRP_IPV4_DST_MAC_ADDRESS
98             kwargs['eth_src'] = \
99                 vrrp.vrrp_ipv4_src_mac_address(self.config.vrid)
100             kwargs['eth_type'] = ether.ETH_TYPE_IP
101             kwargs['ipv4_dst'] = vrrp.VRRP_IPV4_DST_ADDRESS
102
103         if self.interface.vlan_id is not None:
104             kwargs['vlan_vid'] = self.interface.vlan_id
105         kwargs['ip_proto'] = inet.IPPROTO_VRRP
106         # OF1.2 doesn't support TTL match.
107         # It needs to be checked by packet in handler
108
109         return ofproto_parser.OFPMatch(**kwargs)
110
111     def _initialize(self):
112         dp = self._get_dp()
113         if not dp:
114             return
115
116         ofproto = dp.ofproto
117         ofproto_parser = dp.ofproto_parser
118
119         match = self._ofp_match(ofproto_parser)
120         utils.dp_flow_mod(dp, self._TABLE, ofproto.OFPFC_DELETE_STRICT,
121                           self._PRIORITY, match, [],
122                           out_port=ofproto.OFPP_CONTROLLER)
123
124         match = self._ofp_match(ofproto_parser)
125         actions = [ofproto_parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,
126                                                   ofproto.OFPCML_NO_BUFFER)]
127         instructions = [ofproto_parser.OFPInstructionActions(
128             ofproto.OFPIT_APPLY_ACTIONS, actions)]
129         utils.dp_flow_mod(dp, self._TABLE, ofproto.OFPFC_ADD, self._PRIORITY,
130                           match, instructions)
131
132     def _shutdown(self):
133         dp = self._get_dp()
134         if not dp:
135             return
136
137         ofproto = dp.ofproto
138         match = self._ofp_match(dp.ofproto_parser)
139         utils.dp_flow_mod(dp, self._TABLE, ofproto.OFPFC_DELETE_STRICT,
140                           self._PRIORITY, match, [],
141                           out_port=ofproto.OFPP_CONTROLLER)