2 * Copyright © 2016, 2017 Hewlett Packard Enterprise, Co. and others. All rights reserved.
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
8 package org.opendaylight.netvirt.vpnmanager.iplearn.ipv4;
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;
27 public final class ArpUtils {
28 private static final Logger LOG = LoggerFactory.getLogger(ArpUtils.class);
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};
34 private ArpUtils() { }
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);
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<>());
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);
55 public static TransmitPacketInput createArpRequestInput(BigInteger dpnId, Long groupId, byte[] abySenderMAC,
56 byte[] abyTargetMAC, byte[] abySenderIpAddress, byte[] abyTargetIpAddress, NodeConnectorRef ingress,
57 List<ActionInfo> lstActionInfo) {
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) {
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));
73 if (ingress != null) {
74 return MDSALUtil.getPacketOutFromController(lstActionInfo, ethPacket, dpnId.longValue(), ingress);
76 return MDSALUtil.getPacketOutDefault(lstActionInfo, ethPacket, dpnId);
79 LOG.info("SubnetRoutePacketInHandler: Unable to send ARP request because client port has no IP ");
84 public static byte[] getMacInBytes(String macAddress) {
85 String[] macAddressParts = macAddress.split(":");
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();
94 return macAddressBytes;
97 private static byte[] createEthernetPacket(byte[] sourceMAC, byte[] targetMAC, byte[] arp) {
98 Ethernet ethernet = new Ethernet();
99 byte[] rawEthPkt = null;
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) {
108 "VPNUtil: Serialized Ethernet packet with sourceMacAddress {} targetMacAddress {} exception ",
109 sourceMAC, targetMAC, ex);
114 private static byte[] createARPPacket(short opCode, byte[] senderMacAddress, byte[] senderIP,
115 byte[] targetMacAddress, byte[] targetIP) {
117 byte[] rawArpPkt = null;
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,