backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / tests / mininet / packet_lib / arp / test_arp.py
1 # Copyright (C) 2012 Nippon Telegraph and Telephone Corporation.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #    http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 # implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 # vim: tabstop=4 shiftwidth=4 softtabstop=4
17
18 import logging
19 import array
20 import netaddr
21
22 from ryu.base import app_manager
23 from ryu.controller import dpset
24 from ryu.controller import ofp_event
25 from ryu.controller import handler
26 from ryu.ofproto import ofproto_v1_2
27 from ryu.ofproto import ether
28 from ryu.ofproto import inet
29 from ryu.lib import mac
30 from ryu.lib.packet import packet
31 from ryu.lib.packet import ethernet
32 from ryu.lib.packet import arp
33 from ryu.lib.packet import ipv4
34 from ryu.lib.packet import icmp
35
36
37 LOG = logging.getLogger(__name__)
38
39
40 class RunTestMininet(app_manager.RyuApp):
41
42     _CONTEXTS = {'dpset': dpset.DPSet}
43     OFP_VERSIONS = [ofproto_v1_2.OFP_VERSION]
44
45     ZERO_MAC = mac.haddr_to_bin('00:00:00:00:00:00')
46     BROADCAST_MAC = mac.haddr_to_bin('ff:ff:ff:ff:ff:ff')
47     RYU_MAC = mac.haddr_to_bin('fe:ee:ee:ee:ee:ef')
48     HOST_MAC = mac.haddr_to_bin('00:00:00:00:00:01')
49     RYU_IP = int(netaddr.IPAddress('10.0.0.100'))
50     HOST_IP = int(netaddr.IPAddress('10.0.0.1'))
51
52     def __init__(self, *args, **kwargs):
53         super(RunTestMininet, self).__init__(*args, **kwargs)
54
55     def _send_msg(self, dp, data):
56         buffer_id = 0xffffffff
57         in_port = dp.ofproto.OFPP_LOCAL
58         actions = [dp.ofproto_parser.OFPActionOutput(1, 0)]
59         msg = dp.ofproto_parser.OFPPacketOut(
60             dp, buffer_id, in_port, actions, data)
61         dp.send_msg(msg)
62
63     def _add_flow(self, dp, match, actions):
64         inst = [dp.ofproto_parser.OFPInstructionActions(
65             dp.ofproto.OFPIT_APPLY_ACTIONS, actions)]
66         mod = dp.ofproto_parser.OFPFlowMod(
67             dp, cookie=0, cookie_mask=0, table_id=0,
68             command=dp.ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0,
69             priority=0xff, buffer_id=0xffffffff,
70             out_port=dp.ofproto.OFPP_ANY, out_group=dp.ofproto.OFPG_ANY,
71             flags=0, match=match, instructions=inst)
72         dp.send_msg(mod)
73
74     def _find_protocol(self, pkt, name):
75         for p in pkt.protocols:
76             if hasattr(p, 'protocol_name'):
77                 if p.protocol_name == name:
78                     return p
79
80     def _get_protocols(self, pkt):
81         protocols = {}
82         for p in pkt:
83             if hasattr(p, 'protocol_name'):
84                 protocols[p.protocol_name] = p
85             else:
86                 protocols['payload'] = p
87         return protocols
88
89     def _build_ether(self, ethertype, dst_mac=HOST_MAC):
90         e = ethernet.ethernet(dst_mac, self.RYU_MAC, ethertype)
91         return e
92
93     def _build_arp(self, opcode, dst_ip=HOST_IP):
94         if opcode == arp.ARP_REQUEST:
95             _eth_dst_mac = self.BROADCAST_MAC
96             _arp_dst_mac = self.ZERO_MAC
97         elif opcode == arp.ARP_REPLY:
98             _eth_dst_mac = self.HOST_MAC
99             _arp_dst_mac = self.HOST_MAC
100
101         e = self._build_ether(ether.ETH_TYPE_ARP, _eth_dst_mac)
102         a = arp.arp(hwtype=1, proto=ether.ETH_TYPE_IP, hlen=6, plen=4,
103                     opcode=opcode, src_mac=self.RYU_MAC, src_ip=self.RYU_IP,
104                     dst_mac=_arp_dst_mac, dst_ip=dst_ip)
105         p = packet.Packet()
106         p.add_protocol(e)
107         p.add_protocol(a)
108         p.serialize()
109
110         return p
111
112     def _build_echo(self, _type, echo):
113         e = self._build_ether(ether.ETH_TYPE_IP)
114         ip = ipv4.ipv4(version=4, header_length=5, tos=0, total_length=84,
115                        identification=0, flags=0, offset=0, ttl=64,
116                        proto=inet.IPPROTO_ICMP, csum=0,
117                        src=self.RYU_IP, dst=self.HOST_IP)
118         ping = icmp.icmp(_type, code=0, csum=0, data=echo)
119
120         p = packet.Packet()
121         p.add_protocol(e)
122         p.add_protocol(ip)
123         p.add_protocol(ping)
124         p.serialize()
125         return p
126
127     def _garp(self):
128         p = self._build_arp(arp.ARP_REQUEST, self.RYU_IP)
129         return p.data
130
131     def _arp_request(self):
132         p = self._build_arp(arp.ARP_REQUEST, self.HOST_IP)
133         return p.data
134
135     def _arp_reply(self):
136         p = self._build_arp(arp.ARP_REPLY, self.HOST_IP)
137         return p.data
138
139     def _echo_request(self, echo):
140         p = self._build_echo(icmp.ICMP_ECHO_REQUEST, echo)
141         return p.data
142
143     def _echo_reply(self, echo):
144         p = self._build_echo(icmp.ICMP_ECHO_REPLY, echo)
145         return p.data
146
147     @handler.set_ev_cls(ofp_event.EventOFPPacketIn, handler.MAIN_DISPATCHER)
148     def packet_in_handler(self, ev):
149         msg = ev.msg
150         dp = msg.datapath
151
152         pkt = packet.Packet(array.array('B', msg.data))
153         p_arp = self._find_protocol(pkt, "arp")
154         p_icmp = self._find_protocol(pkt, "icmp")
155         p_ipv4 = self._find_protocol(pkt, "ipv4")
156
157         if p_arp:
158             src_ip = str(netaddr.IPAddress(p_arp.src_ip))
159             dst_ip = str(netaddr.IPAddress(p_arp.dst_ip))
160             if p_arp.opcode == arp.ARP_REQUEST:
161                 LOG.debug("--- PacketIn: ARP_Request: %s->%s", src_ip, dst_ip)
162                 if p_arp.dst_ip == self.RYU_IP:
163                     LOG.debug("--- send Pkt: ARP_Reply")
164                     data = self._arp_reply()
165                     self._send_msg(dp, data)
166                 elif p_arp.dst_ip == self.HOST_IP:
167                     LOG.debug("    PacketIn: GARP")
168                     LOG.debug("--- send Pkt: ARP_Request")
169                     data = self._arp_request()
170                     self._send_msg(dp, data)
171             elif p_arp.opcode == arp.ARP_REPLY:
172                 LOG.debug("--- PacketIn: ARP_Reply: %s->%s", src_ip, dst_ip)
173                 LOG.debug("--- send Pkt: Echo_Request")
174                 echo = icmp.echo(id_=66, seq=1)
175                 data = self._echo_request(echo)
176                 self._send_msg(dp, data)
177
178         if p_icmp:
179             src = str(netaddr.IPAddress(p_ipv4.src))
180             dst = str(netaddr.IPAddress(p_ipv4.dst))
181             if p_icmp.type == icmp.ICMP_ECHO_REQUEST:
182                 LOG.debug("--- PacketIn: Echo_Request: %s->%s", src, dst)
183                 if p_ipv4.dst == self.RYU_IP:
184                     LOG.debug("--- send Pkt: Echo_Reply")
185                     echo = p_icmp.data
186                     echo.data = bytearray(echo.data)
187                     data = self._echo_reply(echo)
188                     self._send_msg(dp, data)
189             elif p_icmp.type == icmp.ICMP_ECHO_REPLY:
190                 LOG.debug("--- PacketIn: Echo_Reply: %s->%s", src, dst)
191
192     @handler.set_ev_cls(dpset.EventDP, dpset.DPSET_EV_DISPATCHER)
193     def handler_datapath(self, ev):
194         if ev.enter:
195             dp = ev.dp
196
197             LOG.debug("--- send Pkt: Gratuitous ARP_Request")
198             data = self._garp()
199             self._send_msg(dp, data)