use of org.onosproject.dhcprelay.store.DhcpRecord in project onos by opennetworkinglab.
the class Dhcp4HandlerImpl method handleLeaseQueryMsg.
private void handleLeaseQueryMsg(PacketContext context, Ethernet packet, DHCP dhcpPayload) {
// where queried client is connected to. Otherwise, DHCPLEASEQUERY source may be a separate connected agent
if (learnRouteFromLeasequery) {
log.debug("LQ: Got DHCPLEASEQUERY packet!");
MacAddress clientMacAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
log.debug("LQ: got DHCPLEASEQUERY with MAC " + clientMacAddress.toString());
// add the client mac (hostid) of this request to a store (the entry will be removed with
// the reply sent to the originator)
VlanId vlanId = VlanId.vlanId(packet.getVlanID());
HostId hId = HostId.hostId(clientMacAddress, vlanId);
DhcpRecord record = dhcpRelayStore.getDhcpRecord(hId).orElse(null);
if (record != null) {
// new NH is to be taken from src mac of LQ packet
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
// 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.trace("LeaseQueryMsg forward to server connected to {}", internalPacket.getDestLocation());
forwardPacket(internalPacket);
}
}
}
use of org.onosproject.dhcprelay.store.DhcpRecord 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();
}
use of org.onosproject.dhcprelay.store.DhcpRecord in project onos by opennetworkinglab.
the class Dhcp6HandlerImpl method addHostOrRoute.
/**
* add host or route and update dhcp relay record.
*
* @param directConnFlag flag to show that packet is from directly connected client
* @param location client side connect point
* @param dhcp6Relay the dhcp6 payload
* @param embeddedDhcp6 the dhcp6 payload within relay
* @param srcMac client gw/host macAddress
* @param clientInterface client interface
* @param vlanIdInUse vlanid encoded in the interface id Option
*/
private void addHostOrRoute(boolean directConnFlag, ConnectPoint location, DHCP6 dhcp6Relay, DHCP6 embeddedDhcp6, MacAddress srcMac, Interface clientInterface, VlanId vlanIdInUse) {
log.debug("addHostOrRoute entered.");
VlanId vlanId;
if (clientInterface.vlanTagged().isEmpty()) {
vlanId = clientInterface.vlan();
} else {
// might be multiple vlan in same interface
vlanId = vlanIdInUse;
}
if (vlanId == null) {
vlanId = VlanId.NONE;
}
Boolean isMsgReply = Dhcp6HandlerUtil.isDhcp6Reply(dhcp6Relay);
MacAddress leafClientMac;
Byte leafMsgType;
Dhcp6ClientIdOption clientIdOption = Dhcp6HandlerUtil.extractClientId(directConnFlag, embeddedDhcp6);
if (clientIdOption != null) {
log.debug("CLIENTID option found {}", clientIdOption);
if ((clientIdOption.getDuid().getDuidType() == Dhcp6Duid.DuidType.DUID_LLT) || (clientIdOption.getDuid().getDuidType() == Dhcp6Duid.DuidType.DUID_LL)) {
leafClientMac = MacAddress.valueOf(clientIdOption.getDuid().getLinkLayerAddress());
} else {
log.warn("Link-Layer Address not supported in CLIENTID option. No DhcpRelay Record created.");
// dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_LINKLOCAL_FAIL);
return;
}
} else {
log.warn("CLIENTID option NOT found. No DhcpRelay Record created.");
// dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_CLIENTID_FAIL);
return;
}
HostId leafHostId = HostId.hostId(leafClientMac, vlanId);
DhcpRecord record = dhcpRelayStore.getDhcpRecord(leafHostId).orElse(null);
if (record == null) {
record = new DhcpRecord(HostId.hostId(leafClientMac, vlanId));
} else {
record = record.clone();
}
IpAddressInfo ipInfo;
PdPrefixInfo pdInfo = null;
if (directConnFlag) {
// Add to host store if it connect to network directly
ipInfo = extractIpAddress(embeddedDhcp6);
if (ipInfo != null) {
if (isMsgReply) {
Set<IpAddress> ips = Sets.newHashSet(ipInfo.ip6Address);
HostId hostId = HostId.hostId(srcMac, vlanId);
Host host = hostService.getHost(hostId);
HostLocation hostLocation = new HostLocation(clientInterface.connectPoint(), System.currentTimeMillis());
Set<HostLocation> hostLocations = Sets.newHashSet(hostLocation);
if (host != null) {
// Dual homing support:
// if host exists, use old locations and new location
hostLocations.addAll(host.locations());
}
HostDescription desc = new DefaultHostDescription(srcMac, vlanId, hostLocations, ips, false);
log.debug("adding Host for directly connected.");
log.debug("client mac {} client vlan {} hostlocation {}", HexString.toHexString(srcMac.toBytes(), ":"), vlanId, hostLocation.toString());
// Replace the ip when dhcp server give the host new ip address
providerService.hostDetected(hostId, desc, false);
}
} else {
log.warn("ipAddress not found. Do not add Host {} for directly connected.", HostId.hostId(srcMac, vlanId).toString());
}
leafMsgType = embeddedDhcp6.getMsgType();
} else {
// Add to route store if it does not connect to network directly
// pick out the first link-local ip address
IpAddress nextHopIp = getFirstIpByHost(directConnFlag, srcMac, vlanId);
if (nextHopIp == null) {
log.warn("Can't find link-local IP address of gateway mac {} vlanId {}", srcMac, vlanId);
// dhcpRelayCountersStore.incrementCounter(gCount, DhcpRelayCounters.NO_LINKLOCAL_GW);
return;
}
DHCP6 leafDhcp = Dhcp6HandlerUtil.getDhcp6Leaf(embeddedDhcp6);
ipInfo = extractIpAddress(leafDhcp);
if (ipInfo == null) {
log.debug("ip is null");
} else {
if (isMsgReply) {
Route routeForIP = new Route(Route.Source.DHCP, ipInfo.ip6Address.toIpPrefix(), nextHopIp);
log.debug("adding Route of 128 address for indirectly connected.");
routeStore.replaceRoute(routeForIP);
}
}
pdInfo = extractPrefix(leafDhcp);
if (pdInfo == null) {
log.debug("ipPrefix is null ");
} else {
if (isMsgReply) {
Route routeForPrefix = new Route(Route.Source.DHCP, pdInfo.pdPrefix, nextHopIp);
log.debug("adding Route of PD for indirectly connected.");
routeStore.replaceRoute(routeForPrefix);
if (this.dhcpFpmEnabled) {
FpmRecord fpmRecord = new FpmRecord(pdInfo.pdPrefix, nextHopIp, FpmRecord.Type.DHCP_RELAY);
dhcpFpmPrefixStore.addFpmRecord(pdInfo.pdPrefix, fpmRecord);
}
}
}
leafMsgType = leafDhcp.getMsgType();
}
if (leafMsgType == DHCP6.MsgType.RELEASE.value() || (leafMsgType == DHCP6.MsgType.REPLY.value()) && ipInfo == null) {
log.warn("DHCP6 RELEASE/REPLY(null ip) from Server. MsgType {}", leafMsgType);
// return;
}
record.addLocation(new HostLocation(location, System.currentTimeMillis()));
if (leafMsgType == DHCP6.MsgType.REPLY.value()) {
if (ipInfo != null) {
log.debug("IP6 address is being stored into dhcp-relay store.");
log.debug("Client IP6 address {}", HexString.toHexString(ipInfo.ip6Address.toOctets(), ":"));
record.ip6Address(ipInfo.ip6Address);
record.updateAddrPrefTime(ipInfo.prefTime);
record.updateLastIp6Update();
} else {
log.debug("IP6 address is not returned from server. Maybe only PD is returned.");
}
if (pdInfo != null) {
log.debug("IP6 PD address {}", HexString.toHexString(pdInfo.pdPrefix.address().toOctets(), ":"));
record.pdPrefix(pdInfo.pdPrefix);
record.updatePdPrefTime(pdInfo.prefTime);
record.updateLastPdUpdate();
} else {
log.debug("IP6 PD address is not returned from server. Maybe only IPAddress is returned.");
}
}
record.getV6Counters().incrementCounter(Dhcp6HandlerUtil.getMsgTypeStr(leafMsgType));
record.ip6Status(DHCP6.MsgType.getType(leafMsgType));
record.setDirectlyConnected(directConnFlag);
record.updateLastSeen();
dhcpRelayStore.updateDhcpRecord(leafHostId, record);
/*
// TODO Use AtomicInteger for the counters
try {
recordSemaphore.acquire();
try {
dhcpRelayCountersStore.incrementCounter(gCount, Dhcp6HandlerUtil.getMsgTypeStr(leafMsgType));
} finally {
// calling release() after a successful acquire()
recordSemaphore.release();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
*/
}
use of org.onosproject.dhcprelay.store.DhcpRecord in project onos by opennetworkinglab.
the class DhcpRelayWebResource method resetDhcpRelayCountersInternal.
/**
* To reset dhcp relay counters.
*
* @return counterArray type ArrayNode.
*/
private void resetDhcpRelayCountersInternal() {
DhcpRelayService dhcpDelayService = get(DhcpRelayService.class);
Collection<DhcpRecord> records = dhcpDelayService.getDhcpRecords();
records.forEach(record -> {
DhcpRelayCounters v6Counters = record.getV6Counters();
v6Counters.resetCounters();
});
}
use of org.onosproject.dhcprelay.store.DhcpRecord in project onos by opennetworkinglab.
the class DhcpRelayCommand method doExecute.
@Override
protected void doExecute() {
List<DhcpServerInfo> defaultDhcpServerInfoList = DHCP_RELAY_SERVICE.getDefaultDhcpServerInfoList();
List<DhcpServerInfo> indirectDhcpServerInfoList = DHCP_RELAY_SERVICE.getIndirectDhcpServerInfoList();
if (defaultDhcpServerInfoList.isEmpty() && indirectDhcpServerInfoList.isEmpty()) {
print(MISSING_SERVER_CFG);
return;
}
if (!defaultDhcpServerInfoList.isEmpty()) {
print(DEFAULT_SERVERS);
listServers(defaultDhcpServerInfoList);
}
if (!indirectDhcpServerInfoList.isEmpty()) {
print(INDIRECT_SERVERS);
listServers(indirectDhcpServerInfoList);
}
// DHCP records
Collection<DhcpRecord> records = DHCP_RELAY_SERVICE.getDhcpRecords();
if (records.isEmpty()) {
print(NO_RECORDS);
return;
}
// Handle display of counters
boolean toResetFlag;
if (counter != null) {
if (counter.equals("counter") || counter.equals("[counter]")) {
print(CONUTER_HEADER);
} else {
print("first parameter is [counter]");
return;
}
if (reset != null) {
if (reset.equals("reset") || reset.equals("[reset]")) {
toResetFlag = true;
} else {
print("Last parameter is [reset]");
return;
}
} else {
toResetFlag = false;
}
records.forEach(record -> {
print(COUNTER_HOST, record.macAddress(), record.vlanId(), record.locations(), record.directlyConnected() ? DIRECTLY : EMPTY);
DhcpRelayCounters v6Counters = record.getV6Counters();
Map<String, Integer> countersMap = v6Counters.getCounters();
countersMap.forEach((name, value) -> {
print("%-30s ............................ %-4d packets", name, value);
});
if (toResetFlag) {
v6Counters.resetCounters();
record.updateLastSeen();
DHCP_RELAY_SERVICE.updateDhcpRecord(HostId.hostId(record.macAddress(), record.vlanId()), record);
}
});
return;
}
// Handle display of records
print(HEADER);
records.forEach(record -> print(HOST, record.macAddress(), record.vlanId(), record.locations(), record.directlyConnected() ? DIRECTLY : EMPTY, Tools.timeAgo(record.lastSeen()), ip4State(record), ip6State(record)));
}
Aggregations