use of org.onlab.packet.DHCP6 in project onos by opennetworkinglab.
the class Dhcp6HandlerImpl method processDhcp6PacketFromClient.
/**
* build the DHCP6 solicit/request packet with gatewayip.
*
* @param context packet context
* @param clientPacket client ethernet packet
* @param clientInterfaces set of client side interfaces
*/
private List<InternalPacket> processDhcp6PacketFromClient(PacketContext context, Ethernet clientPacket, Set<Interface> clientInterfaces) {
ConnectPoint receivedFrom = context.inPacket().receivedFrom();
Ip6Address relayAgentIp = Dhcp6HandlerUtil.getRelayAgentIPv6Address(clientInterfaces);
MacAddress relayAgentMac = clientInterfaces.iterator().next().mac();
if (relayAgentIp == null || relayAgentMac == null) {
log.warn("Missing DHCP relay agent interface Ipv6 addr config for " + "packet from client on port: {}. Aborting packet processing", clientInterfaces.iterator().next().connectPoint());
// dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_CLIENT_INTF_MAC);
return Lists.newArrayList();
}
IPv6 clientIpv6 = (IPv6) clientPacket.getPayload();
UDP clientUdp = (UDP) clientIpv6.getPayload();
DHCP6 clientDhcp6 = (DHCP6) clientUdp.getPayload();
boolean directConnFlag = Dhcp6HandlerUtil.directlyConnected(clientDhcp6);
ConnectPoint clientConnectionPoint = context.inPacket().receivedFrom();
VlanId vlanIdInUse = VlanId.vlanId(clientPacket.getVlanID());
Interface clientInterface = interfaceService.getInterfacesByPort(clientConnectionPoint).stream().filter(iface -> Dhcp6HandlerUtil.interfaceContainsVlan(iface, vlanIdInUse)).findFirst().orElse(null);
List<InternalPacket> internalPackets = new ArrayList<>();
List<DhcpServerInfo> serverInfoList = findValidServerInfo(directConnFlag);
List<DhcpServerInfo> copyServerInfoList = new ArrayList<DhcpServerInfo>(serverInfoList);
for (DhcpServerInfo serverInfo : copyServerInfoList) {
if (!Dhcp6HandlerUtil.checkDhcpServerConnPt(directConnFlag, serverInfo)) {
log.warn("Can't get server connect point, ignore");
continue;
}
DhcpServerInfo newServerInfo = getHostInfoForServerInfo(serverInfo, serverInfoList);
if (newServerInfo == null) {
log.warn("Can't get server interface with host info resolved, ignore");
continue;
}
Interface serverInterface = getServerInterface(newServerInfo);
if (serverInterface == null) {
log.warn("Can't get server interface, ignore");
continue;
}
Ethernet etherReply = Dhcp6HandlerUtil.buildDhcp6PacketFromClient(context, clientPacket, clientInterfaces, newServerInfo, serverInterface);
removeHostOrRoute(directConnFlag, clientConnectionPoint, clientDhcp6, clientPacket, clientIpv6, clientInterface);
InternalPacket internalPacket = InternalPacket.internalPacket(etherReply, serverInfo.getDhcpServerConnectPoint().get());
internalPackets.add(internalPacket);
}
log.debug("num of client packets to send is{}", internalPackets.size());
return internalPackets;
}
use of org.onlab.packet.DHCP6 in project onos by opennetworkinglab.
the class Dhcp6HandlerImpl method processLQ6PacketFromClient.
private List<InternalPacket> processLQ6PacketFromClient(PacketContext context, Ethernet clientPacket, Set<Interface> clientInterfaces, DHCP6 dhcp6Payload) {
ConnectPoint inPort = context.inPacket().receivedFrom();
log.info("Got LQ-REQUEST V6 on port {}", inPort);
List<Dhcp6Option> lopt = dhcp6Payload.getOptions();
log.info("Options list: {}", lopt);
Dhcp6LeaseQueryOption lqoption = dhcp6Payload.getOptions().stream().filter(opt -> opt instanceof Dhcp6LeaseQueryOption).map(pld -> (Dhcp6LeaseQueryOption) pld).findFirst().orElse(null);
if (lqoption == null) {
// Can't find dhcp payload
log.warn("Can't find dhcp6 lease query message - aborting");
return null;
} else {
log.info("dhcp6 lqv6 options found: {}", lqoption);
}
log.warn("LQv6 for " + lqoption.linkAddress.toString() + " comes from " + inPort.toString());
Ethernet packet = context.inPacket().parsed();
Ip6Address clientAddress = lqoption.linkAddress;
IPv6 ipv6Packet = (IPv6) packet.getPayload();
Ip6Address nextHopIp = findNextHopIp6FromRelayStore(clientAddress);
// 1. only if there is a route to remove - remove it
if (nextHopIp != null) {
Route routeForIP6 = new Route(Route.Source.DHCP, clientAddress.toIpPrefix(), nextHopIp);
log.debug("Removing route of Client " + clientAddress + " for indirectly connected - next hop ip6 " + nextHopIp);
routeStore.removeRoute(routeForIP6);
}
// 2. note the potential NH this packet came from in case it's a known lease
// this NH will then be used to build the route
MacAddress potentialNH = packet.getSourceMAC();
VlanId vlanId = VlanId.vlanId(packet.getVlanID());
setPotentialNextHopForIp6InRelayStore(clientAddress, vlanId, potentialNH);
// 3. route this LQ6 to all relevant servers
IPv6 clientIpv6 = (IPv6) clientPacket.getPayload();
UDP clientUdp = (UDP) clientIpv6.getPayload();
DHCP6 clientDhcp6 = (DHCP6) clientUdp.getPayload();
boolean directConnFlag = Dhcp6HandlerUtil.directlyConnected(clientDhcp6);
boolean serverFound = false;
List<InternalPacket> internalPackets = new ArrayList<>();
List<DhcpServerInfo> serverInfoList = findValidServerInfo(directConnFlag);
List<DhcpServerInfo> copyServerInfoList = new ArrayList<DhcpServerInfo>(serverInfoList);
for (DhcpServerInfo serverInfo : copyServerInfoList) {
if (!Dhcp6HandlerUtil.checkDhcpServerConnPt(directConnFlag, serverInfo)) {
log.warn("Can't get server connect point, ignore");
continue;
}
DhcpServerInfo newServerInfo = getHostInfoForServerInfo(serverInfo, serverInfoList);
if (newServerInfo == null) {
log.debug("Can't get server interface with host info resolved, ignore serverInfo {} serverInfoList {}", serverInfo, serverInfoList);
continue;
}
Interface serverInterface = getServerInterface(newServerInfo);
if (serverInterface == null) {
log.debug("Can't get server interface, ignore for serverInfo {}, serverInfoList {}", serverInfo, serverInfoList);
continue;
}
serverFound = true;
log.debug("Server Info Found {}", serverInfo.getDhcpConnectMac());
Ethernet etherRouted = (Ethernet) clientPacket.clone();
MacAddress macFacingServer = serverInterface.mac();
if (macFacingServer == null) {
log.warn("No MAC address for server Interface {}", serverInterface);
return null;
}
etherRouted.setSourceMACAddress(macFacingServer);
etherRouted.setDestinationMACAddress(newServerInfo.getDhcpConnectMac().get());
InternalPacket internalPacket = InternalPacket.internalPacket(etherRouted, serverInfo.getDhcpServerConnectPoint().get());
internalPackets.add(internalPacket);
log.debug("Sending LQ to DHCP server {}", newServerInfo.getDhcpServerIp6());
}
if (!serverFound) {
log.warn("ProcessDhcp6PacketFromClient No Server Found");
}
log.debug("num of client packets to send is{}", internalPackets.size());
return internalPackets;
}
use of org.onlab.packet.DHCP6 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 in project onos by opennetworkinglab.
the class Dhcp6HandlerImpl method forwardPacket.
// forward the packet to ConnectPoint where the DHCP server is attached.
private void forwardPacket(InternalPacket packet) {
// send Packetout to dhcp server connectpoint.
if (packet.getDestLocation() != null) {
TrafficTreatment t = DefaultTrafficTreatment.builder().setOutput(packet.getDestLocation().port()).build();
OutboundPacket o = new DefaultOutboundPacket(packet.getDestLocation().deviceId(), t, ByteBuffer.wrap(packet.getPacket().serialize()));
packetService.emit(o);
if (log.isTraceEnabled()) {
IPv6 ip6 = (IPv6) packet.getPacket().getPayload();
UDP udp = (UDP) ip6.getPayload();
DHCP6 dhcp6 = (DHCP6) udp.getPayload();
log.trace("Relaying packet to destination {} eth: {} dhcp: {}", packet.getDestLocation(), packet.getPacket(), dhcp6);
}
}
}
use of org.onlab.packet.DHCP6 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