Adding purgeOnDisconnect feature to delete meters and updating EAPOL trap
flows.
* Calling preSetProperty of componentConfigService for MeterManager
* Remove the meter from programmedMeters map when the device disconnects
* Adding vlanId match criteria to EAPOL trap flows
* Adding c-tag or default vlan to write-metadata instruction value for
EAPOL trap flows
* Change the ONOS dependency to 1.13.9-rc3
* Fixing disable-reenabling ONU issue
* Fixing reboot OLT issue
Change-Id: Icce73e8334925193fa2e63d558814eb3bc836f3d
diff --git a/app/src/main/java/org/opencord/olt/impl/Olt.java b/app/src/main/java/org/opencord/olt/impl/Olt.java
index 13bb9bb..60d9e5d 100644
--- a/app/src/main/java/org/opencord/olt/impl/Olt.java
+++ b/app/src/main/java/org/opencord/olt/impl/Olt.java
@@ -29,6 +29,7 @@
import java.util.Dictionary;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
@@ -36,6 +37,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
import com.google.common.collect.ImmutableSet;
import org.apache.felix.scr.annotations.Activate;
@@ -121,6 +123,7 @@
private static final String APP_NAME = "org.opencord.olt";
private static final short DEFAULT_VLAN = 0;
+ private static final short EAPOL_DEFAULT_VLAN = 4091;
private static final int DEFAULT_TP_ID = 64;
private static final String DEFAULT_BP_ID = "Default";
private static final String ADDITIONAL_VLANS = "additional-vlans";
@@ -225,6 +228,9 @@
componentConfigService
.preSetProperty("org.onosproject.net.flow.impl.FlowRuleManager",
"purgeOnDisconnection", "true");
+ componentConfigService
+ .preSetProperty("org.onosproject.net.meter.impl.MeterManager",
+ "purgeOnDisconnection", "true");
componentConfigService.registerProperties(getClass());
programmedSubs = Maps.newConcurrentMap();
programmedMeters = ConcurrentHashMap.newKeySet();
@@ -340,7 +346,8 @@
//delete Eapol authentication flow with default bandwidth
//wait until Eapol rule with defaultBpId is removed to install subscriber-based rules
- processEapolFilteringObjectives(deviceId, subscriberPortNo, defaultBpId, filterFuture, false);
+ processEapolFilteringObjectives(deviceId, subscriberPortNo, defaultBpId, filterFuture,
+ VlanId.vlanId(EAPOL_DEFAULT_VLAN), false);
removeMeterIdFromBpMapping(deviceId, defaultBpId);
//install subscriber flows
@@ -405,8 +412,9 @@
//re-install eapol
processEapolFilteringObjectives(deviceId, subscriberPortNo,
- subscriber.upstreamBandwidthProfile(), null, false);
- processEapolFilteringObjectives(deviceId, subscriberPortNo, defaultBpId, null, true);
+ subscriber.upstreamBandwidthProfile(), null, subscriber.cTag(), false);
+ processEapolFilteringObjectives(deviceId, subscriberPortNo, defaultBpId,
+ null, VlanId.vlanId(EAPOL_DEFAULT_VLAN), true);
programmedSubs.remove(connectPoint);
return true;
@@ -718,7 +726,7 @@
if (upstreamMeterId != null) {
//re-install Eapol authentication flow with the subscribers' upstream bandwidth profile
processEapolFilteringObjectives(deviceId, subscriberPort, sub.upstreamBandwidthProfile(),
- null, true);
+ null, sub.cTag(), true);
processDhcpFilteringObjectives(deviceId, subscriberPort,
upstreamMeterId, sub.technologyProfileId(), true, true);
@@ -1050,13 +1058,18 @@
}
/**
- * Returns the write metadata value including only tech profile reference.
+ * Returns the write metadata value including tech profile reference and innerVlan.
+ * For param cVlan, null can be sent
*
+ * @param cVlan c (customer) tag of one subscriber
* @param techProfileId tech profile id of one subscriber
- * @return the write metadata value including only tech profile reference
+ * @return the write metadata value including tech profile reference and innerVlan
*/
- private Long createTechProfValueForWm(int techProfileId) {
- return (long) techProfileId << 32;
+ private Long createTechProfValueForWm(VlanId cVlan, int techProfileId) {
+ if (cVlan == null) {
+ return (long) techProfileId << 32;
+ }
+ return ((long) (cVlan.id()) << 48 | (long) techProfileId << 32);
}
/**
@@ -1066,11 +1079,12 @@
* @param portNumber the port for which this trap flow is designated
* @param bpId bandwidth profile id to add the related meter to the flow
* @param filterFuture completable future for this filtering objective operation
+ * @param vlanId the default or customer tag for a subscriber
* @param install true to install the flow, false to remove the flow
*/
private void processEapolFilteringObjectives(DeviceId devId, PortNumber portNumber, String bpId,
CompletableFuture<ObjectiveError> filterFuture,
- boolean install) {
+ VlanId vlanId, boolean install) {
if (!enableEapol) {
log.debug("Eapol filtering is disabled.");
@@ -1107,8 +1121,9 @@
FilteringObjective eapol = (install ? builder.permit() : builder.deny())
.withKey(Criteria.matchInPort(portNumber))
.addCondition(Criteria.matchEthType(EthType.EtherType.EAPOL.ethType()))
+ .addCondition(Criteria.matchVlanId(vlanId))
.withMeta(treatmentBuilder
- .writeMetadata(createTechProfValueForWm(techProfileId), 0)
+ .writeMetadata(createTechProfValueForWm(vlanId, techProfileId), 0)
.setOutput(PortNumber.CONTROLLER).build())
.fromApp(appId)
.withPriority(10000)
@@ -1258,7 +1273,7 @@
}
if (techProfileId != -1) {
- treatmentBuilder.writeMetadata(createTechProfValueForWm(techProfileId), 0);
+ treatmentBuilder.writeMetadata(createTechProfValueForWm(null, techProfileId), 0);
}
FilteringObjective dhcpUpstream = (install ? builder.permit() : builder.deny())
@@ -1313,7 +1328,7 @@
}
if (techProfileId != -1) {
- treatmentBuilder.writeMetadata(createTechProfValueForWm(techProfileId), 0);
+ treatmentBuilder.writeMetadata(createTechProfValueForWm(null, techProfileId), 0);
}
builder = install ? builder.permit() : builder.deny();
@@ -1363,7 +1378,8 @@
// This is an OLT device as per Sadis, we create flows for UNI and NNI ports
for (Port p : deviceService.getPorts(dev.id())) {
if (isUniPort(dev, p)) {
- processEapolFilteringObjectives(dev.id(), p.number(), defaultBpId, null, true);
+ processEapolFilteringObjectives(dev.id(), p.number(), defaultBpId, null,
+ VlanId.vlanId(EAPOL_DEFAULT_VLAN), true);
} else {
processNniFilteringObjectives(dev.id(), p.number(), true);
}
@@ -1519,7 +1535,7 @@
if (port.isEnabled()) {
processEapolFilteringObjectives(devId, port.number(), defaultBpId,
- null, true);
+ null, VlanId.vlanId(EAPOL_DEFAULT_VLAN), true);
}
} else {
checkAndCreateDeviceFlows(dev);
@@ -1528,10 +1544,6 @@
case PORT_REMOVED:
if (isUniPort(dev, port)) {
if (port.isEnabled()) {
- processEapolFilteringObjectives(devId, port.number(),
- getCurrentBandwidthProfile(new ConnectPoint(devId, port.number())),
- null, false);
-
removeSubscriber(new ConnectPoint(devId, port.number()));
}
@@ -1544,15 +1556,20 @@
break;
}
+ SubscriberAndDeviceInformation sub = programmedSubs
+ .get(new ConnectPoint(devId, port.number()));
+ VlanId vlanId = sub == null ? VlanId.vlanId(EAPOL_DEFAULT_VLAN) : sub.cTag();
+
+ String bpId = getCurrentBandwidthProfile(new ConnectPoint(devId, port.number()));
+
if (port.isEnabled()) {
- processEapolFilteringObjectives(devId, port.number(), defaultBpId,
- null, true);
+ processEapolFilteringObjectives(devId, port.number(), bpId,
+ null, vlanId, true);
post(new AccessDeviceEvent(AccessDeviceEvent.Type.UNI_ADDED, devId, port));
} else {
- processEapolFilteringObjectives(devId, port.number(),
- getCurrentBandwidthProfile(new ConnectPoint(devId, port.number())),
- null, false);
+ processEapolFilteringObjectives(devId, port.number(), bpId,
+ null, vlanId, false);
post(new AccessDeviceEvent(AccessDeviceEvent.Type.UNI_REMOVED, devId, port));
}
break;
@@ -1576,6 +1593,7 @@
.forEach(p -> post(new AccessDeviceEvent(
AccessDeviceEvent.Type.UNI_REMOVED, devId, p)));
programmedDevices.remove(devId);
+ removeAllSubscribers(devId);
post(new AccessDeviceEvent(
AccessDeviceEvent.Type.DEVICE_DISCONNECTED, devId,
null, null));
@@ -1585,10 +1603,11 @@
post(new AccessDeviceEvent(
AccessDeviceEvent.Type.DEVICE_CONNECTED, devId,
null, null));
- programmedDevices.add(devId);
+ programmedDevices.add(devId);
checkAndCreateDeviceFlows(dev);
} else {
- programmedDevices.remove(devId);
+ programmedDevices.remove(devId);
+ removeAllSubscribers(devId);
post(new AccessDeviceEvent(
AccessDeviceEvent.Type.DEVICE_DISCONNECTED, devId,
null, null));
@@ -1610,6 +1629,14 @@
}
return defaultBpId;
}
+
+ private void removeAllSubscribers(DeviceId deviceId) {
+ List<ConnectPoint> connectPoints = programmedSubs.keySet().stream()
+ .filter(ks -> Objects.equals(ks.deviceId(), deviceId))
+ .collect(Collectors.toList());
+
+ connectPoints.forEach(cp -> programmedSubs.remove(cp));
+ }
}
private class InternalMeterListener implements MeterListener {
@@ -1650,6 +1677,7 @@
&& meterKey.meterId().equals(meter.id())).findFirst().
ifPresent(mk -> {
meterKeys.remove(mk);
+ programmedMeters.remove(mk);
log.info("Deleted from the internal map. MeterKey {}", mk);
log.info("Programmed meters {}", programmedMeters);
}));
diff --git a/pom.xml b/pom.xml
index d0574ec..8ea7eae 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@
<parent>
<groupId>org.onosproject</groupId>
<artifactId>onos-dependencies</artifactId>
- <version>1.13.9-rc2</version>
+ <version>1.13.9-rc3</version>
<relativePath></relativePath>
</parent>
@@ -33,7 +33,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <onos.version>1.13.9-rc2</onos.version>
+ <onos.version>1.13.9-rc3</onos.version>
</properties>
<modules>