use of org.onlab.packet.DHCP6.MsgType in project onos by opennetworkinglab.
the class Dhcp6HandlerImpl method timeTick.
/**
* Find lease-expired ipaddresses and pd prefixes.
* Removing host/route/fpm entries.
*/
public void timeTick() {
long currentTime = System.currentTimeMillis();
Collection<DhcpRecord> records = dhcpRelayStore.getDhcpRecords();
log.debug("timeTick called currenttime {} records num {} ", currentTime, records.size());
records.forEach(record -> {
boolean addrOrPdRemoved = false;
DHCP6.MsgType ip6Status = record.ip6Status().orElse(null);
if (ip6Status == null) {
log.debug("record is not valid v6 record.");
return;
}
if ((currentTime - record.getLastIp6Update()) > ((record.addrPrefTime() + getDhcp6PollInterval() / 2) * 1000)) {
// remove ipaddress from host/route table
IpAddress ip = record.ip6Address().orElse(null);
if (ip != null) {
if (record.directlyConnected()) {
providerService.removeIpFromHost(HostId.hostId(record.macAddress(), record.vlanId()), ip);
} else {
MacAddress gwMac = record.nextHop().orElse(null);
if (gwMac == null) {
log.warn("Can't find gateway mac address from record {} for ip6Addr", record);
return;
}
IpAddress nextHopIp = getFirstIpByHost(record.directlyConnected(), gwMac, record.vlanId());
Route route = new Route(Route.Source.DHCP, ip.toIpPrefix(), nextHopIp);
routeStore.removeRoute(route);
}
record.updateAddrPrefTime(0);
record.ip6Address(null);
addrOrPdRemoved = true;
dhcpRelayStore.updateDhcpRecord(HostId.hostId(record.macAddress(), record.vlanId()), record);
log.warn("IP6 address is set to null. delta {} lastUpdate {} addrPrefTime {}", (currentTime - record.getLastIp6Update()), record.getLastIp6Update(), record.addrPrefTime());
}
}
if ((currentTime - record.getLastPdUpdate()) > ((record.pdPrefTime() + getDhcp6PollInterval() / 2) * 1000)) {
// remove PD from route/fpm table
IpPrefix pdIpPrefix = record.pdPrefix().orElse(null);
if (pdIpPrefix != null) {
if (record.directlyConnected()) {
providerService.removeIpFromHost(HostId.hostId(record.macAddress(), record.vlanId()), pdIpPrefix.address().getIp6Address());
} else {
MacAddress gwMac = record.nextHop().orElse(null);
if (gwMac == null) {
log.warn("Can't find gateway mac address from record {} for PD prefix", record);
return;
}
IpAddress nextHopIp = getFirstIpByHost(record.directlyConnected(), gwMac, record.vlanId());
Route route = new Route(Route.Source.DHCP, pdIpPrefix, nextHopIp);
routeStore.removeRoute(route);
if (this.dhcpFpmEnabled) {
dhcpFpmPrefixStore.removeFpmRecord(pdIpPrefix);
}
}
record.updatePdPrefTime(0);
record.pdPrefix(null);
addrOrPdRemoved = true;
dhcpRelayStore.updateDhcpRecord(HostId.hostId(record.macAddress(), record.vlanId()), record);
log.warn("PD prefix is set to null.delta {} pdPrefTime {}", (currentTime - record.getLastPdUpdate()), record.pdPrefTime());
}
}
if (addrOrPdRemoved && !record.ip6Address().isPresent() && !record.pdPrefix().isPresent()) {
log.warn("ip6Status {} IP6 address and IP6 PD both are null. Remove record.", ip6Status);
dhcpRelayStore.removeDhcpRecord(HostId.hostId(record.macAddress(), record.vlanId()));
}
});
}
use of org.onlab.packet.DHCP6.MsgType in project onos by opennetworkinglab.
the class Dhcp6HandlerUtil method isDhcp6Reply.
/**
* check if DHCP6 relay-reply is reply.
*
* @param relayPacket dhcp6 relay-reply
* @return boolean relay-reply contains ack
*/
public static boolean isDhcp6Reply(DHCP6 relayPacket) {
DHCP6 leafDhcp6 = getDhcp6Leaf(relayPacket);
if (leafDhcp6 != null) {
if (leafDhcp6.getMsgType() == DHCP6.MsgType.REPLY.value()) {
log.debug("isDhcp6Reply true.");
// must be directly connected
return true;
} else {
log.debug("isDhcp6Reply false. leaf dhcp6 is not replay. MsgType {}", leafDhcp6.getMsgType());
}
} else {
log.debug("isDhcp6Reply false. Expected dhcp6 within relay pkt but not found.");
}
log.debug("isDhcp6Reply false.");
return false;
}
use of org.onlab.packet.DHCP6.MsgType in project onos by opennetworkinglab.
the class Dhcp6HandlerUtil method directlyConnected.
/**
* Check if the host is directly connected to the network or not.
*
* @param dhcp6Payload the dhcp6 payload
* @return true if the host is directly connected to the network; false otherwise
*/
public static boolean directlyConnected(DHCP6 dhcp6Payload) {
log.debug("directlyConnected enters");
if (dhcp6Payload.getMsgType() == DHCP6.MsgType.LEASEQUERY.value() || dhcp6Payload.getMsgType() == DHCP6.MsgType.LEASEQUERY_REPLY.value()) {
log.debug("directlyConnected false. MsgType {}", dhcp6Payload.getMsgType());
return false;
}
if (dhcp6Payload.getMsgType() != DHCP6.MsgType.RELAY_FORW.value() && dhcp6Payload.getMsgType() != DHCP6.MsgType.RELAY_REPL.value()) {
log.debug("directlyConnected true. MsgType {}", dhcp6Payload.getMsgType());
return true;
}
// Regardless of relay-forward or relay-replay, check if we see another relay message
DHCP6 dhcp6Payload2 = dhcp6PacketFromRelayPacket(dhcp6Payload);
if (dhcp6Payload2 != null) {
if (dhcp6Payload.getMsgType() == DHCP6.MsgType.RELAY_FORW.value()) {
log.debug("directlyConnected false. 1st relay-forward, 2nd MsgType {}", dhcp6Payload2.getMsgType());
return false;
} else {
// relay-reply
if (dhcp6Payload2.getMsgType() != DHCP6.MsgType.RELAY_REPL.value() && dhcp6Payload2.getMsgType() != MsgType.LEASEQUERY_REPLY.value()) {
log.debug("directlyConnected true. 2nd MsgType {}", dhcp6Payload2.getMsgType());
// must be directly connected
return true;
} else {
log.debug("directlyConnected false. 1st relay-reply, 2nd relay-reply MsgType {}", dhcp6Payload2.getMsgType());
// must be indirectly connected
return false;
}
}
} else {
log.debug("directlyConnected true.");
return true;
}
}
use of org.onlab.packet.DHCP6.MsgType 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.DHCP6.MsgType in project onos by opennetworkinglab.
the class Dhcp6HandlerImpl method processDhcpPacket.
@Override
public void processDhcpPacket(PacketContext context, BasePacket payload) {
checkNotNull(payload, "DHCP6 payload can't be null");
checkState(payload instanceof DHCP6, "Payload is not a DHCP6");
DHCP6 dhcp6Payload = (DHCP6) payload;
Ethernet receivedPacket = context.inPacket().parsed();
if (!configured()) {
log.warn("Missing DHCP6 relay server config. " + "Abort packet processing dhcp6 payload {}", dhcp6Payload);
return;
}
byte msgTypeVal = dhcp6Payload.getMsgType();
MsgType msgType = DHCP6.MsgType.getType(msgTypeVal);
log.debug("msgType is {}", msgType);
ConnectPoint inPort = context.inPacket().receivedFrom();
if (inPort == null) {
log.warn("incoming ConnectPoint is null");
}
Set<Interface> receivingInterfaces = interfaceService.getInterfacesByPort(inPort);
// ignore the packets if dhcp client interface is not configured on onos.
if (receivingInterfaces.isEmpty()) {
log.warn("Virtual interface is not configured on {}", inPort);
return;
}
if (msgTypeVal == DHCP6.MsgType.LEASEQUERY.value()) {
List<InternalPacket> ethernetClientPackets = learnRouteFromLeasequery ? processLQ6PacketFromClient(context, receivedPacket, receivingInterfaces, dhcp6Payload) : processDhcp6ForwardOnly(context, receivedPacket, receivingInterfaces, dhcp6Payload);
for (InternalPacket internalPacket : ethernetClientPackets) {
forwardPacket(internalPacket);
}
} else if (msgTypeVal == DHCP6.MsgType.LEASEQUERY_REPLY.value() && learnRouteFromLeasequery) {
IPv6 clientIpv6 = (IPv6) receivedPacket.getPayload();
UDP clientUdp = (UDP) clientIpv6.getPayload();
DHCP6 clientDhcp6 = (DHCP6) clientUdp.getPayload();
Interface serverInterface = Dhcp6HandlerUtil.directlyConnected(clientDhcp6) ? getServerInterface() : getIndirectServerInterface();
InternalPacket ethernetPacketReply = Dhcp6HandlerUtil.processLQ6PacketFromServer(defaultServerInfoList, indirectServerInfoList, serverInterface, interfaceService, hostService, context, receivedPacket, receivingInterfaces);
if (ethernetPacketReply != null) {
forwardPacket(ethernetPacketReply);
}
handleLeaseQuery6ReplyMsg(context, dhcp6Payload);
} else if (MSG_TYPE_FROM_CLIENT.contains(msgTypeVal)) {
List<InternalPacket> ethernetClientPacket = processDhcp6PacketFromClient(context, receivedPacket, receivingInterfaces);
for (InternalPacket internalPacket : ethernetClientPacket) {
forwardPacket(internalPacket);
}
} else if (MSG_TYPE_FROM_SERVER.contains(msgTypeVal)) {
log.debug("calling processDhcp6PacketFromServer with RELAY_REPL {}, {}", receivedPacket, dhcp6Payload);
InternalPacket ethernetPacketReply = processDhcp6PacketFromServer(context, receivedPacket, receivingInterfaces);
if (ethernetPacketReply != null) {
forwardPacket(ethernetPacketReply);
}
} else {
log.warn("Not so fast, packet type {} not supported yet", msgTypeVal);
}
}
Aggregations