blob: 0c139d8da1df4c738c73d9440d5bfb92f49f49f9 [file] [log] [blame]
sanghoshin94872a12015-10-16 18:04:34 +09001/*
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*/
16package org.onosproject.openstackswitching;
17
danielbb83ebc2015-10-29 15:13:06 +090018import org.onlab.packet.ARP;
19import org.onlab.packet.Ethernet;
20import org.onlab.packet.Ip4Address;
21import org.onlab.packet.MacAddress;
22import org.onosproject.net.flow.DefaultTrafficTreatment;
23import org.onosproject.net.flow.TrafficTreatment;
24import org.onosproject.net.packet.DefaultOutboundPacket;
sanghoshin94872a12015-10-16 18:04:34 +090025import org.onosproject.net.packet.InboundPacket;
danielbb83ebc2015-10-29 15:13:06 +090026import org.onosproject.net.packet.OutboundPacket;
27import org.onosproject.net.packet.PacketService;
sanghoshin94872a12015-10-16 18:04:34 +090028import org.slf4j.Logger;
29import org.slf4j.LoggerFactory;
danielbb83ebc2015-10-29 15:13:06 +090030import java.nio.ByteBuffer;
31import java.util.Map;
sanghoshin94872a12015-10-16 18:04:34 +090032
33/**
34 * It handles ARP packet from VMs.
35 */
36public class OpenstackArpHandler {
37
38 private static Logger log = LoggerFactory
39 .getLogger(OpenstackArpHandler.class);
danielbb83ebc2015-10-29 15:13:06 +090040 private PacketService packetService;
41 private Map<String, OpenstackPort> openstackPortMap;
sanghoshin94872a12015-10-16 18:04:34 +090042
43 /**
danielbb83ebc2015-10-29 15:13:06 +090044 * Returns OpenstackArpHandler reference.
sanghoshin94872a12015-10-16 18:04:34 +090045 *
danielbb83ebc2015-10-29 15:13:06 +090046 * @param openstackPortMap
47 * @param packetService
sanghoshin94872a12015-10-16 18:04:34 +090048 */
danielbb83ebc2015-10-29 15:13:06 +090049 public OpenstackArpHandler(Map<String, OpenstackPort> openstackPortMap, PacketService packetService) {
50 this.openstackPortMap = openstackPortMap;
51 this.packetService = packetService;
sanghoshin94872a12015-10-16 18:04:34 +090052 }
53
54 /**
55 * Processes ARP packets.
56 *
57 * @param pkt ARP request packet
58 */
59 public void processPacketIn(InboundPacket pkt) {
danielbb83ebc2015-10-29 15:13:06 +090060 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 }
sanghoshin94872a12015-10-16 18:04:34 +0900105 }
106}