X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=ipv6service%2Fimpl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetvirt%2Fipv6service%2Futils%2FIpv6ServiceUtils.java;h=5bbb0933c82e3b0a02834eb8085bef6f03b92060;hb=ea90bfccf358806939d8a1a6c745c3488cc97730;hp=370400440d2b3af3f98cf264e53c1759ff0f13a0;hpb=29d762853ff59b6e14d593d3f1501c85e8c582e8;p=netvirt.git diff --git a/ipv6service/impl/src/main/java/org/opendaylight/netvirt/ipv6service/utils/Ipv6ServiceUtils.java b/ipv6service/impl/src/main/java/org/opendaylight/netvirt/ipv6service/utils/Ipv6ServiceUtils.java index 370400440d..5bbb0933c8 100644 --- a/ipv6service/impl/src/main/java/org/opendaylight/netvirt/ipv6service/utils/Ipv6ServiceUtils.java +++ b/ipv6service/impl/src/main/java/org/opendaylight/netvirt/ipv6service/utils/Ipv6ServiceUtils.java @@ -9,13 +9,10 @@ package org.opendaylight.netvirt.ipv6service.utils; import com.google.common.base.Optional; -import com.google.common.net.InetAddresses; import java.math.BigInteger; import java.net.InetAddress; import java.net.UnknownHostException; -import java.nio.ByteBuffer; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.concurrent.ExecutionException; import javax.inject.Inject; @@ -24,6 +21,8 @@ import org.apache.commons.lang3.StringUtils; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.genius.ipv6util.api.Icmpv6Type; +import org.opendaylight.genius.ipv6util.api.Ipv6Constants; import org.opendaylight.genius.mdsalutil.ActionInfo; import org.opendaylight.genius.mdsalutil.FlowEntity; import org.opendaylight.genius.mdsalutil.InstructionInfo; @@ -49,7 +48,6 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces. import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -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.flow.types.rev131026.instruction.list.Instruction; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceBindings; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeIngress; @@ -62,8 +60,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.ser import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServicesKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; -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.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; @@ -72,7 +68,7 @@ import org.slf4j.LoggerFactory; @Singleton public class Ipv6ServiceUtils { private static final Logger LOG = LoggerFactory.getLogger(Ipv6ServiceUtils.class); - public static final Ipv6Address ALL_NODES_MCAST_ADDR = newIpv6Address("FF02::1"); + public static final Ipv6Address ALL_NODES_MCAST_ADDR = newIpv6Address(Ipv6Constants.ALL_NODES_MCAST_ADDRESS); public static final Ipv6Address UNSPECIFIED_ADDR = newIpv6Address("0:0:0:0:0:0:0:0"); private static Ipv6Address newIpv6Address(String ip) { @@ -164,222 +160,11 @@ public class Ipv6ServiceUtils { return MDSALUtil.read(LogicalDatastoreType.OPERATIONAL, ifStateId, broker).orNull(); } - public static String bytesToHexString(byte[] bytes) { - if (bytes == null) { - return "null"; - } - StringBuilder buf = new StringBuilder(); - for (int i = 0; i < bytes.length; i++) { - if (i > 0) { - buf.append(":"); - } - short u8byte = (short) (bytes[i] & 0xff); - String tmp = Integer.toHexString(u8byte); - if (tmp.length() == 1) { - buf.append("0"); - } - buf.append(tmp); - } - return buf.toString(); - } - - public static byte[] bytesFromHexString(String values) { - String target = ""; - if (values != null) { - target = values; - } - String[] octets = target.split(":"); - - byte[] ret = new byte[octets.length]; - for (int i = 0; i < octets.length; i++) { - ret[i] = Integer.valueOf(octets[i], 16).byteValue(); - } - return ret; - } - - public static int calcIcmpv6Checksum(byte[] packet, Ipv6Header ip6Hdr) { - long checksum = getSummation(ip6Hdr.getSourceIpv6()); - checksum += getSummation(ip6Hdr.getDestinationIpv6()); - checksum = normalizeChecksum(checksum); - - checksum += ip6Hdr.getIpv6Length(); - checksum += ip6Hdr.getNextHeader(); - - int icmp6Offset = Ipv6Constants.ICMPV6_OFFSET; - long value = (packet[icmp6Offset] & 0xff) << 8 | packet[icmp6Offset + 1] & 0xff; - checksum += value; - checksum = normalizeChecksum(checksum); - icmp6Offset += 2; - - //move to icmp6 payload skipping the checksum field - icmp6Offset += 2; - int length = packet.length - icmp6Offset; - while (length > 1) { - value = (packet[icmp6Offset] & 0xff) << 8 | packet[icmp6Offset + 1] & 0xff; - checksum += value; - checksum = normalizeChecksum(checksum); - icmp6Offset += 2; - length -= 2; - } - - if (length > 0) { - checksum += packet[icmp6Offset]; - checksum = normalizeChecksum(checksum); - } - - int finalChecksum = (int)(~checksum & 0xffff); - return finalChecksum; - } - - public static boolean validateChecksum(byte[] packet, Ipv6Header ip6Hdr, int recvChecksum) { - return calcIcmpv6Checksum(packet, ip6Hdr) == recvChecksum; - } - - private static long getSummation(Ipv6Address addr) { - byte[] baddr = null; - try { - baddr = InetAddress.getByName(addr.getValue()).getAddress(); - } catch (UnknownHostException e) { - LOG.error("getSummation: Failed to deserialize address {}", addr.getValue(), e); - return 0; - } - - long sum = 0; - int len = 0; - long value = 0; - while (len < baddr.length) { - value = (baddr[len] & 0xff) << 8 | baddr[len + 1] & 0xff; - sum += value; - sum = normalizeChecksum(sum); - len += 2; - } - return sum; - } - - private static long normalizeChecksum(long value) { - if ((value & 0xffff0000) != 0) { - value = value & 0xffff; - value += 1; - } - return value; - } - - public static byte[] convertEthernetHeaderToByte(EthernetHeader ethPdu) { - byte[] data = new byte[16]; - Arrays.fill(data, (byte)0); - - ByteBuffer buf = ByteBuffer.wrap(data); - buf.put(bytesFromHexString(ethPdu.getDestinationMac().getValue())); - buf.put(bytesFromHexString(ethPdu.getSourceMac().getValue())); - buf.putShort((short)ethPdu.getEthertype().intValue()); - return data; - } - - public static byte[] convertIpv6HeaderToByte(Ipv6Header ip6Pdu) { - byte[] data = new byte[128]; - Arrays.fill(data, (byte)0); - - ByteBuffer buf = ByteBuffer.wrap(data); - long flowLabel = (long)(ip6Pdu.getVersion() & 0x0f) << 28 - | ip6Pdu.getFlowLabel() & 0x0fffffff; - buf.putInt((int)flowLabel); - buf.putShort((short)ip6Pdu.getIpv6Length().intValue()); - buf.put((byte)ip6Pdu.getNextHeader().shortValue()); - buf.put((byte)ip6Pdu.getHopLimit().shortValue()); - try { - byte[] baddr = InetAddress.getByName(ip6Pdu.getSourceIpv6().getValue()).getAddress(); - buf.put(baddr); - baddr = InetAddress.getByName(ip6Pdu.getDestinationIpv6().getValue()).getAddress(); - buf.put(baddr); - } catch (UnknownHostException e) { - LOG.error("convertIpv6HeaderToByte: Failed to serialize src, dest address", e); - } - return data; - } - - public static Ipv6Address getIpv6LinkLocalAddressFromMac(MacAddress mac) { - byte[] octets = bytesFromHexString(mac.getValue()); - - /* As per the RFC2373, steps involved to generate a LLA include - 1. Convert the 48 bit MAC address to 64 bit value by inserting 0xFFFE - between OUI and NIC Specific part. - 2. Invert the Universal/Local flag in the OUI portion of the address. - 3. Use the prefix "FE80::/10" along with the above 64 bit Interface - identifier to generate the IPv6 LLA. */ - - StringBuilder interfaceID = new StringBuilder(); - short u8byte = (short) (octets[0] & 0xff); - u8byte ^= 1 << 1; - interfaceID.append(Integer.toHexString(0xFF & u8byte)); - interfaceID.append(StringUtils.leftPad(Integer.toHexString(0xFF & octets[1]), 2, "0")); - interfaceID.append(":"); - interfaceID.append(Integer.toHexString(0xFF & octets[2])); - interfaceID.append("ff:fe"); - interfaceID.append(StringUtils.leftPad(Integer.toHexString(0xFF & octets[3]), 2, "0")); - interfaceID.append(":"); - interfaceID.append(Integer.toHexString(0xFF & octets[4])); - interfaceID.append(StringUtils.leftPad(Integer.toHexString(0xFF & octets[5]), 2, "0")); - - // Return the address in its fully expanded format. - Ipv6Address ipv6LLA = new Ipv6Address(InetAddresses.forString( - "fe80:0:0:0:" + interfaceID.toString()).getHostAddress()); - return ipv6LLA; - } - - public static Ipv6Address getIpv6SolicitedNodeMcastAddress(Ipv6Address ipv6Address) { - - /* According to RFC 4291, a Solicited Node Multicast Address is derived by adding the 24 - lower order bits with the Solicited Node multicast prefix (i.e., FF02::1:FF00:0/104). - Example: For IPv6Address of FE80::2AA:FF:FE28:9C5A, the corresponding solicited node - multicast address would be FF02::1:FF28:9C5A - */ - - byte[] octets; - try { - octets = InetAddress.getByName(ipv6Address.getValue()).getAddress(); - } catch (UnknownHostException e) { - LOG.error("getIpv6SolicitedNodeMcastAddress: Failed to serialize ipv6Address ", e); - return null; - } - - // Return the address in its fully expanded format. - Ipv6Address solictedV6Address = new Ipv6Address(InetAddresses.forString("ff02::1:ff" - + StringUtils.leftPad(Integer.toHexString(0xFF & octets[13]), 2, "0") + ":" - + StringUtils.leftPad(Integer.toHexString(0xFF & octets[14]), 2, "0") - + StringUtils.leftPad(Integer.toHexString(0xFF & octets[15]), 2, "0")).getHostAddress()); - - return solictedV6Address; - } - - public static MacAddress getIpv6MulticastMacAddress(Ipv6Address ipv6Address) { - - /* According to RFC 2464, a Multicast MAC address is derived by concatenating 32 lower - order bits of IPv6 Multicast Address with the multicast prefix (i.e., 33:33). - Example: For Multicast IPv6Address of FF02::1:FF28:9C5A, the corresponding L2 multicast - address would be 33:33:28:9C:5A - */ - byte[] octets; - try { - octets = InetAddress.getByName(ipv6Address.getValue()).getAddress(); - } catch (UnknownHostException e) { - LOG.error("getIpv6MulticastMacAddress: Failed to serialize ipv6Address ", e); - return null; - } - - String macAddress = "33:33:" - + StringUtils.leftPad(Integer.toHexString(0xFF & octets[12]), 2, "0") + ":" - + StringUtils.leftPad(Integer.toHexString(0xFF & octets[13]), 2, "0") + ":" - + StringUtils.leftPad(Integer.toHexString(0xFF & octets[14]), 2, "0") + ":" - + StringUtils.leftPad(Integer.toHexString(0xFF & octets[15]), 2, "0"); - - return new MacAddress(macAddress); - } - private static List getIcmpv6RSMatch(Long elanTag) { List matches = new ArrayList<>(); matches.add(MatchEthernetType.IPV6); matches.add(MatchIpProtocol.ICMPV6); - matches.add(new MatchIcmpv6(Ipv6Constants.ICMP_V6_RS_CODE, (short) 0)); + matches.add(new MatchIcmpv6(Icmpv6Type.ROUTER_SOLICITATION.getValue(), (short) 0)); matches.add(new MatchMetadata(MetaDataUtil.getElanTagMetadata(elanTag), MetaDataUtil.METADATA_MASK_SERVICE)); return matches; } @@ -388,7 +173,7 @@ public class Ipv6ServiceUtils { List matches = new ArrayList<>(); matches.add(MatchEthernetType.IPV6); matches.add(MatchIpProtocol.ICMPV6); - matches.add(new MatchIcmpv6(Ipv6Constants.ICMP_V6_NS_CODE, (short) 0)); + matches.add(new MatchIcmpv6(Icmpv6Type.NEIGHBOR_SOLICITATION.getValue(), (short) 0)); matches.add(new MatchIpv6NdTarget(new Ipv6Address(ndTarget))); matches.add(new MatchMetadata(MetaDataUtil.getElanTagMetadata(elanTag), MetaDataUtil.METADATA_MASK_SERVICE)); return matches; @@ -398,15 +183,15 @@ public class Ipv6ServiceUtils { List matches = new ArrayList<>(); matches.add(MatchEthernetType.IPV6); matches.add(MatchIpProtocol.ICMPV6); - matches.add(new MatchIcmpv6(Ipv6Constants.ICMP_V6_NA_CODE, (short) 0)); + matches.add(new MatchIcmpv6(Icmpv6Type.NEIGHBOR_ADVERTISEMENT.getValue(), (short) 0)); matches.add(new MatchMetadata(MetaDataUtil.getElanTagMetadata(elanTag), MetaDataUtil.METADATA_MASK_SERVICE)); return matches; } private static String getIPv6FlowRef(BigInteger dpId, Long elanTag, String flowType) { - return new StringBuffer().append(Ipv6Constants.FLOWID_PREFIX) - .append(dpId).append(Ipv6Constants.FLOWID_SEPARATOR) - .append(elanTag).append(Ipv6Constants.FLOWID_SEPARATOR) + return new StringBuffer().append(Ipv6ServiceConstants.FLOWID_PREFIX) + .append(dpId).append(Ipv6ServiceConstants.FLOWID_SEPARATOR) + .append(elanTag).append(Ipv6ServiceConstants.FLOWID_SEPARATOR) .append(flowType).toString(); } @@ -438,10 +223,10 @@ public class Ipv6ServiceUtils { instructions.add(new InstructionApplyActions(actionsInfos)); String formattedIp = getFormattedIpv6Address(ipv6Address); - FlowEntity rsFlowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, - getIPv6FlowRef(dpId, elanTag, formattedIp),Ipv6Constants.DEFAULT_FLOW_PRIORITY, "IPv6NS", - 0, 0, NwConstants.COOKIE_IPV6_TABLE, neighborSolicitationMatch, instructions); - if (addOrRemove == Ipv6Constants.DEL_FLOW) { + FlowEntity rsFlowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, getIPv6FlowRef(dpId, elanTag, formattedIp), + Ipv6ServiceConstants.DEFAULT_FLOW_PRIORITY, "IPv6NS", 0, 0, NwConstants.COOKIE_IPV6_TABLE, + neighborSolicitationMatch, instructions); + if (addOrRemove == Ipv6ServiceConstants.DEL_FLOW) { LOG.trace("Removing IPv6 Neighbor Solicitation Flow DpId {}, elanTag {}", dpId, elanTag); mdsalUtil.removeFlow(rsFlowEntity); } else { @@ -451,7 +236,7 @@ public class Ipv6ServiceUtils { } public void installIcmpv6RsPuntFlow(short tableId, BigInteger dpId, Long elanTag, int addOrRemove) { - if (dpId == null || dpId.equals(Ipv6Constants.INVALID_DPID)) { + if (dpId == null || dpId.equals(Ipv6ServiceConstants.INVALID_DPID)) { return; } List routerSolicitationMatch = getIcmpv6RSMatch(elanTag); @@ -461,9 +246,9 @@ public class Ipv6ServiceUtils { actionsInfos.add(new ActionPuntToController()); instructions.add(new InstructionApplyActions(actionsInfos)); FlowEntity rsFlowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, - getIPv6FlowRef(dpId, elanTag, "IPv6RS"),Ipv6Constants.DEFAULT_FLOW_PRIORITY, "IPv6RS", 0, 0, + getIPv6FlowRef(dpId, elanTag, "IPv6RS"),Ipv6ServiceConstants.DEFAULT_FLOW_PRIORITY, "IPv6RS", 0, 0, NwConstants.COOKIE_IPV6_TABLE, routerSolicitationMatch, instructions); - if (addOrRemove == Ipv6Constants.DEL_FLOW) { + if (addOrRemove == Ipv6ServiceConstants.DEL_FLOW) { LOG.trace("Removing IPv6 Router Solicitation Flow DpId {}, elanTag {}", dpId, elanTag); mdsalUtil.removeFlow(rsFlowEntity); } else { @@ -483,11 +268,11 @@ public class Ipv6ServiceUtils { for (Ipv6Address ipv6Address : vmPort.getIpv6Addresses()) { matches.add(new MatchIpv6Source(ipv6Address.getValue() + NwConstants.IPV6PREFIX)); String flowId = getIPv6FlowRef(dpId, elanTag, - vmPort.getIntfUUID().getValue() + Ipv6Constants.FLOWID_SEPARATOR + ipv6Address.getValue()); + vmPort.getIntfUUID().getValue() + Ipv6ServiceConstants.FLOWID_SEPARATOR + ipv6Address.getValue()); FlowEntity rsFlowEntity = - MDSALUtil.buildFlowEntity(dpId, tableId, flowId, Ipv6Constants.DEFAULT_FLOW_PRIORITY, "IPv6NA", 0, - 0, NwConstants.COOKIE_IPV6_TABLE, matches, instructions); - if (addOrRemove == Ipv6Constants.DEL_FLOW) { + MDSALUtil.buildFlowEntity(dpId, tableId, flowId, Ipv6ServiceConstants.DEFAULT_FLOW_PRIORITY, + "IPv6NA", 0, 0, NwConstants.COOKIE_IPV6_TABLE, matches, instructions); + if (addOrRemove == Ipv6ServiceConstants.DEL_FLOW) { LOG.trace("Removing IPv6 Neighbor Advertisement Flow DpId {}, elanTag {}, ipv6Address {}", dpId, elanTag, ipv6Address.getValue()); mdsalUtil.removeFlow(rsFlowEntity); @@ -512,9 +297,9 @@ public class Ipv6ServiceUtils { String flowId = getIPv6FlowRef(dpId, elanTag, "IPv6NA." + ipv6Prefix.getValue()); FlowEntity rsFlowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, - flowId, Ipv6Constants.PUNT_NA_FLOW_PRIORITY, + flowId, Ipv6ServiceConstants.PUNT_NA_FLOW_PRIORITY, "IPv6NA", 0, 0, NwConstants.COOKIE_IPV6_TABLE, naMatch, instructions); - if (addOrRemove == Ipv6Constants.DEL_FLOW) { + if (addOrRemove == Ipv6ServiceConstants.DEL_FLOW) { LOG.trace("Removing IPv6 Neighbor Advertisement Flow DpId {}, elanTag {}", dpId, elanTag); mdsalUtil.removeFlow(rsFlowEntity); } else { @@ -550,7 +335,7 @@ public class Ipv6ServiceUtils { BoundServices serviceInfo = getBoundServices(String.format("%s.%s", "ipv6", interfaceName), - serviceIndex, Ipv6Constants.DEFAULT_FLOW_PRIORITY, + serviceIndex, Ipv6ServiceConstants.DEFAULT_FLOW_PRIORITY, NwConstants.COOKIE_IPV6_TABLE, instructions); MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, buildServiceId(interfaceName, serviceIndex), serviceInfo); @@ -574,13 +359,13 @@ public class Ipv6ServiceUtils { } public static long getRemoteBCGroup(long elanTag) { - return Ipv6Constants.ELAN_GID_MIN + elanTag % Ipv6Constants.ELAN_GID_MIN * 2; + return Ipv6ServiceConstants.ELAN_GID_MIN + elanTag % Ipv6ServiceConstants.ELAN_GID_MIN * 2; } public static boolean isVmPort(String deviceOwner) { // FIXME: Currently for VM ports, Neutron is sending deviceOwner as empty instead of "compute:nova". - // return Ipv6Constants.DEVICE_OWNER_COMPUTE_NOVA.equalsIgnoreCase(deviceOwner); - return Ipv6Constants.DEVICE_OWNER_COMPUTE_NOVA.equalsIgnoreCase(deviceOwner) + // return Ipv6ServiceConstants.DEVICE_OWNER_COMPUTE_NOVA.equalsIgnoreCase(deviceOwner); + return Ipv6ServiceConstants.DEVICE_OWNER_COMPUTE_NOVA.equalsIgnoreCase(deviceOwner) || StringUtils.isEmpty(deviceOwner); } }