use of org.onlab.packet.dhcp.Dhcp6Option in project onos by opennetworkinglab.
the class Dhcp6HandlerUtil method addDhcp6OptionsFromClient.
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);
}
use of org.onlab.packet.dhcp.Dhcp6Option in project onos by opennetworkinglab.
the class Dhcp6HandlerUtil method getInterfaceIdIdOption.
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() >> 8) & 0xff);
vlanIdBytes[1] = (byte) (clientPacket.getVlanID() & 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 {}, vlanId {}", HexString.toHexString(clientSoureMacBytes, ":"), inPortString, vlanIdBytes);
return interfaceId;
}
use of org.onlab.packet.dhcp.Dhcp6Option in project onos by opennetworkinglab.
the class Dhcp6HandlerUtil method buildDhcp6PacketFromClient.
/**
* 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 {
// 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 (!serverInfo.getRelayAgentIp6(receivedFromDevice).isPresent()) {
log.debug("indirect connection: relayAgentIp NOT availale from config file! Use dynamic. {}", HexString.toHexString(relayAgentIp.toOctets(), ":"));
serverIpFacing = relayAgentIp;
} else {
serverIpFacing = serverInfo.getRelayAgentIp6(receivedFromDevice).get();
}
log.debug("Source IP address set as relay agent IP with value: {}", serverIpFacing);
dhcp6Relay.setLinkAddress(serverIpFacing.toOctets());
ipv6Packet.setSourceAddress(serverIpFacing.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;
}
use of org.onlab.packet.dhcp.Dhcp6Option in project onos by opennetworkinglab.
the class DhcpRelayManagerTest method buildRelayMsg.
private void buildRelayMsg(DHCP6 dhcp6Relay, byte msgType, Ip6Address linkAddr, Ip6Address peerAddr, byte hop, byte[] interfaceIdBytes, DHCP6 dhcp6Payload) {
dhcp6Relay.setMsgType(msgType);
dhcp6Relay.setLinkAddress(linkAddr.toOctets());
dhcp6Relay.setPeerAddress(peerAddr.toOctets());
dhcp6Relay.setHopCount(hop);
List<Dhcp6Option> options = new ArrayList<Dhcp6Option>();
// interfaceId option
Dhcp6Option interfaceId = new Dhcp6Option();
interfaceId.setCode(DHCP6.OptionCode.INTERFACE_ID.value());
interfaceId.setData(interfaceIdBytes);
interfaceId.setLength((short) interfaceIdBytes.length);
Dhcp6InterfaceIdOption interfaceIdOption = new Dhcp6InterfaceIdOption(interfaceId);
byte[] optionData = interfaceIdOption.getData();
ByteBuffer bb = ByteBuffer.wrap(interfaceIdBytes);
byte[] macAddr = new byte[MacAddress.MAC_ADDRESS_LENGTH];
byte[] port = new byte[optionData.length - MacAddress.MAC_ADDRESS_LENGTH - VLAN_LEN - SEPARATOR_LEN * 2];
short vlan;
bb.get(macAddr);
// separator
bb.get();
bb.get(port);
// separator
bb.get();
vlan = bb.getShort();
interfaceIdOption.setMacAddress(MacAddress.valueOf(macAddr));
interfaceIdOption.setInPort(port);
interfaceIdOption.setVlanId(vlan);
options.add(interfaceIdOption);
// relay message option
Dhcp6Option relayMsgOption = new Dhcp6Option();
relayMsgOption.setCode(DHCP6.OptionCode.RELAY_MSG.value());
byte[] dhcp6PayloadByte = dhcp6Payload.serialize();
relayMsgOption.setLength((short) dhcp6PayloadByte.length);
relayMsgOption.setPayload(dhcp6Payload);
Dhcp6RelayOption relayOpt = new Dhcp6RelayOption(relayMsgOption);
options.add(relayOpt);
dhcp6Relay.setOptions(options);
}
use of org.onlab.packet.dhcp.Dhcp6Option 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;
}
Aggregations