mirror of
https://github.com/opennetworkinglab/onos.git
synced 2025-10-15 17:31:31 +02:00
CORD-2870: Bypass DHCP leasequery without learning routes.
Changes: * Add configuration flag to disable old leasequery routing/learning flow * Route leasequery (v4 and v6) responses to an originator * Fix NPE and BufferOverflow exceptions in Dhcp6LeaseQueryOption * Make Dhcp4/Dhcp6HandlerUtil classes static * Fix codestyle issues Change-Id: Ic9e527d73a226e7f1f544dab9fb98398b85c5460
This commit is contained in:
parent
b812ca138c
commit
96a0d34085
@ -26,6 +26,7 @@ import com.google.common.collect.Sets;
|
|||||||
import org.apache.felix.scr.annotations.Activate;
|
import org.apache.felix.scr.annotations.Activate;
|
||||||
import org.apache.felix.scr.annotations.Component;
|
import org.apache.felix.scr.annotations.Component;
|
||||||
import org.apache.felix.scr.annotations.Deactivate;
|
import org.apache.felix.scr.annotations.Deactivate;
|
||||||
|
import org.apache.felix.scr.annotations.Modified;
|
||||||
import org.apache.felix.scr.annotations.Property;
|
import org.apache.felix.scr.annotations.Property;
|
||||||
import org.apache.felix.scr.annotations.Reference;
|
import org.apache.felix.scr.annotations.Reference;
|
||||||
import org.apache.felix.scr.annotations.ReferenceCardinality;
|
import org.apache.felix.scr.annotations.ReferenceCardinality;
|
||||||
@ -43,6 +44,8 @@ import org.onlab.packet.VlanId;
|
|||||||
import org.onlab.packet.dhcp.CircuitId;
|
import org.onlab.packet.dhcp.CircuitId;
|
||||||
import org.onlab.packet.dhcp.DhcpOption;
|
import org.onlab.packet.dhcp.DhcpOption;
|
||||||
import org.onlab.packet.dhcp.DhcpRelayAgentOption;
|
import org.onlab.packet.dhcp.DhcpRelayAgentOption;
|
||||||
|
import org.onlab.util.Tools;
|
||||||
|
import org.onosproject.cfg.ComponentConfigService;
|
||||||
import org.onosproject.core.ApplicationId;
|
import org.onosproject.core.ApplicationId;
|
||||||
import org.onosproject.core.CoreService;
|
import org.onosproject.core.CoreService;
|
||||||
import org.onosproject.dhcprelay.api.DhcpHandler;
|
import org.onosproject.dhcprelay.api.DhcpHandler;
|
||||||
@ -88,14 +91,16 @@ import org.onosproject.net.packet.DefaultOutboundPacket;
|
|||||||
import org.onosproject.net.packet.OutboundPacket;
|
import org.onosproject.net.packet.OutboundPacket;
|
||||||
import org.onosproject.net.packet.PacketContext;
|
import org.onosproject.net.packet.PacketContext;
|
||||||
import org.onosproject.net.packet.PacketService;
|
import org.onosproject.net.packet.PacketService;
|
||||||
|
import org.osgi.service.component.ComponentContext;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Dictionary;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
@ -115,7 +120,6 @@ import static org.onlab.util.Tools.groupedThreads;
|
|||||||
import static org.onosproject.net.flowobjective.Objective.Operation.ADD;
|
import static org.onosproject.net.flowobjective.Objective.Operation.ADD;
|
||||||
import static org.onosproject.net.flowobjective.Objective.Operation.REMOVE;
|
import static org.onosproject.net.flowobjective.Objective.Operation.REMOVE;
|
||||||
|
|
||||||
import org.onosproject.dhcprelay.Dhcp4HandlerUtil.InternalPacket;
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@Service
|
@Service
|
||||||
@ -126,6 +130,8 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
private static final String BROADCAST_IP = "255.255.255.255";
|
private static final String BROADCAST_IP = "255.255.255.255";
|
||||||
private static final int IGNORE_CONTROL_PRIORITY = PacketPriority.CONTROL.priorityValue() + 1000;
|
private static final int IGNORE_CONTROL_PRIORITY = PacketPriority.CONTROL.priorityValue() + 1000;
|
||||||
|
|
||||||
|
private static final String LQ_ROUTE_PROPERTY_NAME = "learnRouteFromLeasequery";
|
||||||
|
|
||||||
private static final TrafficSelector CLIENT_SERVER_SELECTOR = DefaultTrafficSelector.builder()
|
private static final TrafficSelector CLIENT_SERVER_SELECTOR = DefaultTrafficSelector.builder()
|
||||||
.matchEthType(Ethernet.TYPE_IPV4)
|
.matchEthType(Ethernet.TYPE_IPV4)
|
||||||
.matchIPProtocol(IPv4.PROTOCOL_UDP)
|
.matchIPProtocol(IPv4.PROTOCOL_UDP)
|
||||||
@ -173,6 +179,9 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
|
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
|
||||||
protected FlowObjectiveService flowObjectiveService;
|
protected FlowObjectiveService flowObjectiveService;
|
||||||
|
|
||||||
|
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
|
||||||
|
protected ComponentConfigService cfgService;
|
||||||
|
|
||||||
protected HostProviderService providerService;
|
protected HostProviderService providerService;
|
||||||
protected ApplicationId appId;
|
protected ApplicationId appId;
|
||||||
protected Multimap<DeviceId, VlanId> ignoredVlans = Multimaps.synchronizedMultimap(HashMultimap.create());
|
protected Multimap<DeviceId, VlanId> ignoredVlans = Multimaps.synchronizedMultimap(HashMultimap.create());
|
||||||
@ -180,13 +189,18 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
|
|
||||||
private List<DhcpServerInfo> defaultServerInfoList = new CopyOnWriteArrayList<>();
|
private List<DhcpServerInfo> defaultServerInfoList = new CopyOnWriteArrayList<>();
|
||||||
private List<DhcpServerInfo> indirectServerInfoList = new CopyOnWriteArrayList<>();
|
private List<DhcpServerInfo> indirectServerInfoList = new CopyOnWriteArrayList<>();
|
||||||
private Dhcp4HandlerUtil dhcp4HandlerUtil = new Dhcp4HandlerUtil();
|
|
||||||
|
@Property(name = Dhcp4HandlerImpl.LQ_ROUTE_PROPERTY_NAME, boolValue = false,
|
||||||
|
label = "Enable learning routing information from LQ")
|
||||||
|
private Boolean learnRouteFromLeasequery = Boolean.TRUE;
|
||||||
|
|
||||||
private Executor hostEventExecutor = newSingleThreadExecutor(
|
private Executor hostEventExecutor = newSingleThreadExecutor(
|
||||||
groupedThreads("dhcp4-event-host", "%d", log));
|
groupedThreads("dhcp4-event-host", "%d", log));
|
||||||
|
|
||||||
@Activate
|
@Activate
|
||||||
protected void activate() {
|
protected void activate(ComponentContext context) {
|
||||||
|
cfgService.registerProperties(getClass());
|
||||||
|
modified(context);
|
||||||
appId = coreService.registerApplication(DHCP_V4_RELAY_APP);
|
appId = coreService.registerApplication(DHCP_V4_RELAY_APP);
|
||||||
hostService.addListener(hostListener);
|
hostService.addListener(hostListener);
|
||||||
providerService = providerRegistry.register(this);
|
providerService = providerRegistry.register(this);
|
||||||
@ -194,6 +208,7 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
|
|
||||||
@Deactivate
|
@Deactivate
|
||||||
protected void deactivate() {
|
protected void deactivate() {
|
||||||
|
cfgService.unregisterProperties(getClass(), false);
|
||||||
providerRegistry.unregister(this);
|
providerRegistry.unregister(this);
|
||||||
hostService.removeListener(hostListener);
|
hostService.removeListener(hostListener);
|
||||||
defaultServerInfoList.forEach(this::stopMonitoringIps);
|
defaultServerInfoList.forEach(this::stopMonitoringIps);
|
||||||
@ -202,6 +217,18 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
indirectServerInfoList.clear();
|
indirectServerInfoList.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Modified
|
||||||
|
protected void modified(ComponentContext context) {
|
||||||
|
Dictionary<?, ?> properties = context.getProperties();
|
||||||
|
Boolean flag;
|
||||||
|
flag = Tools.isPropertyEnabled(properties, Dhcp4HandlerImpl.LQ_ROUTE_PROPERTY_NAME);
|
||||||
|
if (flag != null) {
|
||||||
|
learnRouteFromLeasequery = flag;
|
||||||
|
log.info("Learning routes from DHCP leasequery is {}",
|
||||||
|
learnRouteFromLeasequery ? "enabled" : "disabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void stopMonitoringIps(DhcpServerInfo serverInfo) {
|
private void stopMonitoringIps(DhcpServerInfo serverInfo) {
|
||||||
serverInfo.getDhcpGatewayIp4().ifPresent(gatewayIp -> {
|
serverInfo.getDhcpGatewayIp4().ifPresent(gatewayIp -> {
|
||||||
hostService.stopMonitoringIp(gatewayIp);
|
hostService.stopMonitoringIp(gatewayIp);
|
||||||
@ -302,7 +329,7 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
// Create new server info according to the config
|
// Create new server info according to the config
|
||||||
serverInfoList.clear();
|
serverInfoList.clear();
|
||||||
for (DhcpServerConfig serverConfig : configs) {
|
for (DhcpServerConfig serverConfig : configs) {
|
||||||
log.info("// Create new server info according to the config");
|
log.debug("Create new server info according to the config");
|
||||||
DhcpServerInfo newServerInfo = new DhcpServerInfo(serverConfig,
|
DhcpServerInfo newServerInfo = new DhcpServerInfo(serverConfig,
|
||||||
DhcpServerInfo.Version.DHCP_V4);
|
DhcpServerInfo.Version.DHCP_V4);
|
||||||
checkState(newServerInfo.getDhcpServerConnectPoint().isPresent(),
|
checkState(newServerInfo.getDhcpServerConnectPoint().isPresent(),
|
||||||
@ -384,9 +411,9 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
break;
|
break;
|
||||||
case DHCPOFFER:
|
case DHCPOFFER:
|
||||||
//reply to dhcp client.
|
//reply to dhcp client.
|
||||||
Ethernet ethernetPacketOffer = processDhcpPacketFromServer(context, packet);
|
InternalPacket ethernetPacketOffer = processDhcpPacketFromServer(context, packet);
|
||||||
if (ethernetPacketOffer != null) {
|
if (ethernetPacketOffer != null) {
|
||||||
writeResponseDhcpRecord(ethernetPacketOffer, dhcpPayload);
|
writeResponseDhcpRecord(ethernetPacketOffer.getPacket(), dhcpPayload);
|
||||||
sendResponseToClient(ethernetPacketOffer, dhcpPayload);
|
sendResponseToClient(ethernetPacketOffer, dhcpPayload);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -405,10 +432,10 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
break;
|
break;
|
||||||
case DHCPACK:
|
case DHCPACK:
|
||||||
// reply to dhcp client.
|
// reply to dhcp client.
|
||||||
Ethernet ethernetPacketAck = processDhcpPacketFromServer(context, packet);
|
InternalPacket ethernetPacketAck = processDhcpPacketFromServer(context, packet);
|
||||||
if (ethernetPacketAck != null) {
|
if (ethernetPacketAck != null) {
|
||||||
writeResponseDhcpRecord(ethernetPacketAck, dhcpPayload);
|
writeResponseDhcpRecord(ethernetPacketAck.getPacket(), dhcpPayload);
|
||||||
handleDhcpAck(ethernetPacketAck, dhcpPayload);
|
handleDhcpAck(ethernetPacketAck.getPacket(), dhcpPayload);
|
||||||
sendResponseToClient(ethernetPacketAck, dhcpPayload);
|
sendResponseToClient(ethernetPacketAck, dhcpPayload);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -520,151 +547,171 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
private void handleLeaseQueryActivateMsg(Ethernet packet, DHCP dhcpPayload) {
|
private void handleLeaseQueryActivateMsg(Ethernet packet, DHCP dhcpPayload) {
|
||||||
log.debug("LQ: Got DHCPLEASEACTIVE packet!");
|
log.debug("LQ: Got DHCPLEASEACTIVE packet!");
|
||||||
|
|
||||||
// TODO: release the ip address from client
|
if (learnRouteFromLeasequery) {
|
||||||
MacAddress clientMacAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
|
// TODO: release the ip address from client
|
||||||
VlanId vlanId = VlanId.vlanId(packet.getVlanID());
|
MacAddress clientMacAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
|
||||||
HostId hostId = HostId.hostId(clientMacAddress, vlanId);
|
VlanId vlanId = VlanId.vlanId(packet.getVlanID());
|
||||||
DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
|
HostId hostId = HostId.hostId(clientMacAddress, vlanId);
|
||||||
|
DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
|
||||||
|
|
||||||
if (record == null) {
|
if (record == null) {
|
||||||
log.warn("Can't find record for host {} when processing DHCPLEASEACTIVE", hostId);
|
log.warn("Can't find record for host {} when processing DHCPLEASEACTIVE", hostId);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// need to update routes
|
||||||
|
log.debug("Lease Query for Client results in DHCPLEASEACTIVE - route needs to be modified");
|
||||||
|
// get current route
|
||||||
|
// find the ip of that client with the DhcpRelay store
|
||||||
|
|
||||||
|
Ip4Address clientIP = record.ip4Address().orElse(null);
|
||||||
|
log.debug("LQ: IP of host is " + clientIP.getIp4Address());
|
||||||
|
|
||||||
|
MacAddress nextHopMac = record.nextHop().orElse(null);
|
||||||
|
log.debug("LQ: MAC of resulting *OLD* NH for that host is " + nextHopMac.toString());
|
||||||
|
|
||||||
|
// find the new NH by looking at the src MAC of the dhcp request
|
||||||
|
// from the LQ store
|
||||||
|
MacAddress newNextHopMac = record.nextHopTemp().orElse(null);
|
||||||
|
log.debug("LQ: MAC of resulting *NEW* NH for that host is " + newNextHopMac.toString());
|
||||||
|
|
||||||
|
log.debug("LQ: updating dhcp relay record with new NH");
|
||||||
|
record.nextHop(newNextHopMac);
|
||||||
|
|
||||||
|
// find the next hop IP from its mac
|
||||||
|
HostId gwHostId = HostId.hostId(newNextHopMac, vlanId);
|
||||||
|
Host gwHost = hostService.getHost(gwHostId);
|
||||||
|
|
||||||
|
if (gwHost == null) {
|
||||||
|
log.warn("Can't find gateway for new NH host " + gwHostId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ip4Address nextHopIp = gwHost.ipAddresses()
|
||||||
|
.stream()
|
||||||
|
.filter(IpAddress::isIp4)
|
||||||
|
.map(IpAddress::getIp4Address)
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
|
if (nextHopIp == null) {
|
||||||
|
log.warn("Can't find IP address of gateway " + gwHost);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug("LQ: *NEW* NH IP for host is " + nextHopIp.getIp4Address());
|
||||||
|
Route route = new Route(Route.Source.DHCP, clientIP.toIpPrefix(), nextHopIp);
|
||||||
|
routeStore.updateRoute(route);
|
||||||
}
|
}
|
||||||
|
|
||||||
// need to update routes
|
|
||||||
log.debug("Lease Query for Client results in DHCPLEASEACTIVE - route needs to be modified");
|
|
||||||
// get current route
|
|
||||||
// find the ip of that client with the DhcpRelay store
|
|
||||||
|
|
||||||
Ip4Address clientIP = record.ip4Address().orElse(null);
|
|
||||||
log.debug("LQ: IP of host is " + clientIP.getIp4Address());
|
|
||||||
|
|
||||||
MacAddress nextHopMac = record.nextHop().orElse(null);
|
|
||||||
log.debug("LQ: MAC of resulting *OLD* NH for that host is " + nextHopMac.toString());
|
|
||||||
|
|
||||||
// find the new NH by looking at the src MAC of the dhcp request
|
|
||||||
// from the LQ store
|
|
||||||
MacAddress newNextHopMac = record.nextHopTemp().orElse(null);
|
|
||||||
log.debug("LQ: MAC of resulting *NEW* NH for that host is " + newNextHopMac.toString());
|
|
||||||
|
|
||||||
log.debug("LQ: updating dhcp relay record with new NH");
|
|
||||||
record.nextHop(newNextHopMac);
|
|
||||||
|
|
||||||
// find the next hop IP from its mac
|
|
||||||
HostId gwHostId = HostId.hostId(newNextHopMac, vlanId);
|
|
||||||
Host gwHost = hostService.getHost(gwHostId);
|
|
||||||
|
|
||||||
if (gwHost == null) {
|
|
||||||
log.warn("Can't find gateway for new NH host " + gwHostId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ip4Address nextHopIp = gwHost.ipAddresses()
|
|
||||||
.stream()
|
|
||||||
.filter(IpAddress::isIp4)
|
|
||||||
.map(IpAddress::getIp4Address)
|
|
||||||
.findFirst()
|
|
||||||
.orElse(null);
|
|
||||||
|
|
||||||
if (nextHopIp == null) {
|
|
||||||
log.warn("Can't find IP address of gateway " + gwHost);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
log.debug("LQ: *NEW* NH IP for host is " + nextHopIp.getIp4Address());
|
|
||||||
Route route = new Route(Route.Source.DHCP, clientIP.toIpPrefix(), nextHopIp);
|
|
||||||
routeStore.updateRoute(route);
|
|
||||||
|
|
||||||
// and forward to client
|
// and forward to client
|
||||||
Ethernet ethernetPacket = processLeaseQueryFromServer(packet);
|
InternalPacket ethernetPacket = processLeaseQueryFromServer(packet);
|
||||||
if (ethernetPacket != null) {
|
if (ethernetPacket != null) {
|
||||||
sendResponseToClient(ethernetPacket, dhcpPayload);
|
sendResponseToClient(ethernetPacket, dhcpPayload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private void handleLeaseQueryMsg(PacketContext context, Ethernet packet, DHCP dhcpPayload) {
|
private void handleLeaseQueryMsg(PacketContext context, Ethernet packet, DHCP dhcpPayload) {
|
||||||
log.debug("LQ: Got DHCPLEASEQUERY packet!");
|
// If this flag is enabled we expect that DHCPLEASEQUERY-ies are sent from an access concentrator
|
||||||
MacAddress clientMacAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
|
// where queried client is connected to. Otherwise, DHCPLEASEQUERY source may be a separate connected agent
|
||||||
log.debug("LQ: got DHCPLEASEQUERY with MAC " + clientMacAddress.toString());
|
if (learnRouteFromLeasequery) {
|
||||||
// add the client mac (hostid) of this request to a store (the entry will be removed with
|
log.debug("LQ: Got DHCPLEASEQUERY packet!");
|
||||||
// the reply sent to the originator)
|
MacAddress clientMacAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
|
||||||
VlanId vlanId = VlanId.vlanId(packet.getVlanID());
|
log.debug("LQ: got DHCPLEASEQUERY with MAC " + clientMacAddress.toString());
|
||||||
HostId hId = HostId.hostId(clientMacAddress, vlanId);
|
// add the client mac (hostid) of this request to a store (the entry will be removed with
|
||||||
DhcpRecord record = dhcpRelayStore.getDhcpRecord(hId).orElse(null);
|
// the reply sent to the originator)
|
||||||
if (record != null) {
|
VlanId vlanId = VlanId.vlanId(packet.getVlanID());
|
||||||
//new NH is to be taken from src mac of LQ packet
|
HostId hId = HostId.hostId(clientMacAddress, vlanId);
|
||||||
MacAddress newNextHop = packet.getSourceMAC();
|
DhcpRecord record = dhcpRelayStore.getDhcpRecord(hId).orElse(null);
|
||||||
record.nextHopTemp(newNextHop);
|
if (record != null) {
|
||||||
record.ip4Status(dhcpPayload.getPacketType());
|
//new NH is to be taken from src mac of LQ packet
|
||||||
record.updateLastSeen();
|
MacAddress newNextHop = packet.getSourceMAC();
|
||||||
|
record.nextHopTemp(newNextHop);
|
||||||
|
record.ip4Status(dhcpPayload.getPacketType());
|
||||||
|
record.updateLastSeen();
|
||||||
|
|
||||||
|
// do a basic routing of the packet (this is unicast routing
|
||||||
|
// not a relay operation like for other broadcast dhcp packets
|
||||||
|
List<InternalPacket> ethernetPacketRequest = processLeaseQueryFromAgent(context, packet);
|
||||||
|
// and forward to server
|
||||||
|
for (InternalPacket internalPacket : ethernetPacketRequest) {
|
||||||
|
log.debug("LeaseQueryMsg forward to server");
|
||||||
|
forwardPacket(internalPacket);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn("LQ: Error! - DHCP relay record for that client not found - ignoring LQ!");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.debug("LQ: Got DHCPLEASEQUERY packet!");
|
||||||
|
|
||||||
|
int giaddr = dhcpPayload.getGatewayIPAddress();
|
||||||
|
|
||||||
|
log.debug("DHCPLEASEQUERY giaddr: {} ({}). Originators connectPoint: {}", giaddr,
|
||||||
|
Ip4Address.valueOf(giaddr), context.inPacket().receivedFrom());
|
||||||
|
|
||||||
// do a basic routing of the packet (this is unicast routing
|
// do a basic routing of the packet (this is unicast routing
|
||||||
// not a relay operation like for other broadcast dhcp packets
|
// not a relay operation like for other broadcast dhcp packets
|
||||||
List<InternalPacket> ethernetPacketRequest = processLeaseQueryFromAgent(context, packet);
|
List<InternalPacket> ethernetPacketRequest = processLeaseQueryFromAgent(context, packet);
|
||||||
// and forward to server
|
// and forward to server
|
||||||
for (InternalPacket internalPacket : ethernetPacketRequest) {
|
for (InternalPacket internalPacket : ethernetPacketRequest) {
|
||||||
log.debug("LeaseQueryMsg forward to server");
|
log.trace("LeaseQueryMsg forward to server connected to {}", internalPacket.getDestLocation());
|
||||||
forwardPacket(internalPacket);
|
forwardPacket(internalPacket);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
log.warn("LQ: Error! - DHCP relay record for that client not found - ignoring LQ!");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleLeaseQueryUnknown(Ethernet packet, DHCP dhcpPayload) {
|
private void handleLeaseQueryUnknown(Ethernet packet, DHCP dhcpPayload) {
|
||||||
log.debug("Lease Query for Client results in DHCPLEASEUNASSIGNED or " +
|
log.debug("Lease Query for Client results in DHCPLEASEUNASSIGNED or " +
|
||||||
"DHCPLEASEUNKNOWN - removing route & forwarding reply to originator");
|
"DHCPLEASEUNKNOWN - removing route & forwarding reply to originator");
|
||||||
MacAddress clientMacAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
|
if (learnRouteFromLeasequery) {
|
||||||
VlanId vlanId = VlanId.vlanId(packet.getVlanID());
|
MacAddress clientMacAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
|
||||||
HostId hostId = HostId.hostId(clientMacAddress, vlanId);
|
VlanId vlanId = VlanId.vlanId(packet.getVlanID());
|
||||||
DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
|
HostId hostId = HostId.hostId(clientMacAddress, vlanId);
|
||||||
|
DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
|
||||||
|
|
||||||
if (record == null) {
|
if (record == null) {
|
||||||
log.warn("Can't find record for host {} when handling LQ UNKNOWN/UNASSIGNED message", hostId);
|
log.warn("Can't find record for host {} when handling LQ UNKNOWN/UNASSIGNED message", hostId);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ip4Address clientIP = record.ip4Address().orElse(null);
|
||||||
|
log.debug("LQ: IP of host is " + clientIP.getIp4Address());
|
||||||
|
|
||||||
|
// find the new NH by looking at the src MAC of the dhcp request
|
||||||
|
// from the LQ store
|
||||||
|
MacAddress nextHopMac = record.nextHop().orElse(null);
|
||||||
|
log.debug("LQ: MAC of resulting *Existing* NH for that route is " + nextHopMac.toString());
|
||||||
|
|
||||||
|
// find the next hop IP from its mac
|
||||||
|
HostId gwHostId = HostId.hostId(nextHopMac, vlanId);
|
||||||
|
Host gwHost = hostService.getHost(gwHostId);
|
||||||
|
|
||||||
|
if (gwHost == null) {
|
||||||
|
log.warn("Can't find gateway for new NH host " + gwHostId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ip4Address nextHopIp = gwHost.ipAddresses()
|
||||||
|
.stream()
|
||||||
|
.filter(IpAddress::isIp4)
|
||||||
|
.map(IpAddress::getIp4Address)
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
|
if (nextHopIp == null) {
|
||||||
|
log.warn("Can't find IP address of gateway {}", gwHost);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug("LQ: *Existing* NH IP for host is " + nextHopIp.getIp4Address() + " removing route for it");
|
||||||
|
Route route = new Route(Route.Source.DHCP, clientIP.toIpPrefix(), nextHopIp);
|
||||||
|
routeStore.removeRoute(route);
|
||||||
|
|
||||||
|
// remove from temp store
|
||||||
|
dhcpRelayStore.removeDhcpRecord(hostId);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ip4Address clientIP = record.ip4Address().orElse(null);
|
|
||||||
log.debug("LQ: IP of host is " + clientIP.getIp4Address());
|
|
||||||
|
|
||||||
// find the new NH by looking at the src MAC of the dhcp request
|
|
||||||
// from the LQ store
|
|
||||||
MacAddress nextHopMac = record.nextHop().orElse(null);
|
|
||||||
log.debug("LQ: MAC of resulting *Existing* NH for that route is " + nextHopMac.toString());
|
|
||||||
|
|
||||||
// find the next hop IP from its mac
|
|
||||||
HostId gwHostId = HostId.hostId(nextHopMac, vlanId);
|
|
||||||
Host gwHost = hostService.getHost(gwHostId);
|
|
||||||
|
|
||||||
if (gwHost == null) {
|
|
||||||
log.warn("Can't find gateway for new NH host " + gwHostId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ip4Address nextHopIp = gwHost.ipAddresses()
|
|
||||||
.stream()
|
|
||||||
.filter(IpAddress::isIp4)
|
|
||||||
.map(IpAddress::getIp4Address)
|
|
||||||
.findFirst()
|
|
||||||
.orElse(null);
|
|
||||||
|
|
||||||
if (nextHopIp == null) {
|
|
||||||
log.warn("Can't find IP address of gateway {}", gwHost);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
log.debug("LQ: *Existing* NH IP for host is " + nextHopIp.getIp4Address() + " removing route for it");
|
|
||||||
Route route = new Route(Route.Source.DHCP, clientIP.toIpPrefix(), nextHopIp);
|
|
||||||
routeStore.removeRoute(route);
|
|
||||||
|
|
||||||
// remove from temp store
|
|
||||||
dhcpRelayStore.removeDhcpRecord(hostId);
|
|
||||||
|
|
||||||
// and forward to client
|
// and forward to client
|
||||||
Ethernet ethernetPacket = processLeaseQueryFromServer(packet);
|
InternalPacket ethernetPacket = processLeaseQueryFromServer(packet);
|
||||||
if (ethernetPacket != null) {
|
if (ethernetPacket != null) {
|
||||||
sendResponseToClient(ethernetPacket, dhcpPayload);
|
sendResponseToClient(ethernetPacket, dhcpPayload);
|
||||||
}
|
}
|
||||||
@ -683,7 +730,7 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
ConnectPoint receivedFrom = context.inPacket().receivedFrom();
|
ConnectPoint receivedFrom = context.inPacket().receivedFrom();
|
||||||
DeviceId receivedFromDevice = receivedFrom.deviceId();
|
DeviceId receivedFromDevice = receivedFrom.deviceId();
|
||||||
Ip4Address relayAgentIp = null;
|
Ip4Address relayAgentIp = null;
|
||||||
relayAgentIp = dhcp4HandlerUtil.getRelayAgentIPv4Address(clientInterfaces);
|
relayAgentIp = Dhcp4HandlerUtil.getRelayAgentIPv4Address(clientInterfaces);
|
||||||
MacAddress relayAgentMac = clientInterfaces.iterator().next().mac();
|
MacAddress relayAgentMac = clientInterfaces.iterator().next().mac();
|
||||||
if (relayAgentIp == null || relayAgentMac == null) {
|
if (relayAgentIp == null || relayAgentMac == null) {
|
||||||
log.warn("Missing DHCP relay agent interface Ipv4 addr config for "
|
log.warn("Missing DHCP relay agent interface Ipv4 addr config for "
|
||||||
@ -724,7 +771,7 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
ConnectPoint clientConnectionPoint = context.inPacket().receivedFrom();
|
ConnectPoint clientConnectionPoint = context.inPacket().receivedFrom();
|
||||||
VlanId vlanIdInUse = VlanId.vlanId(ethernetPacket.getVlanID());
|
VlanId vlanIdInUse = VlanId.vlanId(ethernetPacket.getVlanID());
|
||||||
Interface clientInterface = interfaceService.getInterfacesByPort(clientConnectionPoint)
|
Interface clientInterface = interfaceService.getInterfacesByPort(clientConnectionPoint)
|
||||||
.stream().filter(iface -> dhcp4HandlerUtil.interfaceContainsVlan(iface, vlanIdInUse))
|
.stream().filter(iface -> Dhcp4HandlerUtil.interfaceContainsVlan(iface, vlanIdInUse))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
|
|
||||||
@ -735,9 +782,9 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
|
|
||||||
for (DhcpServerInfo serverInfo : copyServerInfoList) {
|
for (DhcpServerInfo serverInfo : copyServerInfoList) {
|
||||||
etherReply = (Ethernet) ethernetPacket.clone();
|
etherReply = (Ethernet) ethernetPacket.clone();
|
||||||
ipv4Packet = (IPv4) etherReply.getPayload();
|
ipv4Packet = (IPv4) etherReply.getPayload();
|
||||||
udpPacket = (UDP) ipv4Packet.getPayload();
|
udpPacket = (UDP) ipv4Packet.getPayload();
|
||||||
dhcpPacket = (DHCP) udpPacket.getPayload();
|
dhcpPacket = (DHCP) udpPacket.getPayload();
|
||||||
if (!checkDhcpServerConnPt(directConnFlag, serverInfo)) {
|
if (!checkDhcpServerConnPt(directConnFlag, serverInfo)) {
|
||||||
log.warn("Can't get server connect point, ignore");
|
log.warn("Can't get server connect point, ignore");
|
||||||
continue;
|
continue;
|
||||||
@ -850,8 +897,9 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
ipv4Packet.setPayload(udpPacket);
|
ipv4Packet.setPayload(udpPacket);
|
||||||
ipv4Packet.setTtl((byte) 64);
|
ipv4Packet.setTtl((byte) 64);
|
||||||
etherReply.setPayload(ipv4Packet);
|
etherReply.setPayload(ipv4Packet);
|
||||||
InternalPacket internalPacket = new Dhcp4HandlerUtil().new InternalPacket(etherReply,
|
InternalPacket internalPacket = InternalPacket.internalPacket(etherReply,
|
||||||
serverInfo.getDhcpServerConnectPoint().get());
|
serverInfo.getDhcpServerConnectPoint().get());
|
||||||
|
|
||||||
internalPackets.add(internalPacket);
|
internalPackets.add(internalPacket);
|
||||||
}
|
}
|
||||||
return internalPackets;
|
return internalPackets;
|
||||||
@ -898,9 +946,6 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
boolean directConnFlag = directlyConnected(dhcpPacket);
|
boolean directConnFlag = directlyConnected(dhcpPacket);
|
||||||
|
|
||||||
// Multi DHCP Start
|
// Multi DHCP Start
|
||||||
ConnectPoint clientConnectionPoint = context.inPacket().receivedFrom();
|
|
||||||
VlanId vlanIdInUse = VlanId.vlanId(ethernetPacket.getVlanID());
|
|
||||||
|
|
||||||
List<InternalPacket> internalPackets = new ArrayList<>();
|
List<InternalPacket> internalPackets = new ArrayList<>();
|
||||||
List<DhcpServerInfo> serverInfoList = findValidServerInfo(directConnFlag);
|
List<DhcpServerInfo> serverInfoList = findValidServerInfo(directConnFlag);
|
||||||
List<DhcpServerInfo> copyServerInfoList = new ArrayList<>(serverInfoList);
|
List<DhcpServerInfo> copyServerInfoList = new ArrayList<>(serverInfoList);
|
||||||
@ -947,27 +992,28 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
if (newServerInfo.getDhcpConnectVlan().isPresent()) {
|
if (newServerInfo.getDhcpConnectVlan().isPresent()) {
|
||||||
etherReply.setVlanID(serverInfo.getDhcpConnectVlan().get().toShort());
|
etherReply.setVlanID(serverInfo.getDhcpConnectVlan().get().toShort());
|
||||||
}
|
}
|
||||||
relayAgentIp = newServerInfo.getRelayAgentIp4(receivedFromDevice).orElse(null);
|
if (learnRouteFromLeasequery) {
|
||||||
// Sets relay agent IP
|
|
||||||
int effectiveRelayAgentIp = relayAgentIp != null ?
|
|
||||||
relayAgentIp.toInt() : clientInterfaceIp.toInt();
|
|
||||||
dhcpPacket.setGatewayIPAddress(effectiveRelayAgentIp);
|
|
||||||
} else {
|
|
||||||
if (!newServerInfo.getDhcpServerIp4().isPresent()) {
|
|
||||||
//do nothing
|
|
||||||
} else if (!newServerInfo.getDhcpConnectMac().isPresent()) {
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
relayAgentIp = newServerInfo.getRelayAgentIp4(receivedFromDevice).orElse(null);
|
relayAgentIp = newServerInfo.getRelayAgentIp4(receivedFromDevice).orElse(null);
|
||||||
// Sets relay agent IP
|
// Sets relay agent IP
|
||||||
int effectiveRelayAgentIp = relayAgentIp != null ?
|
int effectiveRelayAgentIp = relayAgentIp != null ?
|
||||||
relayAgentIp.toInt() : clientInterfaceIp.toInt();
|
relayAgentIp.toInt() : clientInterfaceIp.toInt();
|
||||||
dhcpPacket.setGatewayIPAddress(effectiveRelayAgentIp);
|
dhcpPacket.setGatewayIPAddress(effectiveRelayAgentIp);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!newServerInfo.getDhcpServerIp4().isPresent()) {
|
||||||
|
//do nothing
|
||||||
|
} else if (!newServerInfo.getDhcpConnectMac().isPresent()) {
|
||||||
|
continue;
|
||||||
|
} else if (learnRouteFromLeasequery) {
|
||||||
|
relayAgentIp = newServerInfo.getRelayAgentIp4(receivedFromDevice).orElse(null);
|
||||||
|
// Sets relay agent IP
|
||||||
|
int effectiveRelayAgentIp = relayAgentIp != null ?
|
||||||
|
relayAgentIp.toInt() : clientInterfaceIp.toInt();
|
||||||
dhcpPacket.setGatewayIPAddress(effectiveRelayAgentIp);
|
dhcpPacket.setGatewayIPAddress(effectiveRelayAgentIp);
|
||||||
log.info("Relay Agent IP {}", relayAgentIp);
|
log.debug("Relay Agent IP {}", relayAgentIp);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("In Direct");
|
log.trace("Indirect");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove broadcast flag
|
// Remove broadcast flag
|
||||||
@ -981,12 +1027,14 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
ipv4Packet.setPayload(udpPacket);
|
ipv4Packet.setPayload(udpPacket);
|
||||||
ipv4Packet.setTtl((byte) 64);
|
ipv4Packet.setTtl((byte) 64);
|
||||||
etherReply.setPayload(ipv4Packet);
|
etherReply.setPayload(ipv4Packet);
|
||||||
|
udpPacket.resetChecksum();
|
||||||
////return etherReply;
|
////return etherReply;
|
||||||
Dhcp4HandlerUtil.InternalPacket internalPacket = new Dhcp4HandlerUtil().new InternalPacket(etherReply,
|
InternalPacket internalPacket = InternalPacket.internalPacket(etherReply,
|
||||||
newServerInfo.getDhcpServerConnectPoint().get());
|
newServerInfo.getDhcpServerConnectPoint().get());
|
||||||
|
|
||||||
internalPackets.add(internalPacket);
|
internalPackets.add(internalPacket);
|
||||||
}
|
}
|
||||||
log.warn("num of processLeaseQueryFromAgent packets to send is{}", internalPackets.size());
|
log.debug("num of processLeaseQueryFromAgent packets to send is: {}", internalPackets.size());
|
||||||
|
|
||||||
return internalPackets;
|
return internalPackets;
|
||||||
}
|
}
|
||||||
@ -1066,7 +1114,7 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
* @param ethernetPacket the original packet comes from server
|
* @param ethernetPacket the original packet comes from server
|
||||||
* @return new packet which will send to the client
|
* @return new packet which will send to the client
|
||||||
*/
|
*/
|
||||||
private Ethernet processDhcpPacketFromServer(PacketContext context, Ethernet ethernetPacket) {
|
private InternalPacket processDhcpPacketFromServer(PacketContext context, Ethernet ethernetPacket) {
|
||||||
// get dhcp header.
|
// get dhcp header.
|
||||||
Ethernet etherReply = (Ethernet) ethernetPacket.clone();
|
Ethernet etherReply = (Ethernet) ethernetPacket.clone();
|
||||||
IPv4 ipv4Packet = (IPv4) etherReply.getPayload();
|
IPv4 ipv4Packet = (IPv4) etherReply.getPayload();
|
||||||
@ -1090,7 +1138,7 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
log.warn("Cannot find server info");
|
log.warn("Cannot find server info");
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
if (dhcp4HandlerUtil.isServerIpEmpty(foundServerInfo)) {
|
if (Dhcp4HandlerUtil.isServerIpEmpty(foundServerInfo)) {
|
||||||
log.warn("Cannot find server info's ipaddress");
|
log.warn("Cannot find server info's ipaddress");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -1160,7 +1208,7 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
udpPacket.setPayload(dhcpPayload);
|
udpPacket.setPayload(dhcpPayload);
|
||||||
ipv4Packet.setPayload(udpPacket);
|
ipv4Packet.setPayload(udpPacket);
|
||||||
etherReply.setPayload(ipv4Packet);
|
etherReply.setPayload(ipv4Packet);
|
||||||
return etherReply;
|
return InternalPacket.internalPacket(etherReply, clientInterface.connectPoint());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1169,7 +1217,7 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
* @param ethernetPacket the original packet comes from server
|
* @param ethernetPacket the original packet comes from server
|
||||||
* @return new packet which will send to the client
|
* @return new packet which will send to the client
|
||||||
*/
|
*/
|
||||||
private Ethernet processLeaseQueryFromServer(Ethernet ethernetPacket) {
|
private InternalPacket processLeaseQueryFromServer(Ethernet ethernetPacket) {
|
||||||
// get dhcp header.
|
// get dhcp header.
|
||||||
Ethernet etherReply = (Ethernet) ethernetPacket.clone();
|
Ethernet etherReply = (Ethernet) ethernetPacket.clone();
|
||||||
IPv4 ipv4Packet = (IPv4) etherReply.getPayload();
|
IPv4 ipv4Packet = (IPv4) etherReply.getPayload();
|
||||||
@ -1178,7 +1226,33 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
|
|
||||||
// determine the vlanId of the client host - note that this vlan id
|
// determine the vlanId of the client host - note that this vlan id
|
||||||
// could be different from the vlan in the packet from the server
|
// could be different from the vlan in the packet from the server
|
||||||
Interface clientInterface = getClientInterface(ethernetPacket, dhcpPayload).orElse(null);
|
Interface clientInterface = null;
|
||||||
|
MacAddress destinationMac = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
|
||||||
|
|
||||||
|
if (!learnRouteFromLeasequery) {
|
||||||
|
int giaddr = ipv4Packet.getDestinationAddress();
|
||||||
|
IpAddress destinationAddress = Ip4Address.valueOf(giaddr);
|
||||||
|
log.debug("DHCPLEASEQUERYRESP giaddr: {}({})", giaddr, destinationAddress);
|
||||||
|
|
||||||
|
Host destinationHost = hostService.getHostsByIp(destinationAddress).stream().findFirst().orElse(null);
|
||||||
|
if (destinationHost != null) {
|
||||||
|
destinationMac = destinationHost.mac();
|
||||||
|
log.trace("DHCPLEASEQUERYRESP destination mac is: {}", destinationMac);
|
||||||
|
ConnectPoint destinationLocation = destinationHost.location();
|
||||||
|
log.trace("Lookup for client interface by destination location {}", destinationLocation);
|
||||||
|
clientInterface = interfaceService.getInterfacesByPort(destinationLocation)
|
||||||
|
.stream()
|
||||||
|
.filter(iface -> interfaceContainsVlan(iface, VlanId.vlanId(etherReply.getVlanID())))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
log.trace("Found Host {} by ip {}", destinationHost, destinationAddress);
|
||||||
|
log.debug("DHCPLEASEQUERYRESP Client interface: {}",
|
||||||
|
(clientInterface != null ? clientInterface : "not resolved"));
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
clientInterface = getClientInterface(ethernetPacket, dhcpPayload).orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
if (clientInterface == null) {
|
if (clientInterface == null) {
|
||||||
log.warn("Cannot find the interface for the DHCP {}", dhcpPayload);
|
log.warn("Cannot find the interface for the DHCP {}", dhcpPayload);
|
||||||
@ -1197,31 +1271,40 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
etherReply.setVlanID(vlanId.toShort());
|
etherReply.setVlanID(vlanId.toShort());
|
||||||
etherReply.setSourceMACAddress(clientInterface.mac());
|
etherReply.setSourceMACAddress(clientInterface.mac());
|
||||||
|
|
||||||
if (!directlyConnected(dhcpPayload)) {
|
if (!directlyConnected(dhcpPayload) && learnRouteFromLeasequery) {
|
||||||
// if client is indirectly connected, try use next hop mac address
|
// if client is indirectly connected, try use next hop mac address
|
||||||
MacAddress macAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
|
MacAddress macAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
|
||||||
HostId hostId = HostId.hostId(macAddress, vlanId);
|
HostId hostId = HostId.hostId(macAddress, vlanId);
|
||||||
DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
|
DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
|
||||||
if (record != null) {
|
if (record != null) {
|
||||||
// if next hop can be found, use mac address of next hop
|
// if next hop can be found, use mac address of next hop
|
||||||
record.nextHop().ifPresent(etherReply::setDestinationMACAddress);
|
Optional<MacAddress> nextHop = record.nextHopTemp();
|
||||||
|
if (!nextHop.isPresent()) {
|
||||||
|
nextHop = record.nextHop();
|
||||||
|
}
|
||||||
|
nextHop.ifPresent(etherReply::setDestinationMACAddress);
|
||||||
} else {
|
} else {
|
||||||
// otherwise, discard the packet
|
// otherwise, discard the packet
|
||||||
log.warn("Can't find record for host id {}, discard packet", hostId);
|
log.warn("Can't find record for host id {}, discard packet", hostId);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
etherReply.setDestinationMACAddress(dhcpPayload.getClientHardwareAddress());
|
etherReply.setDestinationMACAddress(destinationMac);
|
||||||
}
|
}
|
||||||
|
|
||||||
// default is client port
|
|
||||||
udpPacket.setSourcePort(UDP.DHCP_SERVER_PORT);
|
udpPacket.setSourcePort(UDP.DHCP_SERVER_PORT);
|
||||||
udpPacket.setDestinationPort(UDP.DHCP_CLIENT_PORT);
|
if (directlyConnected(dhcpPayload)) {
|
||||||
|
udpPacket.setDestinationPort(UDP.DHCP_CLIENT_PORT);
|
||||||
|
} else {
|
||||||
|
udpPacket.setDestinationPort(UDP.DHCP_SERVER_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
udpPacket.setPayload(dhcpPayload);
|
udpPacket.setPayload(dhcpPayload);
|
||||||
ipv4Packet.setPayload(udpPacket);
|
ipv4Packet.setPayload(udpPacket);
|
||||||
etherReply.setPayload(ipv4Packet);
|
etherReply.setPayload(ipv4Packet);
|
||||||
return etherReply;
|
udpPacket.resetChecksum();
|
||||||
|
|
||||||
|
return InternalPacket.internalPacket(etherReply, clientInterface.connectPoint());
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Extracts VLAN ID from relay agent option.
|
* Extracts VLAN ID from relay agent option.
|
||||||
@ -1274,6 +1357,17 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
return ethernet;
|
return ethernet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isDhcpPacketLeasequery(DHCP dhcpPacket) {
|
||||||
|
switch (dhcpPacket.getPacketType()) {
|
||||||
|
case DHCPLEASEACTIVE:
|
||||||
|
case DHCPLEASEQUERY:
|
||||||
|
case DHCPLEASEUNASSIGNED:
|
||||||
|
case DHCPLEASEUNKNOWN:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the host is directly connected to the network or not.
|
* Check if the host is directly connected to the network or not.
|
||||||
@ -1282,6 +1376,11 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
* @return true if the host is directly connected to the network; false otherwise
|
* @return true if the host is directly connected to the network; false otherwise
|
||||||
*/
|
*/
|
||||||
private boolean directlyConnected(DHCP dhcpPayload) {
|
private boolean directlyConnected(DHCP dhcpPayload) {
|
||||||
|
// leasequery is always indirect
|
||||||
|
if (isDhcpPacketLeasequery(dhcpPayload)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
DhcpRelayAgentOption relayAgentOption =
|
DhcpRelayAgentOption relayAgentOption =
|
||||||
(DhcpRelayAgentOption) dhcpPayload.getOption(OptionCode_CircuitID);
|
(DhcpRelayAgentOption) dhcpPayload.getOption(OptionCode_CircuitID);
|
||||||
|
|
||||||
@ -1445,31 +1544,30 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
/**
|
/**
|
||||||
* Send the response DHCP to the requester host.
|
* Send the response DHCP to the requester host.
|
||||||
*
|
*
|
||||||
* @param ethPacket the packet
|
* @param thePacket the packet
|
||||||
* @param dhcpPayload the DHCP data
|
* @param dhcpPayload the DHCP data
|
||||||
*/
|
*/
|
||||||
private void sendResponseToClient(Ethernet ethPacket, DHCP dhcpPayload) {
|
private void sendResponseToClient(InternalPacket thePacket, DHCP dhcpPayload) {
|
||||||
Optional<Interface> outInterface = getClientInterface(ethPacket, dhcpPayload);
|
checkNotNull(thePacket, "Nothing to send");
|
||||||
|
checkNotNull(thePacket.getPacket(), "Packet to send must not be empty");
|
||||||
|
checkNotNull(thePacket.getDestLocation(), "Packet destination not be empty");
|
||||||
|
|
||||||
|
Ethernet ethPacket = thePacket.getPacket();
|
||||||
if (directlyConnected(dhcpPayload)) {
|
if (directlyConnected(dhcpPayload)) {
|
||||||
ethPacket = removeRelayAgentOption(ethPacket);
|
ethPacket = removeRelayAgentOption(ethPacket);
|
||||||
}
|
}
|
||||||
if (!outInterface.isPresent()) {
|
|
||||||
log.warn("Can't find output interface for client, ignore");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Interface outIface = outInterface.get();
|
|
||||||
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
|
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
|
||||||
.setOutput(outIface.connectPoint().port())
|
.setOutput(thePacket.getDestLocation().port())
|
||||||
.build();
|
.build();
|
||||||
OutboundPacket o = new DefaultOutboundPacket(
|
OutboundPacket o = new DefaultOutboundPacket(
|
||||||
outIface.connectPoint().deviceId(),
|
thePacket.getDestLocation().deviceId(),
|
||||||
treatment,
|
treatment,
|
||||||
ByteBuffer.wrap(ethPacket.serialize()));
|
ByteBuffer.wrap(ethPacket.serialize()));
|
||||||
if (log.isTraceEnabled()) {
|
if (log.isTraceEnabled()) {
|
||||||
log.trace("Relaying packet to DHCP client {} via {}, vlan {}",
|
log.trace("Relaying packet to DHCP client {} via {}",
|
||||||
ethPacket,
|
ethPacket,
|
||||||
outIface.connectPoint(),
|
thePacket.getDestLocation());
|
||||||
outIface.vlan());
|
|
||||||
}
|
}
|
||||||
packetService.emit(o);
|
packetService.emit(o);
|
||||||
}
|
}
|
||||||
@ -1798,7 +1896,7 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
if (dhcpServerConnectPoint != null && dhcpConnectVlan != null) {
|
if (dhcpServerConnectPoint != null && dhcpConnectVlan != null) {
|
||||||
serverInterface = interfaceService.getInterfacesByPort(dhcpServerConnectPoint)
|
serverInterface = interfaceService.getInterfacesByPort(dhcpServerConnectPoint)
|
||||||
.stream()
|
.stream()
|
||||||
.filter(iface -> dhcp4HandlerUtil.interfaceContainsVlan(iface, dhcpConnectVlan))
|
.filter(iface -> Dhcp4HandlerUtil.interfaceContainsVlan(iface, dhcpConnectVlan))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
} else {
|
} else {
|
||||||
@ -1812,15 +1910,15 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
//forward the packet to ConnectPoint where the DHCP server is attached.
|
//forward the packet to ConnectPoint where the DHCP server is attached.
|
||||||
private void forwardPacket(InternalPacket packet) {
|
private void forwardPacket(InternalPacket packet) {
|
||||||
//send Packetout to dhcp server connectpoint.
|
//send Packetout to dhcp server connectpoint.
|
||||||
if (packet.destLocation != null) {
|
if (packet.getDestLocation() != null) {
|
||||||
TrafficTreatment t = DefaultTrafficTreatment.builder()
|
TrafficTreatment t = DefaultTrafficTreatment.builder()
|
||||||
.setOutput(packet.destLocation.port()).build();
|
.setOutput(packet.getDestLocation().port()).build();
|
||||||
OutboundPacket o = new DefaultOutboundPacket(
|
OutboundPacket o = new DefaultOutboundPacket(
|
||||||
packet.destLocation.deviceId(), t, ByteBuffer.wrap(packet.packet.serialize()));
|
packet.getDestLocation().deviceId(), t, ByteBuffer.wrap(packet.getPacket().serialize()));
|
||||||
if (log.isTraceEnabled()) {
|
if (log.isTraceEnabled()) {
|
||||||
log.trace("Relaying packet to destination {}", packet.destLocation);
|
log.trace("Relaying packet to destination {}", packet.getDestLocation());
|
||||||
}
|
}
|
||||||
log.debug("packetService.emit(o) to port {}", packet.destLocation);
|
log.debug("packetService.emit(o) to port {}", packet.getDestLocation());
|
||||||
packetService.emit(o);
|
packetService.emit(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1842,5 +1940,4 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
}
|
}
|
||||||
return foundServerInfo;
|
return foundServerInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,12 +18,8 @@ package org.onosproject.dhcprelay;
|
|||||||
|
|
||||||
import org.onlab.packet.Ip4Address;
|
import org.onlab.packet.Ip4Address;
|
||||||
import org.onlab.packet.VlanId;
|
import org.onlab.packet.VlanId;
|
||||||
|
|
||||||
import org.onlab.packet.Ethernet;
|
|
||||||
|
|
||||||
import org.onlab.util.HexString;
|
import org.onlab.util.HexString;
|
||||||
import org.onosproject.dhcprelay.api.DhcpServerInfo;
|
import org.onosproject.dhcprelay.api.DhcpServerInfo;
|
||||||
import org.onosproject.net.ConnectPoint;
|
|
||||||
import org.onosproject.net.host.InterfaceIpAddress;
|
import org.onosproject.net.host.InterfaceIpAddress;
|
||||||
import org.onosproject.net.intf.Interface;
|
import org.onosproject.net.intf.Interface;
|
||||||
|
|
||||||
@ -31,10 +27,11 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class Dhcp4HandlerUtil {
|
public final class Dhcp4HandlerUtil {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(Dhcp4HandlerUtil.class);
|
||||||
|
|
||||||
|
private Dhcp4HandlerUtil() {
|
||||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the first v4 interface ip out of a set of interfaces or null.
|
* Returns the first v4 interface ip out of a set of interfaces or null.
|
||||||
@ -42,7 +39,7 @@ public class Dhcp4HandlerUtil {
|
|||||||
* @param intfs set of interfaces
|
* @param intfs set of interfaces
|
||||||
* @return Ip4Address / null if not present
|
* @return Ip4Address / null if not present
|
||||||
*/
|
*/
|
||||||
public Ip4Address getRelayAgentIPv4Address(Set<Interface> intfs) {
|
public static Ip4Address getRelayAgentIPv4Address(Set<Interface> intfs) {
|
||||||
for (Interface intf : intfs) {
|
for (Interface intf : intfs) {
|
||||||
for (InterfaceIpAddress ip : intf.ipAddressesList()) {
|
for (InterfaceIpAddress ip : intf.ipAddressesList()) {
|
||||||
Ip4Address relayAgentIp = ip.ipAddress().getIp4Address();
|
Ip4Address relayAgentIp = ip.ipAddress().getIp4Address();
|
||||||
@ -61,7 +58,7 @@ public class Dhcp4HandlerUtil {
|
|||||||
* @param vlanId the vlan id
|
* @param vlanId the vlan id
|
||||||
* @return true if the Interface contains the vlan id
|
* @return true if the Interface contains the vlan id
|
||||||
*/
|
*/
|
||||||
public boolean interfaceContainsVlan(Interface iface, VlanId vlanId) {
|
public static boolean interfaceContainsVlan(Interface iface, VlanId vlanId) {
|
||||||
if (vlanId.equals(VlanId.NONE)) {
|
if (vlanId.equals(VlanId.NONE)) {
|
||||||
// untagged packet, check if vlan untagged or vlan native is not NONE
|
// untagged packet, check if vlan untagged or vlan native is not NONE
|
||||||
return !iface.vlanUntagged().equals(VlanId.NONE) ||
|
return !iface.vlanUntagged().equals(VlanId.NONE) ||
|
||||||
@ -77,7 +74,7 @@ public class Dhcp4HandlerUtil {
|
|||||||
* @param serverInfo server info to check
|
* @param serverInfo server info to check
|
||||||
* @return true if server info has v6 ip address; false otherwise
|
* @return true if server info has v6 ip address; false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean isServerIpEmpty(DhcpServerInfo serverInfo) {
|
public static boolean isServerIpEmpty(DhcpServerInfo serverInfo) {
|
||||||
if (!serverInfo.getDhcpServerIp4().isPresent()) {
|
if (!serverInfo.getDhcpServerIp4().isPresent()) {
|
||||||
log.warn("DhcpServerIp not available, use default DhcpServerIp {}",
|
log.warn("DhcpServerIp not available, use default DhcpServerIp {}",
|
||||||
HexString.toHexString(serverInfo.getDhcpServerIp4().get().toOctets()));
|
HexString.toHexString(serverInfo.getDhcpServerIp4().get().toOctets()));
|
||||||
@ -85,20 +82,5 @@ public class Dhcp4HandlerUtil {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* the new class the contains Ethernet packet and destination port.
|
|
||||||
*/
|
|
||||||
public class InternalPacket {
|
|
||||||
Ethernet packet;
|
|
||||||
ConnectPoint destLocation;
|
|
||||||
public InternalPacket(Ethernet newPacket, ConnectPoint newLocation) {
|
|
||||||
packet = newPacket;
|
|
||||||
destLocation = newLocation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,11 +20,12 @@ import com.google.common.collect.HashMultimap;
|
|||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import com.google.common.collect.Multimaps;
|
import com.google.common.collect.Multimaps;
|
||||||
import org.apache.felix.scr.annotations.Activate;
|
|
||||||
import org.apache.felix.scr.annotations.Deactivate;
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import org.apache.felix.scr.annotations.Activate;
|
||||||
import org.apache.felix.scr.annotations.Component;
|
import org.apache.felix.scr.annotations.Component;
|
||||||
|
import org.apache.felix.scr.annotations.Deactivate;
|
||||||
|
import org.apache.felix.scr.annotations.Modified;
|
||||||
import org.apache.felix.scr.annotations.Property;
|
import org.apache.felix.scr.annotations.Property;
|
||||||
import org.apache.felix.scr.annotations.Reference;
|
import org.apache.felix.scr.annotations.Reference;
|
||||||
import org.apache.felix.scr.annotations.ReferenceCardinality;
|
import org.apache.felix.scr.annotations.ReferenceCardinality;
|
||||||
@ -54,6 +55,8 @@ import org.onlab.packet.dhcp.Dhcp6ClientIdOption;
|
|||||||
import org.onlab.packet.dhcp.Dhcp6Duid;
|
import org.onlab.packet.dhcp.Dhcp6Duid;
|
||||||
import org.onlab.packet.DHCP6.MsgType;
|
import org.onlab.packet.DHCP6.MsgType;
|
||||||
import org.onlab.util.HexString;
|
import org.onlab.util.HexString;
|
||||||
|
import org.onlab.util.Tools;
|
||||||
|
import org.onosproject.cfg.ComponentConfigService;
|
||||||
import org.onosproject.core.ApplicationId;
|
import org.onosproject.core.ApplicationId;
|
||||||
import org.onosproject.core.CoreService;
|
import org.onosproject.core.CoreService;
|
||||||
import org.onosproject.dhcprelay.api.DhcpHandler;
|
import org.onosproject.dhcprelay.api.DhcpHandler;
|
||||||
@ -83,7 +86,6 @@ import org.onosproject.net.host.HostProviderService;
|
|||||||
import org.onosproject.net.host.HostService;
|
import org.onosproject.net.host.HostService;
|
||||||
import org.onosproject.net.host.DefaultHostDescription;
|
import org.onosproject.net.host.DefaultHostDescription;
|
||||||
import org.onosproject.net.host.HostDescription;
|
import org.onosproject.net.host.HostDescription;
|
||||||
import org.onosproject.net.host.InterfaceIpAddress;
|
|
||||||
import org.onosproject.net.host.HostListener;
|
import org.onosproject.net.host.HostListener;
|
||||||
import org.onosproject.net.host.HostEvent;
|
import org.onosproject.net.host.HostEvent;
|
||||||
import org.onosproject.net.intf.Interface;
|
import org.onosproject.net.intf.Interface;
|
||||||
@ -101,17 +103,18 @@ import org.onosproject.net.packet.DefaultOutboundPacket;
|
|||||||
import org.onosproject.net.packet.OutboundPacket;
|
import org.onosproject.net.packet.OutboundPacket;
|
||||||
import org.onosproject.net.packet.PacketContext;
|
import org.onosproject.net.packet.PacketContext;
|
||||||
import org.onosproject.net.packet.PacketService;
|
import org.onosproject.net.packet.PacketService;
|
||||||
|
import org.osgi.service.component.ComponentContext;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.onosproject.net.flow.DefaultTrafficTreatment;
|
import org.onosproject.net.flow.DefaultTrafficTreatment;
|
||||||
import org.onosproject.net.flow.TrafficTreatment;
|
import org.onosproject.net.flow.TrafficTreatment;
|
||||||
import org.onosproject.dhcprelay.Dhcp6HandlerUtil.InternalPacket;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.List;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Dictionary;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
@ -132,6 +135,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
public static final ProviderId PROVIDER_ID = new ProviderId("dhcp6", DHCP_V6_RELAY_APP);
|
public static final ProviderId PROVIDER_ID = new ProviderId("dhcp6", DHCP_V6_RELAY_APP);
|
||||||
private static final int IGNORE_CONTROL_PRIORITY = PacketPriority.CONTROL.priorityValue() + 1000;
|
private static final int IGNORE_CONTROL_PRIORITY = PacketPriority.CONTROL.priorityValue() + 1000;
|
||||||
private String gCount = "global";
|
private String gCount = "global";
|
||||||
|
private static final String LQ_ROUTE_PROPERTY_NAME = "learnRouteFromLeasequery";
|
||||||
private static final TrafficSelector CLIENT_SERVER_SELECTOR = DefaultTrafficSelector.builder()
|
private static final TrafficSelector CLIENT_SERVER_SELECTOR = DefaultTrafficSelector.builder()
|
||||||
.matchEthType(Ethernet.TYPE_IPV6)
|
.matchEthType(Ethernet.TYPE_IPV6)
|
||||||
.matchIPProtocol(IPv6.PROTOCOL_UDP)
|
.matchIPProtocol(IPv6.PROTOCOL_UDP)
|
||||||
@ -194,12 +198,18 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
|
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
|
||||||
protected FlowObjectiveService flowObjectiveService;
|
protected FlowObjectiveService flowObjectiveService;
|
||||||
|
|
||||||
|
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
|
||||||
|
protected ComponentConfigService cfgService;
|
||||||
|
|
||||||
|
@Property(name = Dhcp6HandlerImpl.LQ_ROUTE_PROPERTY_NAME, boolValue = false,
|
||||||
|
label = "Enable learning routing information from LQ")
|
||||||
|
private Boolean learnRouteFromLeasequery = Boolean.TRUE;
|
||||||
|
|
||||||
protected HostProviderService providerService;
|
protected HostProviderService providerService;
|
||||||
protected ApplicationId appId;
|
protected ApplicationId appId;
|
||||||
protected Multimap<DeviceId, VlanId> ignoredVlans = Multimaps.synchronizedMultimap(HashMultimap.create());
|
protected Multimap<DeviceId, VlanId> ignoredVlans = Multimaps.synchronizedMultimap(HashMultimap.create());
|
||||||
private InternalHostListener hostListener = new InternalHostListener();
|
private InternalHostListener hostListener = new InternalHostListener();
|
||||||
private Boolean dhcpFpmEnabled = false;
|
private Boolean dhcpFpmEnabled = false;
|
||||||
private Dhcp6HandlerUtil dhcp6HandlerUtil = new Dhcp6HandlerUtil();
|
|
||||||
private List<DhcpServerInfo> defaultServerInfoList = new CopyOnWriteArrayList<>();
|
private List<DhcpServerInfo> defaultServerInfoList = new CopyOnWriteArrayList<>();
|
||||||
private List<DhcpServerInfo> indirectServerInfoList = new CopyOnWriteArrayList<>();
|
private List<DhcpServerInfo> indirectServerInfoList = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
@ -236,7 +246,9 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
DHCP6.MsgType.LEASEQUERY_REPLY.value());
|
DHCP6.MsgType.LEASEQUERY_REPLY.value());
|
||||||
|
|
||||||
@Activate
|
@Activate
|
||||||
protected void activate() {
|
protected void activate(ComponentContext context) {
|
||||||
|
cfgService.registerProperties(getClass());
|
||||||
|
modified(context);
|
||||||
appId = coreService.registerApplication(DHCP_V6_RELAY_APP);
|
appId = coreService.registerApplication(DHCP_V6_RELAY_APP);
|
||||||
providerService = providerRegistry.register(this);
|
providerService = providerRegistry.register(this);
|
||||||
hostService.addListener(hostListener);
|
hostService.addListener(hostListener);
|
||||||
@ -244,6 +256,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
|
|
||||||
@Deactivate
|
@Deactivate
|
||||||
protected void deactivate() {
|
protected void deactivate() {
|
||||||
|
cfgService.unregisterProperties(getClass(), false);
|
||||||
providerRegistry.unregister(this);
|
providerRegistry.unregister(this);
|
||||||
hostService.removeListener(hostListener);
|
hostService.removeListener(hostListener);
|
||||||
defaultServerInfoList.forEach(this::stopMonitoringIps);
|
defaultServerInfoList.forEach(this::stopMonitoringIps);
|
||||||
@ -252,6 +265,18 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
indirectServerInfoList.clear();
|
indirectServerInfoList.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Modified
|
||||||
|
protected void modified(ComponentContext context) {
|
||||||
|
Dictionary<?, ?> properties = context.getProperties();
|
||||||
|
Boolean flag;
|
||||||
|
flag = Tools.isPropertyEnabled(properties, Dhcp6HandlerImpl.LQ_ROUTE_PROPERTY_NAME);
|
||||||
|
if (flag != null) {
|
||||||
|
learnRouteFromLeasequery = flag;
|
||||||
|
log.info("Learning routes from DHCP leasequery is {}",
|
||||||
|
learnRouteFromLeasequery ? "enabled" : "disabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void stopMonitoringIps(DhcpServerInfo serverInfo) {
|
private void stopMonitoringIps(DhcpServerInfo serverInfo) {
|
||||||
serverInfo.getDhcpGatewayIp6().ifPresent(gatewayIp -> {
|
serverInfo.getDhcpGatewayIp6().ifPresent(gatewayIp -> {
|
||||||
hostService.stopMonitoringIp(gatewayIp);
|
hostService.stopMonitoringIp(gatewayIp);
|
||||||
@ -307,7 +332,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
|
|
||||||
public DhcpRecord getDhcpRelayRecordFor(Ip6Address clientAddress) {
|
public DhcpRecord getDhcpRelayRecordFor(Ip6Address clientAddress) {
|
||||||
|
|
||||||
Collection<DhcpRecord> records = dhcpRelayStore.getDhcpRecords();
|
Collection<DhcpRecord> records = dhcpRelayStore.getDhcpRecords();
|
||||||
DhcpRecord dr = null;
|
DhcpRecord dr = null;
|
||||||
for (DhcpRecord e:records) {
|
for (DhcpRecord e:records) {
|
||||||
if (e.ip6Address().isPresent()) {
|
if (e.ip6Address().isPresent()) {
|
||||||
@ -478,7 +503,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
ConnectPoint inPort = context.inPacket().receivedFrom();
|
ConnectPoint inPort = context.inPacket().receivedFrom();
|
||||||
|
|
||||||
if (inPort == null) {
|
if (inPort == null) {
|
||||||
log.warn("incomming ConnectPoint is null");
|
log.warn("incoming ConnectPoint is null");
|
||||||
}
|
}
|
||||||
Set<Interface> receivingInterfaces = interfaceService.getInterfacesByPort(inPort);
|
Set<Interface> receivingInterfaces = interfaceService.getInterfacesByPort(inPort);
|
||||||
//ignore the packets if dhcp client interface is not configured on onos.
|
//ignore the packets if dhcp client interface is not configured on onos.
|
||||||
@ -488,20 +513,21 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (msgTypeVal == DHCP6.MsgType.LEASEQUERY.value()) {
|
if (msgTypeVal == DHCP6.MsgType.LEASEQUERY.value()) {
|
||||||
List<InternalPacket> ethernetClientPacket =
|
List<InternalPacket> ethernetClientPackets =
|
||||||
processLQ6PacketFromClient(context, receivedPacket, receivingInterfaces, dhcp6Payload);
|
learnRouteFromLeasequery ?
|
||||||
for (InternalPacket internalPacket : ethernetClientPacket) {
|
processLQ6PacketFromClient(context, receivedPacket, receivingInterfaces, dhcp6Payload) :
|
||||||
|
processDhcp6ForwardOnly(context, receivedPacket, receivingInterfaces, dhcp6Payload);
|
||||||
|
for (InternalPacket internalPacket : ethernetClientPackets) {
|
||||||
forwardPacket(internalPacket);
|
forwardPacket(internalPacket);
|
||||||
}
|
}
|
||||||
} else if (msgTypeVal == DHCP6.MsgType.LEASEQUERY_REPLY.value()) {
|
} else if (msgTypeVal == DHCP6.MsgType.LEASEQUERY_REPLY.value() && learnRouteFromLeasequery) {
|
||||||
|
|
||||||
IPv6 clientIpv6 = (IPv6) receivedPacket.getPayload();
|
IPv6 clientIpv6 = (IPv6) receivedPacket.getPayload();
|
||||||
UDP clientUdp = (UDP) clientIpv6.getPayload();
|
UDP clientUdp = (UDP) clientIpv6.getPayload();
|
||||||
DHCP6 clientDhcp6 = (DHCP6) clientUdp.getPayload();
|
DHCP6 clientDhcp6 = (DHCP6) clientUdp.getPayload();
|
||||||
Interface serverInterface = dhcp6HandlerUtil.directlyConnected(clientDhcp6) ?
|
Interface serverInterface = Dhcp6HandlerUtil.directlyConnected(clientDhcp6) ?
|
||||||
getServerInterface() : getIndirectServerInterface();
|
getServerInterface() : getIndirectServerInterface();
|
||||||
InternalPacket ethernetPacketReply =
|
InternalPacket ethernetPacketReply =
|
||||||
dhcp6HandlerUtil.processLQ6PacketFromServer(
|
Dhcp6HandlerUtil.processLQ6PacketFromServer(
|
||||||
defaultServerInfoList, indirectServerInfoList,
|
defaultServerInfoList, indirectServerInfoList,
|
||||||
serverInterface, interfaceService,
|
serverInterface, interfaceService,
|
||||||
hostService,
|
hostService,
|
||||||
@ -510,24 +536,21 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
forwardPacket(ethernetPacketReply);
|
forwardPacket(ethernetPacketReply);
|
||||||
}
|
}
|
||||||
handleLeaseQuery6ReplyMsg(context, dhcp6Payload);
|
handleLeaseQuery6ReplyMsg(context, dhcp6Payload);
|
||||||
} else {
|
} else if (MSG_TYPE_FROM_CLIENT.contains(msgTypeVal)) {
|
||||||
if (MSG_TYPE_FROM_CLIENT.contains(msgTypeVal)) {
|
List<InternalPacket> ethernetClientPacket =
|
||||||
|
processDhcp6PacketFromClient(context, receivedPacket, receivingInterfaces);
|
||||||
List<InternalPacket> ethernetClientPacket =
|
for (InternalPacket internalPacket : ethernetClientPacket) {
|
||||||
processDhcp6PacketFromClient(context, receivedPacket, receivingInterfaces);
|
forwardPacket(internalPacket);
|
||||||
for (InternalPacket internalPacket : ethernetClientPacket) {
|
|
||||||
forwardPacket(internalPacket);
|
|
||||||
}
|
|
||||||
} else if (MSG_TYPE_FROM_SERVER.contains(msgTypeVal)) {
|
|
||||||
log.debug("calling processDhcp6PacketFromServer with RELAY_REPL {}", msgTypeVal);
|
|
||||||
InternalPacket ethernetPacketReply =
|
|
||||||
processDhcp6PacketFromServer(context, receivedPacket, receivingInterfaces);
|
|
||||||
if (ethernetPacketReply != null) {
|
|
||||||
forwardPacket(ethernetPacketReply);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.warn("Not so fast, packet type {} not supported yet", msgTypeVal);
|
|
||||||
}
|
}
|
||||||
|
} 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -553,16 +576,21 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
//forward the packet to ConnectPoint where the DHCP server is attached.
|
//forward the packet to ConnectPoint where the DHCP server is attached.
|
||||||
private void forwardPacket(InternalPacket packet) {
|
private void forwardPacket(InternalPacket packet) {
|
||||||
//send Packetout to dhcp server connectpoint.
|
//send Packetout to dhcp server connectpoint.
|
||||||
if (packet.destLocation != null) {
|
if (packet.getDestLocation() != null) {
|
||||||
TrafficTreatment t = DefaultTrafficTreatment.builder()
|
TrafficTreatment t = DefaultTrafficTreatment.builder()
|
||||||
.setOutput(packet.destLocation.port()).build();
|
.setOutput(packet.getDestLocation().port()).build();
|
||||||
OutboundPacket o = new DefaultOutboundPacket(
|
OutboundPacket o = new DefaultOutboundPacket(
|
||||||
packet.destLocation.deviceId(), t, ByteBuffer.wrap(packet.packet.serialize()));
|
packet.getDestLocation().deviceId(), t, ByteBuffer.wrap(packet.getPacket().serialize()));
|
||||||
if (log.isTraceEnabled()) {
|
|
||||||
log.trace("Relaying packet to destination {}", packet.destLocation);
|
|
||||||
}
|
|
||||||
packetService.emit(o);
|
packetService.emit(o);
|
||||||
} // if
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -683,7 +711,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
} else {
|
} else {
|
||||||
DHCP6 leafDhcp = dhcp6HandlerUtil.getDhcp6Leaf(dhcp6Payload);
|
DHCP6 leafDhcp = Dhcp6HandlerUtil.getDhcp6Leaf(dhcp6Payload);
|
||||||
clientIdOption = leafDhcp.getOptions()
|
clientIdOption = leafDhcp.getOptions()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(opt -> opt instanceof Dhcp6ClientIdOption)
|
.filter(opt -> opt instanceof Dhcp6ClientIdOption)
|
||||||
@ -740,7 +768,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
record = record.clone();
|
record = record.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
Boolean isMsgRelease = dhcp6HandlerUtil.isDhcp6Release(dhcp6Packet);
|
Boolean isMsgRelease = Dhcp6HandlerUtil.isDhcp6Release(dhcp6Packet);
|
||||||
IpAddressInfo ipInfo;
|
IpAddressInfo ipInfo;
|
||||||
PdPrefixInfo pdInfo = null;
|
PdPrefixInfo pdInfo = null;
|
||||||
if (directConnFlag) {
|
if (directConnFlag) {
|
||||||
@ -767,7 +795,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DHCP6 leafDhcp = dhcp6HandlerUtil.getDhcp6Leaf(dhcp6Packet);
|
DHCP6 leafDhcp = Dhcp6HandlerUtil.getDhcp6Leaf(dhcp6Packet);
|
||||||
ipInfo = extractIpAddress(leafDhcp);
|
ipInfo = extractIpAddress(leafDhcp);
|
||||||
if (ipInfo == null) {
|
if (ipInfo == null) {
|
||||||
log.debug("ip is null");
|
log.debug("ip is null");
|
||||||
@ -822,7 +850,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (record != null) {
|
if (record != null) {
|
||||||
record.getV6Counters().incrementCounter(dhcp6HandlerUtil.getMsgTypeStr(leafMsgType));
|
record.getV6Counters().incrementCounter(Dhcp6HandlerUtil.getMsgTypeStr(leafMsgType));
|
||||||
record.addLocation(new HostLocation(location, System.currentTimeMillis()));
|
record.addLocation(new HostLocation(location, System.currentTimeMillis()));
|
||||||
record.ip6Status(DHCP6.MsgType.getType(leafMsgType));
|
record.ip6Status(DHCP6.MsgType.getType(leafMsgType));
|
||||||
record.setDirectlyConnected(directConnFlag);
|
record.setDirectlyConnected(directConnFlag);
|
||||||
@ -837,7 +865,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
try {
|
try {
|
||||||
recordSemaphore.acquire();
|
recordSemaphore.acquire();
|
||||||
try {
|
try {
|
||||||
dhcpRelayCountersStore.incrementCounter(gCount, dhcp6HandlerUtil.getMsgTypeStr(leafMsgType));
|
dhcpRelayCountersStore.incrementCounter(gCount, Dhcp6HandlerUtil.getMsgTypeStr(leafMsgType));
|
||||||
} finally {
|
} finally {
|
||||||
// calling release() after a successful acquire()
|
// calling release() after a successful acquire()
|
||||||
recordSemaphore.release();
|
recordSemaphore.release();
|
||||||
@ -856,13 +884,12 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
* @param embeddedDhcp6 the dhcp6 payload within relay
|
* @param embeddedDhcp6 the dhcp6 payload within relay
|
||||||
* @param srcMac client gw/host macAddress
|
* @param srcMac client gw/host macAddress
|
||||||
* @param clientInterface client interface
|
* @param clientInterface client interface
|
||||||
* @param dhcpServerIp6Address DHCP server IP
|
|
||||||
*/
|
*/
|
||||||
private void addHostOrRoute(boolean directConnFlag, ConnectPoint location, DHCP6 dhcp6Relay,
|
private void addHostOrRoute(boolean directConnFlag, ConnectPoint location, DHCP6 dhcp6Relay,
|
||||||
DHCP6 embeddedDhcp6, MacAddress srcMac, Interface clientInterface) {
|
DHCP6 embeddedDhcp6, MacAddress srcMac, Interface clientInterface) {
|
||||||
log.debug("addHostOrRoute entered.");
|
log.debug("addHostOrRoute entered.");
|
||||||
VlanId vlanId = clientInterface.vlan();
|
VlanId vlanId = clientInterface.vlan();
|
||||||
Boolean isMsgReply = dhcp6HandlerUtil.isDhcp6Reply(dhcp6Relay);
|
Boolean isMsgReply = Dhcp6HandlerUtil.isDhcp6Reply(dhcp6Relay);
|
||||||
MacAddress leafClientMac;
|
MacAddress leafClientMac;
|
||||||
Byte leafMsgType;
|
Byte leafMsgType;
|
||||||
|
|
||||||
@ -931,7 +958,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DHCP6 leafDhcp = dhcp6HandlerUtil.getDhcp6Leaf(embeddedDhcp6);
|
DHCP6 leafDhcp = Dhcp6HandlerUtil.getDhcp6Leaf(embeddedDhcp6);
|
||||||
ipInfo = extractIpAddress(leafDhcp);
|
ipInfo = extractIpAddress(leafDhcp);
|
||||||
if (ipInfo == null) {
|
if (ipInfo == null) {
|
||||||
log.debug("ip is null");
|
log.debug("ip is null");
|
||||||
@ -988,7 +1015,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
record.getV6Counters().incrementCounter(dhcp6HandlerUtil.getMsgTypeStr(leafMsgType));
|
record.getV6Counters().incrementCounter(Dhcp6HandlerUtil.getMsgTypeStr(leafMsgType));
|
||||||
record.ip6Status(DHCP6.MsgType.getType(leafMsgType));
|
record.ip6Status(DHCP6.MsgType.getType(leafMsgType));
|
||||||
record.setDirectlyConnected(directConnFlag);
|
record.setDirectlyConnected(directConnFlag);
|
||||||
record.updateLastSeen();
|
record.updateLastSeen();
|
||||||
@ -997,7 +1024,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
try {
|
try {
|
||||||
recordSemaphore.acquire();
|
recordSemaphore.acquire();
|
||||||
try {
|
try {
|
||||||
dhcpRelayCountersStore.incrementCounter(gCount, dhcp6HandlerUtil.getMsgTypeStr(leafMsgType));
|
dhcpRelayCountersStore.incrementCounter(gCount, Dhcp6HandlerUtil.getMsgTypeStr(leafMsgType));
|
||||||
} finally {
|
} finally {
|
||||||
// calling release() after a successful acquire()
|
// calling release() after a successful acquire()
|
||||||
recordSemaphore.release();
|
recordSemaphore.release();
|
||||||
@ -1007,6 +1034,28 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<InternalPacket> processDhcp6ForwardOnly(PacketContext context,
|
||||||
|
Ethernet clientPacket,
|
||||||
|
Set<Interface> clientInterfaces,
|
||||||
|
DHCP6 dhcpPacket) {
|
||||||
|
ConnectPoint inPort = context.inPacket().receivedFrom();
|
||||||
|
log.trace("Got DHCPv6 on port {}", inPort);
|
||||||
|
boolean directConnFlag = Dhcp6HandlerUtil.directlyConnected(dhcpPacket);
|
||||||
|
|
||||||
|
List<InternalPacket> internalPackets = new ArrayList<>();
|
||||||
|
List<DhcpServerInfo> serverInfoList = findValidServerInfo(directConnFlag);
|
||||||
|
|
||||||
|
for (DhcpServerInfo dhcpServer : serverInfoList) {
|
||||||
|
Ethernet newPacket = Dhcp6HandlerUtil.buildDhcp6PacketFromClient(context,
|
||||||
|
clientPacket, clientInterfaces, dhcpServer, getServerInterface(dhcpServer));
|
||||||
|
log.trace("Built packet for server {} : {}", dhcpServer, newPacket);
|
||||||
|
internalPackets.add(InternalPacket.internalPacket(newPacket,
|
||||||
|
dhcpServer.getDhcpServerConnectPoint().get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return internalPackets;
|
||||||
|
}
|
||||||
|
|
||||||
private List<InternalPacket> processLQ6PacketFromClient(PacketContext context,
|
private List<InternalPacket> processLQ6PacketFromClient(PacketContext context,
|
||||||
Ethernet clientPacket,
|
Ethernet clientPacket,
|
||||||
Set<Interface> clientInterfaces,
|
Set<Interface> clientInterfaces,
|
||||||
@ -1048,27 +1097,18 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
MacAddress potentialNH = packet.getSourceMAC();
|
MacAddress potentialNH = packet.getSourceMAC();
|
||||||
VlanId vlanId = VlanId.vlanId(packet.getVlanID());
|
VlanId vlanId = VlanId.vlanId(packet.getVlanID());
|
||||||
setPotentialNextHopForIp6InRelayStore(clientAddress, vlanId, potentialNH);
|
setPotentialNextHopForIp6InRelayStore(clientAddress, vlanId, potentialNH);
|
||||||
|
|
||||||
// 3. route this LQ6 to all relevant servers
|
// 3. route this LQ6 to all relevant servers
|
||||||
IPv6 clientIpv6 = (IPv6) clientPacket.getPayload();
|
IPv6 clientIpv6 = (IPv6) clientPacket.getPayload();
|
||||||
UDP clientUdp = (UDP) clientIpv6.getPayload();
|
UDP clientUdp = (UDP) clientIpv6.getPayload();
|
||||||
DHCP6 clientDhcp6 = (DHCP6) clientUdp.getPayload();
|
DHCP6 clientDhcp6 = (DHCP6) clientUdp.getPayload();
|
||||||
|
|
||||||
boolean directConnFlag = dhcp6HandlerUtil.directlyConnected(clientDhcp6);
|
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<InternalPacket> internalPackets = new ArrayList<>();
|
||||||
List<DhcpServerInfo> serverInfoList = findValidServerInfo(directConnFlag);
|
List<DhcpServerInfo> serverInfoList = findValidServerInfo(directConnFlag);
|
||||||
List<DhcpServerInfo> copyServerInfoList = new ArrayList<DhcpServerInfo>(serverInfoList);
|
List<DhcpServerInfo> copyServerInfoList = new ArrayList<DhcpServerInfo>(serverInfoList);
|
||||||
|
|
||||||
for (DhcpServerInfo serverInfo : copyServerInfoList) {
|
for (DhcpServerInfo serverInfo : copyServerInfoList) {
|
||||||
if (!dhcp6HandlerUtil.checkDhcpServerConnPt(directConnFlag, serverInfo)) {
|
if (!Dhcp6HandlerUtil.checkDhcpServerConnPt(directConnFlag, serverInfo)) {
|
||||||
log.warn("Can't get server connect point, ignore");
|
log.warn("Can't get server connect point, ignore");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1077,14 +1117,11 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
log.warn("Can't get server interface with host info resolved, ignore");
|
log.warn("Can't get server interface with host info resolved, ignore");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Interface serverInterface = getServerInterface(newServerInfo);
|
Interface serverInterface = getServerInterface(newServerInfo);
|
||||||
if (serverInterface == null) {
|
if (serverInterface == null) {
|
||||||
log.warn("Can't get server interface, ignore");
|
log.warn("Can't get server interface, ignore");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Ethernet etherRouted = (Ethernet) clientPacket.clone();
|
Ethernet etherRouted = (Ethernet) clientPacket.clone();
|
||||||
MacAddress macFacingServer = serverInterface.mac();
|
MacAddress macFacingServer = serverInterface.mac();
|
||||||
if (macFacingServer == null) {
|
if (macFacingServer == null) {
|
||||||
@ -1094,7 +1131,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
etherRouted.setSourceMACAddress(macFacingServer);
|
etherRouted.setSourceMACAddress(macFacingServer);
|
||||||
etherRouted.setDestinationMACAddress(newServerInfo.getDhcpConnectMac().get());
|
etherRouted.setDestinationMACAddress(newServerInfo.getDhcpConnectMac().get());
|
||||||
InternalPacket internalPacket =
|
InternalPacket internalPacket =
|
||||||
new Dhcp6HandlerUtil().new InternalPacket(etherRouted,
|
InternalPacket.internalPacket(etherRouted,
|
||||||
serverInfo.getDhcpServerConnectPoint().get());
|
serverInfo.getDhcpServerConnectPoint().get());
|
||||||
internalPackets.add(internalPacket);
|
internalPackets.add(internalPacket);
|
||||||
log.debug("Sending LQ to DHCP server {}", newServerInfo.getDhcpServerIp6());
|
log.debug("Sending LQ to DHCP server {}", newServerInfo.getDhcpServerIp6());
|
||||||
@ -1115,8 +1152,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
Ethernet clientPacket,
|
Ethernet clientPacket,
|
||||||
Set<Interface> clientInterfaces) {
|
Set<Interface> clientInterfaces) {
|
||||||
ConnectPoint receivedFrom = context.inPacket().receivedFrom();
|
ConnectPoint receivedFrom = context.inPacket().receivedFrom();
|
||||||
DeviceId receivedFromDevice = receivedFrom.deviceId();
|
Ip6Address relayAgentIp = Dhcp6HandlerUtil.getRelayAgentIPv6Address(clientInterfaces);
|
||||||
Ip6Address relayAgentIp = dhcp6HandlerUtil.getRelayAgentIPv6Address(clientInterfaces);
|
|
||||||
MacAddress relayAgentMac = clientInterfaces.iterator().next().mac();
|
MacAddress relayAgentMac = clientInterfaces.iterator().next().mac();
|
||||||
if (relayAgentIp == null || relayAgentMac == null) {
|
if (relayAgentIp == null || relayAgentMac == null) {
|
||||||
log.warn("Missing DHCP relay agent interface Ipv6 addr config for "
|
log.warn("Missing DHCP relay agent interface Ipv6 addr config for "
|
||||||
@ -1130,12 +1166,12 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
UDP clientUdp = (UDP) clientIpv6.getPayload();
|
UDP clientUdp = (UDP) clientIpv6.getPayload();
|
||||||
DHCP6 clientDhcp6 = (DHCP6) clientUdp.getPayload();
|
DHCP6 clientDhcp6 = (DHCP6) clientUdp.getPayload();
|
||||||
|
|
||||||
boolean directConnFlag = dhcp6HandlerUtil.directlyConnected(clientDhcp6);
|
boolean directConnFlag = Dhcp6HandlerUtil.directlyConnected(clientDhcp6);
|
||||||
|
|
||||||
ConnectPoint clientConnectionPoint = context.inPacket().receivedFrom();
|
ConnectPoint clientConnectionPoint = context.inPacket().receivedFrom();
|
||||||
VlanId vlanIdInUse = VlanId.vlanId(clientPacket.getVlanID());
|
VlanId vlanIdInUse = VlanId.vlanId(clientPacket.getVlanID());
|
||||||
Interface clientInterface = interfaceService.getInterfacesByPort(clientConnectionPoint)
|
Interface clientInterface = interfaceService.getInterfacesByPort(clientConnectionPoint)
|
||||||
.stream().filter(iface -> dhcp6HandlerUtil.interfaceContainsVlan(iface, vlanIdInUse))
|
.stream().filter(iface -> Dhcp6HandlerUtil.interfaceContainsVlan(iface, vlanIdInUse))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
|
|
||||||
@ -1144,7 +1180,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
List<DhcpServerInfo> copyServerInfoList = new ArrayList<DhcpServerInfo>(serverInfoList);
|
List<DhcpServerInfo> copyServerInfoList = new ArrayList<DhcpServerInfo>(serverInfoList);
|
||||||
|
|
||||||
for (DhcpServerInfo serverInfo : copyServerInfoList) {
|
for (DhcpServerInfo serverInfo : copyServerInfoList) {
|
||||||
if (!dhcp6HandlerUtil.checkDhcpServerConnPt(directConnFlag, serverInfo)) {
|
if (!Dhcp6HandlerUtil.checkDhcpServerConnPt(directConnFlag, serverInfo)) {
|
||||||
log.warn("Can't get server connect point, ignore");
|
log.warn("Can't get server connect point, ignore");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1160,12 +1196,12 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ethernet etherReply = dhcp6HandlerUtil.buildDhcp6PacketFromClient(context, clientPacket,
|
Ethernet etherReply = Dhcp6HandlerUtil.buildDhcp6PacketFromClient(context, clientPacket,
|
||||||
clientInterfaces, newServerInfo, serverInterface);
|
clientInterfaces, newServerInfo, serverInterface);
|
||||||
removeHostOrRoute(directConnFlag, clientConnectionPoint, clientDhcp6, clientPacket,
|
removeHostOrRoute(directConnFlag, clientConnectionPoint, clientDhcp6, clientPacket,
|
||||||
clientIpv6, clientInterface);
|
clientIpv6, clientInterface);
|
||||||
|
|
||||||
InternalPacket internalPacket = new Dhcp6HandlerUtil().new InternalPacket(etherReply,
|
InternalPacket internalPacket = InternalPacket.internalPacket(etherReply,
|
||||||
serverInfo.getDhcpServerConnectPoint().get());
|
serverInfo.getDhcpServerConnectPoint().get());
|
||||||
internalPackets.add(internalPacket);
|
internalPackets.add(internalPacket);
|
||||||
}
|
}
|
||||||
@ -1189,7 +1225,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
IPv6 ipv6Packet = (IPv6) etherReply.getPayload();
|
IPv6 ipv6Packet = (IPv6) etherReply.getPayload();
|
||||||
UDP udpPacket = (UDP) ipv6Packet.getPayload();
|
UDP udpPacket = (UDP) ipv6Packet.getPayload();
|
||||||
DHCP6 dhcp6Relay = (DHCP6) udpPacket.getPayload();
|
DHCP6 dhcp6Relay = (DHCP6) udpPacket.getPayload();
|
||||||
Boolean directConnFlag = dhcp6HandlerUtil.directlyConnected(dhcp6Relay);
|
Boolean directConnFlag = Dhcp6HandlerUtil.directlyConnected(dhcp6Relay);
|
||||||
|
|
||||||
DHCP6 embeddedDhcp6 = dhcp6Relay.getOptions().stream()
|
DHCP6 embeddedDhcp6 = dhcp6Relay.getOptions().stream()
|
||||||
.filter(opt -> opt instanceof Dhcp6RelayOption)
|
.filter(opt -> opt instanceof Dhcp6RelayOption)
|
||||||
@ -1205,7 +1241,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_SERVER_INFO);
|
dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_SERVER_INFO);
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
if (dhcp6HandlerUtil.isServerIpEmpty(foundServerInfo)) {
|
if (Dhcp6HandlerUtil.isServerIpEmpty(foundServerInfo)) {
|
||||||
log.warn("Cannot find server info's ipaddress");
|
log.warn("Cannot find server info's ipaddress");
|
||||||
dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_SERVER_IP6ADDR);
|
dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_SERVER_IP6ADDR);
|
||||||
return null;
|
return null;
|
||||||
@ -1228,7 +1264,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
ConnectPoint clientConnectionPoint = ConnectPoint.deviceConnectPoint(clientConnectionPointStr);
|
ConnectPoint clientConnectionPoint = ConnectPoint.deviceConnectPoint(clientConnectionPointStr);
|
||||||
VlanId vlanIdInUse = VlanId.vlanId(interfaceIdOption.getVlanId());
|
VlanId vlanIdInUse = VlanId.vlanId(interfaceIdOption.getVlanId());
|
||||||
Interface clientInterface = interfaceService.getInterfacesByPort(clientConnectionPoint)
|
Interface clientInterface = interfaceService.getInterfacesByPort(clientConnectionPoint)
|
||||||
.stream().filter(iface -> dhcp6HandlerUtil.interfaceContainsVlan(iface, vlanIdInUse))
|
.stream().filter(iface -> Dhcp6HandlerUtil.interfaceContainsVlan(iface, vlanIdInUse))
|
||||||
.findFirst().orElse(null);
|
.findFirst().orElse(null);
|
||||||
if (clientInterface == null) {
|
if (clientInterface == null) {
|
||||||
log.warn("Cannot get client interface for from packet, abort... vlan {}", vlanIdInUse.toString());
|
log.warn("Cannot get client interface for from packet, abort... vlan {}", vlanIdInUse.toString());
|
||||||
@ -1274,30 +1310,23 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
} else {
|
} else {
|
||||||
udpPacket.setDestinationPort(UDP.DHCP_V6_SERVER_PORT);
|
udpPacket.setDestinationPort(UDP.DHCP_V6_SERVER_PORT);
|
||||||
}
|
}
|
||||||
// add host or route
|
|
||||||
addHostOrRoute(directConnFlag, clientConnectionPoint, dhcp6Relay, embeddedDhcp6,
|
|
||||||
clientMac, clientInterface);
|
|
||||||
|
|
||||||
|
|
||||||
|
boolean hostOrRouteAllowed = learnRouteFromLeasequery ||
|
||||||
|
Dhcp6HandlerUtil.getDhcp6LeafMessageType(dhcp6Relay) != MsgType.LEASEQUERY_REPLY;
|
||||||
|
log.debug("Can add host or route: {}", hostOrRouteAllowed);
|
||||||
|
|
||||||
|
if (hostOrRouteAllowed) {
|
||||||
|
// add host or route
|
||||||
|
addHostOrRoute(directConnFlag, clientConnectionPoint, dhcp6Relay, embeddedDhcp6,
|
||||||
|
clientMac, clientInterface);
|
||||||
|
}
|
||||||
|
|
||||||
udpPacket.setPayload(embeddedDhcp6);
|
udpPacket.setPayload(embeddedDhcp6);
|
||||||
udpPacket.resetChecksum();
|
udpPacket.resetChecksum();
|
||||||
ipv6Packet.setPayload(udpPacket);
|
ipv6Packet.setPayload(udpPacket);
|
||||||
etherReply.setPayload(ipv6Packet);
|
etherReply.setPayload(ipv6Packet);
|
||||||
return new Dhcp6HandlerUtil().new InternalPacket(etherReply, clientConnectionPoint);
|
return InternalPacket.internalPacket(etherReply, clientConnectionPoint);
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the first v6 interface ip out of a set of interfaces or null.
|
|
||||||
// Checks all interfaces, and ignores v6 interface ips
|
|
||||||
private Ip6Address getRelayAgentIPv6Address(Set<Interface> intfs) {
|
|
||||||
for (Interface intf : intfs) {
|
|
||||||
for (InterfaceIpAddress ip : intf.ipAddressesList()) {
|
|
||||||
Ip6Address relayAgentIp = ip.ipAddress().getIp6Address();
|
|
||||||
if (relayAgentIp != null) {
|
|
||||||
return relayAgentIp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1476,23 +1505,6 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the first interface ip from interface.
|
|
||||||
*
|
|
||||||
* @param iface interface of one connect point
|
|
||||||
* @return the first interface IP; null if not exists an IP address in
|
|
||||||
* these interfaces
|
|
||||||
*/
|
|
||||||
private Ip6Address getFirstIpFromInterface(Interface iface) {
|
|
||||||
checkNotNull(iface, "Interface can't be null");
|
|
||||||
return iface.ipAddressesList().stream()
|
|
||||||
.map(InterfaceIpAddress::ipAddress)
|
|
||||||
.filter(IpAddress::isIp6)
|
|
||||||
.map(IpAddress::getIp6Address)
|
|
||||||
.findFirst()
|
|
||||||
.orElse(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets Interface facing to the server for default host.
|
* Gets Interface facing to the server for default host.
|
||||||
*
|
*
|
||||||
@ -1516,7 +1528,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
}
|
}
|
||||||
return interfaceService.getInterfacesByPort(dhcpServerConnectPoint)
|
return interfaceService.getInterfacesByPort(dhcpServerConnectPoint)
|
||||||
.stream()
|
.stream()
|
||||||
.filter(iface -> dhcp6HandlerUtil.interfaceContainsVlan(iface, dhcpConnectVlan))
|
.filter(iface -> Dhcp6HandlerUtil.interfaceContainsVlan(iface, dhcpConnectVlan))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
}
|
}
|
||||||
@ -1546,7 +1558,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
}
|
}
|
||||||
return interfaceService.getInterfacesByPort(indirectDhcpServerConnectPoint)
|
return interfaceService.getInterfacesByPort(indirectDhcpServerConnectPoint)
|
||||||
.stream()
|
.stream()
|
||||||
.filter(iface -> dhcp6HandlerUtil.interfaceContainsVlan(iface, indirectDhcpConnectVlan))
|
.filter(iface -> Dhcp6HandlerUtil.interfaceContainsVlan(iface, indirectDhcpConnectVlan))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
}
|
}
|
||||||
@ -1615,7 +1627,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
|
|||||||
if (dhcpServerConnectPoint != null && dhcpConnectVlan != null) {
|
if (dhcpServerConnectPoint != null && dhcpConnectVlan != null) {
|
||||||
serverInterface = interfaceService.getInterfacesByPort(dhcpServerConnectPoint)
|
serverInterface = interfaceService.getInterfacesByPort(dhcpServerConnectPoint)
|
||||||
.stream()
|
.stream()
|
||||||
.filter(iface -> dhcp6HandlerUtil.interfaceContainsVlan(iface, dhcpConnectVlan))
|
.filter(iface -> Dhcp6HandlerUtil.interfaceContainsVlan(iface, dhcpConnectVlan))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
} else {
|
} else {
|
||||||
|
@ -52,14 +52,16 @@ import org.onosproject.net.HostLocation;
|
|||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
public final class Dhcp6HandlerUtil {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(Dhcp6HandlerUtil.class);
|
||||||
|
|
||||||
public class Dhcp6HandlerUtil {
|
private Dhcp6HandlerUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
|
||||||
// Returns the first v6 interface ip out of a set of interfaces or null.
|
// Returns the first v6 interface ip out of a set of interfaces or null.
|
||||||
// Checks all interfaces, and ignores v6 interface ips
|
// Checks all interfaces, and ignores v6 interface ips
|
||||||
public Ip6Address getRelayAgentIPv6Address(Set<Interface> intfs) {
|
public static Ip6Address getRelayAgentIPv6Address(Set<Interface> intfs) {
|
||||||
for (Interface intf : intfs) {
|
for (Interface intf : intfs) {
|
||||||
for (InterfaceIpAddress ip : intf.ipAddressesList()) {
|
for (InterfaceIpAddress ip : intf.ipAddressesList()) {
|
||||||
Ip6Address relayAgentIp = ip.ipAddress().getIp6Address();
|
Ip6Address relayAgentIp = ip.ipAddress().getIp6Address();
|
||||||
@ -71,6 +73,22 @@ public class Dhcp6HandlerUtil {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the first interface ip from interface.
|
||||||
|
*
|
||||||
|
* @param iface interface of one connect point
|
||||||
|
* @return the first interface IP; null if not exists an IP address in
|
||||||
|
* these interfaces
|
||||||
|
*/
|
||||||
|
private static Ip6Address getFirstIpFromInterface(Interface iface) {
|
||||||
|
checkNotNull(iface, "Interface can't be null");
|
||||||
|
return iface.ipAddressesList().stream()
|
||||||
|
.map(InterfaceIpAddress::ipAddress)
|
||||||
|
.filter(IpAddress::isIp6)
|
||||||
|
.map(IpAddress::getIp6Address)
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* process the LQ reply packet from dhcp server.
|
* process the LQ reply packet from dhcp server.
|
||||||
@ -85,7 +103,7 @@ public class Dhcp6HandlerUtil {
|
|||||||
* @param recevingInterfaces set of server side interfaces
|
* @param recevingInterfaces set of server side interfaces
|
||||||
* @return a packet ready to be sent to relevant output interface
|
* @return a packet ready to be sent to relevant output interface
|
||||||
*/
|
*/
|
||||||
public InternalPacket processLQ6PacketFromServer(
|
public static InternalPacket processLQ6PacketFromServer(
|
||||||
List<DhcpServerInfo> defaultServerInfoList,
|
List<DhcpServerInfo> defaultServerInfoList,
|
||||||
List<DhcpServerInfo> indirectServerInfoList,
|
List<DhcpServerInfo> indirectServerInfoList,
|
||||||
Interface serverInterface,
|
Interface serverInterface,
|
||||||
@ -141,14 +159,14 @@ public class Dhcp6HandlerUtil {
|
|||||||
if ((directConnFlag || indirectDhcpServerIp == null)
|
if ((directConnFlag || indirectDhcpServerIp == null)
|
||||||
&& !inPort.equals(dhcpServerConnectPoint)) {
|
&& !inPort.equals(dhcpServerConnectPoint)) {
|
||||||
log.warn("Receiving port {} is not the same as server connect point {} for direct or indirect-null",
|
log.warn("Receiving port {} is not the same as server connect point {} for direct or indirect-null",
|
||||||
inPort, dhcpServerConnectPoint);
|
inPort, dhcpServerConnectPoint);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!directConnFlag && indirectDhcpServerIp != null &&
|
if (!directConnFlag && indirectDhcpServerIp != null &&
|
||||||
!inPort.equals(indirectDhcpServerConnectPoint)) {
|
!inPort.equals(indirectDhcpServerConnectPoint)) {
|
||||||
log.warn("Receiving port {} is not the same as server connect point {} for indirect",
|
log.warn("Receiving port {} is not the same as server connect point {} for indirect",
|
||||||
inPort, indirectDhcpServerConnectPoint);
|
inPort, indirectDhcpServerConnectPoint);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,9 +198,6 @@ public class Dhcp6HandlerUtil {
|
|||||||
etherReply.setSourceMACAddress(iface.mac());
|
etherReply.setSourceMACAddress(iface.mac());
|
||||||
etherReply.setDestinationMACAddress(host.mac());
|
etherReply.setDestinationMACAddress(host.mac());
|
||||||
|
|
||||||
|
|
||||||
// add host or route
|
|
||||||
//addHostOrRoute(directConnFlag, clientConnectionPoint, lq6Reply, embeddedDhcp6, clientMac, clientInterface);
|
|
||||||
// workaround for a bug where core sends src port as 547 (server)
|
// workaround for a bug where core sends src port as 547 (server)
|
||||||
udpPacket.setDestinationPort(UDP.DHCP_V6_SERVER_PORT);
|
udpPacket.setDestinationPort(UDP.DHCP_V6_SERVER_PORT);
|
||||||
udpPacket.setPayload(lq6Reply);
|
udpPacket.setPayload(lq6Reply);
|
||||||
@ -190,23 +205,7 @@ public class Dhcp6HandlerUtil {
|
|||||||
ipv6Packet.setPayload(udpPacket);
|
ipv6Packet.setPayload(udpPacket);
|
||||||
etherReply.setPayload(ipv6Packet);
|
etherReply.setPayload(ipv6Packet);
|
||||||
|
|
||||||
return new Dhcp6HandlerUtil().new InternalPacket(etherReply, clientConnectionPoint);
|
return InternalPacket.internalPacket(etherReply, clientConnectionPoint);
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns the first interface ip from interface.
|
|
||||||
*
|
|
||||||
* @param iface interface of one connect point
|
|
||||||
* @return the first interface IP; null if not exists an IP address in
|
|
||||||
* these interfaces
|
|
||||||
*/
|
|
||||||
public Ip6Address getFirstIpFromInterface(Interface iface) {
|
|
||||||
checkNotNull(iface, "Interface can't be null");
|
|
||||||
return iface.ipAddressesList().stream()
|
|
||||||
.map(InterfaceIpAddress::ipAddress)
|
|
||||||
.filter(IpAddress::isIp6)
|
|
||||||
.map(IpAddress::getIp6Address)
|
|
||||||
.findFirst()
|
|
||||||
.orElse(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -215,7 +214,7 @@ public class Dhcp6HandlerUtil {
|
|||||||
* @param dhcp6 dhcp6 relay-reply or relay-foward
|
* @param dhcp6 dhcp6 relay-reply or relay-foward
|
||||||
* @return dhcp6Packet dhcp6 packet extracted from relay-message
|
* @return dhcp6Packet dhcp6 packet extracted from relay-message
|
||||||
*/
|
*/
|
||||||
public DHCP6 dhcp6PacketFromRelayPacket(DHCP6 dhcp6) {
|
public static DHCP6 dhcp6PacketFromRelayPacket(DHCP6 dhcp6) {
|
||||||
|
|
||||||
// extract the relay message if exist
|
// extract the relay message if exist
|
||||||
DHCP6 dhcp6Payload = dhcp6.getOptions().stream()
|
DHCP6 dhcp6Payload = dhcp6.getOptions().stream()
|
||||||
@ -239,7 +238,7 @@ public class Dhcp6HandlerUtil {
|
|||||||
* @param relayPacket dhcp6 relay packet
|
* @param relayPacket dhcp6 relay packet
|
||||||
* @return leafPacket non-relay dhcp6 packet
|
* @return leafPacket non-relay dhcp6 packet
|
||||||
*/
|
*/
|
||||||
public DHCP6 getDhcp6Leaf(DHCP6 relayPacket) {
|
public static DHCP6 getDhcp6Leaf(DHCP6 relayPacket) {
|
||||||
DHCP6 dhcp6Parent = relayPacket;
|
DHCP6 dhcp6Parent = relayPacket;
|
||||||
DHCP6 dhcp6Child = null;
|
DHCP6 dhcp6Child = null;
|
||||||
|
|
||||||
@ -263,13 +262,25 @@ public class Dhcp6HandlerUtil {
|
|||||||
return dhcp6Child;
|
return dhcp6Child;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine DHCP message type (direct DHCPv6 or wrapped into relay messages).
|
||||||
|
*
|
||||||
|
* @param relayPacket {@link DHCP6} packet to be parsed
|
||||||
|
* @return {@link DHCP6.MsgType} contained message type of dhcpv6 packet/relay-message
|
||||||
|
*/
|
||||||
|
public static DHCP6.MsgType getDhcp6LeafMessageType(DHCP6 relayPacket) {
|
||||||
|
checkNotNull(relayPacket);
|
||||||
|
DHCP6 dhcp6Child = getDhcp6Leaf(relayPacket);
|
||||||
|
return DHCP6.MsgType.getType(dhcp6Child != null ? dhcp6Child.getMsgType() : relayPacket.getMsgType());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check if DHCP6 relay-reply is reply.
|
* check if DHCP6 relay-reply is reply.
|
||||||
*
|
*
|
||||||
* @param relayPacket dhcp6 relay-reply
|
* @param relayPacket dhcp6 relay-reply
|
||||||
* @return boolean relay-reply contains ack
|
* @return boolean relay-reply contains ack
|
||||||
*/
|
*/
|
||||||
public boolean isDhcp6Reply(DHCP6 relayPacket) {
|
public static boolean isDhcp6Reply(DHCP6 relayPacket) {
|
||||||
DHCP6 leafDhcp6 = getDhcp6Leaf(relayPacket);
|
DHCP6 leafDhcp6 = getDhcp6Leaf(relayPacket);
|
||||||
if (leafDhcp6 != null) {
|
if (leafDhcp6 != null) {
|
||||||
if (leafDhcp6.getMsgType() == DHCP6.MsgType.REPLY.value()) {
|
if (leafDhcp6.getMsgType() == DHCP6.MsgType.REPLY.value()) {
|
||||||
@ -291,7 +302,7 @@ public class Dhcp6HandlerUtil {
|
|||||||
* @param dhcp6Payload dhcp6 packet
|
* @param dhcp6Payload dhcp6 packet
|
||||||
* @return boolean dhcp6 contains release
|
* @return boolean dhcp6 contains release
|
||||||
*/
|
*/
|
||||||
public boolean isDhcp6Release(DHCP6 dhcp6Payload) {
|
public static boolean isDhcp6Release(DHCP6 dhcp6Payload) {
|
||||||
if (dhcp6Payload.getMsgType() == DHCP6.MsgType.RELEASE.value()) {
|
if (dhcp6Payload.getMsgType() == DHCP6.MsgType.RELEASE.value()) {
|
||||||
log.debug("isDhcp6Release true.");
|
log.debug("isDhcp6Release true.");
|
||||||
return true; // must be directly connected
|
return true; // must be directly connected
|
||||||
@ -319,7 +330,7 @@ public class Dhcp6HandlerUtil {
|
|||||||
* @param msgTypeVal msgType byte of dhcp6 packet
|
* @param msgTypeVal msgType byte of dhcp6 packet
|
||||||
* @return String string value of dhcp6 msg type
|
* @return String string value of dhcp6 msg type
|
||||||
*/
|
*/
|
||||||
public String getMsgTypeStr(byte msgTypeVal) {
|
public static String getMsgTypeStr(byte msgTypeVal) {
|
||||||
MsgType msgType = DHCP6.MsgType.getType(msgTypeVal);
|
MsgType msgType = DHCP6.MsgType.getType(msgTypeVal);
|
||||||
return DHCP6.MsgType.getMsgTypeStr(msgType);
|
return DHCP6.MsgType.getMsgTypeStr(msgType);
|
||||||
}
|
}
|
||||||
@ -331,7 +342,7 @@ public class Dhcp6HandlerUtil {
|
|||||||
* @param dhcp6Packet dhcp6 packet
|
* @param dhcp6Packet dhcp6 packet
|
||||||
* @return String string value of dhcp6 leaf packet msg type
|
* @return String string value of dhcp6 leaf packet msg type
|
||||||
*/
|
*/
|
||||||
public String findLeafMsgType(boolean directConnFlag, DHCP6 dhcp6Packet) {
|
public static String findLeafMsgType(boolean directConnFlag, DHCP6 dhcp6Packet) {
|
||||||
if (directConnFlag) {
|
if (directConnFlag) {
|
||||||
return getMsgTypeStr(dhcp6Packet.getMsgType());
|
return getMsgTypeStr(dhcp6Packet.getMsgType());
|
||||||
} else {
|
} else {
|
||||||
@ -351,7 +362,7 @@ public class Dhcp6HandlerUtil {
|
|||||||
* @param vlanId the vlan id
|
* @param vlanId the vlan id
|
||||||
* @return true if the Interface contains the vlan id
|
* @return true if the Interface contains the vlan id
|
||||||
*/
|
*/
|
||||||
public boolean interfaceContainsVlan(Interface iface, VlanId vlanId) {
|
public static boolean interfaceContainsVlan(Interface iface, VlanId vlanId) {
|
||||||
if (vlanId.equals(VlanId.NONE)) {
|
if (vlanId.equals(VlanId.NONE)) {
|
||||||
// untagged packet, check if vlan untagged or vlan native is not NONE
|
// untagged packet, check if vlan untagged or vlan native is not NONE
|
||||||
return !iface.vlanUntagged().equals(VlanId.NONE) ||
|
return !iface.vlanUntagged().equals(VlanId.NONE) ||
|
||||||
@ -361,27 +372,13 @@ public class Dhcp6HandlerUtil {
|
|||||||
return iface.vlanTagged().contains(vlanId);
|
return iface.vlanTagged().contains(vlanId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* the new class the contains Ethernet packet and destination port.
|
|
||||||
*/
|
|
||||||
public class InternalPacket {
|
|
||||||
Ethernet packet;
|
|
||||||
ConnectPoint destLocation;
|
|
||||||
public InternalPacket(Ethernet newPacket, ConnectPoint newLocation) {
|
|
||||||
packet = newPacket;
|
|
||||||
destLocation = newLocation;
|
|
||||||
}
|
|
||||||
void setLocation(ConnectPoint newLocation) {
|
|
||||||
destLocation = newLocation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Check if the host is directly connected to the network or not.
|
* Check if the host is directly connected to the network or not.
|
||||||
*
|
*
|
||||||
* @param dhcp6Payload the dhcp6 payload
|
* @param dhcp6Payload the dhcp6 payload
|
||||||
* @return true if the host is directly connected to the network; false otherwise
|
* @return true if the host is directly connected to the network; false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean directlyConnected(DHCP6 dhcp6Payload) {
|
public static boolean directlyConnected(DHCP6 dhcp6Payload) {
|
||||||
|
|
||||||
log.debug("directlyConnected enters");
|
log.debug("directlyConnected enters");
|
||||||
if (dhcp6Payload.getMsgType() == DHCP6.MsgType.LEASEQUERY.value() ||
|
if (dhcp6Payload.getMsgType() == DHCP6.MsgType.LEASEQUERY.value() ||
|
||||||
@ -405,7 +402,8 @@ public class Dhcp6HandlerUtil {
|
|||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
// relay-reply
|
// relay-reply
|
||||||
if (dhcp6Payload2.getMsgType() != DHCP6.MsgType.RELAY_REPL.value()) {
|
if (dhcp6Payload2.getMsgType() != DHCP6.MsgType.RELAY_REPL.value()
|
||||||
|
&& dhcp6Payload2.getMsgType() != MsgType.LEASEQUERY_REPLY.value()) {
|
||||||
log.debug("directlyConnected true. 2nd MsgType {}", dhcp6Payload2.getMsgType());
|
log.debug("directlyConnected true. 2nd MsgType {}", dhcp6Payload2.getMsgType());
|
||||||
return true; // must be directly connected
|
return true; // must be directly connected
|
||||||
} else {
|
} else {
|
||||||
@ -425,7 +423,7 @@ public class Dhcp6HandlerUtil {
|
|||||||
* @param serverInfo server info to check
|
* @param serverInfo server info to check
|
||||||
* @return true if server info has v6 ip address; false otherwise
|
* @return true if server info has v6 ip address; false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean isServerIpEmpty(DhcpServerInfo serverInfo) {
|
public static boolean isServerIpEmpty(DhcpServerInfo serverInfo) {
|
||||||
if (!serverInfo.getDhcpServerIp6().isPresent()) {
|
if (!serverInfo.getDhcpServerIp6().isPresent()) {
|
||||||
log.warn("DhcpServerIp not available, use default DhcpServerIp {}",
|
log.warn("DhcpServerIp not available, use default DhcpServerIp {}",
|
||||||
HexString.toHexString(serverInfo.getDhcpServerIp6().get().toOctets()));
|
HexString.toHexString(serverInfo.getDhcpServerIp6().get().toOctets()));
|
||||||
@ -434,7 +432,7 @@ public class Dhcp6HandlerUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isConnectMacEmpty(DhcpServerInfo serverInfo, Set<Interface> clientInterfaces) {
|
private static boolean isConnectMacEmpty(DhcpServerInfo serverInfo, Set<Interface> clientInterfaces) {
|
||||||
if (!serverInfo.getDhcpConnectMac().isPresent()) {
|
if (!serverInfo.getDhcpConnectMac().isPresent()) {
|
||||||
log.warn("DHCP6 {} not yet resolved .. Aborting DHCP "
|
log.warn("DHCP6 {} not yet resolved .. Aborting DHCP "
|
||||||
+ "packet processing from client on port: {}",
|
+ "packet processing from client on port: {}",
|
||||||
@ -446,7 +444,7 @@ public class Dhcp6HandlerUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isRelayAgentIpFromCfgEmpty(DhcpServerInfo serverInfo, DeviceId receivedFromDevice) {
|
private static boolean isRelayAgentIpFromCfgEmpty(DhcpServerInfo serverInfo, DeviceId receivedFromDevice) {
|
||||||
if (!serverInfo.getRelayAgentIp6(receivedFromDevice).isPresent()) {
|
if (!serverInfo.getRelayAgentIp6(receivedFromDevice).isPresent()) {
|
||||||
log.warn("indirect connection: relayAgentIp NOT availale from config file! Use dynamic.");
|
log.warn("indirect connection: relayAgentIp NOT availale from config file! Use dynamic.");
|
||||||
return true;
|
return true;
|
||||||
@ -454,7 +452,7 @@ public class Dhcp6HandlerUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Dhcp6Option getInterfaceIdIdOption(PacketContext context, Ethernet clientPacket) {
|
private static Dhcp6Option getInterfaceIdIdOption(PacketContext context, Ethernet clientPacket) {
|
||||||
String inPortString = "-" + context.inPacket().receivedFrom().toString() + ":";
|
String inPortString = "-" + context.inPacket().receivedFrom().toString() + ":";
|
||||||
Dhcp6Option interfaceId = new Dhcp6Option();
|
Dhcp6Option interfaceId = new Dhcp6Option();
|
||||||
interfaceId.setCode(DHCP6.OptionCode.INTERFACE_ID.value());
|
interfaceId.setCode(DHCP6.OptionCode.INTERFACE_ID.value());
|
||||||
@ -482,7 +480,7 @@ public class Dhcp6HandlerUtil {
|
|||||||
return interfaceId;
|
return interfaceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addDhcp6OptionsFromClient(List<Dhcp6Option> options, byte[] dhcp6PacketByte,
|
private static void addDhcp6OptionsFromClient(List<Dhcp6Option> options, byte[] dhcp6PacketByte,
|
||||||
PacketContext context, Ethernet clientPacket) {
|
PacketContext context, Ethernet clientPacket) {
|
||||||
Dhcp6Option relayMessage = new Dhcp6Option();
|
Dhcp6Option relayMessage = new Dhcp6Option();
|
||||||
relayMessage.setCode(DHCP6.OptionCode.RELAY_MSG.value());
|
relayMessage.setCode(DHCP6.OptionCode.RELAY_MSG.value());
|
||||||
@ -504,7 +502,7 @@ public class Dhcp6HandlerUtil {
|
|||||||
* @param serverInterface target server interface
|
* @param serverInterface target server interface
|
||||||
* @return ethernet packet with dhcp6 packet info
|
* @return ethernet packet with dhcp6 packet info
|
||||||
*/
|
*/
|
||||||
public Ethernet buildDhcp6PacketFromClient(PacketContext context, Ethernet clientPacket,
|
public static Ethernet buildDhcp6PacketFromClient(PacketContext context, Ethernet clientPacket,
|
||||||
Set<Interface> clientInterfaces, DhcpServerInfo serverInfo,
|
Set<Interface> clientInterfaces, DhcpServerInfo serverInfo,
|
||||||
Interface serverInterface) {
|
Interface serverInterface) {
|
||||||
ConnectPoint receivedFrom = context.inPacket().receivedFrom();
|
ConnectPoint receivedFrom = context.inPacket().receivedFrom();
|
||||||
@ -604,7 +602,7 @@ public class Dhcp6HandlerUtil {
|
|||||||
* @param serverInfo server to check its connect point
|
* @param serverInfo server to check its connect point
|
||||||
* @return boolean true if serverInfo is found; false otherwise
|
* @return boolean true if serverInfo is found; false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean checkDhcpServerConnPt(boolean directConnFlag,
|
public static boolean checkDhcpServerConnPt(boolean directConnFlag,
|
||||||
DhcpServerInfo serverInfo) {
|
DhcpServerInfo serverInfo) {
|
||||||
if (serverInfo.getDhcpServerConnectPoint() == null) {
|
if (serverInfo.getDhcpServerConnectPoint() == null) {
|
||||||
log.warn("DHCP6 server connect point for {} connPt {}",
|
log.warn("DHCP6 server connect point for {} connPt {}",
|
||||||
|
@ -56,15 +56,15 @@ import org.onosproject.dhcprelay.api.DhcpHandler;
|
|||||||
import org.onosproject.dhcprelay.api.DhcpRelayService;
|
import org.onosproject.dhcprelay.api.DhcpRelayService;
|
||||||
import org.onosproject.dhcprelay.api.DhcpServerInfo;
|
import org.onosproject.dhcprelay.api.DhcpServerInfo;
|
||||||
import org.onosproject.dhcprelay.config.DefaultDhcpRelayConfig;
|
import org.onosproject.dhcprelay.config.DefaultDhcpRelayConfig;
|
||||||
import org.onosproject.dhcprelay.config.IgnoreDhcpConfig;
|
import org.onosproject.dhcprelay.config.DhcpServerConfig;
|
||||||
import org.onosproject.dhcprelay.config.IndirectDhcpRelayConfig;
|
|
||||||
import org.onosproject.dhcprelay.config.EnableDhcpFpmConfig;
|
import org.onosproject.dhcprelay.config.EnableDhcpFpmConfig;
|
||||||
|
import org.onosproject.dhcprelay.config.IndirectDhcpRelayConfig;
|
||||||
|
import org.onosproject.dhcprelay.config.IgnoreDhcpConfig;
|
||||||
import org.onosproject.dhcprelay.store.DhcpRecord;
|
import org.onosproject.dhcprelay.store.DhcpRecord;
|
||||||
import org.onosproject.dhcprelay.store.DhcpRelayStore;
|
import org.onosproject.dhcprelay.store.DhcpRelayStore;
|
||||||
import org.onosproject.dhcprelay.store.DhcpFpmPrefixStore;
|
import org.onosproject.dhcprelay.store.DhcpFpmPrefixStore;
|
||||||
import org.onosproject.routing.fpm.api.FpmRecord;
|
import org.onosproject.routing.fpm.api.FpmRecord;
|
||||||
import org.onosproject.net.Device;
|
import org.onosproject.net.Device;
|
||||||
import org.onosproject.dhcprelay.config.DhcpServerConfig;
|
|
||||||
import org.onosproject.net.Host;
|
import org.onosproject.net.Host;
|
||||||
import org.onosproject.net.config.Config;
|
import org.onosproject.net.config.Config;
|
||||||
import org.onosproject.net.device.DeviceEvent;
|
import org.onosproject.net.device.DeviceEvent;
|
||||||
@ -206,7 +206,6 @@ public class DhcpRelayManager implements DhcpRelayService {
|
|||||||
label = "Enable DhcpRelay Fpm")
|
label = "Enable DhcpRelay Fpm")
|
||||||
protected boolean dhcpFpmEnabled = false;
|
protected boolean dhcpFpmEnabled = false;
|
||||||
|
|
||||||
|
|
||||||
private ScheduledExecutorService timerExecutor;
|
private ScheduledExecutorService timerExecutor;
|
||||||
|
|
||||||
protected DeviceListener deviceListener = new InternalDeviceListener();
|
protected DeviceListener deviceListener = new InternalDeviceListener();
|
||||||
@ -321,7 +320,6 @@ public class DhcpRelayManager implements DhcpRelayService {
|
|||||||
}
|
}
|
||||||
v6Handler.setDhcpFpmEnabled(dhcpFpmEnabled);
|
v6Handler.setDhcpFpmEnabled(dhcpFpmEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<TrafficSelector> buildClientDhcpSelectors() {
|
private static List<TrafficSelector> buildClientDhcpSelectors() {
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017-present Open Networking Foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.onosproject.dhcprelay;
|
||||||
|
|
||||||
|
import org.onlab.packet.Ethernet;
|
||||||
|
import org.onosproject.net.ConnectPoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Container for Ethernet packet and destination port.
|
||||||
|
*/
|
||||||
|
final class InternalPacket {
|
||||||
|
private Ethernet packet;
|
||||||
|
private ConnectPoint destLocation;
|
||||||
|
|
||||||
|
private InternalPacket(Ethernet newPacket, ConnectPoint newLocation) {
|
||||||
|
packet = newPacket;
|
||||||
|
destLocation = newLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Ethernet getPacket() {
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnectPoint getDestLocation() {
|
||||||
|
return destLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build {@link InternalPacket} object instance.
|
||||||
|
*
|
||||||
|
* @param newPacket {@link Ethernet} packet to be sent
|
||||||
|
* @param newLocation {@link ConnectPoint} packet destination
|
||||||
|
* @return new instance of {@link InternalPacket} class
|
||||||
|
*/
|
||||||
|
public static InternalPacket internalPacket(Ethernet newPacket, ConnectPoint newLocation) {
|
||||||
|
return new InternalPacket(newPacket, newLocation);
|
||||||
|
}
|
||||||
|
}
|
@ -36,9 +36,11 @@ public final class Dhcp6LeaseQueryOption extends Dhcp6Option {
|
|||||||
//public short QueryType;
|
//public short QueryType;
|
||||||
public Ip6Address linkAddress;
|
public Ip6Address linkAddress;
|
||||||
private List<Dhcp6Option> options;
|
private List<Dhcp6Option> options;
|
||||||
|
public byte queryType;
|
||||||
|
|
||||||
public Dhcp6LeaseQueryOption(Dhcp6Option dhcp6Option) {
|
public Dhcp6LeaseQueryOption(Dhcp6Option dhcp6Option) {
|
||||||
super(dhcp6Option);
|
super(dhcp6Option);
|
||||||
|
options = Lists.newArrayList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -66,10 +68,10 @@ public final class Dhcp6LeaseQueryOption extends Dhcp6Option {
|
|||||||
Dhcp6LeaseQueryOption lQ6Option = new Dhcp6LeaseQueryOption(dhcp6Option);
|
Dhcp6LeaseQueryOption lQ6Option = new Dhcp6LeaseQueryOption(dhcp6Option);
|
||||||
|
|
||||||
byte[] optionData = lQ6Option.getData();
|
byte[] optionData = lQ6Option.getData();
|
||||||
if (optionData.length >= 61) { // 61 is LQ option length + 4 header
|
if (optionData.length >= DEFAULT_LEN) {
|
||||||
ByteBuffer bb = ByteBuffer.wrap(optionData);
|
ByteBuffer bb = ByteBuffer.wrap(optionData);
|
||||||
// fetch the Query type - just pop the byte from the byte buffer for subsequent parsing...
|
// fetch the Query type - just pop the byte from the byte buffer for subsequent parsing...
|
||||||
bb.get();
|
lQ6Option.queryType = bb.get();
|
||||||
byte[] ipv6Addr = new byte[16];
|
byte[] ipv6Addr = new byte[16];
|
||||||
bb.get(ipv6Addr);
|
bb.get(ipv6Addr);
|
||||||
lQ6Option.linkAddress = Ip6Address.valueOf(ipv6Addr);
|
lQ6Option.linkAddress = Ip6Address.valueOf(ipv6Addr);
|
||||||
@ -108,10 +110,13 @@ public final class Dhcp6LeaseQueryOption extends Dhcp6Option {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] serialize() {
|
public byte[] serialize() {
|
||||||
ByteBuffer bb = ByteBuffer.allocate(this.getLength() + Dhcp6Option.DEFAULT_LEN);
|
byte[] serializedPayload = payload.serialize();
|
||||||
|
|
||||||
|
ByteBuffer bb = ByteBuffer.allocate(serializedPayload.length + Dhcp6Option.DEFAULT_LEN);
|
||||||
bb.putShort(getCode());
|
bb.putShort(getCode());
|
||||||
bb.putShort(getLength());
|
bb.putShort(getLength());
|
||||||
bb.put(payload.serialize());
|
bb.put(serializedPayload);
|
||||||
|
|
||||||
return bb.array();
|
return bb.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user