org.opendaylight.netvirt.ipv6service.Ipv6NeighborSolicitation Maven / Gradle / Ivy
/*
* Copyright (c) 2017 Red Hat, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.netvirt.ipv6service;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
import org.opendaylight.genius.mdsalutil.NwConstants;
import org.opendaylight.netvirt.ipv6service.utils.Ipv6Constants;
import org.opendaylight.netvirt.ipv6service.utils.Ipv6ServiceUtils;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.ipv6service.nd.packet.rev160620.EthernetHeader;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.ipv6service.nd.packet.rev160620.Ipv6Header;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.ipv6service.nd.packet.rev160620.NeighborSolicitationPacket;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.ipv6service.nd.packet.rev160620.NeighborSolicitationPacketBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInputBuilder;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Ipv6NeighborSolicitation {
private static final Logger LOG = LoggerFactory.getLogger(Ipv6RouterAdvt.class);
private static PacketProcessingService pktService;
private Ipv6ServiceUtils ipv6Utils;
public Ipv6NeighborSolicitation() {
ipv6Utils = Ipv6ServiceUtils.getInstance();
}
public static void setPacketProcessingService(PacketProcessingService packetService) {
pktService = packetService;
}
private byte[] frameNeighborSolicitationRequest(MacAddress srcMacAddress, Ipv6Address srcIpv6Address,
Ipv6Address targetIpv6Address) {
MacAddress macAddress = ipv6Utils.getIpv6MulticastMacAddress(targetIpv6Address);
Ipv6Address snMcastAddr = ipv6Utils.getIpv6SolicitedNodeMcastAddress(targetIpv6Address);
NeighborSolicitationPacketBuilder nsPacket = new NeighborSolicitationPacketBuilder();
nsPacket.setSourceMac(srcMacAddress);
nsPacket.setDestinationMac(macAddress);
nsPacket.setEthertype(NwConstants.ETHTYPE_IPV6);
nsPacket.setVersion(Ipv6Constants.IP_VERSION_6);
nsPacket.setFlowLabel((long) 0);
nsPacket.setIpv6Length(32);
nsPacket.setNextHeader(Ipv6Constants.ICMP_V6_TYPE);
nsPacket.setHopLimit(Ipv6Constants.ICMP_V6_MAX_HOP_LIMIT);
nsPacket.setSourceIpv6(srcIpv6Address);
nsPacket.setDestinationIpv6(snMcastAddr);
nsPacket.setIcmp6Type(Ipv6Constants.ICMP_V6_NS_CODE);
nsPacket.setIcmp6Code((short) 0);
nsPacket.setIcmp6Chksum(0);
nsPacket.setReserved((long) 0);
nsPacket.setTargetIpAddress(targetIpv6Address);
nsPacket.setOptionType(Ipv6Constants.ICMP_V6_OPTION_SOURCE_LLA);
nsPacket.setSourceAddrLength((short)1);
nsPacket.setSourceLlAddress(srcMacAddress);
return fillNeighborSolicitationPacket(nsPacket.build());
}
private byte[] icmp6NsPayloadtoByte(NeighborSolicitationPacket pdu) {
byte[] data = new byte[36];
Arrays.fill(data, (byte)0);
ByteBuffer buf = ByteBuffer.wrap(data);
buf.put((byte)pdu.getIcmp6Type().shortValue());
buf.put((byte)pdu.getIcmp6Code().shortValue());
buf.putShort((short)pdu.getIcmp6Chksum().intValue());
buf.putInt((int)pdu.getReserved().longValue());
try {
byte[] address = null;
address = InetAddress.getByName(pdu.getTargetIpAddress().getValue()).getAddress();
buf.put(address);
} catch (UnknownHostException e) {
LOG.error("Serializing NS target address failed", e);
}
buf.put((byte)pdu.getOptionType().shortValue());
buf.put((byte)pdu.getSourceAddrLength().shortValue());
buf.put(ipv6Utils.bytesFromHexString(pdu.getSourceLlAddress().getValue().toString()));
return data;
}
private byte[] fillNeighborSolicitationPacket(NeighborSolicitationPacket pdu) {
ByteBuffer buf = ByteBuffer.allocate(Ipv6Constants.ICMPV6_OFFSET + pdu.getIpv6Length());
buf.put(ipv6Utils.convertEthernetHeaderToByte((EthernetHeader)pdu), 0, 14);
buf.put(ipv6Utils.convertIpv6HeaderToByte((Ipv6Header)pdu), 0, 40);
buf.put(icmp6NsPayloadtoByte(pdu), 0, pdu.getIpv6Length());
int checksum = ipv6Utils.calcIcmpv6Checksum(buf.array(), (Ipv6Header)pdu);
buf.putShort((Ipv6Constants.ICMPV6_OFFSET + 2), (short)checksum);
return (buf.array());
}
public boolean transmitNeighborSolicitation(BigInteger dpnId, NodeConnectorRef nodeRef,
MacAddress srcMacAddress, Ipv6Address srcIpv6Address,
Ipv6Address targetIpv6Address) {
if (pktService == null) {
LOG.info("transmitNeighborSolicitation packet processing service is not yet configured");
return false;
}
byte[] txPayload = frameNeighborSolicitationRequest(srcMacAddress, srcIpv6Address, targetIpv6Address);
NodeConnectorRef nodeConnectorRef = MDSALUtil.getNodeConnRef(dpnId, "0xfffffffd");
TransmitPacketInput input = new TransmitPacketInputBuilder().setPayload(txPayload)
.setNode(new NodeRef(InstanceIdentifier.builder(Nodes.class)
.child(Node.class, new NodeKey(new NodeId("openflow:" + dpnId))).toInstance()))
.setEgress(nodeRef).setIngress(nodeConnectorRef).build();
// Tx the packet out of the controller.
if (pktService != null) {
LOG.debug("Transmitting the Neighbor Solicitation packet out on {}", dpnId);
pktService.transmitPacket(input);
}
return true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy