use of org.onlab.packet.dhcp.Dhcp6ClientIdOption in project onos by opennetworkinglab.
the class Dhcp6HandlerImpl method removeHostOrRoute.
/**
* remove host or route and update dhcp relay record attributes.
*
* @param directConnFlag flag to show that packet is from directly connected client
* @param location client side connect point
* @param dhcp6Packet the dhcp6 payload
* @param clientPacket client's ethernet packet
* @param clientIpv6 client's Ipv6 packet
* @param clientInterface client interfaces
*/
private void removeHostOrRoute(boolean directConnFlag, ConnectPoint location, DHCP6 dhcp6Packet, Ethernet clientPacket, IPv6 clientIpv6, Interface clientInterface) {
log.debug("removeHostOrRoute enters {}", dhcp6Packet);
VlanId vlanId = clientInterface.vlan();
// could be gw or host
MacAddress srcMac = clientPacket.getSourceMAC();
MacAddress leafClientMac;
byte leafMsgType;
log.debug("client mac {} client vlan {}", HexString.toHexString(srcMac.toBytes(), ":"), vlanId);
Dhcp6ClientIdOption clientIdOption = Dhcp6HandlerUtil.extractClientId(directConnFlag, dhcp6Packet);
if (clientIdOption != null) {
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.");
// dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_LINKLOCAL_FAIL);
return;
}
} else {
log.warn("CLIENTID option NOT found. Don't create DhcpRelay Record.");
// dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_CLIENTID_FAIL);
return;
}
HostId leafHostId = HostId.hostId(leafClientMac, vlanId);
DhcpRecord record = dhcpRelayStore.getDhcpRecord(leafHostId).orElse(null);
if (record == null) {
record = new DhcpRecord(leafHostId);
} else {
record = record.clone();
}
Boolean isMsgRelease = Dhcp6HandlerUtil.isDhcp6Release(dhcp6Packet);
IpAddressInfo ipInfo;
PdPrefixInfo pdInfo = null;
if (directConnFlag) {
// Add to host store if it is connected to network directly
ipInfo = extractIpAddress(dhcp6Packet);
if (ipInfo != null) {
if (isMsgRelease) {
HostId hostId = HostId.hostId(srcMac, vlanId);
log.debug("remove Host {} ip for directly connected.", hostId.toString());
providerService.removeIpFromHost(hostId, ipInfo.ip6Address);
}
} else {
log.debug("ipAddress not found. Do not remove Host {} for directly connected.", HostId.hostId(srcMac, 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(directConnFlag, srcMac, vlanId);
if (nextHopIp == null) {
log.warn("Can't find link-local IP address of gateway mac {} vlanId {}", srcMac, vlanId);
// dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_LINKLOCAL_GW);
return;
}
DHCP6 leafDhcp = Dhcp6HandlerUtil.getDhcp6Leaf(dhcp6Packet);
ipInfo = extractIpAddress(leafDhcp);
if (ipInfo == null) {
log.debug("ip is null");
} else {
if (isMsgRelease) {
Route routeForIP = new Route(Route.Source.DHCP, ipInfo.ip6Address.toIpPrefix(), nextHopIp);
log.debug("removing route of 128 address for indirectly connected.");
log.debug("128 ip {}, nexthop {}", HexString.toHexString(ipInfo.ip6Address.toOctets(), ":"), HexString.toHexString(nextHopIp.toOctets(), ":"));
routeStore.removeRoute(routeForIP);
}
}
pdInfo = extractPrefix(leafDhcp);
if (pdInfo == null) {
log.debug("ipPrefix is null ");
} else {
if (isMsgRelease) {
Route routeForPrefix = new Route(Route.Source.DHCP, pdInfo.pdPrefix, nextHopIp);
log.debug("removing route of PD for indirectly connected.");
log.debug("pd ip {}, nexthop {}", HexString.toHexString(pdInfo.pdPrefix.address().toOctets(), ":"), HexString.toHexString(nextHopIp.toOctets(), ":"));
routeStore.removeRoute(routeForPrefix);
if (this.dhcpFpmEnabled) {
dhcpFpmPrefixStore.removeFpmRecord(pdInfo.pdPrefix);
}
}
}
leafMsgType = leafDhcp.getMsgType();
}
if (isMsgRelease) {
log.debug("DHCP6 RELEASE msg.");
if (record != null) {
if (ipInfo != null) {
log.debug("DhcpRelay Record ip6Address is set to null.");
record.ip6Address(null);
}
if (pdInfo != null) {
log.debug("DhcpRelay Record pdPrefix is set to null.");
}
if (!record.ip6Address().isPresent() && !record.pdPrefix().isPresent()) {
log.warn("IP6 address and IP6 PD both are null. Remove record.");
// do not remove a record. Let timer task handler it.
// dhcpRelayStore.removeDhcpRecord(HostId.hostId(leafClientMac, vlanId));
}
}
}
if (record != null) {
record.getV6Counters().incrementCounter(Dhcp6HandlerUtil.getMsgTypeStr(leafMsgType));
record.addLocation(new HostLocation(location, System.currentTimeMillis()));
record.ip6Status(DHCP6.MsgType.getType(leafMsgType));
record.setDirectlyConnected(directConnFlag);
if (!directConnFlag) {
// Update gateway mac address if the host is not directly connected
record.nextHop(srcMac);
}
record.updateLastSeen();
}
dhcpRelayStore.updateDhcpRecord(leafHostId, record);
/*
// TODO Use AtomicInteger for the counters
try {
recordSemaphore.acquire();
try {
dhcpRelayCountersStore.incrementCounter(gCount, Dhcp6HandlerUtil.getMsgTypeStr(leafMsgType));
} finally {
// calling release() after a successful acquire()
recordSemaphore.release();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
*/
}
use of org.onlab.packet.dhcp.Dhcp6ClientIdOption in project onos by opennetworkinglab.
the class Dhcp6HandlerUtil method extractClientId.
/**
* extract from dhcp6 packet ClientIdOption.
*
* @param directConnFlag directly connected host
* @param dhcp6Payload the dhcp6 payload
* @return Dhcp6ClientIdOption clientIdOption, or null if not exists.
*/
static Dhcp6ClientIdOption extractClientId(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 = Dhcp6HandlerUtil.getDhcp6Leaf(dhcp6Payload);
clientIdOption = leafDhcp.getOptions().stream().filter(opt -> opt instanceof Dhcp6ClientIdOption).map(opt -> (Dhcp6ClientIdOption) opt).findFirst().orElse(null);
}
return clientIdOption;
}
use of org.onlab.packet.dhcp.Dhcp6ClientIdOption in project onos by opennetworkinglab.
the class Dhcp6HandlerImpl method addHostOrRoute.
/**
* add host or route and update dhcp relay record.
*
* @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 the dhcp6 payload within relay
* @param srcMac client gw/host macAddress
* @param clientInterface client interface
* @param vlanIdInUse vlanid encoded in the interface id Option
*/
private void addHostOrRoute(boolean directConnFlag, ConnectPoint location, DHCP6 dhcp6Relay, DHCP6 embeddedDhcp6, MacAddress srcMac, Interface clientInterface, VlanId vlanIdInUse) {
log.debug("addHostOrRoute entered.");
VlanId vlanId;
if (clientInterface.vlanTagged().isEmpty()) {
vlanId = clientInterface.vlan();
} else {
// might be multiple vlan in same interface
vlanId = vlanIdInUse;
}
if (vlanId == null) {
vlanId = VlanId.NONE;
}
Boolean isMsgReply = Dhcp6HandlerUtil.isDhcp6Reply(dhcp6Relay);
MacAddress leafClientMac;
Byte leafMsgType;
Dhcp6ClientIdOption clientIdOption = Dhcp6HandlerUtil.extractClientId(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.");
// dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_LINKLOCAL_FAIL);
return;
}
} else {
log.warn("CLIENTID option NOT found. No DhcpRelay Record created.");
// dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_CLIENTID_FAIL);
return;
}
HostId leafHostId = HostId.hostId(leafClientMac, vlanId);
DhcpRecord record = dhcpRelayStore.getDhcpRecord(leafHostId).orElse(null);
if (record == null) {
record = new DhcpRecord(HostId.hostId(leafClientMac, vlanId));
} else {
record = record.clone();
}
IpAddressInfo ipInfo;
PdPrefixInfo pdInfo = null;
if (directConnFlag) {
// Add to host store if it connect to network directly
ipInfo = extractIpAddress(embeddedDhcp6);
if (ipInfo != null) {
if (isMsgReply) {
Set<IpAddress> ips = Sets.newHashSet(ipInfo.ip6Address);
HostId hostId = HostId.hostId(srcMac, vlanId);
Host host = hostService.getHost(hostId);
HostLocation hostLocation = new HostLocation(clientInterface.connectPoint(), System.currentTimeMillis());
Set<HostLocation> hostLocations = Sets.newHashSet(hostLocation);
if (host != null) {
// Dual homing support:
// if host exists, use old locations and new location
hostLocations.addAll(host.locations());
}
HostDescription desc = new DefaultHostDescription(srcMac, vlanId, hostLocations, ips, false);
log.debug("adding Host for directly connected.");
log.debug("client mac {} client vlan {} hostlocation {}", HexString.toHexString(srcMac.toBytes(), ":"), vlanId, hostLocation.toString());
// Replace the ip when dhcp server give the host new ip address
providerService.hostDetected(hostId, desc, false);
}
} else {
log.warn("ipAddress not found. Do not add Host {} for directly connected.", HostId.hostId(srcMac, 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(directConnFlag, srcMac, vlanId);
if (nextHopIp == null) {
log.warn("Can't find link-local IP address of gateway mac {} vlanId {}", srcMac, vlanId);
// dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_LINKLOCAL_GW);
return;
}
DHCP6 leafDhcp = Dhcp6HandlerUtil.getDhcp6Leaf(embeddedDhcp6);
ipInfo = extractIpAddress(leafDhcp);
if (ipInfo == null) {
log.debug("ip is null");
} else {
if (isMsgReply) {
Route routeForIP = new Route(Route.Source.DHCP, ipInfo.ip6Address.toIpPrefix(), nextHopIp);
log.debug("adding Route of 128 address for indirectly connected.");
routeStore.replaceRoute(routeForIP);
}
}
pdInfo = extractPrefix(leafDhcp);
if (pdInfo == null) {
log.debug("ipPrefix is null ");
} else {
if (isMsgReply) {
Route routeForPrefix = new Route(Route.Source.DHCP, pdInfo.pdPrefix, nextHopIp);
log.debug("adding Route of PD for indirectly connected.");
routeStore.replaceRoute(routeForPrefix);
if (this.dhcpFpmEnabled) {
FpmRecord fpmRecord = new FpmRecord(pdInfo.pdPrefix, nextHopIp, FpmRecord.Type.DHCP_RELAY);
dhcpFpmPrefixStore.addFpmRecord(pdInfo.pdPrefix, fpmRecord);
}
}
}
leafMsgType = leafDhcp.getMsgType();
}
if (leafMsgType == DHCP6.MsgType.RELEASE.value() || (leafMsgType == DHCP6.MsgType.REPLY.value()) && ipInfo == null) {
log.warn("DHCP6 RELEASE/REPLY(null ip) from Server. MsgType {}", leafMsgType);
// return;
}
record.addLocation(new HostLocation(location, System.currentTimeMillis()));
if (leafMsgType == DHCP6.MsgType.REPLY.value()) {
if (ipInfo != null) {
log.debug("IP6 address is being stored into dhcp-relay store.");
log.debug("Client IP6 address {}", HexString.toHexString(ipInfo.ip6Address.toOctets(), ":"));
record.ip6Address(ipInfo.ip6Address);
record.updateAddrPrefTime(ipInfo.prefTime);
record.updateLastIp6Update();
} else {
log.debug("IP6 address is not returned from server. Maybe only PD is returned.");
}
if (pdInfo != null) {
log.debug("IP6 PD address {}", HexString.toHexString(pdInfo.pdPrefix.address().toOctets(), ":"));
record.pdPrefix(pdInfo.pdPrefix);
record.updatePdPrefTime(pdInfo.prefTime);
record.updateLastPdUpdate();
} else {
log.debug("IP6 PD address is not returned from server. Maybe only IPAddress is returned.");
}
}
record.getV6Counters().incrementCounter(Dhcp6HandlerUtil.getMsgTypeStr(leafMsgType));
record.ip6Status(DHCP6.MsgType.getType(leafMsgType));
record.setDirectlyConnected(directConnFlag);
record.updateLastSeen();
dhcpRelayStore.updateDhcpRecord(leafHostId, record);
/*
// TODO Use AtomicInteger for the counters
try {
recordSemaphore.acquire();
try {
dhcpRelayCountersStore.incrementCounter(gCount, Dhcp6HandlerUtil.getMsgTypeStr(leafMsgType));
} finally {
// calling release() after a successful acquire()
recordSemaphore.release();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
*/
}
use of org.onlab.packet.dhcp.Dhcp6ClientIdOption in project onos by opennetworkinglab.
the class Dhcp6HandlerImpl method handleLeaseQuery6ReplyMsg.
public void handleLeaseQuery6ReplyMsg(PacketContext context, DHCP6 dhcp6Payload) {
ConnectPoint inPort = context.inPacket().receivedFrom();
log.info("Got LQV6-REPLY on port {}", inPort);
List<Dhcp6Option> lopt = dhcp6Payload.getOptions();
log.info("Options list: {}", lopt);
// find out if this lease is known is
Dhcp6ClientDataOption clientDataOption = dhcp6Payload.getOptions().stream().filter(opt -> opt instanceof Dhcp6ClientDataOption).map(pld -> (Dhcp6ClientDataOption) pld).findFirst().orElse(null);
if (clientDataOption == null) {
log.warn("clientDataOption option is not present, " + "lease is UNKNOWN - not adding any new route...");
} else {
Dhcp6IaAddressOption aiAddressOption = clientDataOption.getOptions().stream().filter(opt -> opt instanceof Dhcp6IaAddressOption).map(pld -> (Dhcp6IaAddressOption) pld).findFirst().orElse(null);
Dhcp6ClientIdOption clientIdOption = clientDataOption.getOptions().stream().filter(opt -> opt instanceof Dhcp6ClientIdOption).map(pld -> (Dhcp6ClientIdOption) pld).findFirst().orElse(null);
if (aiAddressOption == null) {
log.warn("clientDataOption from DHCP server does not " + "contains Dhcp6IaAddressOption for the client - giving up...");
} else {
Ip6Address clientAddress = aiAddressOption.getIp6Address();
MacAddress clientMacAddress = MacAddress.valueOf(clientIdOption.getDuid().getLinkLayerAddress());
Ethernet packet = context.inPacket().parsed();
VlanId vlanId = VlanId.vlanId(packet.getVlanID());
MacAddress potentialNextHopMac = findNextHopMacForIp6FromRelayStore(clientAddress, clientMacAddress, vlanId);
if (potentialNextHopMac == null) {
log.warn("Can't find next hop host mac for client {} mac:{}/{}", clientAddress, clientMacAddress, vlanId);
return;
} else {
log.info("Next hop mac for {}/{}/{} is {}", clientAddress, clientMacAddress, vlanId, potentialNextHopMac.toString());
}
// search the next hop in the hosts store
HostId gwHostId = HostId.hostId(potentialNextHopMac, vlanId);
Host gwHost = hostService.getHost(gwHostId);
if (gwHost == null) {
log.warn("Can't find next hop host ID {}", gwHostId);
return;
}
Ip6Address nextHopIp = gwHost.ipAddresses().stream().filter(IpAddress::isIp6).filter(IpAddress::isLinkLocal).map(IpAddress::getIp6Address).findFirst().orElse(null);
if (nextHopIp == null) {
log.warn("Can't find IP6 address of next hop {}", gwHost);
return;
}
log.info("client " + clientAddress + " is known !");
Route routeForIP6 = new Route(Route.Source.DHCP, clientAddress.toIpPrefix(), nextHopIp);
log.debug("updating route of Client for indirectly connected.");
log.debug("client ip: " + clientAddress + ", next hop ip6: " + nextHopIp);
routeStore.updateRoute(routeForIP6);
}
}
}
use of org.onlab.packet.dhcp.Dhcp6ClientIdOption in project onos by opennetworkinglab.
the class DhcpRelayManagerTest method buildDhcp6Packet.
/**
* Generates DHCP6 REQUEST packet.
*/
private void buildDhcp6Packet(DHCP6 dhcp6, byte msgType, Ip6Address ip6Addr, IpPrefix prefix) {
// build address option
Dhcp6IaAddressOption iaAddressOption = new Dhcp6IaAddressOption();
iaAddressOption.setCode(DHCP6.OptionCode.IAADDR.value());
iaAddressOption.setIp6Address(ip6Addr);
iaAddressOption.setPreferredLifetime(3600);
iaAddressOption.setValidLifetime(1200);
iaAddressOption.setLength((short) Dhcp6IaAddressOption.DEFAULT_LEN);
Dhcp6ClientIdOption clientIdOption = new Dhcp6ClientIdOption();
Dhcp6Duid dhcp6Duip = new Dhcp6Duid();
dhcp6Duip.setDuidType(Dhcp6Duid.DuidType.DUID_LLT);
// Ethernet
dhcp6Duip.setHardwareType((short) 0x01);
dhcp6Duip.setDuidTime(1234);
dhcp6Duip.setLinkLayerAddress(CLIENT_MAC.toBytes());
clientIdOption.setDuid(dhcp6Duip);
Dhcp6IaNaOption iaNaOption = new Dhcp6IaNaOption();
iaNaOption.setCode(DHCP6.OptionCode.IA_NA.value());
iaNaOption.setIaId(0);
iaNaOption.setT1(302400);
iaNaOption.setT2(483840);
List<Dhcp6Option> iaNaSubOptions = new ArrayList<Dhcp6Option>();
iaNaSubOptions.add(iaAddressOption);
iaNaOption.setOptions(iaNaSubOptions);
iaNaOption.setLength((short) (Dhcp6IaNaOption.DEFAULT_LEN + iaAddressOption.getLength()));
// build prefix option
Dhcp6IaPrefixOption iaPrefixOption = new Dhcp6IaPrefixOption();
iaPrefixOption.setCode(DHCP6.OptionCode.IAPREFIX.value());
iaPrefixOption.setIp6Prefix(prefix.address().getIp6Address());
iaPrefixOption.setPrefixLength((byte) prefix.prefixLength());
iaPrefixOption.setPreferredLifetime(3601);
iaPrefixOption.setValidLifetime(1201);
iaPrefixOption.setLength((short) Dhcp6IaPrefixOption.DEFAULT_LEN);
Dhcp6IaPdOption iaPdOption = new Dhcp6IaPdOption();
iaPdOption.setCode(DHCP6.OptionCode.IA_PD.value());
iaPdOption.setIaId(0);
iaPdOption.setT1(302401);
iaPdOption.setT2(483841);
List<Dhcp6Option> iaPdSubOptions = new ArrayList<Dhcp6Option>();
iaPdSubOptions.add(iaPrefixOption);
iaPdOption.setOptions(iaPdSubOptions);
iaPdOption.setLength((short) (Dhcp6IaPdOption.DEFAULT_LEN + iaPrefixOption.getLength()));
dhcp6.setMsgType(msgType);
List<Dhcp6Option> dhcp6Options = new ArrayList<Dhcp6Option>();
dhcp6Options.add(iaNaOption);
dhcp6Options.add(clientIdOption);
dhcp6Options.add(iaPdOption);
dhcp6.setOptions(dhcp6Options);
}
Aggregations