use of org.onosproject.dhcprelay.api.DhcpServerInfo in project onos by opennetworkinglab.
the class Dhcp6HandlerImpl method processDhcp6PacketFromServer.
/**
* process the DHCP6 relay-reply packet from dhcp server.
*
* @param context packet context
* @param receivedPacket server ethernet packet
* @param recevingInterfaces set of server side interfaces
* @return internalPacket toward client
*/
private InternalPacket processDhcp6PacketFromServer(PacketContext context, Ethernet receivedPacket, Set<Interface> recevingInterfaces) {
// get dhcp6 header.
Ethernet etherReply = receivedPacket.duplicate();
IPv6 ipv6Packet = (IPv6) etherReply.getPayload();
UDP udpPacket = (UDP) ipv6Packet.getPayload();
DHCP6 dhcp6Relay = (DHCP6) udpPacket.getPayload();
Boolean directConnFlag = Dhcp6HandlerUtil.directlyConnected(dhcp6Relay);
DHCP6 embeddedDhcp6 = dhcp6Relay.getOptions().stream().filter(opt -> opt instanceof Dhcp6RelayOption).map(BasePacket::getPayload).map(pld -> (DHCP6) pld).findFirst().orElse(null);
ConnectPoint inPort = context.inPacket().receivedFrom();
DhcpServerInfo foundServerInfo = findServerInfoFromServer(directConnFlag, inPort);
if (foundServerInfo == null) {
log.warn("Cannot find server info for {} server, inPort {}", directConnFlag ? "direct" : "indirect", inPort);
// dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_SERVER_INFO);
return null;
} else {
if (Dhcp6HandlerUtil.isServerIpEmpty(foundServerInfo)) {
log.warn("Cannot find server info's ipaddress");
// dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_SERVER_IP6ADDR);
return null;
}
}
Dhcp6InterfaceIdOption interfaceIdOption = dhcp6Relay.getOptions().stream().filter(opt -> opt instanceof Dhcp6InterfaceIdOption).map(opt -> (Dhcp6InterfaceIdOption) opt).findFirst().orElse(null);
if (interfaceIdOption == null) {
log.warn("Interface Id option is not present, abort packet...");
// dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.OPTION_MISSING_FAIL);
return null;
}
MacAddress peerMac = interfaceIdOption.getMacAddress();
String clientConnectionPointStr = new String(interfaceIdOption.getInPort());
ConnectPoint clientConnectionPoint = ConnectPoint.deviceConnectPoint(clientConnectionPointStr);
VlanId vlanIdInUse = VlanId.vlanId(interfaceIdOption.getVlanId());
log.debug("processDhcp6PacketFromServer Interface Id Mac {}, port{}, vlan {}", peerMac, clientConnectionPointStr, vlanIdInUse);
Interface clientInterface = interfaceService.getInterfacesByPort(clientConnectionPoint).stream().filter(iface -> Dhcp6HandlerUtil.interfaceContainsVlan(iface, vlanIdInUse)).findFirst().orElse(null);
if (clientInterface == null) {
log.warn("Cannot get client interface for from packet, abort... vlan {}", vlanIdInUse.toString());
// dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_MATCHING_INTF);
return null;
}
etherReply.setVlanID(vlanIdInUse.toShort());
MacAddress relayAgentMac = clientInterface.mac();
if (relayAgentMac == null) {
log.warn("Can not get client interface mac, abort packet..");
// dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_CLIENT_INTF_MAC);
return null;
}
etherReply.setSourceMACAddress(relayAgentMac);
// find destMac
MacAddress clientMac;
Ip6Address peerAddress = Ip6Address.valueOf(dhcp6Relay.getPeerAddress());
Set<Host> clients = hostService.getHostsByIp(peerAddress);
if (clients.isEmpty()) {
log.trace("There's no host found for this address {}", HexString.toHexString(dhcp6Relay.getPeerAddress(), ":"));
log.trace("Let's look up interfaceId {}", HexString.toHexString(peerMac.toBytes(), ":"));
clientMac = peerMac;
} else {
clientMac = clients.iterator().next().mac();
if (clientMac == null) {
log.warn("No client mac address found, abort packet...");
// dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_CLIENT_INTF_MAC);
return null;
}
log.trace("Client mac address found from getHostByIp");
}
etherReply.setDestinationMACAddress(clientMac);
// ip header
ipv6Packet.setSourceAddress(dhcp6Relay.getLinkAddress());
ipv6Packet.setDestinationAddress(dhcp6Relay.getPeerAddress());
// udp header
udpPacket.setSourcePort(UDP.DHCP_V6_SERVER_PORT);
if (directConnFlag) {
udpPacket.setDestinationPort(UDP.DHCP_V6_CLIENT_PORT);
} else {
udpPacket.setDestinationPort(UDP.DHCP_V6_SERVER_PORT);
}
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, vlanIdInUse);
}
udpPacket.setPayload(embeddedDhcp6);
udpPacket.resetChecksum();
ipv6Packet.setPayload(udpPacket);
etherReply.setPayload(ipv6Packet);
return InternalPacket.internalPacket(etherReply, clientConnectionPoint);
}
use of org.onosproject.dhcprelay.api.DhcpServerInfo in project onos by opennetworkinglab.
the class Dhcp6HandlerImpl method processDhcp6PacketFromClient.
/**
* build the DHCP6 solicit/request packet with gatewayip.
*
* @param context packet context
* @param clientPacket client ethernet packet
* @param clientInterfaces set of client side interfaces
*/
private List<InternalPacket> processDhcp6PacketFromClient(PacketContext context, Ethernet clientPacket, Set<Interface> clientInterfaces) {
ConnectPoint receivedFrom = context.inPacket().receivedFrom();
Ip6Address relayAgentIp = Dhcp6HandlerUtil.getRelayAgentIPv6Address(clientInterfaces);
MacAddress relayAgentMac = clientInterfaces.iterator().next().mac();
if (relayAgentIp == null || relayAgentMac == null) {
log.warn("Missing DHCP relay agent interface Ipv6 addr config for " + "packet from client on port: {}. Aborting packet processing", clientInterfaces.iterator().next().connectPoint());
// dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_CLIENT_INTF_MAC);
return Lists.newArrayList();
}
IPv6 clientIpv6 = (IPv6) clientPacket.getPayload();
UDP clientUdp = (UDP) clientIpv6.getPayload();
DHCP6 clientDhcp6 = (DHCP6) clientUdp.getPayload();
boolean directConnFlag = Dhcp6HandlerUtil.directlyConnected(clientDhcp6);
ConnectPoint clientConnectionPoint = context.inPacket().receivedFrom();
VlanId vlanIdInUse = VlanId.vlanId(clientPacket.getVlanID());
Interface clientInterface = interfaceService.getInterfacesByPort(clientConnectionPoint).stream().filter(iface -> Dhcp6HandlerUtil.interfaceContainsVlan(iface, vlanIdInUse)).findFirst().orElse(null);
List<InternalPacket> internalPackets = new ArrayList<>();
List<DhcpServerInfo> serverInfoList = findValidServerInfo(directConnFlag);
List<DhcpServerInfo> copyServerInfoList = new ArrayList<DhcpServerInfo>(serverInfoList);
for (DhcpServerInfo serverInfo : copyServerInfoList) {
if (!Dhcp6HandlerUtil.checkDhcpServerConnPt(directConnFlag, serverInfo)) {
log.warn("Can't get server connect point, ignore");
continue;
}
DhcpServerInfo newServerInfo = getHostInfoForServerInfo(serverInfo, serverInfoList);
if (newServerInfo == null) {
log.warn("Can't get server interface with host info resolved, ignore");
continue;
}
Interface serverInterface = getServerInterface(newServerInfo);
if (serverInterface == null) {
log.warn("Can't get server interface, ignore");
continue;
}
Ethernet etherReply = Dhcp6HandlerUtil.buildDhcp6PacketFromClient(context, clientPacket, clientInterfaces, newServerInfo, serverInterface);
removeHostOrRoute(directConnFlag, clientConnectionPoint, clientDhcp6, clientPacket, clientIpv6, clientInterface);
InternalPacket internalPacket = InternalPacket.internalPacket(etherReply, serverInfo.getDhcpServerConnectPoint().get());
internalPackets.add(internalPacket);
}
log.debug("num of client packets to send is{}", internalPackets.size());
return internalPackets;
}
use of org.onosproject.dhcprelay.api.DhcpServerInfo in project onos by opennetworkinglab.
the class Dhcp6HandlerImpl method processLQ6PacketFromClient.
private List<InternalPacket> processLQ6PacketFromClient(PacketContext context, Ethernet clientPacket, Set<Interface> clientInterfaces, DHCP6 dhcp6Payload) {
ConnectPoint inPort = context.inPacket().receivedFrom();
log.info("Got LQ-REQUEST V6 on port {}", inPort);
List<Dhcp6Option> lopt = dhcp6Payload.getOptions();
log.info("Options list: {}", lopt);
Dhcp6LeaseQueryOption lqoption = dhcp6Payload.getOptions().stream().filter(opt -> opt instanceof Dhcp6LeaseQueryOption).map(pld -> (Dhcp6LeaseQueryOption) pld).findFirst().orElse(null);
if (lqoption == null) {
// Can't find dhcp payload
log.warn("Can't find dhcp6 lease query message - aborting");
return null;
} else {
log.info("dhcp6 lqv6 options found: {}", lqoption);
}
log.warn("LQv6 for " + lqoption.linkAddress.toString() + " comes from " + inPort.toString());
Ethernet packet = context.inPacket().parsed();
Ip6Address clientAddress = lqoption.linkAddress;
IPv6 ipv6Packet = (IPv6) packet.getPayload();
Ip6Address nextHopIp = findNextHopIp6FromRelayStore(clientAddress);
// 1. only if there is a route to remove - remove it
if (nextHopIp != null) {
Route routeForIP6 = new Route(Route.Source.DHCP, clientAddress.toIpPrefix(), nextHopIp);
log.debug("Removing route of Client " + clientAddress + " for indirectly connected - next hop ip6 " + nextHopIp);
routeStore.removeRoute(routeForIP6);
}
// 2. note the potential NH this packet came from in case it's a known lease
// this NH will then be used to build the route
MacAddress potentialNH = packet.getSourceMAC();
VlanId vlanId = VlanId.vlanId(packet.getVlanID());
setPotentialNextHopForIp6InRelayStore(clientAddress, vlanId, potentialNH);
// 3. route this LQ6 to all relevant servers
IPv6 clientIpv6 = (IPv6) clientPacket.getPayload();
UDP clientUdp = (UDP) clientIpv6.getPayload();
DHCP6 clientDhcp6 = (DHCP6) clientUdp.getPayload();
boolean directConnFlag = Dhcp6HandlerUtil.directlyConnected(clientDhcp6);
boolean serverFound = false;
List<InternalPacket> internalPackets = new ArrayList<>();
List<DhcpServerInfo> serverInfoList = findValidServerInfo(directConnFlag);
List<DhcpServerInfo> copyServerInfoList = new ArrayList<DhcpServerInfo>(serverInfoList);
for (DhcpServerInfo serverInfo : copyServerInfoList) {
if (!Dhcp6HandlerUtil.checkDhcpServerConnPt(directConnFlag, serverInfo)) {
log.warn("Can't get server connect point, ignore");
continue;
}
DhcpServerInfo newServerInfo = getHostInfoForServerInfo(serverInfo, serverInfoList);
if (newServerInfo == null) {
log.debug("Can't get server interface with host info resolved, ignore serverInfo {} serverInfoList {}", serverInfo, serverInfoList);
continue;
}
Interface serverInterface = getServerInterface(newServerInfo);
if (serverInterface == null) {
log.debug("Can't get server interface, ignore for serverInfo {}, serverInfoList {}", serverInfo, serverInfoList);
continue;
}
serverFound = true;
log.debug("Server Info Found {}", serverInfo.getDhcpConnectMac());
Ethernet etherRouted = (Ethernet) clientPacket.clone();
MacAddress macFacingServer = serverInterface.mac();
if (macFacingServer == null) {
log.warn("No MAC address for server Interface {}", serverInterface);
return null;
}
etherRouted.setSourceMACAddress(macFacingServer);
etherRouted.setDestinationMACAddress(newServerInfo.getDhcpConnectMac().get());
InternalPacket internalPacket = InternalPacket.internalPacket(etherRouted, serverInfo.getDhcpServerConnectPoint().get());
internalPackets.add(internalPacket);
log.debug("Sending LQ to DHCP server {}", newServerInfo.getDhcpServerIp6());
}
if (!serverFound) {
log.warn("ProcessDhcp6PacketFromClient No Server Found");
}
log.debug("num of client packets to send is{}", internalPackets.size());
return internalPackets;
}
use of org.onosproject.dhcprelay.api.DhcpServerInfo in project onos by opennetworkinglab.
the class Dhcp6HandlerImpl method findServerInfoFromServer.
private DhcpServerInfo findServerInfoFromServer(boolean directConnFlag, ConnectPoint inPort) {
List<DhcpServerInfo> validServerInfoList = findValidServerInfo(directConnFlag);
DhcpServerInfo foundServerInfo = null;
for (DhcpServerInfo serverInfo : validServerInfoList) {
if (inPort.equals(serverInfo.getDhcpServerConnectPoint().get())) {
foundServerInfo = serverInfo;
log.debug("ServerInfo found for Rcv port {} Server Connect Point {} for {}", inPort, serverInfo.getDhcpServerConnectPoint(), directConnFlag ? "direct" : "indirect");
break;
}
}
return foundServerInfo;
}
use of org.onosproject.dhcprelay.api.DhcpServerInfo in project onos by opennetworkinglab.
the class Dhcp6HandlerImpl method getIndirectServerInterface.
/**
* Gets Interface facing to the server for indirect hosts.
* Use default server Interface if indirect server not configured.
*
* @return the Interface facing to the server; null if not found
*/
private Interface getIndirectServerInterface() {
DhcpServerInfo serverInfo;
ConnectPoint indirectDhcpServerConnectPoint;
VlanId indirectDhcpConnectVlan;
if (!indirectServerInfoList.isEmpty()) {
serverInfo = indirectServerInfoList.get(0);
indirectDhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
indirectDhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
} else {
return getServerInterface();
}
if (indirectDhcpServerConnectPoint == null || indirectDhcpConnectVlan == null) {
log.info("Indirect DHCP server {} not resolve yet", serverInfo.getDhcpGatewayIp6());
return null;
}
return interfaceService.getInterfacesByPort(indirectDhcpServerConnectPoint).stream().filter(iface -> Dhcp6HandlerUtil.interfaceContainsVlan(iface, indirectDhcpConnectVlan)).findFirst().orElse(null);
}
Aggregations