blob: 81748c6249adf344f829192b576907b92e6f7ea3 [file] [log] [blame]
/*
* 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.BasePacket;
import org.onlab.packet.DHCP6;
import org.onlab.packet.DHCP6.MsgType;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.IpAddress;
import org.onlab.packet.VlanId;
import org.onlab.packet.dhcp.Dhcp6RelayOption;
import org.onlab.packet.dhcp.Dhcp6Option;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv6;
import org.onlab.packet.MacAddress;
import org.onlab.packet.UDP;
import org.onlab.util.HexString;
import org.onosproject.dhcprelay.api.DhcpServerInfo;
import org.onosproject.dhcprelay.store.DhcpRelayCounters;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.host.InterfaceIpAddress;
import org.onosproject.net.intf.Interface;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.DeviceId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Set;
import java.util.List;
import java.util.ArrayList;
import org.onosproject.net.intf.InterfaceService;
import org.onosproject.net.Host;
import org.onosproject.net.host.HostService;
import org.onosproject.net.HostLocation;
import static com.google.common.base.Preconditions.checkNotNull;
public final class Dhcp6HandlerUtil {
private static final Logger log = LoggerFactory.getLogger(Dhcp6HandlerUtil.class);
private Dhcp6HandlerUtil() {
}
// Returns the first v6 interface ip out of a set of interfaces or null.
// Checks all interfaces, and ignores v6 interface ips
public static 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;
}
/**
* 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.
*
* @param defaultServerInfoList default server list
* @param indirectServerInfoList default indirect server list
* @param serverInterface server interface
* @param interfaceService interface service
* @param hostService host service
* @param context packet context
* @param receivedPacket server ethernet packet
* @param recevingInterfaces set of server side interfaces
* @return a packet ready to be sent to relevant output interface
*/
public static InternalPacket processLQ6PacketFromServer(
List<DhcpServerInfo> defaultServerInfoList,
List<DhcpServerInfo> indirectServerInfoList,
Interface serverInterface,
InterfaceService interfaceService,
HostService hostService,
PacketContext context,
Ethernet receivedPacket, Set<Interface> recevingInterfaces) {
// get dhcp6 header.
Ethernet etherReply = (Ethernet) receivedPacket.clone();
IPv6 ipv6Packet = (IPv6) etherReply.getPayload();
UDP udpPacket = (UDP) ipv6Packet.getPayload();
DHCP6 lq6Reply = (DHCP6) udpPacket.getPayload();
// TODO: refactor
ConnectPoint receivedFrom = context.inPacket().receivedFrom();
DeviceId receivedFromDevice = receivedFrom.deviceId();
DhcpServerInfo serverInfo;
Ip6Address dhcpServerIp = null;
ConnectPoint dhcpServerConnectPoint = null;
MacAddress dhcpConnectMac = null;
VlanId dhcpConnectVlan = null;
Ip6Address dhcpGatewayIp = null;
// todo: refactor
Ip6Address indirectDhcpServerIp = null;
ConnectPoint indirectDhcpServerConnectPoint = null;
MacAddress indirectDhcpConnectMac = null;
VlanId indirectDhcpConnectVlan = null;
Ip6Address indirectDhcpGatewayIp = null;
Ip6Address indirectRelayAgentIpFromCfg = null;
if (!defaultServerInfoList.isEmpty()) {
serverInfo = defaultServerInfoList.get(0);
dhcpConnectMac = serverInfo.getDhcpConnectMac().orElse(null);
dhcpGatewayIp = serverInfo.getDhcpGatewayIp6().orElse(null);
dhcpServerIp = serverInfo.getDhcpServerIp6().orElse(null);
dhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
dhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
}
if (!indirectServerInfoList.isEmpty()) {
serverInfo = indirectServerInfoList.get(0);
indirectDhcpConnectMac = serverInfo.getDhcpConnectMac().orElse(null);
indirectDhcpGatewayIp = serverInfo.getDhcpGatewayIp6().orElse(null);
indirectDhcpServerIp = serverInfo.getDhcpServerIp6().orElse(null);
indirectDhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
indirectDhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
indirectRelayAgentIpFromCfg = serverInfo.getRelayAgentIp6(receivedFromDevice).orElse(null);
}
Boolean directConnFlag = directlyConnected(lq6Reply);
ConnectPoint inPort = context.inPacket().receivedFrom();
if ((directConnFlag || indirectDhcpServerIp == null)
&& !inPort.equals(dhcpServerConnectPoint)) {
log.warn("Receiving port {} is not the same as server connect point {} for direct or indirect-null",
inPort, dhcpServerConnectPoint);
return null;
}
if (!directConnFlag && indirectDhcpServerIp != null &&
!inPort.equals(indirectDhcpServerConnectPoint)) {
log.warn("Receiving port {} is not the same as server connect point {} for indirect",
inPort, indirectDhcpServerConnectPoint);
return null;
}
Ip6Address nextHopIP = Ip6Address.valueOf(ipv6Packet.getDestinationAddress());
// use hosts store to find out the next hop mac and connection point
Set<Host> hosts = hostService.getHostsByIp(nextHopIP);
Host host;
if (!hosts.isEmpty()) {
host = hosts.iterator().next();
} else {
log.warn("Host {} is not in store", nextHopIP);
return null;
}
HostLocation hl = host.location();
String clientConnectionPointStr = hl.toString(); // iterator().next());
ConnectPoint clientConnectionPoint = ConnectPoint.deviceConnectPoint(clientConnectionPointStr);
VlanId originalPacketVlanId = VlanId.vlanId(etherReply.getVlanID());
Interface iface;
iface = interfaceService.getInterfacesByPort(clientConnectionPoint)
.stream()
.filter(iface1 -> interfaceContainsVlan(iface1, originalPacketVlanId))
.findFirst()
.orElse(null);
etherReply.setSourceMACAddress(iface.mac());
etherReply.setDestinationMACAddress(host.mac());
// workaround for a bug where core sends src port as 547 (server)
udpPacket.setDestinationPort(UDP.DHCP_V6_SERVER_PORT);
udpPacket.setPayload(lq6Reply);
udpPacket.resetChecksum();
ipv6Packet.setPayload(udpPacket);
etherReply.setPayload(ipv6Packet);
return InternalPacket.internalPacket(etherReply, clientConnectionPoint);
}
/**
* extract DHCP6 payload from dhcp6 relay message within relay-forwrd/reply.
*
* @param dhcp6 dhcp6 relay-reply or relay-forward
* @return dhcp6Packet dhcp6 packet extracted from relay-message
*/
public static DHCP6 dhcp6PacketFromRelayPacket(DHCP6 dhcp6) {
// extract the relay message if exist
DHCP6 dhcp6Payload = dhcp6.getOptions().stream()
.filter(opt -> opt instanceof Dhcp6RelayOption)
.map(BasePacket::getPayload)
.map(pld -> (DHCP6) pld)
.findFirst()
.orElse(null);
if (dhcp6Payload == null) {
// Can't find dhcp payload
log.debug("Can't find dhcp6 payload from relay message");
} else {
log.debug("dhcp6 payload found from relay message {}", dhcp6Payload);
}
return dhcp6Payload;
}
/**
* find the leaf DHCP6 packet from multi-level relay packet.
*
* @param relayPacket dhcp6 relay packet
* @return leafPacket non-relay dhcp6 packet
*/
public static DHCP6 getDhcp6Leaf(DHCP6 relayPacket) {
DHCP6 dhcp6Parent = relayPacket;
DHCP6 dhcp6Child = null;
log.debug("getDhcp6Leaf entered.");
while (dhcp6Parent != null) {
dhcp6Child = dhcp6PacketFromRelayPacket(dhcp6Parent);
if (dhcp6Child != null) {
if (dhcp6Child.getMsgType() != DHCP6.MsgType.RELAY_FORW.value() &&
dhcp6Child.getMsgType() != DHCP6.MsgType.RELAY_REPL.value()) {
log.debug("leaf dhcp6 packet found.");
break;
} else {
// found another relay, go for another loop
dhcp6Parent = dhcp6Child;
}
} else {
log.debug("Expected dhcp6 within relay pkt, but no dhcp6 leaf found.");
break;
}
}
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.
*
* @param relayPacket dhcp6 relay-reply
* @return boolean relay-reply contains ack
*/
public static boolean isDhcp6Reply(DHCP6 relayPacket) {
DHCP6 leafDhcp6 = getDhcp6Leaf(relayPacket);
if (leafDhcp6 != null) {
if (leafDhcp6.getMsgType() == DHCP6.MsgType.REPLY.value()) {
log.debug("isDhcp6Reply true.");
return true; // must be directly connected
} else {
log.debug("isDhcp6Reply false. leaf dhcp6 is not replay. MsgType {}", leafDhcp6.getMsgType());
}
} else {
log.debug("isDhcp6Reply false. Expected dhcp6 within relay pkt but not found.");
}
log.debug("isDhcp6Reply false.");
return false;
}
/**
* check if DHCP6 is release or relay-forward contains release.
*
* @param dhcp6Payload dhcp6 packet
* @return boolean dhcp6 contains release
*/
public static boolean isDhcp6Release(DHCP6 dhcp6Payload) {
if (dhcp6Payload.getMsgType() == DHCP6.MsgType.RELEASE.value()) {
log.debug("isDhcp6Release true.");
return true; // must be directly connected
} else {
DHCP6 dhcp6Leaf = getDhcp6Leaf(dhcp6Payload);
if (dhcp6Leaf != null) {
if (dhcp6Leaf.getMsgType() == DHCP6.MsgType.RELEASE.value()) {
log.debug("isDhcp6Release true. indirectlry connected");
return true;
} else {
log.debug("leaf dhcp6 is not release. MsgType {}", dhcp6Leaf.getMsgType());
return false;
}
} else {
log.debug("isDhcp6Release false. dhcp6 is niether relay nor release.");
return false;
}
}
}
/**
* convert dhcp6 msgType to String.
*
* @param msgTypeVal msgType byte of dhcp6 packet
* @return String string value of dhcp6 msg type
*/
public static String getMsgTypeStr(byte msgTypeVal) {
MsgType msgType = DHCP6.MsgType.getType(msgTypeVal);
return DHCP6.MsgType.getMsgTypeStr(msgType);
}
/**
* find the string of dhcp6 leaf packets's msg type.
*
* @param directConnFlag boolean value indicating direct/indirect connection
* @param dhcp6Packet dhcp6 packet
* @return String string value of dhcp6 leaf packet msg type
*/
public static String findLeafMsgType(boolean directConnFlag, DHCP6 dhcp6Packet) {
if (directConnFlag) {
return getMsgTypeStr(dhcp6Packet.getMsgType());
} else {
DHCP6 leafDhcp = getDhcp6Leaf(dhcp6Packet);
if (leafDhcp != null) {
return getMsgTypeStr(leafDhcp.getMsgType());
} else {
return DhcpRelayCounters.INVALID_PACKET;
}
}
}
/**
* Determind if an Interface contains a vlan id.
*
* @param iface the Interface
* @param vlanId the vlan id
* @return true if the Interface contains the vlan id
*/
public static boolean interfaceContainsVlan(Interface iface, VlanId vlanId) {
if (vlanId.equals(VlanId.NONE)) {
// untagged packet, check if vlan untagged or vlan native is not NONE
return !iface.vlanUntagged().equals(VlanId.NONE) ||
!iface.vlanNative().equals(VlanId.NONE);
}
// tagged packet, check if the interface contains the vlan
return iface.vlanTagged().contains(vlanId);
}
/**
* Check if the host is directly connected to the network or not.
*
* @param dhcp6Payload the dhcp6 payload
* @return true if the host is directly connected to the network; false otherwise
*/
public static boolean directlyConnected(DHCP6 dhcp6Payload) {
log.debug("directlyConnected enters");
if (dhcp6Payload.getMsgType() == DHCP6.MsgType.LEASEQUERY.value() ||
dhcp6Payload.getMsgType() == DHCP6.MsgType.LEASEQUERY_REPLY.value()) {
log.debug("directlyConnected false. MsgType {}", dhcp6Payload.getMsgType());
return false;
}
if (dhcp6Payload.getMsgType() != DHCP6.MsgType.RELAY_FORW.value() &&
dhcp6Payload.getMsgType() != DHCP6.MsgType.RELAY_REPL.value()) {
log.debug("directlyConnected true. MsgType {}", dhcp6Payload.getMsgType());
return true;
}
// Regardless of relay-forward or relay-replay, check if we see another relay message
DHCP6 dhcp6Payload2 = dhcp6PacketFromRelayPacket(dhcp6Payload);
if (dhcp6Payload2 != null) {
if (dhcp6Payload.getMsgType() == DHCP6.MsgType.RELAY_FORW.value()) {
log.debug("directlyConnected false. 1st relay-forward, 2nd MsgType {}", dhcp6Payload2.getMsgType());
return false;
} else {
// relay-reply
if (dhcp6Payload2.getMsgType() != DHCP6.MsgType.RELAY_REPL.value()
&& dhcp6Payload2.getMsgType() != MsgType.LEASEQUERY_REPLY.value()) {
log.debug("directlyConnected true. 2nd MsgType {}", dhcp6Payload2.getMsgType());
return true; // must be directly connected
} else {
log.debug("directlyConnected false. 1st relay-reply, 2nd relay-reply MsgType {}",
dhcp6Payload2.getMsgType());
return false; // must be indirectly connected
}
}
} else {
log.debug("directlyConnected true.");
return true;
}
}
/**
* Check if a given server info has v6 ipaddress.
*
* @param serverInfo server info to check
* @return true if server info has v6 ip address; false otherwise
*/
public static boolean isServerIpEmpty(DhcpServerInfo serverInfo) {
if (!serverInfo.getDhcpServerIp6().isPresent()) {
log.warn("DhcpServerIp not available, use default DhcpServerIp {}",
HexString.toHexString(serverInfo.getDhcpServerIp6().get().toOctets()));
return true;
}
return false;
}
private static boolean isConnectMacEmpty(DhcpServerInfo serverInfo, Set<Interface> clientInterfaces) {
if (!serverInfo.getDhcpConnectMac().isPresent()) {
log.warn("DHCP6 {} not yet resolved .. Aborting DHCP "
+ "packet processing from client on port: {}",
!serverInfo.getDhcpGatewayIp6().isPresent() ? "server IP " + serverInfo.getDhcpServerIp6()
: "gateway IP " + serverInfo.getDhcpGatewayIp6(),
clientInterfaces.iterator().next().connectPoint());
return true;
}
return false;
}
private static boolean isRelayAgentIpFromCfgEmpty(DhcpServerInfo serverInfo, DeviceId receivedFromDevice) {
if (!serverInfo.getRelayAgentIp6(receivedFromDevice).isPresent()) {
log.warn("indirect connection: relayAgentIp NOT availale from config file! Use dynamic.");
return true;
}
return false;
}
private static Dhcp6Option getInterfaceIdIdOption(PacketContext context, Ethernet clientPacket) {
String inPortString = "-" + context.inPacket().receivedFrom().toString() + ":";
Dhcp6Option interfaceId = new Dhcp6Option();
interfaceId.setCode(DHCP6.OptionCode.INTERFACE_ID.value());
byte[] clientSoureMacBytes = clientPacket.getSourceMACAddress();
byte[] inPortStringBytes = inPortString.getBytes();
byte[] vlanIdBytes = new byte[2];
vlanIdBytes[0] = (byte) (clientPacket.getVlanID() & 0xff);
vlanIdBytes[1] = (byte) ((clientPacket.getVlanID() >> 8) & 0xff);
byte[] interfaceIdBytes = new byte[clientSoureMacBytes.length +
inPortStringBytes.length + vlanIdBytes.length];
log.debug("Length: interfaceIdBytes {} clientSoureMacBytes {} inPortStringBytes {} vlan {}",
interfaceIdBytes.length, clientSoureMacBytes.length, inPortStringBytes.length,
vlanIdBytes.length);
System.arraycopy(clientSoureMacBytes, 0, interfaceIdBytes, 0, clientSoureMacBytes.length);
System.arraycopy(inPortStringBytes, 0, interfaceIdBytes, clientSoureMacBytes.length,
inPortStringBytes.length);
System.arraycopy(vlanIdBytes, 0, interfaceIdBytes,
clientSoureMacBytes.length + inPortStringBytes.length,
vlanIdBytes.length);
interfaceId.setData(interfaceIdBytes);
interfaceId.setLength((short) interfaceIdBytes.length);
log.debug("interfaceId write srcMac {} portString {}",
HexString.toHexString(clientSoureMacBytes, ":"), inPortString);
return interfaceId;
}
private static void addDhcp6OptionsFromClient(List<Dhcp6Option> options, byte[] dhcp6PacketByte,
PacketContext context, Ethernet clientPacket) {
Dhcp6Option relayMessage = new Dhcp6Option();
relayMessage.setCode(DHCP6.OptionCode.RELAY_MSG.value());
relayMessage.setLength((short) dhcp6PacketByte.length);
relayMessage.setData(dhcp6PacketByte);
options.add(relayMessage);
// create interfaceId option
Dhcp6Option interfaceId = getInterfaceIdIdOption(context, clientPacket);
options.add(interfaceId);
}
/**
* build the DHCP6 solicit/request packet with gatewayip.
*
* @param context packet context
* @param clientPacket client ethernet packet
* @param clientInterfaces set of client side interfaces
* @param serverInfo target server which a packet is generated for
* @param serverInterface target server interface
* @return ethernet packet with dhcp6 packet info
*/
public static Ethernet buildDhcp6PacketFromClient(PacketContext context, Ethernet clientPacket,
Set<Interface> clientInterfaces, DhcpServerInfo serverInfo,
Interface serverInterface) {
ConnectPoint receivedFrom = context.inPacket().receivedFrom();
DeviceId receivedFromDevice = receivedFrom.deviceId();
Ip6Address relayAgentIp = 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());
return null;
}
IPv6 clientIpv6 = (IPv6) clientPacket.getPayload();
UDP clientUdp = (UDP) clientIpv6.getPayload();
DHCP6 clientDhcp6 = (DHCP6) clientUdp.getPayload();
boolean directConnFlag = directlyConnected(clientDhcp6);
Ip6Address serverIpFacing = getFirstIpFromInterface(serverInterface);
if (serverIpFacing == null || serverInterface.mac() == null) {
log.warn("No IP v6 address for server Interface {}", serverInterface);
return null;
}
Ethernet etherReply = clientPacket.duplicate();
etherReply.setSourceMACAddress(serverInterface.mac());
// set default info and replace with indirect if available later on.
if (serverInfo.getDhcpConnectMac().isPresent()) {
etherReply.setDestinationMACAddress(serverInfo.getDhcpConnectMac().get());
}
if (serverInfo.getDhcpConnectVlan().isPresent()) {
etherReply.setVlanID(serverInfo.getDhcpConnectVlan().get().toShort());
}
IPv6 ipv6Packet = (IPv6) etherReply.getPayload();
byte[] peerAddress = clientIpv6.getSourceAddress();
ipv6Packet.setSourceAddress(serverIpFacing.toOctets());
ipv6Packet.setDestinationAddress(serverInfo.getDhcpServerIp6().get().toOctets());
UDP udpPacket = (UDP) ipv6Packet.getPayload();
udpPacket.setSourcePort(UDP.DHCP_V6_SERVER_PORT);
DHCP6 dhcp6Packet = (DHCP6) udpPacket.getPayload();
byte[] dhcp6PacketByte = dhcp6Packet.serialize();
DHCP6 dhcp6Relay = new DHCP6();
dhcp6Relay.setMsgType(DHCP6.MsgType.RELAY_FORW.value());
if (directConnFlag) {
dhcp6Relay.setLinkAddress(relayAgentIp.toOctets());
} else {
if (isServerIpEmpty(serverInfo)) {
log.warn("indirect DhcpServerIp empty... use default server ");
} else {
// Indirect case, replace destination to indirect dhcp server if exist
// Check if mac is obtained for valid server ip
if (isConnectMacEmpty(serverInfo, clientInterfaces)) {
log.warn("indirect Dhcp ConnectMac empty ...");
return null;
}
etherReply.setDestinationMACAddress(serverInfo.getDhcpConnectMac().get());
etherReply.setVlanID(serverInfo.getDhcpConnectVlan().get().toShort());
ipv6Packet.setDestinationAddress(serverInfo.getDhcpServerIp6().get().toOctets());
}
if (isRelayAgentIpFromCfgEmpty(serverInfo, receivedFromDevice)) {
dhcp6Relay.setLinkAddress(relayAgentIp.toOctets());
log.debug("indirect connection: relayAgentIp NOT availale from config file! Use dynamic. {}",
HexString.toHexString(relayAgentIp.toOctets(), ":"));
} else {
dhcp6Relay.setLinkAddress(serverInfo.getRelayAgentIp6(receivedFromDevice).get().toOctets());
}
}
// peer address: address of the client or relay agent from which the message to be relayed was received.
dhcp6Relay.setPeerAddress(peerAddress);
// directly connected case, hop count is zero; otherwise, hop count + 1
if (directConnFlag) {
dhcp6Relay.setHopCount((byte) 0);
} else {
dhcp6Relay.setHopCount((byte) (dhcp6Packet.getHopCount() + 1));
}
List<Dhcp6Option> options = new ArrayList<>();
addDhcp6OptionsFromClient(options, dhcp6PacketByte, context, clientPacket);
dhcp6Relay.setOptions(options);
udpPacket.setPayload(dhcp6Relay);
udpPacket.resetChecksum();
ipv6Packet.setPayload(udpPacket);
ipv6Packet.setHopLimit((byte) 64);
etherReply.setPayload(ipv6Packet);
return etherReply;
}
/**
* build the DHCP6 solicit/request packet with gatewayip.
*
* @param directConnFlag flag indicating if packet is from direct client or not
* @param serverInfo server to check its connect point
* @return boolean true if serverInfo is found; false otherwise
*/
public static boolean checkDhcpServerConnPt(boolean directConnFlag,
DhcpServerInfo serverInfo) {
if (serverInfo.getDhcpServerConnectPoint() == null) {
log.warn("DHCP6 server connect point for {} connPt {}",
directConnFlag ? "direct" : "indirect", serverInfo.getDhcpServerConnectPoint());
return false;
}
return true;
}
}