VOL-4736 : oltapp unable to remove fttb flows on port down as learnt mac address is lost
Change-Id: Ibfc704af33d134538512b250c719727ec6a19522
diff --git a/impl/src/main/java/org/opencord/olt/impl/OltFlowService.java b/impl/src/main/java/org/opencord/olt/impl/OltFlowService.java
index 04ea492..7a1cdc7 100644
--- a/impl/src/main/java/org/opencord/olt/impl/OltFlowService.java
+++ b/impl/src/main/java/org/opencord/olt/impl/OltFlowService.java
@@ -231,6 +231,13 @@
private final Lock provisionedSubscribersReadLock = provisionedSubscribersLock.readLock();
/**
+ * For storing the mapping of ConnectPoints to FTTB DPU MAC addresses.
+ */
+ protected Map<ConnectPoint, MacAddress> fttbMacAddresses;
+ private final ReentrantReadWriteLock fttbMacAddressesLock = new ReentrantReadWriteLock();
+ private final Lock fttbMacAddressesWriteLock = fttbMacAddressesLock.writeLock();
+
+ /**
* Create DHCP trap flow on NNI port(s).
*/
protected boolean enableDhcpOnNni = ENABLE_DHCP_ON_NNI_DEFAULT;
@@ -305,6 +312,18 @@
.withSerializer(Serializer.using(serializer))
.build().asJavaMap();
+ KryoNamespace fttbMacSerializer = KryoNamespace.newBuilder()
+ .register(KryoNamespaces.API)
+ .register(ConnectPoint.class)
+ .register(MacAddress.class)
+ .build();
+
+ fttbMacAddresses = storageService.<ConnectPoint, MacAddress>consistentMapBuilder()
+ .withName("fttb-mac-addresses")
+ .withApplicationId(appId)
+ .withSerializer(Serializer.using(fttbMacSerializer))
+ .build().asJavaMap();
+
flowRuleService.addListener(internalFlowListener);
log.info("Started");
@@ -1824,8 +1843,10 @@
VlanId innerVlan = null;
treatmentBuilder.setOutput(nniPort.number());
if (serviceName.equals(FTTB_SERVICE_DPU_MGMT_TRAFFIC) || serviceName.equals(FTTB_SERVICE_DPU_ANCP_TRAFFIC)) {
+ fttbMacAddressesWriteLock.lock();
MacAddress mac = FttbUtils.getMacAddressFromDhcpEnabledUti(
- hostService, si, deviceId, port);
+ hostService, si, deviceId, port, fttbMacAddresses);
+ fttbMacAddressesWriteLock.unlock();
if (mac == null) {
log.error("Mac address not found port:{}, vlan:{}, service:{}",
@@ -1884,8 +1905,10 @@
VlanId innerVlan = null;
if (serviceName.equals(FTTB_SERVICE_DPU_MGMT_TRAFFIC) || serviceName.equals(FTTB_SERVICE_DPU_ANCP_TRAFFIC)) {
+ fttbMacAddressesWriteLock.lock();
MacAddress mac = FttbUtils.getMacAddressFromDhcpEnabledUti(
- hostService, si, deviceId, port);
+ hostService, si, deviceId, port, fttbMacAddresses);
+ fttbMacAddressesWriteLock.unlock();
if (mac == null) {
log.error("Mac address not found port:{}, vlan:{}, service:{}",
@@ -1951,4 +1974,4 @@
flowObjectiveService.forward(deviceId, flow);
}
}
-}
\ No newline at end of file
+}
diff --git a/impl/src/main/java/org/opencord/olt/impl/fttb/FttbUtils.java b/impl/src/main/java/org/opencord/olt/impl/fttb/FttbUtils.java
index 1ffb732..9ce0181 100644
--- a/impl/src/main/java/org/opencord/olt/impl/fttb/FttbUtils.java
+++ b/impl/src/main/java/org/opencord/olt/impl/fttb/FttbUtils.java
@@ -31,6 +31,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.Map;
import java.util.Optional;
/**
@@ -158,24 +159,36 @@
/**
* Returns mac address from the Dhcp Enabled UniTagInformation for a FTTB service.
*
- * @param hostService Service for interacting with the inventory of end-station hosts
- * @param si Information about a subscriber
- * @param deviceId Device id for mac lookup.
- * @param port Uni port on the device for mac lookup.
+ * @param hostService Service for interacting with the inventory of end-station hosts
+ * @param si Information about a subscriber
+ * @param deviceId Device id for mac lookup.
+ * @param port Uni port on the device for mac lookup.
+ * @param localAddresses Map of the addresses that this app has locally
* @return Mac address of the subscriber.
*/
public static MacAddress getMacAddressFromDhcpEnabledUti(HostService hostService,
SubscriberAndDeviceInformation si,
DeviceId deviceId,
- Port port) {
+ Port port,
+ Map<ConnectPoint, MacAddress> localAddresses) {
for (UniTagInformation uniTagInfo : si.uniTagList()) {
boolean isMacLearningEnabled = uniTagInfo.getEnableMacLearning();
if (isMacLearningEnabled) {
- Optional<Host> optHost = hostService.getConnectedHosts(new ConnectPoint(deviceId, port.number()))
+ ConnectPoint cp = new ConnectPoint(deviceId, port.number());
+ Optional<Host> optHost = hostService.getConnectedHosts(cp)
.stream().filter(host -> host.vlan().equals(uniTagInfo.getPonSTag())).findFirst();
if (optHost.isPresent()) {
- if (optHost.get().mac() != null) {
- return optHost.get().mac();
+ MacAddress learntMac = optHost.get().mac();
+ if (learntMac != null) {
+ localAddresses.put(cp, learntMac);
+ log.info("Stored mac {} locally for connectPoint {}", learntMac, cp);
+ return learntMac;
+ }
+ } else {
+ MacAddress localMac = localAddresses.get(new ConnectPoint(deviceId, port.number()));
+ if (localMac != null) {
+ log.debug("Returning local mac {} for connectPoint {}", localMac, cp);
+ return localMac;
}
}
} else if (uniTagInfo.getConfiguredMacAddress() != null &&