0c139d8da1df4c738c73d9440d5bfb92f49f49f9
[onosfw.git] /
1 /*
2 * Copyright 2015 Open Networking Laboratory
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 implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.onosproject.openstackswitching;
17
18 import org.onlab.packet.ARP;
19 import org.onlab.packet.Ethernet;
20 import org.onlab.packet.Ip4Address;
21 import org.onlab.packet.MacAddress;
22 import org.onosproject.net.flow.DefaultTrafficTreatment;
23 import org.onosproject.net.flow.TrafficTreatment;
24 import org.onosproject.net.packet.DefaultOutboundPacket;
25 import org.onosproject.net.packet.InboundPacket;
26 import org.onosproject.net.packet.OutboundPacket;
27 import org.onosproject.net.packet.PacketService;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30 import java.nio.ByteBuffer;
31 import java.util.Map;
32
33 /**
34  * It handles ARP packet from VMs.
35  */
36 public class OpenstackArpHandler {
37
38     private static Logger log = LoggerFactory
39             .getLogger(OpenstackArpHandler.class);
40     private PacketService packetService;
41     private Map<String, OpenstackPort> openstackPortMap;
42
43     /**
44      * Returns OpenstackArpHandler reference.
45      *
46      * @param openstackPortMap
47      * @param packetService
48      */
49     public OpenstackArpHandler(Map<String, OpenstackPort> openstackPortMap, PacketService packetService) {
50         this.openstackPortMap = openstackPortMap;
51         this.packetService = packetService;
52     }
53
54     /**
55      * Processes ARP packets.
56      *
57      * @param pkt ARP request packet
58      */
59     public void processPacketIn(InboundPacket pkt) {
60         Ethernet ethernet = pkt.parsed();
61         ARP arp = (ARP) ethernet.getPayload();
62
63         if (arp.getOpCode() == ARP.OP_REQUEST) {
64             byte[] srcMacAddress = arp.getSenderHardwareAddress();
65             byte[] srcIPAddress = arp.getSenderProtocolAddress();
66             byte[] dstIPAddress = arp.getTargetProtocolAddress();
67
68             //Searches the Dst MAC Address based on openstackPortMap
69             MacAddress macAddress = null;
70
71             OpenstackPort openstackPort = openstackPortMap.values().stream().filter(e -> e.fixedIps().
72                     containsValue(Ip4Address.valueOf(dstIPAddress))).findAny().orElse(null);
73
74             if (openstackPort != null) {
75                 macAddress = openstackPort.macAddress();
76                 log.debug("Found MACAddress: {}", macAddress.toString());
77             } else {
78                 return;
79             }
80
81             //Creates a response packet
82             ARP arpReply = new ARP();
83             arpReply.setOpCode(ARP.OP_REPLY)
84                     .setHardwareAddressLength(arp.getHardwareAddressLength())
85                     .setHardwareType(arp.getHardwareType())
86                     .setProtocolAddressLength(arp.getProtocolAddressLength())
87                     .setProtocolType(arp.getProtocolType())
88                     .setSenderHardwareAddress(macAddress.toBytes())
89                     .setSenderProtocolAddress(dstIPAddress)
90                     .setTargetHardwareAddress(srcMacAddress)
91                     .setTargetProtocolAddress(srcIPAddress);
92
93             //Sends a response packet
94             ethernet.setDestinationMACAddress(srcMacAddress)
95                     .setSourceMACAddress(macAddress)
96                     .setEtherType(Ethernet.TYPE_ARP)
97                     .setPayload(arpReply);
98
99             TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
100             builder.setOutput(pkt.receivedFrom().port());
101             OutboundPacket packet = new DefaultOutboundPacket(pkt.receivedFrom().deviceId(),
102                     builder.build(), ByteBuffer.wrap(ethernet.serialize()));
103             packetService.emit(packet);
104         }
105     }
106 }