From ea4b6c2649478c1927547932ec7484c42494df24 Mon Sep 17 00:00:00 2001 From: Kalhee Kim Date: Thu, 9 Nov 2017 14:38:37 +0000 Subject: [PATCH] [CORD-2226] Dhcp6 Relay uses to store dhcp record for LeaseQuery Change-Id: Ib3baadb38e3f5f6ebe6efc884660fe0c77cfe689 --- .../dhcprelay/Dhcp6HandlerImpl.java | 306 ++++++++++++++---- .../dhcprelay/cli/DhcpRelayCommand.java | 39 ++- .../dhcprelay/store/DhcpRecord.java | 27 +- .../src/main/java/org/onlab/packet/DHCP6.java | 32 ++ 4 files changed, 330 insertions(+), 74 deletions(-) diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java index 17028d6c89..1472082644 100644 --- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java +++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java @@ -48,6 +48,8 @@ import org.onlab.packet.dhcp.Dhcp6IaTaOption; import org.onlab.packet.dhcp.Dhcp6IaPdOption; import org.onlab.packet.dhcp.Dhcp6IaAddressOption; import org.onlab.packet.dhcp.Dhcp6IaPrefixOption; +import org.onlab.packet.dhcp.Dhcp6ClientIdOption; +import org.onlab.packet.dhcp.Dhcp6Duid; import org.onlab.util.HexString; import org.onosproject.core.ApplicationId; import org.onosproject.core.CoreService; @@ -55,6 +57,7 @@ import org.onosproject.dhcprelay.api.DhcpHandler; import org.onosproject.dhcprelay.api.DhcpServerInfo; import org.onosproject.dhcprelay.config.IgnoreDhcpConfig; import org.onosproject.dhcprelay.store.DhcpRelayStore; +import org.onosproject.dhcprelay.store.DhcpRecord; import org.onosproject.dhcprelay.store.DhcpFpmPrefixStore; import org.onosproject.net.Device; import org.onosproject.net.DeviceId; @@ -613,6 +616,35 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider { return prefixPrefix; } + /** + * extract from dhcp6 packet ClientIdOption. + * + * @param directConnFlag directly connected host + * @param dhcp6Payload the dhcp6 payload + * @return Dhcp6ClientIdOption clientIdOption, or null if not exists. + */ + private Dhcp6ClientIdOption extractClinedId(Boolean directConnFlag, DHCP6 dhcp6Payload) { + Dhcp6ClientIdOption clientIdOption; + + if (directConnFlag) { + clientIdOption = dhcp6Payload.getOptions() + .stream() + .filter(opt -> opt instanceof Dhcp6ClientIdOption) + .map(opt -> (Dhcp6ClientIdOption) opt) + .findFirst() + .orElse(null); + } else { + DHCP6 leafDhcp = getDhcp6Leaf(dhcp6Payload); + clientIdOption = leafDhcp.getOptions() + .stream() + .filter(opt -> opt instanceof Dhcp6ClientIdOption) + .map(opt -> (Dhcp6ClientIdOption) opt) + .findFirst() + .orElse(null); + } + + return clientIdOption; + } /** * remove host or route. * @@ -622,55 +654,65 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider { * @param clientIpv6 client's Ipv6 packet * @param clientInterface client interfaces */ - private void removeHostOrRoute(boolean directConnFlag, DHCP6 dhcp6Packet, + private void removeHostOrRoute(boolean directConnFlag, ConnectPoint location, + DHCP6 dhcp6Packet, Ethernet clientPacket, IPv6 clientIpv6, Interface clientInterface) { log.debug("extractPrefix enters {}", dhcp6Packet); VlanId vlanId = clientInterface.vlan(); - MacAddress clientMac = clientPacket.getSourceMAC(); - log.debug("client mac {} client vlan {}", HexString.toHexString(clientMac.toBytes(), ":"), vlanId); + MacAddress gwMac = clientPacket.getSourceMAC(); // could be gw or host + MacAddress leafClientMac; + byte leafMsgType; + log.debug("client mac {} client vlan {}", HexString.toHexString(gwMac.toBytes(), ":"), vlanId); // add host or route - if (isDhcp6Release(dhcp6Packet)) { - IpAddress ip = null; - if (directConnFlag) { - // Add to host store if it is connected to network directly - ip = extractIpAddress(dhcp6Packet); - if (ip != null) { - - HostId hostId = HostId.hostId(clientMac, vlanId); + boolean isMsgRelease = isDhcp6Release(dhcp6Packet); + IpAddress ip; + IpPrefix ipPrefix = null; + if (directConnFlag) { + // Add to host store if it is connected to network directly + ip = extractIpAddress(dhcp6Packet); + if (ip != null) { + if (isMsgRelease) { + HostId hostId = HostId.hostId(gwMac, vlanId); log.debug("remove Host {} ip for directly connected.", hostId.toString()); // Remove host's ip of when dhcp release msg is received providerService.removeIpFromHost(hostId, ip); - } else { - log.debug("ipAddress not found. Do not add Host for directly connected."); } } else { - // Remove from route store if it is not connected to network directly - // pick out the first link-local ip address - IpAddress nextHopIp = getFirstIpByHost(clientMac, vlanId); - if (nextHopIp == null) { - log.warn("Can't find link-local IP address of gateway mac {} vlanId {}", - clientMac, vlanId); - return; - } + log.debug("ipAddress not found. Do not remove Host {} for directly connected.", + HostId.hostId(gwMac, vlanId).toString()); + } + leafMsgType = dhcp6Packet.getMsgType(); + } else { + // Remove from route store if it is not connected to network directly + // pick out the first link-local ip address + IpAddress nextHopIp = getFirstIpByHost(gwMac, vlanId); + if (nextHopIp == null) { + log.warn("Can't find link-local IP address of gateway mac {} vlanId {}", + gwMac, vlanId); + return; + } - DHCP6 leafDhcp = getDhcp6Leaf(dhcp6Packet); - ip = extractIpAddress(leafDhcp); - if (ip == null) { - log.debug("ip is null"); - } else { + DHCP6 leafDhcp = getDhcp6Leaf(dhcp6Packet); + ip = extractIpAddress(leafDhcp); + if (ip == null) { + log.debug("ip is null"); + } else { + if (isMsgRelease) { Route routeForIP = new Route(Route.Source.STATIC, ip.toIpPrefix(), nextHopIp); log.debug("removing route of 128 address for indirectly connected."); log.debug("128 ip {}, nexthop {}", HexString.toHexString(ip.toOctets(), ":"), HexString.toHexString(nextHopIp.toOctets(), ":")); routeStore.removeRoute(routeForIP); } + } - IpPrefix ipPrefix = extractPrefix(leafDhcp); - if (ipPrefix == null) { - log.debug("ipPrefix is null "); - } else { + ipPrefix = extractPrefix(leafDhcp); + if (ipPrefix == null) { + log.debug("ipPrefix is null "); + } else { + if (isMsgRelease) { Route routeForPrefix = new Route(Route.Source.STATIC, ipPrefix, nextHopIp); log.debug("removing route of PD for indirectly connected."); log.debug("pd ip {}, nexthop {}", HexString.toHexString(ipPrefix.address().toOctets(), ":"), @@ -682,38 +724,102 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider { } } } + leafMsgType = leafDhcp.getMsgType(); } + + Dhcp6ClientIdOption clientIdOption = extractClinedId(directConnFlag, dhcp6Packet); + if (clientIdOption != null) { + log.warn("CLIENTID option found {}", clientIdOption); + if ((clientIdOption.getDuid().getDuidType() == Dhcp6Duid.DuidType.DUID_LLT) || + (clientIdOption.getDuid().getDuidType() == Dhcp6Duid.DuidType.DUID_LL)) { + leafClientMac = MacAddress.valueOf(clientIdOption.getDuid().getLinkLayerAddress()); + } else { + log.warn("Link-Layer Address not supported in CLIENTID option. No DhcpRelay Record created."); + return; + } + + } else { + log.warn("CLIENTID option NOT found. No DhcpRelay Record created."); + return; + } + + HostId hostId = HostId.hostId(leafClientMac, vlanId); + DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null); + + if (leafMsgType == DHCP6.MsgType.RELEASE.value()) { + log.debug("DHCP6 RELEASE msg."); + if (record != null) { + if (ip != null) { + log.warn("DhcpRelay Record ip6Address is set to null."); + record.ip6Address(null); + } + if (ipPrefix != null) { + log.warn("DhcpRelay Record pdPrefix is set to null."); + record.pdPrefix(null); + } + log.debug("ip {} pd {}", record.ip6Address(), record.pdPrefix()); + + if (!record.ip6Address().isPresent() && !record.pdPrefix().isPresent()) { + log.warn("IP6 address and IP6 PD both are null. Remove record."); + dhcpRelayStore.removeDhcpRecord(HostId.hostId(leafClientMac, vlanId)); + } + } + return; + } + if (record == null) { + record = new DhcpRecord(HostId.hostId(leafClientMac, vlanId)); + } else { + record = record.clone(); + } + record.addLocation(new HostLocation(location, System.currentTimeMillis())); + record.ip6Status(DHCP6.MsgType.getType(dhcp6Packet.getMsgType())); + record.setDirectlyConnected(directConnFlag); + if (!directConnFlag) { + // Update gateway mac address if the host is not directly connected + record.nextHop(gwMac); + } + record.updateLastSeen(); + dhcpRelayStore.updateDhcpRecord(HostId.hostId(leafClientMac, vlanId), record); + + } /** * add host or route. * * @param directConnFlag flag to show that packet is from directly connected client + * @param location client side connect point * @param dhcp6Relay the dhcp6 payload - * @param embeddedDhcp6 client's ethernet packetthe dhcp6 payload within relay - * @param clientMac client macAddress + * @param embeddedDhcp6 the dhcp6 payload within relay + * @param gwMac client gw/host macAddress * @param clientInterface client interface */ - private void addHostOrRoute(boolean directConnFlag, DHCP6 dhcp6Relay, - DHCP6 embeddedDhcp6, - MacAddress clientMac, - Interface clientInterface) { + private void addHostOrRoute(boolean directConnFlag, + ConnectPoint location, + DHCP6 dhcp6Relay, + DHCP6 embeddedDhcp6, + MacAddress gwMac, + Interface clientInterface) { log.debug("addHostOrRoute entered."); VlanId vlanId = clientInterface.vlan(); + Boolean isMsgReply = isDhcp6Reply(dhcp6Relay); + MacAddress leafClientMac; + Byte leafMsgType; + // add host or route - if (isDhcp6Reply(dhcp6Relay)) { - IpAddress ip = null; - if (directConnFlag) { - // Add to host store if it connect to network directly - ip = extractIpAddress(embeddedDhcp6); - if (ip != null) { + IpAddress ip; + IpPrefix ipPrefix = null; + if (directConnFlag) { + // Add to host store if it connect to network directly + ip = extractIpAddress(embeddedDhcp6); + if (ip != null) { + if (isMsgReply) { Set ips = Sets.newHashSet(ip); - // FIXME: we should use vlan id from original packet (solicit, request) - HostId hostId = HostId.hostId(clientMac, vlanId); + HostId hostId = HostId.hostId(gwMac, vlanId); Host host = hostService.getHost(hostId); HostLocation hostLocation = new HostLocation(clientInterface.connectPoint(), - System.currentTimeMillis()); + System.currentTimeMillis()); Set hostLocations = Sets.newHashSet(hostLocation); if (host != null) { @@ -721,43 +827,49 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider { // if host exists, use old locations and new location hostLocations.addAll(host.locations()); } - HostDescription desc = new DefaultHostDescription(clientMac, vlanId, - hostLocations, ips, - false); + HostDescription desc = new DefaultHostDescription(gwMac, vlanId, + hostLocations, ips, + false); log.debug("adding Host for directly connected."); log.debug("client mac {} client vlan {} hostlocation {}", - HexString.toHexString(clientMac.toBytes(), ":"), + HexString.toHexString(gwMac.toBytes(), ":"), vlanId, hostLocation.toString()); // Replace the ip when dhcp server give the host new ip address providerService.hostDetected(hostId, desc, false); - } else { - log.debug("ipAddress not found. Do not add Host for directly connected."); } } else { - // Add to route store if it does not connect to network directly - // pick out the first link-local ip address - IpAddress nextHopIp = getFirstIpByHost(clientMac, vlanId); - if (nextHopIp == null) { - log.warn("Can't find link-local IP address of gateway mac {} vlanId {}", - clientMac, vlanId); - return; - } + log.warn("ipAddress not found. Do not add Host {} for directly connected.", + HostId.hostId(gwMac, vlanId).toString()); + } + leafMsgType = embeddedDhcp6.getMsgType(); + } else { + // Add to route store if it does not connect to network directly + // pick out the first link-local ip address + IpAddress nextHopIp = getFirstIpByHost(gwMac, vlanId); + if (nextHopIp == null) { + log.warn("Can't find link-local IP address of gateway mac {} vlanId {}", + gwMac, vlanId); + return; + } - DHCP6 leafDhcp = getDhcp6Leaf(embeddedDhcp6); - ip = extractIpAddress(leafDhcp); - if (ip == null) { + DHCP6 leafDhcp = getDhcp6Leaf(embeddedDhcp6); + ip = extractIpAddress(leafDhcp); + if (ip == null) { log.debug("ip is null"); - } else { + } else { + if (isMsgReply) { Route routeForIP = new Route(Route.Source.STATIC, ip.toIpPrefix(), nextHopIp); log.debug("adding Route of 128 address for indirectly connected."); routeStore.updateRoute(routeForIP); } + } - IpPrefix ipPrefix = extractPrefix(leafDhcp); - if (ipPrefix == null) { + ipPrefix = extractPrefix(leafDhcp); + if (ipPrefix == null) { log.debug("ipPrefix is null "); - } else { + } else { + if (isMsgReply) { Route routeForPrefix = new Route(Route.Source.STATIC, ipPrefix, nextHopIp); log.debug("adding Route of PD for indirectly connected."); routeStore.updateRoute(routeForPrefix); @@ -767,7 +879,60 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider { } } } + leafMsgType = leafDhcp.getMsgType(); } + + Dhcp6ClientIdOption clientIdOption = extractClinedId(directConnFlag, embeddedDhcp6); + if (clientIdOption != null) { + log.debug("CLIENTID option found {}", clientIdOption); + if ((clientIdOption.getDuid().getDuidType() == Dhcp6Duid.DuidType.DUID_LLT) || + (clientIdOption.getDuid().getDuidType() == Dhcp6Duid.DuidType.DUID_LL)) { + leafClientMac = MacAddress.valueOf(clientIdOption.getDuid().getLinkLayerAddress()); + } else { + log.warn("Link-Layer Address not supported in CLIENTID option. No DhcpRelay Record created."); + return; + } + + } else { + log.warn("CLIENTID option NOT found. No DhcpRelay Record created."); + return; + } + + if (leafMsgType == DHCP6.MsgType.RELEASE.value() || + (leafMsgType == DHCP6.MsgType.REPLY.value()) && ip == null) { + log.warn("DHCP6 RELEASE/REPLY(null ip) from Server. MsgType {}", DHCP6.MsgType.getType(leafMsgType)); + return; + } + + HostId hostId = HostId.hostId(leafClientMac, vlanId); + DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null); + if (record == null) { + record = new DhcpRecord(HostId.hostId(leafClientMac, vlanId)); + } else { + record = record.clone(); + } + record.addLocation(new HostLocation(location, System.currentTimeMillis())); + if (leafMsgType == DHCP6.MsgType.REPLY.value()) { + if (ip != null) { + log.debug("IP6 address is being stored into dhcp-relay store."); + log.debug("IP6 address {}", HexString.toHexString(ip.toOctets(), ":")); + record.ip6Address(ip.getIp6Address()); + } else { + log.debug("IP6 address is not returned from server. Maybe only PD is returned."); + } + if (ipPrefix != null) { + log.debug("IP6 PD address is being stored into dhcp-relay store."); + log.debug("IP6 PD address {}", HexString.toHexString(ipPrefix.address().toOctets(), ":")); + record.pdPrefix(ipPrefix); + } else { + log.debug("IP6 PD address is not returned from server. Maybe only IPAddress is returned."); + } + } + record.ip6Status(DHCP6.MsgType.getType(dhcp6Relay.getMsgType())); + record.setDirectlyConnected(directConnFlag); + record.updateLastSeen(); + dhcpRelayStore.updateDhcpRecord(HostId.hostId(leafClientMac, vlanId), record); + } /** @@ -878,7 +1043,8 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider { .stream().filter(iface -> interfaceContainsVlan(iface, vlanIdInUse)) .findFirst().orElse(null); - removeHostOrRoute(directConnFlag, dhcp6Packet, clientPacket, clientIpv6, clientInterface); + removeHostOrRoute(directConnFlag, clientConnectionPoint, dhcp6Packet, clientPacket, + clientIpv6, clientInterface); DHCP6 dhcp6Relay = new DHCP6(); dhcp6Relay.setMsgType(DHCP6.MsgType.RELAY_FORW.value()); @@ -905,6 +1071,8 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider { etherReply.setDestinationMACAddress(indirectDhcpConnectMac); etherReply.setVlanID(indirectDhcpConnectVlan.toShort()); ipv6Packet.setDestinationAddress(indirectDhcpServerIp.toOctets()); + + } if (indirectRelayAgentIpFromCfg == null) { dhcp6Relay.setLinkAddress(relayAgentIp.toOctets()); @@ -916,6 +1084,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider { HexString.toHexString(indirectRelayAgentIpFromCfg.toOctets(), ":")); } } + // peer address: address of the client or relay agent from which // the message to be relayed was received. dhcp6Relay.setPeerAddress(peerAddress); @@ -1111,7 +1280,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider { // add host or route - addHostOrRoute(directConnFlag, dhcp6Relay, embeddedDhcp6, clientMac, clientInterface); + addHostOrRoute(directConnFlag, clientConnectionPoint, dhcp6Relay, embeddedDhcp6, clientMac, clientInterface); udpPacket.setPayload(embeddedDhcp6); udpPacket.resetChecksum(); @@ -1581,4 +1750,5 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider { .orElse(null); return nextHopIp; } + } diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayCommand.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayCommand.java index bd41ecf039..e872971020 100644 --- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayCommand.java +++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayCommand.java @@ -49,6 +49,8 @@ public class DhcpRelayCommand extends AbstractShellCommand { private static final String NA = "N/A"; private static final String STATUS_FMT = "[%s, %s]"; private static final String STATUS_FMT_NH = "[%s via %s, %s]"; + private static final String STATUS_FMT_V6 = "[%s, %s, %s]"; + private static final String STATUS_FMT_V6_NH = "[%s, %s via %s, %s]"; private static final String DEFAULT_SERVERS = "Default DHCP servers:"; private static final String INDIRECT_SERVERS = "Indirect DHCP servers:"; @@ -135,13 +137,22 @@ public class DhcpRelayCommand extends AbstractShellCommand { } private String ip6State(DhcpRecord record) { - String nextHopIp = findNextHopIp(IpAddress::isIp6, + String nextHopIp = findNextHopIp6(IpAddress::isIp6, record.nextHop().orElse(null), record.vlanId()); - return ipState(record.ip6Address().map(Object::toString).orElse(NA), - record.ip6Status().map(Object::toString).orElse(NA), - record.directlyConnected(), - nextHopIp); + + if (record.directlyConnected()) { + return String.format(STATUS_FMT_V6, + record.ip6Address().map(Object::toString).orElse(NA), + record.pdPrefix().map(Object::toString).orElse(NA), + record.ip6Status().map(Object::toString).orElse(NA)); + } else { + return String.format(STATUS_FMT_V6_NH, + record.ip6Address().map(Object::toString).orElse(NA), + record.pdPrefix().map(Object::toString).orElse(NA), + nextHopIp, + record.ip6Status().map(Object::toString).orElse(NA)); + } } private String ipState(String ipAddress, String status, @@ -158,6 +169,7 @@ public class DhcpRelayCommand extends AbstractShellCommand { if (ipFilter == null || nextHopMac == null || vlanId == null) { return NA; } + Host host = HOST_SERVICE.getHost(HostId.hostId(nextHopMac, vlanId)); if (host == null) { return NA; @@ -169,4 +181,21 @@ public class DhcpRelayCommand extends AbstractShellCommand { .findFirst() .orElse(NA); } + + private String findNextHopIp6(Predicate ipFilter, MacAddress nextHopMac, VlanId vlanId) { + if (ipFilter == null || nextHopMac == null || vlanId == null) { + return NA; + } + + Host host = HOST_SERVICE.getHost(HostId.hostId(nextHopMac, vlanId)); + if (host == null) { + return NA; + } + return host.ipAddresses().stream() + .filter(ipFilter) + .filter(ip -> ip.isLinkLocal()) + .map(Object::toString) + .findFirst() + .orElse(NA); + } } diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/store/DhcpRecord.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/store/DhcpRecord.java index e133f031f0..6f620db4c4 100644 --- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/store/DhcpRecord.java +++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/store/DhcpRecord.java @@ -22,6 +22,7 @@ import org.onlab.packet.DHCP; import org.onlab.packet.DHCP6; import org.onlab.packet.Ip4Address; import org.onlab.packet.Ip6Address; +import org.onlab.packet.IpPrefix; import org.onlab.packet.MacAddress; import org.onlab.packet.VlanId; import org.onosproject.net.HostId; @@ -49,6 +50,7 @@ public class DhcpRecord { private DHCP.MsgType ip4Status; private Ip6Address ip6Address; + private IpPrefix pdPrefix; private DHCP6.MsgType ip6Status; private long lastSeen; @@ -158,6 +160,26 @@ public class DhcpRecord { return this; } + /** + * Gets IPv6 PD address which assigned to the host. + * + * @return the PD IP address assigned to the host + */ + public Optional pdPrefix() { + return Optional.ofNullable(pdPrefix); + } + + /** + * Sets IPv6 PD address. + * + * @param pdPrefix the IPv6 PD address + * @return the DHCP record + */ + public DhcpRecord pdPrefix(IpPrefix pdPrefix) { + this.pdPrefix = pdPrefix; + return this; + } + /** * Gets the latest time this record updated. * @@ -292,6 +314,7 @@ public class DhcpRecord { newRecord.ip4Address = ip4Address; newRecord.ip4Status = ip4Status; newRecord.ip6Address = ip6Address; + newRecord.pdPrefix = pdPrefix; newRecord.ip6Status = ip6Status; newRecord.lastSeen = lastSeen; return newRecord; @@ -300,7 +323,7 @@ public class DhcpRecord { @Override public int hashCode() { return Objects.hash(locations, macAddress, vlanId, ip4Address, ip4Status, - nextHop, nextHopTemp, ip6Address, ip6Status, lastSeen); + nextHop, nextHopTemp, ip6Address, pdPrefix, ip6Status, lastSeen); } @Override @@ -320,6 +343,7 @@ public class DhcpRecord { Objects.equals(nextHop, that.nextHop) && Objects.equals(nextHopTemp, that.nextHopTemp) && Objects.equals(ip6Address, that.ip6Address) && + Objects.equals(pdPrefix, that.pdPrefix) && Objects.equals(ip6Status, that.ip6Status) && Objects.equals(lastSeen, that.lastSeen) && Objects.equals(directlyConnected, that.directlyConnected); @@ -336,6 +360,7 @@ public class DhcpRecord { .add("nextHop", nextHop) .add("nextHopTemp", nextHopTemp) .add("ip6Address", ip6Address) + .add("pdPrefix", pdPrefix) .add("ip6State", ip6Status) .add("lastSeen", lastSeen) .add("directlyConnected", directlyConnected) diff --git a/utils/misc/src/main/java/org/onlab/packet/DHCP6.java b/utils/misc/src/main/java/org/onlab/packet/DHCP6.java index 054552cc95..25ef6a3b77 100644 --- a/utils/misc/src/main/java/org/onlab/packet/DHCP6.java +++ b/utils/misc/src/main/java/org/onlab/packet/DHCP6.java @@ -79,6 +79,38 @@ public class DHCP6 extends BasePacket { public byte value() { return this.value; } + public static MsgType getType(final int value) { + switch (value) { + case 1: + return SOLICIT; + case 2: + return ADVERTISE; + case 3: + return REQUEST; + case 4: + return CONFIRM; + case 5: + return RENEW; + case 6: + return REBIND; + case 7: + return REPLY; + case 8: + return RELEASE; + case 9: + return DECLINE; + case 10: + return RECONFIGURE; + case 11: + return INFORMATION_REQUEST; + case 12: + return RELAY_FORW; + case 13: + return RELAY_REPL; + default: + return null; + } + } } /**