From 126aba949906ca828812ec321d6163d00c37170c Mon Sep 17 00:00:00 2001 From: Pier Luigi Ventre <5659115+pierventre@users.noreply.github.com> Date: Tue, 29 Mar 2022 01:33:47 +0200 Subject: [PATCH] [SDFAB-1100] Leverage in-order FlowRuleService APIs (#512) * [SDFAB-1100] Leverage in-order FlowRuleService APIs FabricUpfProgrammable leverages the new APIs to guarantee in-order processing of the requests coming from the north. If batch APIs are not used there is no guarantee about the processing order in the FlowRuleService. Instead, the `striped` API allow the apps to signal a preference in the requests processing which is used by the FlowRuleService to serialize all the requests, having equal key, on the same executor. Depends on https://gerrit.onosproject.org/c/onos/+/25423 * Update snapshot version Co-authored-by: Carmelo Cascone --- README.md | 2 +- pom.xml | 2 +- .../behaviour/upf/FabricUpfProgrammable.java | 27 ++++++++++--------- .../behaviour/upf/MockFlowRuleService.java | 10 +++++++ 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index f276ed7a0..ebfe0ef13 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ multiple targets: To build and test this project you will need the following software: * Barefoot SDE (a.k.a. Intel P4 Studio) = 9.7.0 -* ONOS >= 2.5.7 +* ONOS >= 2.5.8 * Docker (to run the build scripts without worrying about dependencies) * cURL (to interact with the ONOS REST APIs) diff --git a/pom.xml b/pom.xml index 103b1995c..57817c6e9 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ SPDX-License-Identifier: Apache-2.0 org.onosproject onos-dependencies - 2.5.7-SNAPSHOT + 2.5.8-SNAPSHOT org.stratumproject diff --git a/src/main/java/org/stratumproject/fabric/tna/behaviour/upf/FabricUpfProgrammable.java b/src/main/java/org/stratumproject/fabric/tna/behaviour/upf/FabricUpfProgrammable.java index 855fd7fef..20b0f5abc 100644 --- a/src/main/java/org/stratumproject/fabric/tna/behaviour/upf/FabricUpfProgrammable.java +++ b/src/main/java/org/stratumproject/fabric/tna/behaviour/upf/FabricUpfProgrammable.java @@ -298,7 +298,7 @@ public void enablePscEncap() { FABRIC_EGRESS_UPF_GTPU_ENCAP, deviceId); return; } - flowRuleService.applyFlowRules(upfTranslator.buildGtpuWithPscEncapRule( + flowRuleService.applyFlowRules(deviceId.hashCode(), upfTranslator.buildGtpuWithPscEncapRule( deviceId, appId)); } @@ -312,7 +312,7 @@ public void disablePscEncap() { FABRIC_EGRESS_UPF_GTPU_ENCAP, deviceId); return; } - flowRuleService.applyFlowRules(upfTranslator.buildGtpuOnlyEncapRule( + flowRuleService.applyFlowRules(deviceId.hashCode(), upfTranslator.buildGtpuOnlyEncapRule( deviceId, appId)); } @@ -407,7 +407,7 @@ public void deleteAll(UpfEntityType entityType) throws UpfProgrammableException break; } } - flowRuleService.removeFlowRules(toBeRemoved.toArray(FlowRule[]::new)); + flowRuleService.removeFlowRules(deviceId.hashCode(), toBeRemoved.toArray(FlowRule[]::new)); log.info("Cleared {} UPF entities of type {}", entitiesCleared, entityType.humanReadableName()); } @@ -763,7 +763,7 @@ private void addUpfApplication(UpfApplication appFilter) throws UpfProgrammableE assertSliceId(appFilter.sliceId()); FlowRule flowRule = upfTranslator.upfApplicationToFabricEntry(appFilter, deviceId, appId); log.info("Installing {}", appFilter); - flowRuleService.applyFlowRules(flowRule); + flowRuleService.applyFlowRules(deviceId.hashCode(), flowRule); log.debug("Application added with flowID {}", flowRule.id().value()); } @@ -771,7 +771,7 @@ private void addInterface(UpfInterface upfInterface) throws UpfProgrammableExcep assertSliceId(upfInterface.sliceId()); FlowRule flowRule = upfTranslator.interfaceToFabricEntry(upfInterface, deviceId, appId, DEFAULT_PRIORITY); log.info("Installing {}", upfInterface); - flowRuleService.applyFlowRules(flowRule); + flowRuleService.applyFlowRules(deviceId.hashCode(), flowRule); log.debug("Interface added with flowID {}", flowRule.id().value()); // By default we enable UE-to-UE communication on the UE subnet identified by the CORE interface. // TODO: allow enabling/disabling UE-to-UE via netcfg or other API. @@ -785,7 +785,8 @@ private void addGtpTunnelPeer(UpfGtpTunnelPeer peer) throws UpfProgrammableExcep peer, deviceId, appId, DEFAULT_PRIORITY); log.info("Installing ingress and egress rules {}, {}", fabricGtpTunnelPeers.getLeft().toString(), fabricGtpTunnelPeers.getRight().toString()); - flowRuleService.applyFlowRules(fabricGtpTunnelPeers.getLeft(), fabricGtpTunnelPeers.getRight()); + flowRuleService.applyFlowRules(deviceId.hashCode(), fabricGtpTunnelPeers.getLeft(), + fabricGtpTunnelPeers.getRight()); log.debug("GTP tunnel peer added with flowIDs ingress={}, egress={}", fabricGtpTunnelPeers.getLeft().id().value(), fabricGtpTunnelPeers.getRight().id().value()); } @@ -794,7 +795,7 @@ private void addUeSessionUplink(UpfSessionUplink ueSession) throws UpfProgrammab FlowRule fabricUeSession = upfTranslator.sessionUplinkToFabricEntry( ueSession, deviceId, appId, DEFAULT_PRIORITY); log.info("Installing {}", ueSession.toString()); - flowRuleService.applyFlowRules(fabricUeSession); + flowRuleService.applyFlowRules(deviceId.hashCode(), fabricUeSession); log.debug("Uplink UE session added with flowID {}", fabricUeSession.id().value()); } @@ -802,7 +803,7 @@ private void addUeSessionDownlink(UpfSessionDownlink ueSession) throws UpfProgra FlowRule fabricUeSession = upfTranslator.sessionDownlinkToFabricEntry( ueSession, deviceId, appId, DEFAULT_PRIORITY); log.info("Installing {}", ueSession.toString()); - flowRuleService.applyFlowRules(fabricUeSession); + flowRuleService.applyFlowRules(deviceId.hashCode(), fabricUeSession); log.debug("Downlink UE session added with flowID {}", fabricUeSession.id().value()); } @@ -810,7 +811,7 @@ private void addUpfTerminationUplink(UpfTerminationUplink upfTermination) throws FlowRule fabricUpfTermination = upfTranslator.upfTerminationUplinkToFabricEntry( upfTermination, deviceId, appId, DEFAULT_PRIORITY); log.info("Installing {}", upfTermination.toString()); - flowRuleService.applyFlowRules(fabricUpfTermination); + flowRuleService.applyFlowRules(deviceId.hashCode(), fabricUpfTermination); log.debug("Uplink UPF termination added with flowID {}", fabricUpfTermination.id().value()); } @@ -818,7 +819,7 @@ private void addUpfTerminationDownlink(UpfTerminationDownlink upfTermination) th FlowRule fabricUpfTermination = upfTranslator.upfTerminationDownlinkToFabricEntry( upfTermination, deviceId, appId, DEFAULT_PRIORITY); log.info("Installing {}", upfTermination.toString()); - flowRuleService.applyFlowRules(fabricUpfTermination); + flowRuleService.applyFlowRules(deviceId.hashCode(), fabricUpfTermination); log.debug("Downlink UPF termination added with flowID {}", fabricUpfTermination.id().value()); } @@ -882,7 +883,7 @@ private boolean removeEntries(Collection> entriesTo .collect(Collectors.toList()); try { - flowRuleService.removeFlowRules(entries.toArray(FlowRule[]::new)); + flowRuleService.removeFlowRules(deviceId.hashCode(), entries.toArray(FlowRule[]::new)); // TODO in future we may need to send other notifications to the pfcp agent //if (!failSilent) { // throw new UpfProgrammableException("Match criterion " + match.toString() + @@ -999,9 +1000,9 @@ private void applyUplinkRecirculation(Ip4Prefix subnet, boolean remove) { FlowRule allowRule = upfTranslator.buildFabricUplinkRecircEntry( deviceId, appId, subnet, subnet, true, DEFAULT_PRIORITY + 10); if (!remove) { - flowRuleService.applyFlowRules(denyRule, allowRule); + flowRuleService.applyFlowRules(deviceId.hashCode(), denyRule, allowRule); } else { - flowRuleService.removeFlowRules(denyRule, allowRule); + flowRuleService.removeFlowRules(deviceId.hashCode(), denyRule, allowRule); } } diff --git a/src/test/java/org/stratumproject/fabric/tna/behaviour/upf/MockFlowRuleService.java b/src/test/java/org/stratumproject/fabric/tna/behaviour/upf/MockFlowRuleService.java index 2591296ba..155a68dfc 100644 --- a/src/test/java/org/stratumproject/fabric/tna/behaviour/upf/MockFlowRuleService.java +++ b/src/test/java/org/stratumproject/fabric/tna/behaviour/upf/MockFlowRuleService.java @@ -65,6 +65,16 @@ public void apply(FlowRuleOperations ops) { } } + @Override + public void applyFlowRules(int key, FlowRule... flowRules) { + applyFlowRules(flowRules); + } + + @Override + public void removeFlowRules(int key, FlowRule... flowRules) { + removeFlowRules(flowRules); + } + @Override public int getFlowRuleCount() { return flows.size();