Switch to JDT annotations for Nullable and NonNull
[netvirt.git] / vpnmanager / impl / src / main / java / org / opendaylight / netvirt / vpnmanager / iplearn / ipv4 / ArpUtils.java
1 /*
2  * Copyright © 2016, 2017 Hewlett Packard Enterprise, Co. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.netvirt.vpnmanager.iplearn.ipv4;
9
10 import java.math.BigInteger;
11 import java.util.ArrayList;
12 import java.util.List;
13 import org.eclipse.jdt.annotation.Nullable;
14 import org.opendaylight.genius.mdsalutil.ActionInfo;
15 import org.opendaylight.genius.mdsalutil.MDSALUtil;
16 import org.opendaylight.genius.mdsalutil.NWUtil;
17 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
18 import org.opendaylight.genius.mdsalutil.packet.ARP;
19 import org.opendaylight.genius.mdsalutil.packet.Ethernet;
20 import org.opendaylight.openflowplugin.libraries.liblldp.EtherTypes;
21 import org.opendaylight.openflowplugin.libraries.liblldp.PacketException;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 public final class ArpUtils {
28     private static final Logger LOG = LoggerFactory.getLogger(ArpUtils.class);
29
30     private static final byte[] ETHERNETDESTINATION_BROADCAST = new byte[] {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
31         (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
32     private static final byte[] MAC_BROADCAST = new byte[] {(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0};
33
34     private ArpUtils() { }
35
36     public static TransmitPacketInput createArpRequestInput(BigInteger dpnId, long groupId, byte[] abySenderMAC,
37         byte[] abySenderIpAddress, byte[] abyTargetIpAddress) {
38         return createArpRequestInput(dpnId, groupId, abySenderMAC, abySenderIpAddress, abyTargetIpAddress, null);
39     }
40
41     public static TransmitPacketInput createArpRequestInput(BigInteger dpnId, byte[] abySenderMAC,
42         byte[] abySenderIpAddress, byte[] abyTargetIpAddress, NodeConnectorRef ingress) {
43         return createArpRequestInput(dpnId, null, abySenderMAC, (byte[]) null, abySenderIpAddress, abyTargetIpAddress,
44             ingress, new ArrayList<>());
45     }
46
47     public static TransmitPacketInput createArpRequestInput(BigInteger dpnId, Long groupId, byte[] abySenderMAC,
48         byte[] abySenderIpAddress, byte[] abyTargetIpAddress, NodeConnectorRef ingress) {
49         List<ActionInfo> lstActionInfo = new ArrayList<>();
50         return createArpRequestInput(dpnId, groupId, abySenderMAC, null, abySenderIpAddress, abyTargetIpAddress,
51             ingress, lstActionInfo);
52     }
53
54     @Nullable
55     public static TransmitPacketInput createArpRequestInput(BigInteger dpnId, Long groupId, byte[] abySenderMAC,
56             byte[] abyTargetMAC, byte[] abySenderIpAddress, byte[] abyTargetIpAddress, NodeConnectorRef ingress,
57             List<ActionInfo> lstActionInfo) {
58
59         LOG.info("SubnetRoutePacketInHandler: sendArpRequest dpnId {}, actions {},"
60                  + " groupId {}, senderIPAddress {}, targetIPAddress {}",
61                 dpnId, lstActionInfo, groupId, NWUtil.toStringIpAddress(abySenderIpAddress),
62                 NWUtil.toStringIpAddress(abyTargetIpAddress));
63         if (abySenderIpAddress != null) {
64             byte[] arpPacket;
65             byte[] ethPacket;
66
67             byte[] targetMac = abyTargetMAC != null ? abyTargetMAC : MAC_BROADCAST;
68             arpPacket = createARPPacket(ARP.REQUEST, abySenderMAC, abySenderIpAddress, targetMac, abyTargetIpAddress);
69             ethPacket = createEthernetPacket(abySenderMAC, ETHERNETDESTINATION_BROADCAST, arpPacket);
70             if (groupId != null) {
71                 lstActionInfo.add(new ActionGroup(groupId));
72             }
73             if (ingress != null) {
74                 return MDSALUtil.getPacketOutFromController(lstActionInfo, ethPacket, dpnId.longValue(), ingress);
75             } else {
76                 return MDSALUtil.getPacketOutDefault(lstActionInfo, ethPacket, dpnId);
77             }
78         } else {
79             LOG.info("SubnetRoutePacketInHandler: Unable to send ARP request because client port has no IP  ");
80             return null;
81         }
82     }
83
84     public static byte[] getMacInBytes(String macAddress) {
85         String[] macAddressParts = macAddress.split(":");
86
87         // convert hex string to byte values
88         byte[] macAddressBytes = new byte[6];
89         for (int i = 0; i < 6; i++) {
90             Integer hex = Integer.parseInt(macAddressParts[i], 16);
91             macAddressBytes[i] = hex.byteValue();
92         }
93
94         return macAddressBytes;
95     }
96
97     private static byte[] createEthernetPacket(byte[] sourceMAC, byte[] targetMAC, byte[] arp) {
98         Ethernet ethernet = new Ethernet();
99         byte[] rawEthPkt = null;
100         try {
101             ethernet.setSourceMACAddress(sourceMAC);
102             ethernet.setDestinationMACAddress(targetMAC);
103             ethernet.setEtherType(EtherTypes.ARP.shortValue());
104             ethernet.setRawPayload(arp);
105             rawEthPkt = ethernet.serialize();
106         } catch (PacketException ex) {
107             LOG.error(
108                 "VPNUtil:  Serialized Ethernet packet with sourceMacAddress {} targetMacAddress {} exception ",
109                 sourceMAC, targetMAC, ex);
110         }
111         return rawEthPkt;
112     }
113
114     private static byte[] createARPPacket(short opCode, byte[] senderMacAddress, byte[] senderIP,
115         byte[] targetMacAddress, byte[] targetIP) {
116         ARP arp = new ARP();
117         byte[] rawArpPkt = null;
118         try {
119             arp.setHardwareType(ARP.HW_TYPE_ETHERNET);
120             arp.setProtocolType(EtherTypes.IPv4.shortValue());
121             arp.setHardwareAddressLength((byte) 6);
122             arp.setProtocolAddressLength((byte) 4);
123             arp.setOpCode(opCode);
124             arp.setSenderHardwareAddress(senderMacAddress);
125             arp.setSenderProtocolAddress(senderIP);
126             arp.setTargetHardwareAddress(targetMacAddress);
127             arp.setTargetProtocolAddress(targetIP);
128             rawArpPkt = arp.serialize();
129         } catch (PacketException ex) {
130             LOG.error("VPNUtil:  Serialized ARP packet with senderIp {} targetIP {} exception ", senderIP,
131                 targetIP, ex);
132         }
133
134         return rawArpPkt;
135     }
136 }