use of org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_CircuitID in project onos by opennetworkinglab.
the class Dhcp4HandlerImpl method getClientInterface.
/**
* Gets output interface of a dhcp packet.
* If option 82 exists in the dhcp packet and the option was sent by
* ONOS (circuit format is correct), use the connect
* point and vlan id from circuit id; otherwise, find host by destination
* address and use vlan id from sender (dhcp server).
*
* @param ethPacket the ethernet packet
* @param dhcpPayload the dhcp packet
* @return an interface represent the output port and vlan; empty value
* if the host or circuit id not found
*/
private Optional<Interface> getClientInterface(Ethernet ethPacket, DHCP dhcpPayload) {
VlanId originalPacketVlanId = VlanId.vlanId(ethPacket.getVlanID());
DhcpRelayAgentOption option = (DhcpRelayAgentOption) dhcpPayload.getOption(OptionCode_CircuitID);
DhcpOption circuitIdSubOption = option.getSubOption(CIRCUIT_ID.getValue());
try {
CircuitId circuitId = CircuitId.deserialize(circuitIdSubOption.getData());
ConnectPoint connectPoint = ConnectPoint.deviceConnectPoint(circuitId.connectPoint());
VlanId vlanId = circuitId.vlanId();
return interfaceService.getInterfacesByPort(connectPoint).stream().filter(iface -> interfaceContainsVlan(iface, vlanId)).findFirst();
} catch (IllegalArgumentException ex) {
// invalid circuit format, didn't sent by ONOS
log.debug("Invalid circuit {}, use information from dhcp payload", circuitIdSubOption.getData());
}
// Use Vlan Id from DHCP server if DHCP relay circuit id was not
// sent by ONOS or circuit Id can't be parsed
// TODO: remove relay store from this method
MacAddress dstMac = valueOf(dhcpPayload.getClientHardwareAddress());
VlanId filteredVlanId = getVlanIdFromDhcpRecord(dstMac, originalPacketVlanId);
// Get the vlan from the dhcp record
if (filteredVlanId == null) {
log.debug("not find the matching DHCP record for mac: {} and vlan: {}", dstMac, originalPacketVlanId);
return Optional.empty();
}
Optional<DhcpRecord> dhcpRecord = dhcpRelayStore.getDhcpRecord(HostId.hostId(dstMac, filteredVlanId));
ConnectPoint clientConnectPoint = dhcpRecord.map(DhcpRecord::locations).orElse(Collections.emptySet()).stream().reduce((hl1, hl2) -> {
// find latest host connect point
if (hl1 == null || hl2 == null) {
return hl1 == null ? hl2 : hl1;
}
return hl1.time() > hl2.time() ? hl1 : hl2;
}).orElse(null);
if (clientConnectPoint != null) {
return interfaceService.getInterfacesByPort(clientConnectPoint).stream().filter(iface -> interfaceContainsVlan(iface, filteredVlanId)).findFirst();
}
return Optional.empty();
}
Aggregations