diff --git a/apps/bmv2-demo/common/pom.xml b/apps/bmv2-demo/common/pom.xml deleted file mode 100644 index 37bdb18e0e..0000000000 --- a/apps/bmv2-demo/common/pom.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - 4.0.0 - - - onos-app-bmv2-demo - org.onosproject - 1.11.0-SNAPSHOT - - - onos-app-bmv2-demo-common - - bundle - - - - org.onosproject - onos-bmv2-protocol-api - ${project.version} - - - \ No newline at end of file diff --git a/apps/bmv2-demo/common/src/main/java/org/onosproject/bmv2/demo/app/common/AbstractUpgradableFabricApp.java b/apps/bmv2-demo/common/src/main/java/org/onosproject/bmv2/demo/app/common/AbstractUpgradableFabricApp.java deleted file mode 100644 index 66ac4fcd21..0000000000 --- a/apps/bmv2-demo/common/src/main/java/org/onosproject/bmv2/demo/app/common/AbstractUpgradableFabricApp.java +++ /dev/null @@ -1,560 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.demo.app.common; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import org.apache.felix.scr.annotations.Activate; -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.Deactivate; -import org.apache.felix.scr.annotations.Reference; -import org.apache.felix.scr.annotations.ReferenceCardinality; -import org.onosproject.app.ApplicationAdminService; -import org.onosproject.bmv2.api.context.Bmv2DeviceContext; -import org.onosproject.bmv2.api.service.Bmv2DeviceContextService; -import org.onosproject.core.ApplicationId; -import org.onosproject.core.CoreService; -import org.onosproject.net.ConnectPoint; -import org.onosproject.net.Device; -import org.onosproject.net.DeviceId; -import org.onosproject.net.Host; -import org.onosproject.net.Port; -import org.onosproject.net.device.DeviceEvent; -import org.onosproject.net.device.DeviceListener; -import org.onosproject.net.device.DeviceService; -import org.onosproject.net.flow.DefaultFlowRule; -import org.onosproject.net.flow.FlowRule; -import org.onosproject.net.flow.FlowRuleOperations; -import org.onosproject.net.flow.FlowRuleService; -import org.onosproject.net.host.HostEvent; -import org.onosproject.net.host.HostListener; -import org.onosproject.net.host.HostService; -import org.onosproject.net.topology.Topology; -import org.onosproject.net.topology.TopologyEvent; -import org.onosproject.net.topology.TopologyGraph; -import org.onosproject.net.topology.TopologyListener; -import org.onosproject.net.topology.TopologyService; -import org.onosproject.net.topology.TopologyVertex; -import org.slf4j.Logger; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static com.google.common.base.Preconditions.checkNotNull; -import static java.util.stream.Collectors.toSet; -import static java.util.stream.Stream.concat; -import static org.onlab.util.Tools.groupedThreads; -import static org.onosproject.net.device.DeviceEvent.Type.*; -import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED; -import static org.slf4j.LoggerFactory.getLogger; - -/** - * Abstract implementation of an app providing fabric connectivity for a 2-stage Clos topology of BMv2 devices. - */ -@Component(immediate = true) -public abstract class AbstractUpgradableFabricApp { - - private static final Map APP_HANDLES = Maps.newConcurrentMap(); - - private static final int NUM_LEAFS = 3; - private static final int NUM_SPINES = 3; - private static final int FLOW_PRIORITY = 100; - - private static final int CLEANUP_SLEEP = 2000; - - protected final Logger log = getLogger(getClass()); - - private final TopologyListener topologyListener = new InternalTopologyListener(); - private final DeviceListener deviceListener = new InternalDeviceListener(); - private final HostListener hostListener = new InternalHostListener(); - - private final ExecutorService executorService = Executors - .newFixedThreadPool(8, groupedThreads("onos/bmv2-demo-app", "bmv2-app-task", log)); - - private final String appName; - private final String configurationName; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected TopologyService topologyService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected DeviceService deviceService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - private HostService hostService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - private FlowRuleService flowRuleService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - private ApplicationAdminService appService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - private CoreService coreService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - private Bmv2DeviceContextService bmv2ContextService; - - private boolean appActive = false; - private boolean appFreezed = false; - - private boolean otherAppFound = false; - private AbstractUpgradableFabricApp otherApp; - - private boolean flowRuleGenerated = false; - private ApplicationId appId; - - private Bmv2DeviceContext bmv2Context; - - private Set leafSwitches; - private Set spineSwitches; - - private Map> deviceFlowRules; - private Map previousContexts; - private Map contextFlags; - private Map ruleFlags; - - private ConcurrentMap deviceLocks = Maps.newConcurrentMap(); - - /** - * Creates a new BMv2 fabric app. - * - * @param appName app name - * @param configurationName a common name for the P4 program / BMv2 configuration used by this app - * @param context a BMv2 device context to be used on devices - */ - protected AbstractUpgradableFabricApp(String appName, String configurationName, Bmv2DeviceContext context) { - this.appName = checkNotNull(appName); - this.configurationName = checkNotNull(configurationName); - this.bmv2Context = checkNotNull(context); - } - - @Activate - public void activate() { - log.info("Starting..."); - - appActive = true; - appFreezed = false; - - if (APP_HANDLES.size() > 0) { - if (APP_HANDLES.size() > 1) { - throw new IllegalStateException("Found more than 1 active app handles"); - } - otherAppFound = true; - otherApp = APP_HANDLES.values().iterator().next(); - log.info("Found other fabric app active, signaling to freeze to {}...", otherApp.appName); - otherApp.setAppFreezed(true); - } - - APP_HANDLES.put(appName, this); - - appId = coreService.registerApplication(appName); - - topologyService.addListener(topologyListener); - deviceService.addListener(deviceListener); - hostService.addListener(hostListener); - - bmv2ContextService.registerInterpreterClassLoader(bmv2Context.interpreter().getClass(), - this.getClass().getClassLoader()); - - init(); - - log.info("STARTED", appId.id()); - } - - @Deactivate - public void deactivate() { - log.info("Stopping..."); - try { - executorService.shutdown(); - executorService.awaitTermination(5, TimeUnit.SECONDS); - } catch (InterruptedException e) { - List runningTasks = executorService.shutdownNow(); - log.warn("Unable to stop the following tasks: {}", runningTasks); - } - deviceService.removeListener(deviceListener); - topologyService.removeListener(topologyListener); - hostService.removeListener(hostListener); - flowRuleService.removeFlowRulesById(appId); - - appActive = false; - APP_HANDLES.remove(appName); - - log.info("STOPPED"); - } - - private void init() { - - // Reset any previous state - synchronized (this) { - flowRuleGenerated = Boolean.FALSE; - leafSwitches = Sets.newHashSet(); - spineSwitches = Sets.newHashSet(); - deviceFlowRules = Maps.newConcurrentMap(); - ruleFlags = Maps.newConcurrentMap(); - contextFlags = Maps.newConcurrentMap(); - } - - // Start flow rules generator... - spawnTask(() -> generateFlowRules(topologyService.currentTopology(), Sets.newHashSet(hostService.getHosts()))); - } - - private void setAppFreezed(boolean appFreezed) { - this.appFreezed = appFreezed; - if (appFreezed) { - log.info("Freezing..."); - } else { - log.info("Unfreezing...!"); - } - } - - /** - * Perform device initialization. Returns true if the operation was successful, false otherwise. - * - * @param deviceId a device id - * @return a boolean value - */ - public abstract boolean initDevice(DeviceId deviceId); - - /** - * Generates a list of flow rules for the given leaf switch, source host, destination hosts, spine switches and - * topology. - * - * @param leaf a leaf device id - * @param srcHost a source host - * @param dstHosts a collection of destination hosts - * @param spines a collection of spine device IDs - * @param topology a topology - * @return a list of flow rules - * @throws FlowRuleGeneratorException if flow rules cannot be generated - */ - public abstract List generateLeafRules(DeviceId leaf, Host srcHost, Collection dstHosts, - Collection spines, Topology topology) - throws FlowRuleGeneratorException; - - /** - * Generates a list of flow rules for the given spine switch, destination hosts and topology. - * - * @param deviceId a spine device id - * @param dstHosts a collection of destination hosts - * @param topology a topology - * @return a list of flow rules - * @throws FlowRuleGeneratorException if flow rules cannot be generated - */ - public abstract List generateSpineRules(DeviceId deviceId, Collection dstHosts, Topology topology) - throws FlowRuleGeneratorException; - - private void deployAllDevices() { - if (otherAppFound && otherApp.appActive) { - log.info("Deactivating other app..."); - appService.deactivate(otherApp.appId); - try { - Thread.sleep(CLEANUP_SLEEP); - } catch (InterruptedException e) { - log.warn("Cleanup sleep interrupted!"); - Thread.interrupted(); - } - } - - Stream.concat(leafSwitches.stream(), spineSwitches.stream()) - .map(deviceService::getDevice) - .forEach(device -> spawnTask(() -> deployDevice(device))); - } - - /** - * Executes a device deploy. - * - * @param device a device - */ - public void deployDevice(Device device) { - - DeviceId deviceId = device.id(); - - // Synchronize executions over the same device. - Lock lock = deviceLocks.computeIfAbsent(deviceId, k -> new ReentrantLock()); - lock.lock(); - - try { - // Set context if not already done. - if (!contextFlags.getOrDefault(deviceId, false)) { - log.info("Setting context to {} for {}...", configurationName, deviceId); - bmv2ContextService.setContext(deviceId, bmv2Context); - contextFlags.put(device.id(), true); - } - - // Initialize device. - if (!initDevice(deviceId)) { - log.warn("Failed to initialize device {}", deviceId); - } - - // Install rules. - if (!ruleFlags.getOrDefault(deviceId, false)) { - List rules = deviceFlowRules.getOrDefault(deviceId, Collections.emptyList()); - if (rules.size() > 0) { - log.info("Installing rules for {}...", deviceId); - installFlowRules(rules); - ruleFlags.put(deviceId, true); - } - } - } finally { - lock.unlock(); - } - } - - private void spawnTask(Runnable task) { - executorService.execute(task); - } - - - private void installFlowRules(Collection rules) { - FlowRuleOperations.Builder opsBuilder = FlowRuleOperations.builder(); - rules.forEach(opsBuilder::add); - flowRuleService.apply(opsBuilder.build()); - } - - private void removeFlowRules(Collection rules) { - FlowRuleOperations.Builder opsBuilder = FlowRuleOperations.builder(); - rules.forEach(opsBuilder::remove); - flowRuleService.apply(opsBuilder.build()); - } - - /** - * Generates the flow rules to provide host-to-host connectivity for the given topology and hosts. - * - * @param topo a topology - * @param hosts a collection of hosts - */ - private synchronized void generateFlowRules(Topology topo, Collection hosts) { - - if (flowRuleGenerated) { - log.debug("Flow rules have been already generated, aborting..."); - return; - } - - log.debug("Starting flow rules generator..."); - - TopologyGraph graph = topologyService.getGraph(topo); - Set spines = Sets.newHashSet(); - Set leafs = Sets.newHashSet(); - graph.getVertexes().stream() - .map(TopologyVertex::deviceId) - .forEach(did -> (isSpine(did, topo) ? spines : leafs).add(did)); - - if (spines.size() != NUM_SPINES || leafs.size() != NUM_LEAFS) { - log.info("Invalid leaf/spine switches count, aborting... > leafCount={}, spineCount={}", - spines.size(), leafs.size()); - return; - } - - for (DeviceId did : spines) { - int portCount = deviceService.getPorts(did).size(); - // Expected port count: num leafs + 1 redundant leaf link - if (portCount != (NUM_LEAFS + 1)) { - log.info("Invalid port count for spine, aborting... > deviceId={}, portCount={}", did, portCount); - return; - } - } - for (DeviceId did : leafs) { - int portCount = deviceService.getPorts(did).size(); - // Expected port count: num spines + host port + 1 redundant spine link - if (portCount != (NUM_SPINES + 2)) { - log.info("Invalid port count for leaf, aborting... > deviceId={}, portCount={}", did, portCount); - return; - } - } - - // Check hosts, number and exactly one per leaf - Map hostMap = Maps.newHashMap(); - hosts.forEach(h -> hostMap.put(h.location().deviceId(), h)); - if (hosts.size() != NUM_LEAFS || !leafs.equals(hostMap.keySet())) { - log.info("Wrong host configuration, aborting... > hostCount={}, hostMapz={}", hosts.size(), hostMap); - return; - } - - List newFlowRules = Lists.newArrayList(); - - try { - for (DeviceId deviceId : leafs) { - Host srcHost = hostMap.get(deviceId); - Set dstHosts = hosts.stream().filter(h -> h != srcHost).collect(toSet()); - newFlowRules.addAll(generateLeafRules(deviceId, srcHost, dstHosts, spines, topo)); - } - for (DeviceId deviceId : spines) { - newFlowRules.addAll(generateSpineRules(deviceId, hosts, topo)); - } - } catch (FlowRuleGeneratorException e) { - log.warn("Exception while executing flow rule generator: ", e.toString()); - return; - } - - if (newFlowRules.size() == 0) { - // Something went wrong - log.error("0 flow rules generated, BUG?"); - return; - } - - // All good! - // Divide flow rules per device id... - ImmutableMap.Builder> mapBuilder = ImmutableMap.builder(); - concat(spines.stream(), leafs.stream()) - .map(deviceId -> ImmutableList.copyOf(newFlowRules - .stream() - .filter(fr -> fr.deviceId().equals(deviceId)) - .iterator())) - .forEach(frs -> mapBuilder.put(frs.get(0).deviceId(), frs)); - this.deviceFlowRules = mapBuilder.build(); - - this.leafSwitches = ImmutableSet.copyOf(leafs); - this.spineSwitches = ImmutableSet.copyOf(spines); - - // Avoid other executions to modify the generated flow rules. - flowRuleGenerated = true; - - log.info("Generated {} flow rules for {} devices", newFlowRules.size(), spines.size() + leafs.size()); - - spawnTask(this::deployAllDevices); - } - - /** - * Returns a new, pre-configured flow rule builder. - * - * @param did a device id - * @param tableName a table name - * @return a new flow rule builder - */ - protected FlowRule.Builder flowRuleBuilder(DeviceId did, String tableName) throws FlowRuleGeneratorException { - Map tableMap = bmv2Context.interpreter().tableIdMap().inverse(); - if (tableMap.get(tableName) == null) { - throw new FlowRuleGeneratorException("Unknown table " + tableName); - } - return DefaultFlowRule.builder() - .forDevice(did) - .forTable(tableMap.get(tableName)) - .fromApp(appId) - .withPriority(FLOW_PRIORITY) - .makePermanent(); - } - - private List getHostPorts(DeviceId deviceId, Topology topology) { - // Get all non-fabric ports. - return deviceService - .getPorts(deviceId) - .stream() - .filter(p -> !isFabricPort(p, topology)) - .collect(Collectors.toList()); - } - - private boolean isSpine(DeviceId deviceId, Topology topology) { - // True if all ports are fabric. - return getHostPorts(deviceId, topology).size() == 0; - } - - protected boolean isFabricPort(Port port, Topology topology) { - // True if the port connects this device to another infrastructure device. - return topologyService.isInfrastructure(topology, new ConnectPoint(port.element().id(), port.number())); - } - - /** - * A listener of topology events that executes a flow rule generation task each time a device is added. - */ - private class InternalTopologyListener implements TopologyListener { - - @Override - public void event(TopologyEvent event) { - spawnTask(() -> generateFlowRules(event.subject(), Sets.newHashSet(hostService.getHosts()))); - } - - @Override - public boolean isRelevant(TopologyEvent event) { - return !appFreezed && - // If at least one reason is of type DEVICE_ADDED. - event.reasons().stream(). - filter(r -> r instanceof DeviceEvent) - .filter(r -> ((DeviceEvent) r).type() == DEVICE_ADDED) - .findAny() - .isPresent(); - } - } - - /** - * A listener of device events that executes a device deploy task each time a device is added, updated or - * re-connects. - */ - private class InternalDeviceListener implements DeviceListener { - @Override - public void event(DeviceEvent event) { - spawnTask(() -> deployDevice(event.subject())); - } - - @Override - public boolean isRelevant(DeviceEvent event) { - return !appFreezed && - (event.type() == DEVICE_ADDED || - event.type() == DEVICE_UPDATED || - (event.type() == DEVICE_AVAILABILITY_CHANGED && - deviceService.isAvailable(event.subject().id()))); - } - } - - /** - * A listener of host events that generates flow rules each time a new host is added. - */ - private class InternalHostListener implements HostListener { - @Override - public void event(HostEvent event) { - spawnTask(() -> generateFlowRules(topologyService.currentTopology(), - Sets.newHashSet(hostService.getHosts()))); - } - - @Override - public boolean isRelevant(HostEvent event) { - return !appFreezed && event.type() == HOST_ADDED; - } - } - - /** - * An exception occurred while generating flow rules for this fabric. - */ - public class FlowRuleGeneratorException extends Exception { - - public FlowRuleGeneratorException() { - } - - public FlowRuleGeneratorException(String msg) { - super(msg); - } - - public FlowRuleGeneratorException(Exception cause) { - super(cause); - } - } -} \ No newline at end of file diff --git a/apps/bmv2-demo/common/src/main/java/org/onosproject/bmv2/demo/app/common/package-info.java b/apps/bmv2-demo/common/src/main/java/org/onosproject/bmv2/demo/app/common/package-info.java deleted file mode 100644 index b8eab5cdb3..0000000000 --- a/apps/bmv2-demo/common/src/main/java/org/onosproject/bmv2/demo/app/common/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Bmv2 demo app common classes. - */ -package org.onosproject.bmv2.demo.app.common; \ No newline at end of file diff --git a/apps/bmv2-demo/ecmp/features.xml b/apps/bmv2-demo/ecmp/features.xml deleted file mode 100644 index 0bfb8274b1..0000000000 --- a/apps/bmv2-demo/ecmp/features.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - mvn:${project.groupId}/${project.artifactId}/${project.version} - mvn:${project.groupId}/onos-app-bmv2-demo-common/${project.version} - - diff --git a/apps/bmv2-demo/ecmp/pom.xml b/apps/bmv2-demo/ecmp/pom.xml deleted file mode 100644 index 283e1edcd9..0000000000 --- a/apps/bmv2-demo/ecmp/pom.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - 4.0.0 - - - onos-app-bmv2-demo - org.onosproject - 1.11.0-SNAPSHOT - - - onos-app-bmv2-demo-ecmp - - bundle - - - org.onosproject.bmv2-ecmp-fabric - P4/BMv2 Demo Fabric App v1 (ECMP) - Traffic Steering - http://onosproject.org - P4/BMv2 demo application with ECMP support for a 2-stage clos fabric topology - - - - - org.onosproject - onos-app-bmv2-demo-common - ${project.version} - - - - \ No newline at end of file diff --git a/apps/bmv2-demo/ecmp/src/main/java/org/onosproject/bmv2/demo/app/ecmp/EcmpFabricApp.java b/apps/bmv2-demo/ecmp/src/main/java/org/onosproject/bmv2/demo/app/ecmp/EcmpFabricApp.java deleted file mode 100644 index ab42d2fae3..0000000000 --- a/apps/bmv2-demo/ecmp/src/main/java/org/onosproject/bmv2/demo/app/ecmp/EcmpFabricApp.java +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.demo.app.ecmp; - -import com.eclipsesource.json.Json; -import com.eclipsesource.json.JsonObject; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import org.apache.commons.lang3.tuple.Pair; -import org.apache.felix.scr.annotations.Component; -import org.onosproject.bmv2.api.context.Bmv2Configuration; -import org.onosproject.bmv2.api.context.Bmv2DefaultConfiguration; -import org.onosproject.bmv2.api.context.Bmv2DeviceContext; -import org.onosproject.bmv2.api.runtime.Bmv2ExtensionSelector; -import org.onosproject.bmv2.api.runtime.Bmv2ExtensionTreatment; -import org.onosproject.bmv2.demo.app.common.AbstractUpgradableFabricApp; -import org.onosproject.net.DeviceId; -import org.onosproject.net.Host; -import org.onosproject.net.Path; -import org.onosproject.net.Port; -import org.onosproject.net.PortNumber; -import org.onosproject.net.flow.DefaultTrafficSelector; -import org.onosproject.net.flow.DefaultTrafficTreatment; -import org.onosproject.net.flow.FlowRule; -import org.onosproject.net.flow.TrafficTreatment; -import org.onosproject.net.flow.criteria.ExtensionSelector; -import org.onosproject.net.flow.instructions.ExtensionTreatment; -import org.onosproject.net.topology.DefaultTopologyVertex; -import org.onosproject.net.topology.Topology; -import org.onosproject.net.topology.TopologyGraph; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import static java.util.stream.Collectors.toSet; -import static org.onlab.packet.EthType.EtherType.IPV4; -import static org.onosproject.bmv2.demo.app.ecmp.EcmpInterpreter.*; - -/** - * Implementation of an upgradable fabric app for the ECMP configuration. - */ -@Component(immediate = true) -public class EcmpFabricApp extends AbstractUpgradableFabricApp { - - private static final String APP_NAME = "org.onosproject.bmv2-ecmp-fabric"; - private static final String MODEL_NAME = "ECMP"; - private static final String JSON_CONFIG_PATH = "/ecmp.json"; - - private static final Bmv2Configuration ECMP_CONFIGURATION = loadConfiguration(); - private static final EcmpInterpreter ECMP_INTERPRETER = new EcmpInterpreter(); - protected static final Bmv2DeviceContext ECMP_CONTEXT = new Bmv2DeviceContext(ECMP_CONFIGURATION, ECMP_INTERPRETER); - - private static final Map, Short>> DEVICE_GROUP_ID_MAP = Maps.newHashMap(); - - public EcmpFabricApp() { - super(APP_NAME, MODEL_NAME, ECMP_CONTEXT); - } - - @Override - public boolean initDevice(DeviceId deviceId) { - // Nothing to do. - return true; - } - - @Override - public List generateLeafRules(DeviceId leaf, Host srcHost, Collection dstHosts, - Collection availableSpines, Topology topo) - throws FlowRuleGeneratorException { - - // Get ports which connect this leaf switch to hosts. - Set hostPorts = deviceService.getPorts(leaf) - .stream() - .filter(port -> !isFabricPort(port, topo)) - .map(Port::number) - .collect(Collectors.toSet()); - - // Get ports which connect this leaf to the given available spines. - TopologyGraph graph = topologyService.getGraph(topo); - Set fabricPorts = graph.getEdgesFrom(new DefaultTopologyVertex(leaf)) - .stream() - .filter(e -> availableSpines.contains(e.dst().deviceId())) - .map(e -> e.link().src().port()) - .collect(Collectors.toSet()); - - if (hostPorts.size() != 1 || fabricPorts.size() == 0) { - log.error("Leaf switch has invalid port configuration: hostPorts={}, fabricPorts={}", - hostPorts.size(), fabricPorts.size()); - throw new FlowRuleGeneratorException(); - } - PortNumber hostPort = hostPorts.iterator().next(); - - List rules = Lists.newArrayList(); - - TrafficTreatment treatment; - if (fabricPorts.size() > 1) { - // Do ECMP. - Pair> result = provisionEcmpTreatment(leaf, fabricPorts); - rules.addAll(result.getRight()); - ExtensionTreatment extTreatment = result.getLeft(); - treatment = DefaultTrafficTreatment.builder().extension(extTreatment, leaf).build(); - } else { - // Output on port. - PortNumber outPort = fabricPorts.iterator().next(); - treatment = DefaultTrafficTreatment.builder().setOutput(outPort).build(); - } - - // From srHost to dstHosts. - for (Host dstHost : dstHosts) { - FlowRule rule = flowRuleBuilder(leaf, TABLE0) - .withSelector( - DefaultTrafficSelector.builder() - .matchInPort(hostPort) - .matchEthType(IPV4.ethType().toShort()) - .matchEthSrc(srcHost.mac()) - .matchEthDst(dstHost.mac()) - .build()) - .withTreatment(treatment) - .build(); - rules.add(rule); - } - - // From fabric ports to this leaf host. - for (PortNumber port : fabricPorts) { - FlowRule rule = flowRuleBuilder(leaf, TABLE0) - .withSelector( - DefaultTrafficSelector.builder() - .matchInPort(port) - .matchEthType(IPV4.ethType().toShort()) - .matchEthDst(srcHost.mac()) - .build()) - .withTreatment( - DefaultTrafficTreatment.builder() - .setOutput(hostPort) - .build()) - .build(); - rules.add(rule); - } - - return rules; - } - - @Override - public List generateSpineRules(DeviceId deviceId, Collection dstHosts, Topology topo) - throws FlowRuleGeneratorException { - - List rules = Lists.newArrayList(); - - // for each host - for (Host dstHost : dstHosts) { - - Set paths = topologyService.getPaths(topo, deviceId, dstHost.location().deviceId()); - - if (paths.size() == 0) { - log.warn("Can't find any path between spine {} and host {}", deviceId, dstHost); - throw new FlowRuleGeneratorException(); - } - - TrafficTreatment treatment; - - if (paths.size() == 1) { - // Only one path, do output on port. - PortNumber port = paths.iterator().next().src().port(); - treatment = DefaultTrafficTreatment.builder().setOutput(port).build(); - } else { - // Multiple paths, do ECMP. - Set portNumbers = paths.stream().map(p -> p.src().port()).collect(toSet()); - Pair> result = provisionEcmpTreatment(deviceId, portNumbers); - rules.addAll(result.getRight()); - treatment = DefaultTrafficTreatment.builder().extension(result.getLeft(), deviceId).build(); - } - - FlowRule rule = flowRuleBuilder(deviceId, TABLE0) - .withSelector( - DefaultTrafficSelector.builder() - .matchEthType(IPV4.ethType().toShort()) - .matchEthDst(dstHost.mac()) - .build()) - .withTreatment(treatment) - .build(); - - rules.add(rule); - } - - return rules; - } - - private Pair> provisionEcmpTreatment(DeviceId deviceId, - Set fabricPorts) - throws FlowRuleGeneratorException { - - // Install ECMP group table entries that map from hash values to actual fabric ports... - int groupId = groupIdOf(deviceId, fabricPorts); - int groupSize = fabricPorts.size(); - Iterator portIterator = fabricPorts.iterator(); - List rules = Lists.newArrayList(); - for (short i = 0; i < groupSize; i++) { - ExtensionSelector extSelector = buildEcmpSelector(groupId, i); - FlowRule rule = flowRuleBuilder(deviceId, ECMP_GROUP_TABLE) - .withSelector( - DefaultTrafficSelector.builder() - .extension(extSelector, deviceId) - .build()) - .withTreatment( - DefaultTrafficTreatment.builder() - .setOutput(portIterator.next()) - .build()) - .build(); - rules.add(rule); - } - - ExtensionTreatment extTreatment = buildEcmpTreatment(groupId, groupSize); - - return Pair.of(extTreatment, rules); - } - - private Bmv2ExtensionTreatment buildEcmpTreatment(int groupId, int groupSize) { - return Bmv2ExtensionTreatment.builder() - .forConfiguration(ECMP_CONTEXT.configuration()) - .setActionName(ECMP_GROUP) - .addParameter(GROUP_ID, groupId) - .addParameter(GROUP_SIZE, groupSize) - .build(); - } - - private Bmv2ExtensionSelector buildEcmpSelector(int groupId, int selector) { - return Bmv2ExtensionSelector.builder() - .forConfiguration(ECMP_CONTEXT.configuration()) - .matchExact(ECMP_METADATA, GROUP_ID, groupId) - .matchExact(ECMP_METADATA, SELECTOR, selector) - .build(); - } - - - public int groupIdOf(DeviceId deviceId, Set ports) { - DEVICE_GROUP_ID_MAP.putIfAbsent(deviceId, Maps.newHashMap()); - // Counts the number of unique portNumber sets for each deviceId. - // Each distinct set of portNumbers will have a unique ID. - return DEVICE_GROUP_ID_MAP.get(deviceId).computeIfAbsent(ports, (pp) -> - (short) (DEVICE_GROUP_ID_MAP.get(deviceId).size() + 1)); - } - - private static Bmv2Configuration loadConfiguration() { - try { - JsonObject json = Json.parse(new BufferedReader(new InputStreamReader( - EcmpFabricApp.class.getResourceAsStream(JSON_CONFIG_PATH)))).asObject(); - return Bmv2DefaultConfiguration.parse(json); - } catch (IOException e) { - throw new RuntimeException("Unable to load configuration", e); - } - } -} \ No newline at end of file diff --git a/apps/bmv2-demo/ecmp/src/main/java/org/onosproject/bmv2/demo/app/ecmp/EcmpInterpreter.java b/apps/bmv2-demo/ecmp/src/main/java/org/onosproject/bmv2/demo/app/ecmp/EcmpInterpreter.java deleted file mode 100644 index c5ea2aea1b..0000000000 --- a/apps/bmv2-demo/ecmp/src/main/java/org/onosproject/bmv2/demo/app/ecmp/EcmpInterpreter.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.demo.app.ecmp; - -import com.google.common.collect.ImmutableBiMap; -import org.onlab.util.ImmutableByteSequence; -import org.onosproject.bmv2.api.context.Bmv2Configuration; -import org.onosproject.bmv2.api.context.Bmv2Interpreter; -import org.onosproject.bmv2.api.context.Bmv2InterpreterException; -import org.onosproject.bmv2.api.runtime.Bmv2Action; -import org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils; -import org.onosproject.net.PortNumber; -import org.onosproject.net.flow.TrafficTreatment; -import org.onosproject.net.flow.criteria.Criterion; -import org.onosproject.net.flow.instructions.Instruction; - -import static org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils.fitByteSequence; -import static org.onosproject.net.PortNumber.CONTROLLER; -import static org.onosproject.net.flow.instructions.Instructions.OutputInstruction; - -/** - * Implementation of a BMv2 interpreter for the ecmp.json configuration. - */ -public class EcmpInterpreter implements Bmv2Interpreter { - - protected static final String ECMP_METADATA = "ecmp_metadata"; - protected static final String SELECTOR = "selector"; - protected static final String GROUP_ID = "groupId"; - protected static final String GROUP_SIZE = "groupSize"; - protected static final String ECMP_GROUP = "ecmp_group"; - protected static final String ECMP_GROUP_TABLE = "ecmp_group_table"; - protected static final String TABLE0 = "table0"; - protected static final String SEND_TO_CPU = "send_to_cpu"; - protected static final String DROP = "_drop"; - protected static final String SET_EGRESS_PORT = "set_egress_port"; - protected static final String PORT = "port"; - - private static final ImmutableBiMap CRITERION_TYPE_MAP = ImmutableBiMap.of( - Criterion.Type.IN_PORT, "standard_metadata.ingress_port", - Criterion.Type.ETH_DST, "ethernet.dstAddr", - Criterion.Type.ETH_SRC, "ethernet.srcAddr", - Criterion.Type.ETH_TYPE, "ethernet.etherType"); - - private static final ImmutableBiMap TABLE_ID_MAP = ImmutableBiMap.of( - 0, TABLE0, - 1, ECMP_GROUP_TABLE); - - @Override - public ImmutableBiMap tableIdMap() { - return TABLE_ID_MAP; - } - - @Override - public ImmutableBiMap criterionTypeMap() { - return CRITERION_TYPE_MAP; - } - - @Override - public Bmv2Action mapTreatment(TrafficTreatment treatment, Bmv2Configuration configuration) - throws Bmv2InterpreterException { - - if (treatment.allInstructions().size() == 0) { - // No instructions means drop for us. - return actionWithName(DROP); - } else if (treatment.allInstructions().size() > 1) { - // Otherwise, we understand treatments with only 1 instruction. - throw new Bmv2InterpreterException("Treatment has multiple instructions"); - } - - Instruction instruction = treatment.allInstructions().get(0); - - switch (instruction.type()) { - case OUTPUT: - OutputInstruction outInstruction = (OutputInstruction) instruction; - PortNumber port = outInstruction.port(); - if (!port.isLogical()) { - return buildEgressAction(port, configuration); - } else if (port.equals(CONTROLLER)) { - return actionWithName(SEND_TO_CPU); - } else { - throw new Bmv2InterpreterException("Egress on logical port not supported: " + port); - } - case NOACTION: - return actionWithName(DROP); - default: - throw new Bmv2InterpreterException("Instruction type not supported: " + instruction.type().name()); - } - } - - private static Bmv2Action buildEgressAction(PortNumber port, Bmv2Configuration configuration) - throws Bmv2InterpreterException { - - int portBitWidth = configuration.action(SET_EGRESS_PORT).runtimeData(PORT).bitWidth(); - - try { - ImmutableByteSequence portBs = fitByteSequence(ImmutableByteSequence.copyFrom(port.toLong()), portBitWidth); - return Bmv2Action.builder() - .withName(SET_EGRESS_PORT) - .addParameter(portBs) - .build(); - } catch (Bmv2TranslatorUtils.ByteSequenceFitException e) { - throw new Bmv2InterpreterException(e.getMessage()); - } - } - - private static Bmv2Action actionWithName(String name) { - return Bmv2Action.builder().withName(name).build(); - } -} diff --git a/apps/bmv2-demo/ecmp/src/main/java/org/onosproject/bmv2/demo/app/ecmp/package-info.java b/apps/bmv2-demo/ecmp/src/main/java/org/onosproject/bmv2/demo/app/ecmp/package-info.java deleted file mode 100644 index 29802429e1..0000000000 --- a/apps/bmv2-demo/ecmp/src/main/java/org/onosproject/bmv2/demo/app/ecmp/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * BMv2 demo app for the ECMP configuration. - */ -package org.onosproject.bmv2.demo.app.ecmp; \ No newline at end of file diff --git a/apps/bmv2-demo/ecmp/src/main/resources/ecmp.json b/apps/bmv2-demo/ecmp/src/main/resources/ecmp.json deleted file mode 100644 index 5bf2d4a95c..0000000000 --- a/apps/bmv2-demo/ecmp/src/main/resources/ecmp.json +++ /dev/null @@ -1,909 +0,0 @@ -{ - "header_types": [ - { - "name": "standard_metadata_t", - "id": 0, - "fields": [ - [ - "ingress_port", - 9 - ], - [ - "packet_length", - 32 - ], - [ - "egress_spec", - 9 - ], - [ - "egress_port", - 9 - ], - [ - "egress_instance", - 32 - ], - [ - "instance_type", - 32 - ], - [ - "clone_spec", - 32 - ], - [ - "_padding", - 5 - ] - ], - "length_exp": null, - "max_length": null - }, - { - "name": "intrinsic_metadata_t", - "id": 1, - "fields": [ - [ - "ingress_global_timestamp", - 32 - ], - [ - "lf_field_list", - 32 - ], - [ - "mcast_grp", - 16 - ], - [ - "egress_rid", - 16 - ] - ], - "length_exp": null, - "max_length": null - }, - { - "name": "ethernet_t", - "id": 2, - "fields": [ - [ - "dstAddr", - 48 - ], - [ - "srcAddr", - 48 - ], - [ - "etherType", - 16 - ] - ], - "length_exp": null, - "max_length": null - }, - { - "name": "ipv4_t", - "id": 3, - "fields": [ - [ - "version", - 4 - ], - [ - "ihl", - 4 - ], - [ - "diffserv", - 8 - ], - [ - "totalLen", - 16 - ], - [ - "identification", - 16 - ], - [ - "flags", - 3 - ], - [ - "fragOffset", - 13 - ], - [ - "ttl", - 8 - ], - [ - "protocol", - 8 - ], - [ - "hdrChecksum", - 16 - ], - [ - "srcAddr", - 32 - ], - [ - "dstAddr", - 32 - ] - ], - "length_exp": null, - "max_length": null - }, - { - "name": "tcp_t", - "id": 4, - "fields": [ - [ - "srcPort", - 16 - ], - [ - "dstPort", - 16 - ], - [ - "seqNo", - 32 - ], - [ - "ackNo", - 32 - ], - [ - "dataOffset", - 4 - ], - [ - "res", - 3 - ], - [ - "ecn", - 3 - ], - [ - "ctrl", - 6 - ], - [ - "window", - 16 - ], - [ - "checksum", - 16 - ], - [ - "urgentPtr", - 16 - ] - ], - "length_exp": null, - "max_length": null - }, - { - "name": "udp_t", - "id": 5, - "fields": [ - [ - "srcPort", - 16 - ], - [ - "dstPort", - 16 - ], - [ - "length_", - 16 - ], - [ - "checksum", - 16 - ] - ], - "length_exp": null, - "max_length": null - }, - { - "name": "ecmp_metadata_t", - "id": 6, - "fields": [ - [ - "groupId", - 16 - ], - [ - "selector", - 16 - ] - ], - "length_exp": null, - "max_length": null - } - ], - "headers": [ - { - "name": "standard_metadata", - "id": 0, - "header_type": "standard_metadata_t", - "metadata": true - }, - { - "name": "intrinsic_metadata", - "id": 1, - "header_type": "intrinsic_metadata_t", - "metadata": true - }, - { - "name": "ethernet", - "id": 2, - "header_type": "ethernet_t", - "metadata": false - }, - { - "name": "ipv4", - "id": 3, - "header_type": "ipv4_t", - "metadata": false - }, - { - "name": "tcp", - "id": 4, - "header_type": "tcp_t", - "metadata": false - }, - { - "name": "udp", - "id": 5, - "header_type": "udp_t", - "metadata": false - }, - { - "name": "ecmp_metadata", - "id": 6, - "header_type": "ecmp_metadata_t", - "metadata": true - } - ], - "header_stacks": [], - "parsers": [ - { - "name": "parser", - "id": 0, - "init_state": "start", - "parse_states": [ - { - "name": "start", - "id": 0, - "parser_ops": [], - "transition_key": [], - "transitions": [ - { - "value": "default", - "mask": null, - "next_state": "parse_ethernet" - } - ] - }, - { - "name": "parse_ethernet", - "id": 1, - "parser_ops": [ - { - "op": "extract", - "parameters": [ - { - "type": "regular", - "value": "ethernet" - } - ] - } - ], - "transition_key": [ - { - "type": "field", - "value": [ - "ethernet", - "etherType" - ] - } - ], - "transitions": [ - { - "value": "0x0800", - "mask": null, - "next_state": "parse_ipv4" - }, - { - "value": "default", - "mask": null, - "next_state": null - } - ] - }, - { - "name": "parse_ipv4", - "id": 2, - "parser_ops": [ - { - "op": "extract", - "parameters": [ - { - "type": "regular", - "value": "ipv4" - } - ] - } - ], - "transition_key": [ - { - "type": "field", - "value": [ - "ipv4", - "fragOffset" - ] - }, - { - "type": "field", - "value": [ - "ipv4", - "protocol" - ] - } - ], - "transitions": [ - { - "value": "0x000006", - "mask": null, - "next_state": "parse_tcp" - }, - { - "value": "0x000011", - "mask": null, - "next_state": "parse_udp" - }, - { - "value": "default", - "mask": null, - "next_state": null - } - ] - }, - { - "name": "parse_tcp", - "id": 3, - "parser_ops": [ - { - "op": "extract", - "parameters": [ - { - "type": "regular", - "value": "tcp" - } - ] - } - ], - "transition_key": [], - "transitions": [ - { - "value": "default", - "mask": null, - "next_state": null - } - ] - }, - { - "name": "parse_udp", - "id": 4, - "parser_ops": [ - { - "op": "extract", - "parameters": [ - { - "type": "regular", - "value": "udp" - } - ] - } - ], - "transition_key": [], - "transitions": [ - { - "value": "default", - "mask": null, - "next_state": null - } - ] - } - ] - } - ], - "deparsers": [ - { - "name": "deparser", - "id": 0, - "order": [ - "ethernet", - "ipv4", - "udp", - "tcp" - ] - } - ], - "meter_arrays": [], - "actions": [ - { - "name": "_drop", - "id": 0, - "runtime_data": [], - "primitives": [ - { - "op": "modify_field", - "parameters": [ - { - "type": "field", - "value": [ - "standard_metadata", - "egress_spec" - ] - }, - { - "type": "hexstr", - "value": "0x1ff" - } - ] - } - ] - }, - { - "name": "ecmp_group", - "id": 1, - "runtime_data": [ - { - "name": "groupId", - "bitwidth": 16 - }, - { - "name": "groupSize", - "bitwidth": 16 - } - ], - "primitives": [ - { - "op": "modify_field", - "parameters": [ - { - "type": "field", - "value": [ - "ecmp_metadata", - "groupId" - ] - }, - { - "type": "runtime_data", - "value": 0 - } - ] - }, - { - "op": "modify_field_with_hash_based_offset", - "parameters": [ - { - "type": "field", - "value": [ - "ecmp_metadata", - "selector" - ] - }, - { - "type": "hexstr", - "value": "0x0" - }, - { - "type": "calculation", - "value": "ecmp_hash" - }, - { - "type": "runtime_data", - "value": 1 - } - ] - } - ] - }, - { - "name": "send_to_cpu", - "id": 2, - "runtime_data": [], - "primitives": [ - { - "op": "modify_field", - "parameters": [ - { - "type": "field", - "value": [ - "standard_metadata", - "egress_spec" - ] - }, - { - "type": "hexstr", - "value": "0xff" - } - ] - } - ] - }, - { - "name": "count_packet", - "id": 3, - "runtime_data": [], - "primitives": [ - { - "op": "count", - "parameters": [ - { - "type": "counter_array", - "value": "ingress_port_counter" - }, - { - "type": "field", - "value": [ - "standard_metadata", - "ingress_port" - ] - } - ] - }, - { - "op": "count", - "parameters": [ - { - "type": "counter_array", - "value": "egress_port_counter" - }, - { - "type": "field", - "value": [ - "standard_metadata", - "egress_spec" - ] - } - ] - } - ] - }, - { - "name": "set_egress_port", - "id": 4, - "runtime_data": [ - { - "name": "port", - "bitwidth": 9 - } - ], - "primitives": [ - { - "op": "modify_field", - "parameters": [ - { - "type": "field", - "value": [ - "standard_metadata", - "egress_spec" - ] - }, - { - "type": "runtime_data", - "value": 0 - } - ] - } - ] - } - ], - "pipelines": [ - { - "name": "ingress", - "id": 0, - "init_table": "table0", - "tables": [ - { - "name": "port_count_table", - "id": 0, - "match_type": "exact", - "type": "simple", - "max_size": 16384, - "with_counters": false, - "direct_meters": null, - "support_timeout": false, - "key": [], - "actions": [ - "count_packet" - ], - "next_tables": { - "count_packet": null - }, - "default_action": null, - "base_default_next": null - }, - { - "name": "table0", - "id": 1, - "match_type": "ternary", - "type": "simple", - "max_size": 16384, - "with_counters": true, - "direct_meters": null, - "support_timeout": true, - "key": [ - { - "match_type": "ternary", - "target": [ - "standard_metadata", - "ingress_port" - ], - "mask": null - }, - { - "match_type": "ternary", - "target": [ - "ethernet", - "dstAddr" - ], - "mask": null - }, - { - "match_type": "ternary", - "target": [ - "ethernet", - "srcAddr" - ], - "mask": null - }, - { - "match_type": "ternary", - "target": [ - "ethernet", - "etherType" - ], - "mask": null - } - ], - "actions": [ - "set_egress_port", - "ecmp_group", - "send_to_cpu", - "_drop" - ], - "next_tables": { - "set_egress_port": "_condition_0", - "ecmp_group": "ecmp_group_table", - "send_to_cpu": "_condition_0", - "_drop": "_condition_0" - }, - "default_action": null, - "base_default_next": "_condition_0" - }, - { - "name": "ecmp_group_table", - "id": 2, - "match_type": "exact", - "type": "simple", - "max_size": 16384, - "with_counters": true, - "direct_meters": null, - "support_timeout": false, - "key": [ - { - "match_type": "exact", - "target": [ - "ecmp_metadata", - "groupId" - ], - "mask": null - }, - { - "match_type": "exact", - "target": [ - "ecmp_metadata", - "selector" - ], - "mask": null - } - ], - "actions": [ - "set_egress_port" - ], - "next_tables": { - "set_egress_port": "_condition_0" - }, - "default_action": null, - "base_default_next": "_condition_0" - } - ], - "conditionals": [ - { - "name": "_condition_0", - "id": 0, - "expression": { - "type": "expression", - "value": { - "op": "<", - "left": { - "type": "field", - "value": [ - "standard_metadata", - "egress_spec" - ] - }, - "right": { - "type": "hexstr", - "value": "0xfe" - } - } - }, - "true_next": "port_count_table", - "false_next": null - } - ] - }, - { - "name": "egress", - "id": 1, - "init_table": null, - "tables": [], - "conditionals": [] - } - ], - "calculations": [ - { - "name": "ecmp_hash", - "id": 0, - "input": [ - { - "type": "field", - "value": [ - "ipv4", - "srcAddr" - ] - }, - { - "type": "field", - "value": [ - "ipv4", - "dstAddr" - ] - }, - { - "type": "field", - "value": [ - "ipv4", - "protocol" - ] - }, - { - "type": "field", - "value": [ - "tcp", - "srcPort" - ] - }, - { - "type": "field", - "value": [ - "tcp", - "dstPort" - ] - }, - { - "type": "field", - "value": [ - "udp", - "srcPort" - ] - }, - { - "type": "field", - "value": [ - "udp", - "dstPort" - ] - } - ], - "algo": "bmv2_hash" - } - ], - "checksums": [], - "learn_lists": [], - "field_lists": [], - "counter_arrays": [ - { - "name": "ingress_port_counter", - "id": 0, - "is_direct": false, - "size": 254 - }, - { - "name": "egress_port_counter", - "id": 1, - "is_direct": false, - "size": 254 - }, - { - "name": "table0_counter", - "id": 2, - "is_direct": true, - "binding": "table0" - }, - { - "name": "ecmp_group_table_counter", - "id": 3, - "is_direct": true, - "binding": "ecmp_group_table" - } - ], - "register_arrays": [], - "force_arith": [ - [ - "standard_metadata", - "ingress_port" - ], - [ - "standard_metadata", - "packet_length" - ], - [ - "standard_metadata", - "egress_spec" - ], - [ - "standard_metadata", - "egress_port" - ], - [ - "standard_metadata", - "egress_instance" - ], - [ - "standard_metadata", - "instance_type" - ], - [ - "standard_metadata", - "clone_spec" - ], - [ - "standard_metadata", - "_padding" - ], - [ - "intrinsic_metadata", - "ingress_global_timestamp" - ], - [ - "intrinsic_metadata", - "lf_field_list" - ], - [ - "intrinsic_metadata", - "mcast_grp" - ], - [ - "intrinsic_metadata", - "egress_rid" - ] - ] -} \ No newline at end of file diff --git a/apps/bmv2-demo/pom.xml b/apps/bmv2-demo/pom.xml deleted file mode 100644 index 9738528d9a..0000000000 --- a/apps/bmv2-demo/pom.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - 4.0.0 - - - org.onosproject - onos-apps - 1.11.0-SNAPSHOT - - - onos-app-bmv2-demo - - pom - - - common - ecmp - wcmp - - - diff --git a/apps/bmv2-demo/wcmp/features.xml b/apps/bmv2-demo/wcmp/features.xml deleted file mode 100644 index 0bfb8274b1..0000000000 --- a/apps/bmv2-demo/wcmp/features.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - mvn:${project.groupId}/${project.artifactId}/${project.version} - mvn:${project.groupId}/onos-app-bmv2-demo-common/${project.version} - - diff --git a/apps/bmv2-demo/wcmp/pom.xml b/apps/bmv2-demo/wcmp/pom.xml deleted file mode 100644 index 3193d514cc..0000000000 --- a/apps/bmv2-demo/wcmp/pom.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - 4.0.0 - - - onos-app-bmv2-demo - org.onosproject - 1.11.0-SNAPSHOT - - - onos-app-bmv2-demo-wcmp - - bundle - - - org.onosproject.bmv2-wcmp-fabric - P4/BMv2 Demo Fabric App v2 (WCMP) - Traffic Steering - http://onosproject.org - P4/BMv2 demo application with WCMP support for a 2-stage clos fabric topology - - - - - org.onosproject - onos-app-bmv2-demo-common - ${project.version} - - - - \ No newline at end of file diff --git a/apps/bmv2-demo/wcmp/src/main/java/org/onosproject/bmv2/demo/app/wcmp/WcmpFabricApp.java b/apps/bmv2-demo/wcmp/src/main/java/org/onosproject/bmv2/demo/app/wcmp/WcmpFabricApp.java deleted file mode 100644 index 2d47afbdea..0000000000 --- a/apps/bmv2-demo/wcmp/src/main/java/org/onosproject/bmv2/demo/app/wcmp/WcmpFabricApp.java +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.demo.app.wcmp; - -import com.eclipsesource.json.Json; -import com.eclipsesource.json.JsonObject; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import org.apache.commons.lang3.tuple.Pair; -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.Reference; -import org.apache.felix.scr.annotations.ReferenceCardinality; -import org.onosproject.bmv2.api.context.Bmv2Configuration; -import org.onosproject.bmv2.api.context.Bmv2DefaultConfiguration; -import org.onosproject.bmv2.api.context.Bmv2DeviceContext; -import org.onosproject.bmv2.api.runtime.Bmv2Action; -import org.onosproject.bmv2.api.runtime.Bmv2DeviceAgent; -import org.onosproject.bmv2.api.runtime.Bmv2ExtensionSelector; -import org.onosproject.bmv2.api.runtime.Bmv2ExtensionTreatment; -import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException; -import org.onosproject.bmv2.api.service.Bmv2Controller; -import org.onosproject.bmv2.demo.app.common.AbstractUpgradableFabricApp; -import org.onosproject.net.DeviceId; -import org.onosproject.net.Host; -import org.onosproject.net.Path; -import org.onosproject.net.PortNumber; -import org.onosproject.net.flow.DefaultTrafficSelector; -import org.onosproject.net.flow.DefaultTrafficTreatment; -import org.onosproject.net.flow.FlowRule; -import org.onosproject.net.flow.TrafficTreatment; -import org.onosproject.net.flow.criteria.ExtensionSelector; -import org.onosproject.net.flow.instructions.ExtensionTreatment; -import org.onosproject.net.topology.DefaultTopologyVertex; -import org.onosproject.net.topology.Topology; -import org.onosproject.net.topology.TopologyGraph; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import static java.util.stream.Collectors.toList; -import static java.util.stream.Collectors.toSet; -import static org.onlab.packet.EthType.EtherType.IPV4; -import static org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils.roundToBytes; -import static org.onosproject.bmv2.demo.app.wcmp.WcmpInterpreter.*; - -/** - * Implementation of an upgradable fabric app for the WCMP configuration. - */ -@Component(immediate = true) -public class WcmpFabricApp extends AbstractUpgradableFabricApp { - - private static final String APP_NAME = "org.onosproject.bmv2-wcmp-fabric"; - private static final String MODEL_NAME = "WCMP"; - private static final String JSON_CONFIG_PATH = "/wcmp.json"; - - private static final double MULTI_PORT_WEIGHT_COEFFICIENT = 0.85; - - private static final Bmv2Configuration WCMP_CONFIGURATION = loadConfiguration(); - private static final WcmpInterpreter WCMP_INTERPRETER = new WcmpInterpreter(); - protected static final Bmv2DeviceContext WCMP_CONTEXT = new Bmv2DeviceContext(WCMP_CONFIGURATION, WCMP_INTERPRETER); - - private static final Map, Integer>> DEVICE_GROUP_ID_MAP = Maps.newHashMap(); - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - private Bmv2Controller bmv2Controller; - - /** - * TODO. - */ - public WcmpFabricApp() { - super(APP_NAME, MODEL_NAME, WCMP_CONTEXT); - } - - - @Override - public boolean initDevice(DeviceId deviceId) { - try { - Bmv2DeviceAgent agent = bmv2Controller.getAgent(deviceId); - for (Map.Entry entry : WCMP_INTERPRETER.defaultActionsMap().entrySet()) { - agent.setTableDefaultAction(entry.getKey(), entry.getValue()); - } - return true; - } catch (Bmv2RuntimeException e) { - log.debug("Exception while initializing device {}: {}", deviceId, e.explain()); - return false; - } - } - - @Override - public List generateLeafRules(DeviceId deviceId, Host srcHost, Collection dstHosts, - Collection availableSpines, Topology topo) - throws FlowRuleGeneratorException { - - Set hostPortNumbers = Sets.newHashSet(); - Set fabricPortNumbers = Sets.newHashSet(); - deviceService.getPorts(deviceId) - .forEach(p -> (isFabricPort(p, topo) ? fabricPortNumbers : hostPortNumbers).add(p.number())); - - if (hostPortNumbers.size() != 1 || fabricPortNumbers.size() == 0) { - log.error("Leaf switch has invalid port configuration: hostPorts={}, fabricPorts={}", - hostPortNumbers.size(), fabricPortNumbers.size()); - throw new FlowRuleGeneratorException(); - } - PortNumber hostPort = hostPortNumbers.iterator().next(); - - TopologyGraph graph = topologyService.getGraph(topo); - // Map key: spine device id, value: leaf switch ports which connect to spine in the key. - Map> spineToPortsMap = Maps.newHashMap(); - graph.getEdgesFrom(new DefaultTopologyVertex(deviceId)).forEach(edge -> { - spineToPortsMap.putIfAbsent(edge.dst().deviceId(), Sets.newHashSet()); - spineToPortsMap.get(edge.dst().deviceId()).add(edge.link().src().port()); - }); - - double baseWeight = 1d / spineToPortsMap.size(); - - int numSinglePorts = (int) spineToPortsMap.values().stream().filter(s -> s.size() == 1).count(); - int numMultiPorts = spineToPortsMap.size() - numSinglePorts; - - // Reduce weight portion assigned to multi-ports to mitigate flow assignment imbalance (measured empirically). - double multiPortBaseWeight = baseWeight * MULTI_PORT_WEIGHT_COEFFICIENT; - double excess = (baseWeight - multiPortBaseWeight) * numMultiPorts; - double singlePortBaseWeight = baseWeight + (excess / numSinglePorts); - - Map weighedPortNumbers = Maps.newHashMap(); - spineToPortsMap.forEach((did, portSet) -> { - double base = (portSet.size() == 1) ? singlePortBaseWeight : multiPortBaseWeight; - double weight = base / portSet.size(); - portSet.forEach(portNumber -> weighedPortNumbers.put(portNumber, weight)); - }); - - List rules = Lists.newArrayList(); - - - Pair> result = provisionWcmpTreatment(deviceId, weighedPortNumbers); - ExtensionTreatment wcmpTreatment = result.getLeft(); - rules.addAll(result.getRight()); - - // From src host to dst hosts, WCMP to all fabric ports. - for (Host dstHost : dstHosts) { - FlowRule rule = flowRuleBuilder(deviceId, TABLE0) - .withSelector( - DefaultTrafficSelector.builder() - .matchInPort(hostPort) - .matchEthType(IPV4.ethType().toShort()) - .matchEthSrc(srcHost.mac()) - .matchEthDst(dstHost.mac()) - .build()) - .withTreatment( - DefaultTrafficTreatment.builder() - .extension(wcmpTreatment, deviceId) - .build()) - .build(); - rules.add(rule); - } - - // From fabric ports to src host. - for (PortNumber port : fabricPortNumbers) { - FlowRule rule = flowRuleBuilder(deviceId, TABLE0) - .withSelector( - DefaultTrafficSelector.builder() - .matchInPort(port) - .matchEthType(IPV4.ethType().toShort()) - .matchEthDst(srcHost.mac()) - .build()) - .withTreatment( - DefaultTrafficTreatment.builder() - .setOutput(hostPort) - .build()) - .build(); - rules.add(rule); - } - - return rules; - } - - @Override - public List generateSpineRules(DeviceId deviceId, Collection dstHosts, Topology topo) - throws FlowRuleGeneratorException { - - List rules = Lists.newArrayList(); - - for (Host dstHost : dstHosts) { - - Set paths = topologyService.getPaths(topo, deviceId, dstHost.location().deviceId()); - - if (paths.size() == 0) { - log.warn("Can't find any path between spine {} and host {}", deviceId, dstHost); - throw new FlowRuleGeneratorException(); - } - - TrafficTreatment treatment; - - if (paths.size() == 1) { - // Only one path. - PortNumber port = paths.iterator().next().src().port(); - treatment = DefaultTrafficTreatment.builder().setOutput(port).build(); - } else { - // Multiple paths, do WCMP. - Set portNumbers = paths.stream().map(p -> p.src().port()).collect(toSet()); - double weight = 1d / portNumbers.size(); - // Same weight for all ports. - Map weightedPortNumbers = portNumbers.stream() - .collect(Collectors.toMap(p -> p, p -> weight)); - Pair> result = provisionWcmpTreatment(deviceId, weightedPortNumbers); - rules.addAll(result.getRight()); - treatment = DefaultTrafficTreatment.builder().extension(result.getLeft(), deviceId).build(); - } - - FlowRule rule = flowRuleBuilder(deviceId, TABLE0) - .withSelector( - DefaultTrafficSelector.builder() - .matchEthType(IPV4.ethType().toShort()) - .matchEthDst(dstHost.mac()) - .build()) - .withTreatment(treatment) - .build(); - - rules.add(rule); - } - - return rules; - } - - private Pair> provisionWcmpTreatment(DeviceId deviceId, - Map weightedFabricPorts) - throws FlowRuleGeneratorException { - - // Install WCMP group table entries that map from hash values to fabric ports. - - int groupId = groupIdOf(deviceId, weightedFabricPorts); - List portNumbers = Lists.newArrayList(); - List weights = Lists.newArrayList(); - weightedFabricPorts.forEach((p, w) -> { - portNumbers.add(p); - weights.add(w); - }); - List prefixLengths = toPrefixLengths(weights); - - List rules = Lists.newArrayList(); - for (int i = 0; i < portNumbers.size(); i++) { - ExtensionSelector extSelector = buildWcmpSelector(groupId, prefixLengths.get(i)); - FlowRule rule = flowRuleBuilder(deviceId, WCMP_GROUP_TABLE) - .withSelector(DefaultTrafficSelector.builder() - .extension(extSelector, deviceId) - .build()) - .withTreatment( - DefaultTrafficTreatment.builder() - .setOutput(portNumbers.get(i)) - .build()) - .build(); - rules.add(rule); - } - - ExtensionTreatment extTreatment = buildWcmpTreatment(groupId); - - return Pair.of(extTreatment, rules); - } - - private Bmv2ExtensionSelector buildWcmpSelector(int groupId, int prefixLength) { - byte[] ones = new byte[roundToBytes(prefixLength)]; - Arrays.fill(ones, (byte) 0xFF); - return Bmv2ExtensionSelector.builder() - .forConfiguration(WCMP_CONTEXT.configuration()) - .matchExact(WCMP_META, GROUP_ID, groupId) - .matchLpm(WCMP_META, SELECTOR, ones, prefixLength) - .build(); - } - - private Bmv2ExtensionTreatment buildWcmpTreatment(int groupId) { - return Bmv2ExtensionTreatment.builder() - .forConfiguration(WCMP_CONTEXT.configuration()) - .setActionName(WCMP_GROUP) - .addParameter(GROUP_ID, groupId) - .build(); - } - - public int groupIdOf(DeviceId did, Map weightedPorts) { - DEVICE_GROUP_ID_MAP.putIfAbsent(did, Maps.newHashMap()); - // Counts the number of unique portNumber sets for each device ID. - // Each distinct set of portNumbers will have a unique ID. - return DEVICE_GROUP_ID_MAP.get(did).computeIfAbsent(weightedPorts, - (pp) -> DEVICE_GROUP_ID_MAP.get(did).size() + 1); - } - - public List toPrefixLengths(List weigths) { - - final double weightSum = weigths.stream() - .mapToDouble(Double::doubleValue) - .map(this::roundDouble) - .sum(); - - if (Math.abs(weightSum - 1) > 0.0001) { - throw new RuntimeException("WCMP weights sum is expected to be 1, found was " + weightSum); - } - - final int selectorBitWidth = WCMP_CONTEXT.configuration().headerType(WCMP_META_T).field(SELECTOR).bitWidth(); - final int availableBits = selectorBitWidth - 1; - - List prefixDiffs = weigths.stream().map(w -> Math.round(w * availableBits)).collect(toList()); - - final long bitSum = prefixDiffs.stream().mapToLong(Long::longValue).sum(); - final long error = availableBits - bitSum; - - if (error != 0) { - // Lazy intuition here is that the error can be absorbed by the longest prefixDiff with the minor impact. - Long maxDiff = Collections.max(prefixDiffs); - int idx = prefixDiffs.indexOf(maxDiff); - prefixDiffs.remove(idx); - prefixDiffs.add(idx, maxDiff + error); - } - List prefixLengths = Lists.newArrayList(); - - int prefix = 1; - for (Long p : prefixDiffs) { - prefixLengths.add(prefix); - prefix += p; - } - return ImmutableList.copyOf(prefixLengths); - } - - private double roundDouble(double n) { - // 5 digits precision. - return (double) Math.round(n * 100000d) / 100000d; - } - - private static Bmv2Configuration loadConfiguration() { - try { - JsonObject json = Json.parse(new BufferedReader(new InputStreamReader( - WcmpFabricApp.class.getResourceAsStream(JSON_CONFIG_PATH)))).asObject(); - return Bmv2DefaultConfiguration.parse(json); - } catch (IOException e) { - throw new RuntimeException("Unable to load configuration", e); - } - } -} \ No newline at end of file diff --git a/apps/bmv2-demo/wcmp/src/main/java/org/onosproject/bmv2/demo/app/wcmp/WcmpInterpreter.java b/apps/bmv2-demo/wcmp/src/main/java/org/onosproject/bmv2/demo/app/wcmp/WcmpInterpreter.java deleted file mode 100644 index 19d042db17..0000000000 --- a/apps/bmv2-demo/wcmp/src/main/java/org/onosproject/bmv2/demo/app/wcmp/WcmpInterpreter.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.demo.app.wcmp; - -import com.google.common.collect.ImmutableBiMap; -import org.onlab.util.ImmutableByteSequence; -import org.onosproject.bmv2.api.context.Bmv2Configuration; -import org.onosproject.bmv2.api.context.Bmv2Interpreter; -import org.onosproject.bmv2.api.context.Bmv2InterpreterException; -import org.onosproject.bmv2.api.runtime.Bmv2Action; -import org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils; -import org.onosproject.net.PortNumber; -import org.onosproject.net.flow.TrafficTreatment; -import org.onosproject.net.flow.criteria.Criterion; -import org.onosproject.net.flow.instructions.Instruction; -import org.onosproject.net.flow.instructions.Instructions.OutputInstruction; - -import java.util.Map; - -import static org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils.fitByteSequence; -import static org.onosproject.net.PortNumber.CONTROLLER; - -/** - * Implementation of a BMv2 interpreter for the wcmp.json configuration. - */ -public final class WcmpInterpreter implements Bmv2Interpreter { - - protected static final String WCMP_META_T = "wcmp_meta_t"; - protected static final String WCMP_META = "wcmp_meta"; - protected static final String SELECTOR = "selector"; - protected static final String GROUP_ID = "groupId"; - protected static final String WCMP_GROUP = "wcmp_group"; - protected static final String WCMP_SET_SELECTOR = "wcmp_set_selector"; - protected static final String WCMP_SET_SELECTOR_TABLE = "wcmp_set_selector_table"; - protected static final String WCMP_GROUP_TABLE = "wcmp_group_table"; - protected static final String TABLE0 = "table0"; - protected static final String SEND_TO_CPU = "send_to_cpu"; - protected static final String DROP = "_drop"; - protected static final String SET_EGRESS_PORT = "set_egress_port"; - protected static final String PORT = "port"; - - private static final ImmutableBiMap CRITERION_TYPE_MAP = ImmutableBiMap.of( - Criterion.Type.IN_PORT, "standard_metadata.ingress_port", - Criterion.Type.ETH_DST, "ethernet.dstAddr", - Criterion.Type.ETH_SRC, "ethernet.srcAddr", - Criterion.Type.ETH_TYPE, "ethernet.etherType"); - - private static final ImmutableBiMap TABLE_ID_MAP = ImmutableBiMap.of( - 0, TABLE0, - 1, WCMP_GROUP_TABLE); - - private static final Map DEFAULT_ACTIONS_MAP = ImmutableBiMap.of( - WCMP_SET_SELECTOR_TABLE, actionWithName(WCMP_SET_SELECTOR)); - - @Override - public ImmutableBiMap tableIdMap() { - return TABLE_ID_MAP; - } - - @Override - public ImmutableBiMap criterionTypeMap() { - return CRITERION_TYPE_MAP; - } - - public Map defaultActionsMap() { - return DEFAULT_ACTIONS_MAP; - } - - @Override - public Bmv2Action mapTreatment(TrafficTreatment treatment, Bmv2Configuration configuration) - throws Bmv2InterpreterException { - - if (treatment.allInstructions().size() == 0) { - // No instructions means drop for us. - return actionWithName(DROP); - } else if (treatment.allInstructions().size() > 1) { - // Otherwise, we understand treatments with only 1 instruction. - throw new Bmv2InterpreterException("Treatment has multiple instructions"); - } - - Instruction instruction = treatment.allInstructions().get(0); - - switch (instruction.type()) { - case OUTPUT: - OutputInstruction outInstruction = (OutputInstruction) instruction; - PortNumber port = outInstruction.port(); - if (!port.isLogical()) { - return buildEgressAction(port, configuration); - } else if (port.equals(CONTROLLER)) { - return actionWithName(SEND_TO_CPU); - } else { - throw new Bmv2InterpreterException("Egress on logical port not supported: " + port); - } - case NOACTION: - return actionWithName(DROP); - default: - throw new Bmv2InterpreterException("Instruction type not supported: " + instruction.type().name()); - } - } - - private static Bmv2Action buildEgressAction(PortNumber port, Bmv2Configuration configuration) - throws Bmv2InterpreterException { - - int portBitWidth = configuration.action(SET_EGRESS_PORT).runtimeData(PORT).bitWidth(); - - try { - ImmutableByteSequence portBs = fitByteSequence(ImmutableByteSequence.copyFrom(port.toLong()), portBitWidth); - return Bmv2Action.builder() - .withName(SET_EGRESS_PORT) - .addParameter(portBs) - .build(); - } catch (Bmv2TranslatorUtils.ByteSequenceFitException e) { - throw new Bmv2InterpreterException(e.getMessage()); - } - } - - private static Bmv2Action actionWithName(String name) { - return Bmv2Action.builder().withName(name).build(); - } -} diff --git a/apps/bmv2-demo/wcmp/src/main/java/org/onosproject/bmv2/demo/app/wcmp/package-info.java b/apps/bmv2-demo/wcmp/src/main/java/org/onosproject/bmv2/demo/app/wcmp/package-info.java deleted file mode 100644 index d4fd1e2914..0000000000 --- a/apps/bmv2-demo/wcmp/src/main/java/org/onosproject/bmv2/demo/app/wcmp/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * BMv2 demo app for the WCMP configuration. - */ -package org.onosproject.bmv2.demo.app.wcmp; \ No newline at end of file diff --git a/apps/bmv2-demo/wcmp/src/main/resources/wcmp.json b/apps/bmv2-demo/wcmp/src/main/resources/wcmp.json deleted file mode 100644 index 1dd6c025dc..0000000000 --- a/apps/bmv2-demo/wcmp/src/main/resources/wcmp.json +++ /dev/null @@ -1,1000 +0,0 @@ -{ - "header_types": [ - { - "name": "standard_metadata_t", - "id": 0, - "fields": [ - [ - "ingress_port", - 9 - ], - [ - "packet_length", - 32 - ], - [ - "egress_spec", - 9 - ], - [ - "egress_port", - 9 - ], - [ - "egress_instance", - 32 - ], - [ - "instance_type", - 32 - ], - [ - "clone_spec", - 32 - ], - [ - "_padding", - 5 - ] - ], - "length_exp": null, - "max_length": null - }, - { - "name": "intrinsic_metadata_t", - "id": 1, - "fields": [ - [ - "ingress_global_timestamp", - 32 - ], - [ - "lf_field_list", - 32 - ], - [ - "mcast_grp", - 16 - ], - [ - "egress_rid", - 16 - ] - ], - "length_exp": null, - "max_length": null - }, - { - "name": "ethernet_t", - "id": 2, - "fields": [ - [ - "dstAddr", - 48 - ], - [ - "srcAddr", - 48 - ], - [ - "etherType", - 16 - ] - ], - "length_exp": null, - "max_length": null - }, - { - "name": "ipv4_t", - "id": 3, - "fields": [ - [ - "version", - 4 - ], - [ - "ihl", - 4 - ], - [ - "diffserv", - 8 - ], - [ - "totalLen", - 16 - ], - [ - "identification", - 16 - ], - [ - "flags", - 3 - ], - [ - "fragOffset", - 13 - ], - [ - "ttl", - 8 - ], - [ - "protocol", - 8 - ], - [ - "hdrChecksum", - 16 - ], - [ - "srcAddr", - 32 - ], - [ - "dstAddr", - 32 - ] - ], - "length_exp": null, - "max_length": null - }, - { - "name": "tcp_t", - "id": 4, - "fields": [ - [ - "srcPort", - 16 - ], - [ - "dstPort", - 16 - ], - [ - "seqNo", - 32 - ], - [ - "ackNo", - 32 - ], - [ - "dataOffset", - 4 - ], - [ - "res", - 3 - ], - [ - "ecn", - 3 - ], - [ - "ctrl", - 6 - ], - [ - "window", - 16 - ], - [ - "checksum", - 16 - ], - [ - "urgentPtr", - 16 - ] - ], - "length_exp": null, - "max_length": null - }, - { - "name": "udp_t", - "id": 5, - "fields": [ - [ - "srcPort", - 16 - ], - [ - "dstPort", - 16 - ], - [ - "length_", - 16 - ], - [ - "checksum", - 16 - ] - ], - "length_exp": null, - "max_length": null - }, - { - "name": "wcmp_meta_t", - "id": 6, - "fields": [ - [ - "groupId", - 16 - ], - [ - "numBits", - 8 - ], - [ - "selector", - 64 - ] - ], - "length_exp": null, - "max_length": null - } - ], - "headers": [ - { - "name": "standard_metadata", - "id": 0, - "header_type": "standard_metadata_t", - "metadata": true - }, - { - "name": "intrinsic_metadata", - "id": 1, - "header_type": "intrinsic_metadata_t", - "metadata": true - }, - { - "name": "ethernet", - "id": 2, - "header_type": "ethernet_t", - "metadata": false - }, - { - "name": "ipv4", - "id": 3, - "header_type": "ipv4_t", - "metadata": false - }, - { - "name": "tcp", - "id": 4, - "header_type": "tcp_t", - "metadata": false - }, - { - "name": "udp", - "id": 5, - "header_type": "udp_t", - "metadata": false - }, - { - "name": "wcmp_meta", - "id": 6, - "header_type": "wcmp_meta_t", - "metadata": true - } - ], - "header_stacks": [], - "parsers": [ - { - "name": "parser", - "id": 0, - "init_state": "start", - "parse_states": [ - { - "name": "start", - "id": 0, - "parser_ops": [], - "transition_key": [], - "transitions": [ - { - "value": "default", - "mask": null, - "next_state": "parse_ethernet" - } - ] - }, - { - "name": "parse_ethernet", - "id": 1, - "parser_ops": [ - { - "op": "extract", - "parameters": [ - { - "type": "regular", - "value": "ethernet" - } - ] - } - ], - "transition_key": [ - { - "type": "field", - "value": [ - "ethernet", - "etherType" - ] - } - ], - "transitions": [ - { - "value": "0x0800", - "mask": null, - "next_state": "parse_ipv4" - }, - { - "value": "default", - "mask": null, - "next_state": null - } - ] - }, - { - "name": "parse_ipv4", - "id": 2, - "parser_ops": [ - { - "op": "extract", - "parameters": [ - { - "type": "regular", - "value": "ipv4" - } - ] - } - ], - "transition_key": [ - { - "type": "field", - "value": [ - "ipv4", - "fragOffset" - ] - }, - { - "type": "field", - "value": [ - "ipv4", - "protocol" - ] - } - ], - "transitions": [ - { - "value": "0x000006", - "mask": null, - "next_state": "parse_tcp" - }, - { - "value": "0x000011", - "mask": null, - "next_state": "parse_udp" - }, - { - "value": "default", - "mask": null, - "next_state": null - } - ] - }, - { - "name": "parse_tcp", - "id": 3, - "parser_ops": [ - { - "op": "extract", - "parameters": [ - { - "type": "regular", - "value": "tcp" - } - ] - } - ], - "transition_key": [], - "transitions": [ - { - "value": "default", - "mask": null, - "next_state": null - } - ] - }, - { - "name": "parse_udp", - "id": 4, - "parser_ops": [ - { - "op": "extract", - "parameters": [ - { - "type": "regular", - "value": "udp" - } - ] - } - ], - "transition_key": [], - "transitions": [ - { - "value": "default", - "mask": null, - "next_state": null - } - ] - } - ] - } - ], - "deparsers": [ - { - "name": "deparser", - "id": 0, - "order": [ - "ethernet", - "ipv4", - "tcp", - "udp" - ] - } - ], - "meter_arrays": [], - "actions": [ - { - "name": "set_egress_port", - "id": 0, - "runtime_data": [ - { - "name": "port", - "bitwidth": 9 - } - ], - "primitives": [ - { - "op": "modify_field", - "parameters": [ - { - "type": "field", - "value": [ - "standard_metadata", - "egress_spec" - ] - }, - { - "type": "runtime_data", - "value": 0 - } - ] - } - ] - }, - { - "name": "_drop", - "id": 1, - "runtime_data": [], - "primitives": [ - { - "op": "modify_field", - "parameters": [ - { - "type": "field", - "value": [ - "standard_metadata", - "egress_spec" - ] - }, - { - "type": "hexstr", - "value": "0x1ff" - } - ] - } - ] - }, - { - "name": "send_to_cpu", - "id": 2, - "runtime_data": [], - "primitives": [ - { - "op": "modify_field", - "parameters": [ - { - "type": "field", - "value": [ - "standard_metadata", - "egress_spec" - ] - }, - { - "type": "hexstr", - "value": "0xff" - } - ] - } - ] - }, - { - "name": "wcmp_group", - "id": 3, - "runtime_data": [ - { - "name": "groupId", - "bitwidth": 16 - } - ], - "primitives": [ - { - "op": "modify_field", - "parameters": [ - { - "type": "field", - "value": [ - "wcmp_meta", - "groupId" - ] - }, - { - "type": "runtime_data", - "value": 0 - } - ] - }, - { - "op": "modify_field_with_hash_based_offset", - "parameters": [ - { - "type": "field", - "value": [ - "wcmp_meta", - "numBits" - ] - }, - { - "type": "hexstr", - "value": "0x2" - }, - { - "type": "calculation", - "value": "wcmp_hash" - }, - { - "type": "hexstr", - "value": "0x3e" - } - ] - } - ] - }, - { - "name": "wcmp_set_selector", - "id": 4, - "runtime_data": [], - "primitives": [ - { - "op": "modify_field", - "parameters": [ - { - "type": "field", - "value": [ - "wcmp_meta", - "selector" - ] - }, - { - "type": "expression", - "value": { - "type": "expression", - "value": { - "op": "<<", - "left": { - "type": "expression", - "value": { - "op": "-", - "left": { - "type": "expression", - "value": { - "op": "<<", - "left": { - "type": "hexstr", - "value": "0x1" - }, - "right": { - "type": "field", - "value": [ - "wcmp_meta", - "numBits" - ] - } - } - }, - "right": { - "type": "hexstr", - "value": "0x1" - } - } - }, - "right": { - "type": "expression", - "value": { - "op": "-", - "left": { - "type": "hexstr", - "value": "0x40" - }, - "right": { - "type": "field", - "value": [ - "wcmp_meta", - "numBits" - ] - } - } - } - } - } - } - ] - } - ] - }, - { - "name": "count_packet", - "id": 5, - "runtime_data": [], - "primitives": [ - { - "op": "count", - "parameters": [ - { - "type": "counter_array", - "value": "ingress_port_counter" - }, - { - "type": "field", - "value": [ - "standard_metadata", - "ingress_port" - ] - } - ] - }, - { - "op": "count", - "parameters": [ - { - "type": "counter_array", - "value": "egress_port_counter" - }, - { - "type": "field", - "value": [ - "standard_metadata", - "egress_spec" - ] - } - ] - } - ] - } - ], - "pipelines": [ - { - "name": "ingress", - "id": 0, - "init_table": "table0", - "tables": [ - { - "name": "port_count_table", - "id": 0, - "match_type": "exact", - "type": "simple", - "max_size": 16384, - "with_counters": false, - "direct_meters": null, - "support_timeout": false, - "key": [], - "actions": [ - "count_packet" - ], - "next_tables": { - "count_packet": null - }, - "default_action": null, - "base_default_next": null - }, - { - "name": "table0", - "id": 1, - "match_type": "ternary", - "type": "simple", - "max_size": 16384, - "with_counters": true, - "direct_meters": null, - "support_timeout": true, - "key": [ - { - "match_type": "ternary", - "target": [ - "standard_metadata", - "ingress_port" - ], - "mask": null - }, - { - "match_type": "ternary", - "target": [ - "ethernet", - "dstAddr" - ], - "mask": null - }, - { - "match_type": "ternary", - "target": [ - "ethernet", - "srcAddr" - ], - "mask": null - }, - { - "match_type": "ternary", - "target": [ - "ethernet", - "etherType" - ], - "mask": null - } - ], - "actions": [ - "set_egress_port", - "wcmp_group", - "send_to_cpu", - "_drop" - ], - "next_tables": { - "set_egress_port": "_condition_0", - "wcmp_group": "wcmp_set_selector_table", - "send_to_cpu": "_condition_0", - "_drop": "_condition_0" - }, - "default_action": null, - "base_default_next": "_condition_0" - }, - { - "name": "wcmp_set_selector_table", - "id": 2, - "match_type": "exact", - "type": "simple", - "max_size": 16384, - "with_counters": false, - "direct_meters": null, - "support_timeout": false, - "key": [], - "actions": [ - "wcmp_set_selector" - ], - "next_tables": { - "wcmp_set_selector": "wcmp_group_table" - }, - "default_action": null, - "base_default_next": "_condition_0" - }, - { - "name": "wcmp_group_table", - "id": 3, - "match_type": "lpm", - "type": "simple", - "max_size": 16384, - "with_counters": true, - "direct_meters": null, - "support_timeout": false, - "key": [ - { - "match_type": "exact", - "target": [ - "wcmp_meta", - "groupId" - ], - "mask": null - }, - { - "match_type": "lpm", - "target": [ - "wcmp_meta", - "selector" - ], - "mask": null - } - ], - "actions": [ - "set_egress_port" - ], - "next_tables": { - "set_egress_port": "_condition_0" - }, - "default_action": null, - "base_default_next": "_condition_0" - } - ], - "conditionals": [ - { - "name": "_condition_0", - "id": 0, - "expression": { - "type": "expression", - "value": { - "op": "<", - "left": { - "type": "field", - "value": [ - "standard_metadata", - "egress_spec" - ] - }, - "right": { - "type": "hexstr", - "value": "0xfe" - } - } - }, - "true_next": "port_count_table", - "false_next": null - } - ] - }, - { - "name": "egress", - "id": 1, - "init_table": null, - "tables": [], - "conditionals": [] - } - ], - "calculations": [ - { - "name": "wcmp_hash", - "id": 0, - "input": [ - { - "type": "field", - "value": [ - "ipv4", - "srcAddr" - ] - }, - { - "type": "field", - "value": [ - "ipv4", - "dstAddr" - ] - }, - { - "type": "field", - "value": [ - "ipv4", - "protocol" - ] - }, - { - "type": "field", - "value": [ - "tcp", - "srcPort" - ] - }, - { - "type": "field", - "value": [ - "tcp", - "dstPort" - ] - }, - { - "type": "field", - "value": [ - "udp", - "srcPort" - ] - }, - { - "type": "field", - "value": [ - "udp", - "dstPort" - ] - } - ], - "algo": "bmv2_hash" - } - ], - "checksums": [], - "learn_lists": [], - "field_lists": [], - "counter_arrays": [ - { - "name": "ingress_port_counter", - "id": 0, - "is_direct": false, - "size": 254 - }, - { - "name": "egress_port_counter", - "id": 1, - "is_direct": false, - "size": 254 - }, - { - "name": "table0_counter", - "id": 2, - "is_direct": true, - "binding": "table0" - }, - { - "name": "wcmp_group_table_counter", - "id": 3, - "is_direct": true, - "binding": "wcmp_group_table" - } - ], - "register_arrays": [], - "force_arith": [ - [ - "standard_metadata", - "ingress_port" - ], - [ - "standard_metadata", - "packet_length" - ], - [ - "standard_metadata", - "egress_spec" - ], - [ - "standard_metadata", - "egress_port" - ], - [ - "standard_metadata", - "egress_instance" - ], - [ - "standard_metadata", - "instance_type" - ], - [ - "standard_metadata", - "clone_spec" - ], - [ - "standard_metadata", - "_padding" - ], - [ - "intrinsic_metadata", - "ingress_global_timestamp" - ], - [ - "intrinsic_metadata", - "lf_field_list" - ], - [ - "intrinsic_metadata", - "mcast_grp" - ], - [ - "intrinsic_metadata", - "egress_rid" - ] - ] -} \ No newline at end of file diff --git a/apps/pom.xml b/apps/pom.xml index d9f93a294d..36f95cff0f 100644 --- a/apps/pom.xml +++ b/apps/pom.xml @@ -72,7 +72,6 @@ gangliametrics graphitemetrics scalablegateway - bmv2-demo yms tetopology rabbitmq diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionSelectorType.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionSelectorType.java index e9715a6c03..afe139557b 100644 --- a/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionSelectorType.java +++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionSelectorType.java @@ -47,7 +47,6 @@ public class ExtensionSelectorType { OFDPA_MATCH_OVID(17), OFDPA_MATCH_MPLS_L2_PORT(18), EXT_MATCH_FLOW_TYPE(20), - BMV2_MATCH_PARAMS(128), UNRESOLVED_TYPE(200); diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatmentType.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatmentType.java index d11a9a97f6..ca26ecb0c7 100644 --- a/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatmentType.java +++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatmentType.java @@ -72,7 +72,6 @@ public final class ExtensionTreatmentType { NICIRA_ENCAP_ETH_SRC(121), NICIRA_ENCAP_ETH_DST(122), NICIRA_ENCAP_ETH_TYPE(123), - BMV2_ACTION(128), OPLINK_ATTENUATION(130), UNRESOLVED_TYPE(200); diff --git a/drivers/bmv2/features.xml b/drivers/bmv2/features.xml deleted file mode 100644 index 0d72ca5d4c..0000000000 --- a/drivers/bmv2/features.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - mvn:${project.groupId}/${project.artifactId}/${project.version} - mvn:${project.groupId}/onos-bmv2-protocol-api/${project.version} - - diff --git a/drivers/bmv2/pom.xml b/drivers/bmv2/pom.xml deleted file mode 100644 index cb9a81228a..0000000000 --- a/drivers/bmv2/pom.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - onos-drivers-general - org.onosproject - 1.11.0-SNAPSHOT - - 4.0.0 - - onos-drivers-bmv2 - - bundle - - Device drivers for p4.org reference softswitch BMv2 - - - org.onosproject.drivers.bmv2 - ON.Lab - Drivers - BMv2 Drivers - http://onosproject.org - - org.onosproject.bmv2 - - - - - - org.onosproject - onos-bmv2-protocol-api - ${project.version} - - - org.onosproject - onos-drivers - ${project.version} - - - - \ No newline at end of file diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DeviceDescriptionDiscovery.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DeviceDescriptionDiscovery.java deleted file mode 100644 index 29543bfe02..0000000000 --- a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DeviceDescriptionDiscovery.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.drivers.bmv2; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import org.onlab.osgi.ServiceNotFoundException; -import org.onlab.packet.ChassisId; -import org.onosproject.bmv2.api.runtime.Bmv2DeviceAgent; -import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException; -import org.onosproject.bmv2.api.service.Bmv2Controller; -import org.onosproject.net.AnnotationKeys; -import org.onosproject.net.DefaultAnnotations; -import org.onosproject.net.DeviceId; -import org.onosproject.net.PortNumber; -import org.onosproject.net.device.DefaultDeviceDescription; -import org.onosproject.net.device.DefaultPortDescription; -import org.onosproject.net.device.DeviceDescription; -import org.onosproject.net.device.DeviceDescriptionDiscovery; -import org.onosproject.net.device.PortDescription; -import org.onosproject.net.driver.AbstractHandlerBehaviour; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.math.BigInteger; -import java.util.List; - -import static org.onosproject.bmv2.api.runtime.Bmv2Device.*; -import static org.onosproject.net.Device.Type.SWITCH; - -/** - * Implementation of the device description discovery behaviour for BMv2. - */ -public class Bmv2DeviceDescriptionDiscovery extends AbstractHandlerBehaviour implements DeviceDescriptionDiscovery { - - private static final String JSON_CONFIG_MD5 = "bmv2JsonConfigMd5"; - private static final String PROCESS_INSTANCE_ID = "bmv2ProcessInstanceId"; - - private final Logger log = LoggerFactory.getLogger(this.getClass()); - - private Bmv2Controller controller; - - private boolean init() { - try { - controller = handler().get(Bmv2Controller.class); - return true; - } catch (ServiceNotFoundException e) { - log.warn(e.getMessage()); - return false; - } - } - - @Override - public DeviceDescription discoverDeviceDetails() { - - if (!init()) { - return null; - } - - DeviceId deviceId = handler().data().deviceId(); - - Bmv2DeviceAgent deviceAgent; - try { - deviceAgent = controller.getAgent(deviceId); - } catch (Bmv2RuntimeException e) { - log.error("Failed to connect to Bmv2 device", e); - return null; - } - - DefaultAnnotations.Builder annotationsBuilder = DefaultAnnotations.builder(); - - try { - String md5 = deviceAgent.getJsonConfigMd5(); - BigInteger i = new BigInteger(1, md5.getBytes()); - annotationsBuilder.set(JSON_CONFIG_MD5, String.format("%1$032X", i).toLowerCase()); - } catch (Bmv2RuntimeException e) { - log.warn("Unable to dump JSON configuration from {}: {}", deviceId, e.explain()); - } - try { - int instanceId = deviceAgent.getProcessInstanceId(); - annotationsBuilder.set(PROCESS_INSTANCE_ID, String.valueOf(instanceId)); - } catch (Bmv2RuntimeException e) { - log.warn("Unable to get process instance ID from {}: {}", deviceId, e.explain()); - } - - annotationsBuilder.set(AnnotationKeys.PROTOCOL, PROTOCOL); - - return new DefaultDeviceDescription(deviceId.uri(), - SWITCH, - MANUFACTURER, - HW_VERSION, - SW_VERSION, - SERIAL_NUMBER, - new ChassisId(), - annotationsBuilder.build()); - } - - @Override - public List discoverPortDetails() { - - if (!init()) { - return null; - } - - DeviceId deviceId = handler().data().deviceId(); - - Bmv2DeviceAgent deviceAgent; - try { - deviceAgent = controller.getAgent(deviceId); - } catch (Bmv2RuntimeException e) { - log.error("Failed to connect to Bmv2 device", e); - return null; - } - - List portDescriptions = Lists.newArrayList(); - - try { - deviceAgent.getPortsInfo().forEach(p -> { - PortNumber portNumber = PortNumber.portNumber((long) p.number(), p.ifaceName()); - portDescriptions.add(new DefaultPortDescription(portNumber, p.isUp(), DefaultAnnotations.EMPTY)); - }); - } catch (Bmv2RuntimeException e) { - log.error("Unable to get port descriptions of {}: {}", deviceId, e); - } - - return ImmutableList.copyOf(portDescriptions); - } -} diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DriversLoader.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DriversLoader.java deleted file mode 100644 index cf1a2c5d11..0000000000 --- a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DriversLoader.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.drivers.bmv2; - -import org.apache.felix.scr.annotations.Component; -import org.onosproject.net.driver.AbstractDriverLoader; - -/** - * Loader for BMv2 drivers from xml file. - */ -@Component(immediate = true) -public class Bmv2DriversLoader extends AbstractDriverLoader { - - private static final String DRIVERS_XML = "/bmv2-drivers.xml"; - - public Bmv2DriversLoader() { - super(DRIVERS_XML); - } -} \ No newline at end of file diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2ExtensionSelectorResolver.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2ExtensionSelectorResolver.java deleted file mode 100644 index 78986a6ec1..0000000000 --- a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2ExtensionSelectorResolver.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.drivers.bmv2; - -import org.onosproject.bmv2.api.runtime.Bmv2ExtensionSelector; -import org.onosproject.net.behaviour.ExtensionSelectorResolver; -import org.onosproject.net.driver.AbstractHandlerBehaviour; -import org.onosproject.net.flow.criteria.ExtensionSelector; -import org.onosproject.net.flow.criteria.ExtensionSelectorType; - -import static org.onosproject.net.flow.criteria.ExtensionSelectorType.ExtensionSelectorTypes.BMV2_MATCH_PARAMS; - -/** - * Implementation of the extension selector resolver behaviour for BMv2. - */ -public class Bmv2ExtensionSelectorResolver extends AbstractHandlerBehaviour implements ExtensionSelectorResolver { - - @Override - public ExtensionSelector getExtensionSelector(ExtensionSelectorType type) { - if (type.equals(BMV2_MATCH_PARAMS.type())) { - return Bmv2ExtensionSelector.empty(); - } - - return null; - } -} diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2ExtensionTreatmentResolver.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2ExtensionTreatmentResolver.java deleted file mode 100644 index 6ef46d1b0c..0000000000 --- a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2ExtensionTreatmentResolver.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.drivers.bmv2; - -import org.onosproject.bmv2.api.runtime.Bmv2ExtensionTreatment; -import org.onosproject.net.behaviour.ExtensionTreatmentResolver; -import org.onosproject.net.driver.AbstractHandlerBehaviour; -import org.onosproject.net.flow.instructions.ExtensionTreatment; -import org.onosproject.net.flow.instructions.ExtensionTreatmentType; - -import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.BMV2_ACTION; - -/** - * Implementation of the extension treatment resolver behavior for BMv2. - */ -public class Bmv2ExtensionTreatmentResolver extends AbstractHandlerBehaviour implements ExtensionTreatmentResolver { - - @Override - public ExtensionTreatment getExtensionInstruction(ExtensionTreatmentType type) { - if (type.equals(BMV2_ACTION.type())) { - return Bmv2ExtensionTreatment.empty(); - } - return null; - } -} diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2FlowRuleProgrammable.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2FlowRuleProgrammable.java deleted file mode 100644 index cc8574ce9c..0000000000 --- a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2FlowRuleProgrammable.java +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.drivers.bmv2; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import org.apache.commons.lang3.tuple.Pair; -import org.onlab.osgi.ServiceNotFoundException; -import org.onosproject.bmv2.api.context.Bmv2Configuration; -import org.onosproject.bmv2.api.context.Bmv2DeviceContext; -import org.onosproject.bmv2.api.context.Bmv2FlowRuleTranslator; -import org.onosproject.bmv2.api.context.Bmv2FlowRuleTranslatorException; -import org.onosproject.bmv2.api.context.Bmv2Interpreter; -import org.onosproject.bmv2.api.context.Bmv2TableModel; -import org.onosproject.bmv2.api.runtime.Bmv2DeviceAgent; -import org.onosproject.bmv2.api.runtime.Bmv2FlowRuleWrapper; -import org.onosproject.bmv2.api.runtime.Bmv2MatchKey; -import org.onosproject.bmv2.api.runtime.Bmv2ParsedTableEntry; -import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException; -import org.onosproject.bmv2.api.runtime.Bmv2TableEntry; -import org.onosproject.bmv2.api.runtime.Bmv2TableEntryReference; -import org.onosproject.bmv2.api.service.Bmv2Controller; -import org.onosproject.bmv2.api.service.Bmv2DeviceContextService; -import org.onosproject.bmv2.api.service.Bmv2TableEntryService; -import org.onosproject.net.DeviceId; -import org.onosproject.net.driver.AbstractHandlerBehaviour; -import org.onosproject.net.flow.DefaultFlowEntry; -import org.onosproject.net.flow.FlowEntry; -import org.onosproject.net.flow.FlowRule; -import org.onosproject.net.flow.FlowRuleProgrammable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -import static org.onosproject.bmv2.api.runtime.Bmv2RuntimeException.Code.*; -import static org.onosproject.net.flow.FlowEntry.FlowEntryState.ADDED; - -/** - * Implementation of the flow rule programmable behaviour for BMv2. - */ -public class Bmv2FlowRuleProgrammable extends AbstractHandlerBehaviour implements FlowRuleProgrammable { - - private final Logger log = LoggerFactory.getLogger(this.getClass()); - - // Needed to synchronize operations over the same table entry. - private static final ConcurrentMap ENTRY_LOCKS = Maps.newConcurrentMap(); - - private Bmv2Controller controller; - private Bmv2TableEntryService tableEntryService; - private Bmv2DeviceContextService contextService; - - private boolean init() { - try { - controller = handler().get(Bmv2Controller.class); - tableEntryService = handler().get(Bmv2TableEntryService.class); - contextService = handler().get(Bmv2DeviceContextService.class); - return true; - } catch (ServiceNotFoundException e) { - log.warn(e.getMessage()); - return false; - } - } - - @Override - public Collection getFlowEntries() { - - if (!init()) { - return Collections.emptyList(); - } - - DeviceId deviceId = handler().data().deviceId(); - - Bmv2DeviceAgent deviceAgent; - try { - deviceAgent = controller.getAgent(deviceId); - } catch (Bmv2RuntimeException e) { - log.error("Failed to get BMv2 device agent: {}", e.explain()); - return Collections.emptyList(); - } - - Bmv2DeviceContext context = contextService.getContext(deviceId); - if (context == null) { - log.warn("Unable to get device context for {}", deviceId); - return Collections.emptyList(); - } - - Bmv2Interpreter interpreter = context.interpreter(); - Bmv2Configuration configuration = context.configuration(); - - List entryList = Lists.newArrayList(); - - for (Bmv2TableModel table : configuration.tables()) { - // For each table in the configuration AND exposed by the interpreter. - if (!interpreter.tableIdMap().inverse().containsKey(table.name())) { - continue; // next table - } - - List installedEntries; - try { - installedEntries = deviceAgent.getTableEntries(table.name()); - } catch (Bmv2RuntimeException e) { - log.warn("Failed to get table entries of table {} of {}: {}", table.name(), deviceId, e.explain()); - continue; // next table - } - - for (Bmv2ParsedTableEntry parsedEntry : installedEntries) { - Bmv2TableEntryReference entryRef = new Bmv2TableEntryReference(deviceId, table.name(), - parsedEntry.matchKey()); - - Lock lock = ENTRY_LOCKS.computeIfAbsent(entryRef, key -> new ReentrantLock()); - lock.lock(); - - try { - Bmv2FlowRuleWrapper frWrapper = tableEntryService.lookup(entryRef); - - if (frWrapper == null) { - log.debug("Missing reference from table entry service. Deleting it. BUG? " + - "deviceId={}, tableName={}, matchKey={}", - deviceId, table.name(), entryRef.matchKey()); - try { - doRemove(deviceAgent, table.name(), parsedEntry.entryId(), parsedEntry.matchKey()); - } catch (Bmv2RuntimeException e) { - log.warn("Unable to remove inconsistent flow rule: {}", e.explain()); - } - continue; // next entry - } - - long remoteEntryId = parsedEntry.entryId(); - long localEntryId = frWrapper.entryId(); - - if (remoteEntryId != localEntryId) { - log.debug("getFlowEntries(): inconsistent entry id! BUG? Updating it... remote={}, local={}", - remoteEntryId, localEntryId); - frWrapper = new Bmv2FlowRuleWrapper(frWrapper.rule(), remoteEntryId, - frWrapper.installedOnMillis()); - tableEntryService.bind(entryRef, frWrapper); - } - - long bytes = 0L; - long packets = 0L; - - if (table.hasCounters()) { - // Read counter values from device. - try { - Pair counterValue = deviceAgent.readTableEntryCounter(table.name(), - remoteEntryId); - bytes = counterValue.getLeft(); - packets = counterValue.getRight(); - } catch (Bmv2RuntimeException e) { - log.warn("Unable to get counters for entry {}/{} of device {}: {}", - table.name(), remoteEntryId, deviceId, e.explain()); - } - } - - FlowEntry entry = new DefaultFlowEntry(frWrapper.rule(), ADDED, frWrapper.lifeInSeconds(), - packets, bytes); - entryList.add(entry); - - } finally { - lock.unlock(); - } - } - } - - return Collections.unmodifiableCollection(entryList); - } - - @Override - public Collection applyFlowRules(Collection rules) { - - return processFlowRules(rules, Operation.APPLY); - } - - @Override - public Collection removeFlowRules(Collection rules) { - - return processFlowRules(rules, Operation.REMOVE); - } - - private Collection processFlowRules(Collection rules, Operation operation) { - - if (!init()) { - return Collections.emptyList(); - } - - DeviceId deviceId = handler().data().deviceId(); - - Bmv2DeviceAgent deviceAgent; - try { - deviceAgent = controller.getAgent(deviceId); - } catch (Bmv2RuntimeException e) { - log.error("Failed to get BMv2 device agent: {}", e.explain()); - return Collections.emptyList(); - } - - Bmv2DeviceContext context = contextService.getContext(deviceId); - if (context == null) { - log.error("Unable to get device context for {}", deviceId); - return Collections.emptyList(); - } - - Bmv2FlowRuleTranslator translator = tableEntryService.getFlowRuleTranslator(); - - List processedFlowRules = Lists.newArrayList(); - - for (FlowRule rule : rules) { - - Bmv2TableEntry bmv2Entry; - - try { - bmv2Entry = translator.translate(rule, context); - } catch (Bmv2FlowRuleTranslatorException e) { - log.warn("Unable to translate flow rule: {} - {}", e.getMessage(), rule); - continue; // next rule - } - - String tableName = bmv2Entry.tableName(); - Bmv2TableEntryReference entryRef = new Bmv2TableEntryReference(deviceId, tableName, bmv2Entry.matchKey()); - - Lock lock = ENTRY_LOCKS.computeIfAbsent(entryRef, k -> new ReentrantLock()); - lock.lock(); - try { - // Get from store - Bmv2FlowRuleWrapper frWrapper = tableEntryService.lookup(entryRef); - try { - if (operation == Operation.APPLY) { - // Apply entry - long entryId; - if (frWrapper != null) { - // Existing entry. - entryId = frWrapper.entryId(); - // Tentatively delete entry before re-adding. - // It might not exist on device due to inconsistencies. - silentlyRemove(deviceAgent, entryRef.tableName(), entryId); - } - // Add entry. - entryId = doAddEntry(deviceAgent, bmv2Entry); - frWrapper = new Bmv2FlowRuleWrapper(rule, entryId, System.currentTimeMillis()); - } else { - // Remove entry - if (frWrapper == null) { - // Entry not found in map, how come? - forceRemove(deviceAgent, entryRef.tableName(), entryRef.matchKey()); - } else { - long entryId = frWrapper.entryId(); - doRemove(deviceAgent, entryRef.tableName(), entryId, entryRef.matchKey()); - } - frWrapper = null; - } - // If here, no exceptions... things went well :) - processedFlowRules.add(rule); - } catch (Bmv2RuntimeException e) { - log.warn("Unable to {} flow rule: {}", operation.name(), e.explain()); - } - - // Update entryRef binding in table entry service. - if (frWrapper != null) { - tableEntryService.bind(entryRef, frWrapper); - } else { - tableEntryService.unbind(entryRef); - } - } finally { - lock.unlock(); - } - } - - return processedFlowRules; - } - - private long doAddEntry(Bmv2DeviceAgent agent, Bmv2TableEntry entry) throws Bmv2RuntimeException { - try { - return agent.addTableEntry(entry); - } catch (Bmv2RuntimeException e) { - if (e.getCode().equals(TABLE_DUPLICATE_ENTRY)) { - forceRemove(agent, entry.tableName(), entry.matchKey()); - return agent.addTableEntry(entry); - } else { - throw e; - } - } - } - - private void doRemove(Bmv2DeviceAgent agent, String tableName, long entryId, Bmv2MatchKey matchKey) - throws Bmv2RuntimeException { - try { - agent.deleteTableEntry(tableName, entryId); - } catch (Bmv2RuntimeException e) { - if (e.getCode().equals(TABLE_INVALID_HANDLE) || e.getCode().equals(TABLE_EXPIRED_HANDLE)) { - // entry is not there with the declared ID, try with a forced remove. - forceRemove(agent, tableName, matchKey); - } else { - throw e; - } - } - } - - private void forceRemove(Bmv2DeviceAgent agent, String tableName, Bmv2MatchKey matchKey) - throws Bmv2RuntimeException { - // Find the entryID (expensive call!) - for (Bmv2ParsedTableEntry pEntry : agent.getTableEntries(tableName)) { - if (pEntry.matchKey().equals(matchKey)) { - // Remove entry and drop exceptions. - silentlyRemove(agent, tableName, pEntry.entryId()); - break; - } - } - } - - private void silentlyRemove(Bmv2DeviceAgent agent, String tableName, long entryId) { - try { - agent.deleteTableEntry(tableName, entryId); - } catch (Bmv2RuntimeException e) { - // do nothing - } - } - - private enum Operation { - APPLY, REMOVE - } -} diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2PacketProgrammable.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2PacketProgrammable.java deleted file mode 100644 index e04d8757cd..0000000000 --- a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2PacketProgrammable.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.drivers.bmv2; - -import org.onlab.osgi.ServiceNotFoundException; -import org.onlab.util.ImmutableByteSequence; -import org.onosproject.bmv2.api.runtime.Bmv2DeviceAgent; -import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException; -import org.onosproject.bmv2.api.service.Bmv2Controller; -import org.onosproject.net.DeviceId; -import org.onosproject.net.driver.AbstractHandlerBehaviour; -import org.onosproject.net.flow.TrafficTreatment; -import org.onosproject.net.packet.OutboundPacket; -import org.onosproject.net.packet.PacketProgrammable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; - -import static java.lang.Math.toIntExact; -import static java.util.stream.Collectors.toList; -import static org.onosproject.net.flow.instructions.Instruction.Type.OUTPUT; -import static org.onosproject.net.flow.instructions.Instructions.OutputInstruction; - -/** - * Implementation of the packet programmable behaviour for BMv2. - */ -public class Bmv2PacketProgrammable extends AbstractHandlerBehaviour implements PacketProgrammable { - - private final Logger log = LoggerFactory.getLogger(this.getClass()); - - @Override - public void emit(OutboundPacket packet) { - - TrafficTreatment treatment = packet.treatment(); - - // BMv2 supports only OUTPUT instructions. - List outInstructions = treatment.allInstructions() - .stream() - .filter(i -> i.type().equals(OUTPUT)) - .map(i -> (OutputInstruction) i) - .collect(toList()); - - if (treatment.allInstructions().size() != outInstructions.size()) { - // There are other instructions that are not of type OUTPUT - log.warn("Dropping emit request, treatment nor supported: {}", treatment); - return; - } - - outInstructions.forEach(outInst -> { - if (outInst.port().isLogical()) { - log.warn("Dropping emit request, logical port not supported: {}", outInst.port()); - } else { - try { - int portNumber = toIntExact(outInst.port().toLong()); - send(portNumber, packet); - } catch (ArithmeticException e) { - log.error("Dropping emit request, port number too big: {}", outInst.port().toLong()); - } - } - }); - } - - private void send(int port, OutboundPacket packet) { - - DeviceId deviceId = handler().data().deviceId(); - - Bmv2Controller controller; - try { - controller = handler().get(Bmv2Controller.class); - } catch (ServiceNotFoundException e) { - log.warn(e.getMessage()); - return; - } - - Bmv2DeviceAgent deviceAgent; - try { - deviceAgent = controller.getAgent(deviceId); - } catch (Bmv2RuntimeException e) { - log.error("Failed to get Bmv2 device agent for {}: {}", deviceId, e.explain()); - return; - } - - ImmutableByteSequence bs = ImmutableByteSequence.copyFrom(packet.data()); - try { - deviceAgent.transmitPacket(port, bs); - } catch (Bmv2RuntimeException e) { - log.warn("Unable to emit packet trough {}: {}", deviceId, e.explain()); - } - } -} diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2Pipeliner.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2Pipeliner.java deleted file mode 100644 index 1ce30bdec7..0000000000 --- a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2Pipeliner.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.drivers.bmv2; - -import org.onosproject.driver.pipeline.DefaultSingleTablePipeline; -import org.onosproject.net.DeviceId; -import org.onosproject.net.behaviour.NextGroup; -import org.onosproject.net.behaviour.Pipeliner; -import org.onosproject.net.behaviour.PipelinerContext; -import org.onosproject.net.driver.AbstractHandlerBehaviour; -import org.onosproject.net.flowobjective.FilteringObjective; -import org.onosproject.net.flowobjective.ForwardingObjective; -import org.onosproject.net.flowobjective.NextObjective; - -import java.util.List; - -/** - * Pipeliner device behaviour implementation for BMv2. - */ -public class Bmv2Pipeliner extends AbstractHandlerBehaviour implements Pipeliner { - - private Pipeliner pipeliner; - - @Override - public void init(DeviceId deviceId, PipelinerContext context) { - // TODO: get multi-table pipeliner dynamically based on BMv2 device running model (hard). - // Right now we are able to map flow objectives only in the first table of the pipeline. - pipeliner = new DefaultSingleTablePipeline(); - pipeliner.init(deviceId, context); - } - - @Override - public void filter(FilteringObjective filterObjective) { - pipeliner.filter(filterObjective); - } - - @Override - public void forward(ForwardingObjective forwardObjective) { - pipeliner.forward(forwardObjective); - } - - @Override - public void next(NextObjective nextObjective) { - pipeliner.next(nextObjective); - } - - @Override - public List getNextMappings(NextGroup nextGroup) { - return pipeliner.getNextMappings(nextGroup); - } -} diff --git a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/package-info.java b/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/package-info.java deleted file mode 100644 index f56998cdb1..0000000000 --- a/drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * BMv2 driver implementation. - */ -package org.onosproject.drivers.bmv2; \ No newline at end of file diff --git a/drivers/bmv2/src/main/resources/bmv2-drivers.xml b/drivers/bmv2/src/main/resources/bmv2-drivers.xml deleted file mode 100644 index fd0912ccce..0000000000 --- a/drivers/bmv2/src/main/resources/bmv2-drivers.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - diff --git a/drivers/pom.xml b/drivers/pom.xml index aafcc0492a..99016d918f 100644 --- a/drivers/pom.xml +++ b/drivers/pom.xml @@ -41,7 +41,6 @@ lumentum - bmv2 corsa optical arista diff --git a/protocols/bmv2/api/pom.xml b/protocols/bmv2/api/pom.xml deleted file mode 100644 index c3bd01e88b..0000000000 --- a/protocols/bmv2/api/pom.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - onos-bmv2-protocol - org.onosproject - 1.11.0-SNAPSHOT - - 4.0.0 - - bundle - - onos-bmv2-protocol-api - - - - org.onosproject - onos-api - - - org.apache.felix - org.apache.felix.scr.annotations - - - org.onosproject - onos-core-serializers - ${project.version} - - - - \ No newline at end of file diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2ActionModel.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2ActionModel.java deleted file mode 100644 index ea70b658ca..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2ActionModel.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.context; - -import com.google.common.annotations.Beta; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Maps; - -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; - -/** - * A BMv2 action model. - */ -@Beta -public final class Bmv2ActionModel { - - private final String name; - private final int id; - private final LinkedHashMap runtimeDatas = Maps.newLinkedHashMap(); - - /** - * Creates a new action model. - * - * @param name name - * @param id id - * @param runtimeDatas list of runtime data - */ - protected Bmv2ActionModel(String name, int id, List runtimeDatas) { - this.name = name; - this.id = id; - runtimeDatas.forEach(r -> this.runtimeDatas.put(r.name(), r)); - } - - /** - * Returns the name of this action. - * - * @return a string value - */ - public String name() { - return name; - } - - /** - * Returns the id of this action. - * - * @return an integer value - */ - public int id() { - return id; - } - - /** - * Returns this action's runtime data defined by the given name, null - * if not present. - * - * @return runtime data or null - */ - public Bmv2RuntimeDataModel runtimeData(String name) { - return runtimeDatas.get(name); - } - - /** - * Returns an immutable list of runtime data for this action. - * The list is ordered according to the values defined in the configuration. - * - * @return list of runtime data. - */ - public List runtimeDatas() { - return ImmutableList.copyOf(runtimeDatas.values()); - } - - @Override - public int hashCode() { - return Objects.hash(name, id, runtimeDatas); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2ActionModel other = (Bmv2ActionModel) obj; - return Objects.equals(this.name, other.name) - && Objects.equals(this.id, other.id) - && Objects.equals(this.runtimeDatas, other.runtimeDatas); - } - - @Override - public String toString() { - return toStringHelper(this) - .add("name", name) - .add("id", id) - .add("runtimeDatas", runtimeDatas) - .toString(); - } - -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2Configuration.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2Configuration.java deleted file mode 100644 index 1cbb146b71..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2Configuration.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.context; - -import com.eclipsesource.json.JsonObject; -import com.google.common.annotations.Beta; - -import java.util.List; - -/** - * BMv2 packet processing configuration. Such a configuration is used to define the way BMv2 should process packets - * (i.e. it defines the device ingress/egress pipelines, parser, tables, actions, etc.). It must be noted that this - * class exposes only a subset of the configuration properties of a BMv2 device (only those that are needed for the - * purpose of translating ONOS structures to BMv2 structures). Such a configuration is backed by a JSON object. - * BMv2 JSON configuration files are usually generated using a P4 frontend compiler such as p4c-bmv2. - */ -@Beta -public interface Bmv2Configuration { - - /** - * Return an unmodifiable view of the JSON backing this configuration. - * - * @return a JSON object. - */ - JsonObject json(); - - /** - * Returns the header type associated with the given numeric ID, null if there's no such an ID in the configuration. - * - * @param id integer value - * @return header type object or null - */ - Bmv2HeaderTypeModel headerType(int id); - - /** - * Returns the header type associated with the given name, null if there's no such a name in the configuration. - * - * @param name string value - * @return header type object or null - */ - Bmv2HeaderTypeModel headerType(String name); - - /** - * Returns the list of all the header types defined by in this configuration. Values returned are sorted in - * ascending order based on the numeric ID. - * - * @return list of header types - */ - List headerTypes(); - - /** - * Returns the header associated with the given numeric ID, null if there's no such an ID in the configuration. - * - * @param id integer value - * @return header object or null - */ - Bmv2HeaderModel header(int id); - - /** - * Returns the header associated with the given name, null if there's no such a name in the configuration. - * - * @param name string value - * @return header object or null - */ - Bmv2HeaderModel header(String name); - - /** - * Returns the list of all the header instances defined in this configuration. Values returned are sorted in - * ascending order based on the numeric ID. - * - * @return list of header types - */ - List headers(); - - /** - * Returns the action associated with the given numeric ID, null if there's no such an ID in the configuration. - * - * @param id integer value - * @return action object or null - */ - Bmv2ActionModel action(int id); - - /** - * Returns the action associated with the given name, null if there's no such a name in the configuration. - * - * @param name string value - * @return action object or null - */ - Bmv2ActionModel action(String name); - - /** - * Returns the list of all the actions defined by in this configuration. Values returned are sorted in ascending - * order based on the numeric ID. - * - * @return list of actions - */ - List actions(); - - /** - * Returns the table associated with the given numeric ID, null if there's no such an ID in the configuration. - * - * @param id integer value - * @return table object or null - */ - Bmv2TableModel table(int id); - - /** - * Returns the table associated with the given name, null if there's no such a name in the configuration. - * - * @param name string value - * @return table object or null - */ - Bmv2TableModel table(String name); - - /** - * Returns the list of all the tables defined by in this configuration. Values returned are sorted in ascending - * order based on the numeric ID. - * - * @return list of actions - */ - List tables(); -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2DefaultConfiguration.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2DefaultConfiguration.java deleted file mode 100644 index f047306476..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2DefaultConfiguration.java +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.context; - -import com.eclipsesource.json.JsonArray; -import com.eclipsesource.json.JsonObject; -import com.google.common.annotations.Beta; -import com.google.common.base.MoreObjects; -import com.google.common.base.Objects; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import org.onosproject.bmv2.api.runtime.Bmv2MatchParam; - -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; - -import static com.google.common.base.Preconditions.checkArgument; - -/** - * Default implementation of a BMv2 configuration backed by a JSON object. - */ -@Beta -public final class Bmv2DefaultConfiguration implements Bmv2Configuration { - - private final JsonObject json; - private final DualKeySortedMap headerTypes = new DualKeySortedMap<>(); - private final DualKeySortedMap headers = new DualKeySortedMap<>(); - private final DualKeySortedMap actions = new DualKeySortedMap<>(); - private final DualKeySortedMap tables = new DualKeySortedMap<>(); - - private Bmv2DefaultConfiguration(JsonObject json) { - this.json = JsonObject.unmodifiableObject(json); - } - - /** - * Returns a new BMv2 configuration object by parsing the passed JSON. - * - * @param json json - * @return a new BMv2 configuration object - * @see - * BMv2 JSON specification - */ - public static Bmv2DefaultConfiguration parse(JsonObject json) { - checkArgument(json != null, "json cannot be null"); - // TODO: implement caching, no need to parse a json if we already have the configuration - Bmv2DefaultConfiguration configuration = new Bmv2DefaultConfiguration(json); - configuration.doParse(); - return configuration; - } - - @Override - public Bmv2HeaderTypeModel headerType(int id) { - return headerTypes.get(id); - } - - @Override - public Bmv2HeaderTypeModel headerType(String name) { - return headerTypes.get(name); - } - - @Override - public List headerTypes() { - return ImmutableList.copyOf(headerTypes.sortedMap().values()); - } - - @Override - public Bmv2HeaderModel header(int id) { - return headers.get(id); - } - - @Override - public Bmv2HeaderModel header(String name) { - return headers.get(name); - } - - @Override - public List headers() { - return ImmutableList.copyOf(headers.sortedMap().values()); - } - - @Override - public Bmv2ActionModel action(int id) { - return actions.get(id); - } - - @Override - public Bmv2ActionModel action(String name) { - return actions.get(name); - } - - @Override - public List actions() { - return ImmutableList.copyOf(actions.sortedMap().values()); - } - - @Override - public Bmv2TableModel table(int id) { - return tables.get(id); - } - - @Override - public Bmv2TableModel table(String name) { - return tables.get(name); - } - - @Override - public List tables() { - return ImmutableList.copyOf(tables.sortedMap().values()); - } - - @Override - public JsonObject json() { - return this.json; - } - - /** - * Generates a hash code for this BMv2 configuration. The hash function is based solely on the JSON backing this - * configuration. - */ - @Override - public int hashCode() { - return json.hashCode(); - } - - /** - * Indicates whether some other BMv2 configuration is equal to this one. - * Equality is based solely on the low-level JSON representation. - * - * @param obj other object - * @return true if equals, false elsewhere - */ - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2DefaultConfiguration other = (Bmv2DefaultConfiguration) obj; - return Objects.equal(this.json, other.json); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("jsonHash", json.hashCode()) - .toString(); - } - - /** - * Parse the JSON object and build the corresponding objects. - */ - private void doParse() { - // parse header types - json.get("header_types").asArray().forEach(val -> { - - JsonObject jHeaderType = val.asObject(); - - // populate fields list - List fieldTypes = Lists.newArrayList(); - - jHeaderType.get("fields").asArray().forEach(x -> fieldTypes.add( - new Bmv2FieldTypeModel( - x.asArray().get(0).asString(), - x.asArray().get(1).asInt()))); - - // add header type instance - String name = jHeaderType.get("name").asString(); - int id = jHeaderType.get("id").asInt(); - - Bmv2HeaderTypeModel headerType = new Bmv2HeaderTypeModel(name, - id, - fieldTypes); - - headerTypes.put(name, id, headerType); - }); - - // parse headers - json.get("headers").asArray().forEach(val -> { - - JsonObject jHeader = val.asObject(); - - String name = jHeader.get("name").asString(); - int id = jHeader.get("id").asInt(); - String typeName = jHeader.get("header_type").asString(); - - Bmv2HeaderModel header = new Bmv2HeaderModel(name, - id, - headerTypes.get(typeName), - jHeader.get("metadata").asBoolean()); - - // add instance - headers.put(name, id, header); - }); - - // parse actions - json.get("actions").asArray().forEach(val -> { - - JsonObject jAction = val.asObject(); - - // populate runtime data list - List runtimeDatas = Lists.newArrayList(); - - jAction.get("runtime_data").asArray().forEach(jData -> runtimeDatas.add( - new Bmv2RuntimeDataModel( - jData.asObject().get("name").asString(), - jData.asObject().get("bitwidth").asInt() - ))); - - // add action instance - String name = jAction.get("name").asString(); - int id = jAction.get("id").asInt(); - - Bmv2ActionModel action = new Bmv2ActionModel(name, - id, - runtimeDatas); - - actions.put(name, id, action); - }); - - // parse tables - json.get("pipelines").asArray().forEach(pipeline -> { - - pipeline.asObject().get("tables").asArray().forEach(val -> { - - JsonObject jTable = val.asObject(); - - // populate keys - List keys = Lists.newArrayList(); - - jTable.get("key").asArray().forEach(jKey -> { - JsonArray target = jKey.asObject().get("target").asArray(); - - Bmv2HeaderModel header = header(target.get(0).asString()); - String typeName = target.get(1).asString(); - - Bmv2FieldModel field = new Bmv2FieldModel( - header, header.type().field(typeName)); - - String matchTypeStr = jKey.asObject().get("match_type").asString(); - - Bmv2MatchParam.Type matchType; - - switch (matchTypeStr) { - case "ternary": - matchType = Bmv2MatchParam.Type.TERNARY; - break; - case "exact": - matchType = Bmv2MatchParam.Type.EXACT; - break; - case "lpm": - matchType = Bmv2MatchParam.Type.LPM; - break; - case "valid": - matchType = Bmv2MatchParam.Type.VALID; - break; - default: - throw new RuntimeException( - "Unable to parse match type: " + matchTypeStr); - } - - keys.add(new Bmv2TableKeyModel(matchType, field)); - }); - - // populate actions set - Set actionzz = Sets.newHashSet(); - jTable.get("actions").asArray().forEach( - jAction -> actionzz.add(action(jAction.asString()))); - - // add table instance - String name = jTable.get("name").asString(); - int id = jTable.get("id").asInt(); - - Bmv2TableModel table = new Bmv2TableModel(name, - id, - jTable.get("match_type").asString(), - jTable.get("type").asString(), - jTable.get("max_size").asInt(), - jTable.get("with_counters").asBoolean(), - jTable.get("support_timeout").asBoolean(), - keys, - actionzz); - - tables.put(name, id, table); - }); - }); - } - - /** - * Handy class for a map indexed by two keys, a string and an integer. - * - * @param type of value stored by the map - */ - private class DualKeySortedMap { - private final SortedMap intMap = Maps.newTreeMap(); - private final Map strToIntMap = Maps.newHashMap(); - - private void put(String name, int id, T object) { - strToIntMap.put(name, id); - intMap.put(id, object); - } - - private T get(int id) { - return intMap.get(id); - } - - private T get(String name) { - return strToIntMap.get(name) == null ? null : get(strToIntMap.get(name)); - } - - private SortedMap sortedMap() { - return intMap; - } - - @Override - public int hashCode() { - return Objects.hashCode(intMap, strToIntMap); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final DualKeySortedMap other = (DualKeySortedMap) obj; - return Objects.equal(this.intMap, other.intMap) - && Objects.equal(this.strToIntMap, other.strToIntMap); - } - } -} \ No newline at end of file diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2DeviceContext.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2DeviceContext.java deleted file mode 100644 index f54cc1d1e6..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2DeviceContext.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.context; - -import com.google.common.annotations.Beta; -import com.google.common.base.MoreObjects; -import com.google.common.base.Objects; - -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * A BMv2 device context, defined by a configuration and an interpreter. - */ -@Beta -public final class Bmv2DeviceContext { - - private final Bmv2Configuration configuration; - private final Bmv2Interpreter interpreter; - - /** - * Creates a new BMv2 device context. - * - * @param configuration a configuration - * @param interpreter an interpreter - */ - public Bmv2DeviceContext(Bmv2Configuration configuration, Bmv2Interpreter interpreter) { - this.configuration = checkNotNull(configuration, "configuration cannot be null"); - this.interpreter = checkNotNull(interpreter, "interpreter cannot be null"); - } - - /** - * Returns the BMv2 configuration of this context. - * - * @return a configuration - */ - public Bmv2Configuration configuration() { - return configuration; - } - - /** - * Returns the BMv2 interpreter of this context. - * - * @return an interpreter - */ - public Bmv2Interpreter interpreter() { - return interpreter; - } - - @Override - public int hashCode() { - return Objects.hashCode(configuration, interpreter); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2DeviceContext other = (Bmv2DeviceContext) obj; - return Objects.equal(this.configuration, other.configuration) - && Objects.equal(this.interpreter, other.interpreter); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("configuration", configuration) - .add("interpreter", interpreter) - .toString(); - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2FieldModel.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2FieldModel.java deleted file mode 100644 index b1b5ce895d..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2FieldModel.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.context; - -import com.google.common.annotations.Beta; -import com.google.common.base.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; - -/** - * A BMv2 header field model. - */ -@Beta -public final class Bmv2FieldModel { - - private final Bmv2HeaderModel header; - private final Bmv2FieldTypeModel type; - - protected Bmv2FieldModel(Bmv2HeaderModel header, Bmv2FieldTypeModel type) { - this.header = header; - this.type = type; - } - - /** - * Returns the header instance of this field instance. - * - * @return a header instance - */ - public Bmv2HeaderModel header() { - return header; - } - - /** - * Returns the type of this field instance. - * - * @return a field type value - */ - public Bmv2FieldTypeModel type() { - return type; - } - - @Override - public int hashCode() { - return Objects.hashCode(header, type); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2FieldModel other = (Bmv2FieldModel) obj; - return Objects.equal(this.header, other.header) - && Objects.equal(this.type, other.type); - } - - @Override - public String toString() { - return toStringHelper(this) - .add("header", header) - .add("type", type) - .toString(); - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2FieldTypeModel.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2FieldTypeModel.java deleted file mode 100644 index 5b944cc3ff..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2FieldTypeModel.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.context; - -import com.google.common.annotations.Beta; -import com.google.common.base.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; - -/** - * A BMv2 header type field model. - */ -@Beta -public final class Bmv2FieldTypeModel { - - private final String name; - private final int bitWidth; - - protected Bmv2FieldTypeModel(String name, int bitWidth) { - this.name = name; - this.bitWidth = bitWidth; - } - - /** - * Returns the name of this header type field. - * - * @return a string value - */ - public String name() { - return name; - } - - /** - * Returns the bit width of this header type field. - * - * @return an integer value - */ - public int bitWidth() { - return bitWidth; - } - - @Override - public int hashCode() { - return Objects.hashCode(name, bitWidth); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2FieldTypeModel other = (Bmv2FieldTypeModel) obj; - return Objects.equal(this.name, other.name) - && Objects.equal(this.bitWidth, other.bitWidth); - } - - @Override - public String toString() { - return toStringHelper(this) - .add("name", name) - .add("bitWidth", bitWidth) - .toString(); - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2FlowRuleTranslator.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2FlowRuleTranslator.java deleted file mode 100644 index bc768d093f..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2FlowRuleTranslator.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.context; - -import com.google.common.annotations.Beta; -import org.onosproject.bmv2.api.runtime.Bmv2TableEntry; -import org.onosproject.net.flow.FlowRule; - -/** - * Translator of ONOS flow rules to BMv2 table entries. - */ -@Beta -public interface Bmv2FlowRuleTranslator { - - /** - * Returns a BMv2 table entry equivalent to the given flow rule for the given context. - *

- * Translation is performed according to the following logic: - *

    - *
  • table name: obtained from the context interpreter {@link Bmv2Interpreter#tableIdMap() table ID map}. - *
  • match key: is built using both the context interpreter {@link Bmv2Interpreter#criterionTypeMap() criterion - * map} and all {@link org.onosproject.bmv2.api.runtime.Bmv2ExtensionSelector extension selectors} (if any). - *
  • action: is built using the context interpreter - * {@link Bmv2Interpreter#mapTreatment(org.onosproject.net.flow.TrafficTreatment, Bmv2Configuration) - * treatment mapping function} or the flow rule - * {@link org.onosproject.bmv2.api.runtime.Bmv2ExtensionTreatment extension treatment} (if any). - *
  • timeout: if the table supports timeout, use the same as the flow rule, otherwise none (i.e. returns a - * permanent entry). - *
- * - * @param rule a flow rule - * @param context a context - * @return a BMv2 table entry - * @throws Bmv2FlowRuleTranslatorException if the flow rule cannot be translated - */ - Bmv2TableEntry translate(FlowRule rule, Bmv2DeviceContext context) throws Bmv2FlowRuleTranslatorException; -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2FlowRuleTranslatorException.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2FlowRuleTranslatorException.java deleted file mode 100644 index 645ac3355b..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2FlowRuleTranslatorException.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.context; - -import com.google.common.annotations.Beta; - -/** - * BMv2 flow rule translator exception. - */ -@Beta -public final class Bmv2FlowRuleTranslatorException extends Exception { - - public Bmv2FlowRuleTranslatorException(String msg) { - super(msg); - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2HeaderModel.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2HeaderModel.java deleted file mode 100644 index 5c1f4ff840..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2HeaderModel.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.context; - -import com.google.common.annotations.Beta; -import com.google.common.base.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; - -/** - * BMv2 header instance model. - */ -@Beta -public final class Bmv2HeaderModel { - - private final String name; - private final int id; - private final Bmv2HeaderTypeModel type; - private final boolean isMetadata; - - /** - * Creates a new header instance model. - * - * @param name name - * @param id id - * @param type header type - * @param metadata if is metadata - */ - protected Bmv2HeaderModel(String name, int id, Bmv2HeaderTypeModel type, boolean metadata) { - this.name = name; - this.id = id; - this.type = type; - this.isMetadata = metadata; - } - - /** - * Returns the name of this header instance. - * - * @return a string value - */ - public String name() { - return name; - } - - /** - * Return the id of this header instance. - * - * @return an integer value - */ - public int id() { - return id; - } - - /** - * Return the type of this header instance. - * - * @return a header type value - */ - public Bmv2HeaderTypeModel type() { - return type; - } - - /** - * Return true if this header instance is a metadata, false elsewhere. - * - * @return a boolean value - */ - public boolean isMetadata() { - return isMetadata; - } - - @Override - public int hashCode() { - return Objects.hashCode(name, id, type, isMetadata); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2HeaderModel other = (Bmv2HeaderModel) obj; - return Objects.equal(this.name, other.name) - && Objects.equal(this.id, other.id) - && Objects.equal(this.type, other.type) - && Objects.equal(this.isMetadata, other.isMetadata); - } - - @Override - public String toString() { - return toStringHelper(this) - .add("name", name) - .add("id", id) - .add("type", type) - .add("isMetadata", isMetadata) - .toString(); - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2HeaderTypeModel.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2HeaderTypeModel.java deleted file mode 100644 index 53503401ca..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2HeaderTypeModel.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.context; - -import com.google.common.annotations.Beta; -import com.google.common.base.Objects; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Maps; - -import java.util.LinkedHashMap; -import java.util.List; - -import static com.google.common.base.MoreObjects.toStringHelper; - -/** - * BMv2 header type model. - */ -@Beta -public final class Bmv2HeaderTypeModel { - - private final String name; - private final int id; - private final LinkedHashMap fields = Maps.newLinkedHashMap(); - - /** - * Creates a new header type model. - * - * @param name name - * @param id id - * @param fieldTypes fields - */ - protected Bmv2HeaderTypeModel(String name, int id, List fieldTypes) { - this.name = name; - this.id = id; - fieldTypes.forEach(f -> this.fields.put(f.name(), f)); - } - - /** - * Returns this header type name. - * - * @return name - */ - public String name() { - return name; - } - - /** - * Returns this header type id. - * - * @return id - */ - public int id() { - return id; - } - - /** - * Returns this header type's field defined by the passed name, null if - * not present. - * - * @param fieldName field name - * @return field or null - */ - public Bmv2FieldTypeModel field(String fieldName) { - return fields.get(fieldName); - } - - /** - * Return and immutable list of header fields for this header - * type. The list is ordered according to the values defined in the - * model. - * - * @return list of fields - */ - public List fields() { - return ImmutableList.copyOf(fields.values()); - } - - @Override - public int hashCode() { - return Objects.hashCode(name, id, fields); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2HeaderTypeModel other = (Bmv2HeaderTypeModel) obj; - return Objects.equal(this.name, other.name) - && Objects.equal(this.id, other.id) - && Objects.equal(this.fields, other.fields); - } - - @Override - public String toString() { - return toStringHelper(this) - .add("name", name) - .add("id", id) - .add("fields", fields) - .toString(); - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2Interpreter.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2Interpreter.java deleted file mode 100644 index 8d44494bc2..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2Interpreter.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.context; - -import com.google.common.annotations.Beta; -import com.google.common.collect.ImmutableBiMap; -import org.onosproject.bmv2.api.runtime.Bmv2Action; -import org.onosproject.net.flow.TrafficTreatment; -import org.onosproject.net.flow.criteria.Criterion; - -/** - * A BMv2 configuration interpreter. - */ -@Beta -public interface Bmv2Interpreter { - - /** - * Returns a bi-map describing a one-to-one relationship between ONOS flow rule table IDs and BMv2 table names. - * - * @return a {@link com.google.common.collect.BiMap} where the key is a ONOS flow rule table id and - * the value is a BMv2 table names - */ - ImmutableBiMap tableIdMap(); - - /** - * Returns a bi-map describing a one-to-one relationship between ONOS criterion types and BMv2 header field names. - * Header field names are formatted using the notation {@code header_name.field_member_name}. - * - * @return a {@link com.google.common.collect.BiMap} where the keys are ONOS criterion types and the values are - * BMv2 header field names - */ - ImmutableBiMap criterionTypeMap(); - - /** - * Return a BMv2 action that is functionally equivalent to the given ONOS traffic treatment for the given - * configuration. - * - * @param treatment a ONOS traffic treatment - * @param configuration a BMv2 configuration - * @return a BMv2 action object - * @throws Bmv2InterpreterException if the treatment cannot be mapped to any BMv2 action - */ - Bmv2Action mapTreatment(TrafficTreatment treatment, Bmv2Configuration configuration) - throws Bmv2InterpreterException; - -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2InterpreterException.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2InterpreterException.java deleted file mode 100644 index 7c143fcfed..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2InterpreterException.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.context; - -import com.google.common.annotations.Beta; - -/** - * A BMv2 interpreter exception. - */ -@Beta -public final class Bmv2InterpreterException extends Exception { - - public Bmv2InterpreterException(String message) { - super(message); - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2RuntimeDataModel.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2RuntimeDataModel.java deleted file mode 100644 index e97d2bbea5..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2RuntimeDataModel.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.context; - -import com.google.common.annotations.Beta; - -import java.util.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; - -/** - * A BMv2 action runtime data model. - */ -@Beta -public final class Bmv2RuntimeDataModel { - - private final String name; - private final int bitWidth; - - /** - * Creates a new runtime data model. - * - * @param name name - * @param bitWidth bitwidth - */ - protected Bmv2RuntimeDataModel(String name, int bitWidth) { - this.name = name; - this.bitWidth = bitWidth; - } - - /** - * Return the name of this runtime data. - * - * @return a string value - */ - public String name() { - return name; - } - - /** - * Return the bit width of this runtime data. - * - * @return an integer value - */ - public int bitWidth() { - return bitWidth; - } - - @Override - public int hashCode() { - return Objects.hash(name, bitWidth); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2RuntimeDataModel other = (Bmv2RuntimeDataModel) obj; - return Objects.equals(this.name, other.name) - && Objects.equals(this.bitWidth, other.bitWidth); - } - - @Override - public String toString() { - return toStringHelper(this) - .add("name", name) - .add("bitWidth", bitWidth) - .toString(); - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2TableKeyModel.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2TableKeyModel.java deleted file mode 100644 index 8f2f0222cd..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2TableKeyModel.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.context; - -import com.google.common.annotations.Beta; -import com.google.common.base.Objects; -import org.onosproject.bmv2.api.runtime.Bmv2MatchParam; - -import static com.google.common.base.MoreObjects.toStringHelper; - -/** - * A BMv2 table key model. - */ -@Beta -public final class Bmv2TableKeyModel { - - private final Bmv2MatchParam.Type matchType; - private final Bmv2FieldModel field; - - /** - * Creates a new table key model. - * - * @param matchType match type - * @param field field instance - */ - protected Bmv2TableKeyModel(Bmv2MatchParam.Type matchType, Bmv2FieldModel field) { - this.matchType = matchType; - this.field = field; - } - - /** - * Returns the match type of this key. - * - * @return a string value - * TODO returns enum of match type - */ - public Bmv2MatchParam.Type matchType() { - return matchType; - } - - /** - * Returns the header field instance matched by this key. - * - * @return a header field value - */ - public Bmv2FieldModel field() { - return field; - } - - @Override - public int hashCode() { - return Objects.hashCode(matchType, field); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2TableKeyModel other = (Bmv2TableKeyModel) obj; - return Objects.equal(this.matchType, other.matchType) - && Objects.equal(this.field, other.field); - } - - @Override - public String toString() { - return toStringHelper(this) - .add("matchType", matchType) - .add("field", field) - .toString(); - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2TableModel.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2TableModel.java deleted file mode 100644 index 8f6fa55c4e..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/Bmv2TableModel.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.context; - -import com.google.common.annotations.Beta; -import com.google.common.base.Objects; - -import java.util.List; -import java.util.Set; - -import static com.google.common.base.MoreObjects.toStringHelper; - -/** - * A BMv2 table model. - */ -@Beta -public final class Bmv2TableModel { - - private final String name; - private final int id; - private final String matchType; - private final String type; - private final int maxSize; - private final boolean hasCounters; - private final boolean hasTimeouts; - private final List keys; - private final Set actions; - - /** - * Creates a new table model. - * - * @param name name - * @param id id - * @param matchType match type - * @param type type - * @param maxSize max number of entries - * @param withCounters if table has counters - * @param supportTimeout if table supports aging - * @param keys list of match keys - * @param actions list of actions - */ - protected Bmv2TableModel(String name, int id, String matchType, String type, - int maxSize, boolean withCounters, boolean supportTimeout, - List keys, Set actions) { - this.name = name; - this.id = id; - this.matchType = matchType; - this.type = type; - this.maxSize = maxSize; - this.hasCounters = withCounters; - this.hasTimeouts = supportTimeout; - this.keys = keys; - this.actions = actions; - } - - /** - * Returns the name of this table. - * - * @return a string value - */ - public String name() { - return name; - } - - /** - * Returns the id of this table. - * - * @return an integer value - */ - public int id() { - return id; - } - - /** - * Return the match type of this table. - * - * @return a string value - */ - public String matchType() { - return matchType; - } - - /** - * Return the match type of this table. - * - * @return a string value - */ - public String type() { - return type; - } - - /** - * Returns the maximum number of entries supported by this table. - * - * @return an integer value - */ - public int maxSize() { - return maxSize; - } - - /** - * Returns true if this table has counters, false otherwise. - * - * @return a boolean value - */ - public boolean hasCounters() { - return hasCounters; - } - - /** - * Returns true if this table supports aging, false otherwise. - * - * @return a boolean value - */ - public boolean hasTimeouts() { - return hasTimeouts; - } - - /** - * Returns the list of match keys supported by this table. - * The list is ordered accordingly to the model's table definition. - * - * @return a list of match keys - */ - public List keys() { - return keys; - } - - /** - * Returns the set of actions supported by this table. - * - * @return a list of actions - */ - public Set actions() { - return actions; - } - - @Override - public int hashCode() { - return Objects.hashCode(name, id, matchType, type, maxSize, hasCounters, - hasTimeouts, keys, actions); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2TableModel other = (Bmv2TableModel) obj; - return Objects.equal(this.name, other.name) - && Objects.equal(this.id, other.id) - && Objects.equal(this.matchType, other.matchType) - && Objects.equal(this.type, other.type) - && Objects.equal(this.maxSize, other.maxSize) - && Objects.equal(this.hasCounters, other.hasCounters) - && Objects.equal(this.hasTimeouts, other.hasTimeouts) - && Objects.equal(this.keys, other.keys) - && Objects.equal(this.actions, other.actions); - } - - @Override - public String toString() { - return toStringHelper(this) - .add("name", name) - .add("id", id) - .add("matchType", matchType) - .add("type", type) - .add("maxSize", maxSize) - .add("hasCounters", hasCounters) - .add("hasTimeouts", hasTimeouts) - .add("keys", keys) - .add("actions", actions) - .toString(); - } - -} \ No newline at end of file diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/package-info.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/package-info.java deleted file mode 100644 index 7489aa4cf7..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/context/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * BMv2 device context API. - */ -package org.onosproject.bmv2.api.context; \ No newline at end of file diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/package-info.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/package-info.java deleted file mode 100644 index ce6d5216d5..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * BMv2 protocol API. - */ -package org.onosproject.bmv2.api; \ No newline at end of file diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2Action.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2Action.java deleted file mode 100644 index a9d3ed8fd4..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2Action.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.runtime; - -import com.google.common.annotations.Beta; -import com.google.common.base.MoreObjects; -import com.google.common.collect.Lists; -import org.onlab.util.ImmutableByteSequence; - -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -/** - * An action of a BMv2 match-action table entry. - */ -@Beta -public final class Bmv2Action { - - private final String name; - private final List parameters; - - protected Bmv2Action(String name, List parameters) { - // hide constructor - this.name = name; - this.parameters = parameters; - } - - /** - * Returns a new action builder. - */ - public static Builder builder() { - return new Builder(); - } - - /** - * Return the name of this action. - * - * @return action name - */ - public final String name() { - return name; - } - - /** - * Returns an immutable view of the list of parameters of this action. - * - * @return list of byte sequence - */ - public final List parameters() { - return Collections.unmodifiableList(parameters); - } - - @Override - public final int hashCode() { - return Objects.hash(name, parameters); - } - - @Override - public final boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2Action other = (Bmv2Action) obj; - return Objects.equals(this.name, other.name) - && Objects.equals(this.parameters, other.parameters); - } - - @Override - public final String toString() { - return MoreObjects.toStringHelper(this) - .add("name", name) - .add("parameters", parameters) - .toString(); - } - - /** - * A BMv2 action builder. - */ - public static final class Builder { - - private String name = null; - private List parameters; - - private Builder() { - this.parameters = Lists.newArrayList(); - } - - /** - * Sets the action name. - * - * @param actionName a string value - * @return this - */ - public Builder withName(String actionName) { - this.name = checkNotNull(actionName); - return this; - } - - /** - * Adds a parameter at the end of the parameters list. - * - * @param parameter a ByteBuffer value - * @return this - */ - public Builder addParameter(ImmutableByteSequence parameter) { - parameters.add(checkNotNull(parameter)); - return this; - } - - /** - * Builds a BMv2 action object. - * - * @return a BMv2 action - */ - public Bmv2Action build() { - checkState(name != null, "action name not set"); - return new Bmv2Action(name, parameters); - } - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2Device.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2Device.java deleted file mode 100644 index c3efce3a36..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2Device.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.runtime; - -import com.google.common.annotations.Beta; -import com.google.common.base.Objects; -import org.onosproject.net.DeviceId; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * A BMv2 device. - */ -@Beta -public final class Bmv2Device { - - public static final String N_A = "n/a"; - - public static final String SCHEME = "bmv2"; - public static final String PROTOCOL = "bmv2-thrift"; - public static final String MANUFACTURER = "p4.org"; - public static final String HW_VERSION = "bmv2"; - public static final String SW_VERSION = "1.0.0"; - public static final String SERIAL_NUMBER = N_A; - - private final String thriftServerHost; - private final int thriftServerPort; - private final int internalDeviceId; - - /** - * Creates a new BMv2 device object. - * - * @param thriftServerHost the hostname or IP address of the Thrift RPC server running on the device - * @param thriftServerPort the listening port used by the device Thrift RPC server - * @param internalDeviceId the internal numeric device ID - */ - public Bmv2Device(String thriftServerHost, int thriftServerPort, int internalDeviceId) { - this.thriftServerHost = checkNotNull(thriftServerHost, "host cannot be null"); - this.thriftServerPort = checkNotNull(thriftServerPort, "port cannot be null"); - this.internalDeviceId = internalDeviceId; - } - - /** - * Returns a Bmv2Device representing the given deviceId. - * - * @param deviceId a deviceId - * @return - */ - public static Bmv2Device of(DeviceId deviceId) { - return DeviceIdParser.parse(checkNotNull(deviceId, "deviceId cannot be null")); - } - - /** - * Returns the hostname or IP address of the Thrift RPC server running on the device. - * - * @return a string value - */ - public String thriftServerHost() { - return thriftServerHost; - } - - /** - * Returns the listening port of the Thrift RPC server running on the device. - * - * @return an integer value - */ - public int thriftServerPort() { - return thriftServerPort; - } - - /** - * Returns the BMv2-internal device ID, which is an integer arbitrary chosen at device boot. - * Such an ID must not be confused with the ONOS-internal {@link org.onosproject.net.DeviceId}. - * - * @return an integer value - */ - public int internalDeviceId() { - return internalDeviceId; - } - - /** - * Returns a new ONOS device ID for this device. - * - * @return a new device ID - */ - public DeviceId asDeviceId() { - try { - return DeviceId.deviceId(new URI(SCHEME, this.thriftServerHost + ":" + this.thriftServerPort, - String.valueOf(this.internalDeviceId))); - } catch (URISyntaxException e) { - throw new IllegalArgumentException("Unable to build deviceID for device " + this.toString(), e); - } - } - - @Override - public int hashCode() { - return Objects.hashCode(thriftServerHost, thriftServerPort, internalDeviceId); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2Device other = (Bmv2Device) obj; - return Objects.equal(this.thriftServerHost, other.thriftServerHost) - && Objects.equal(this.thriftServerPort, other.thriftServerPort) - && Objects.equal(this.internalDeviceId, other.internalDeviceId); - } - - @Override - public String toString() { - return asDeviceId().toString(); - } - - private static class DeviceIdParser { - - private static final Pattern REGEX = Pattern.compile(SCHEME + ":(.+):(\\d+)#(\\d+)"); - - public static Bmv2Device parse(DeviceId deviceId) { - Matcher matcher = REGEX.matcher(deviceId.toString()); - if (matcher.find()) { - String host = matcher.group(1); - int port = Integer.valueOf(matcher.group(2)); - int internalDeviceId = Integer.valueOf(matcher.group(3)); - return new Bmv2Device(host, port, internalDeviceId); - } else { - throw new RuntimeException("Unable to parse bmv2 device id string: " + deviceId.toString()); - } - } - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2DeviceAgent.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2DeviceAgent.java deleted file mode 100644 index c128aebbed..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2DeviceAgent.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.runtime; - -import com.google.common.annotations.Beta; -import org.apache.commons.lang3.tuple.Pair; -import org.onlab.util.ImmutableByteSequence; -import org.onosproject.net.DeviceId; - -import java.util.Collection; -import java.util.List; - -/** - * An agent to control a BMv2 device. - */ -@Beta -public interface Bmv2DeviceAgent { - - /** - * Returns the device ID of this agent. - * - * @return a device id - */ - DeviceId deviceId(); - - /** - * Pings the device, returns true if the device is reachable, false otherwise. - * - * @return true if reachable, false otherwise - */ - boolean ping(); - - /** - * Adds a new table entry. If successful returns a table-specific identifier of the installed entry. - * - * @param entry a table entry - * @return a long value - * @throws Bmv2RuntimeException if any error occurs - */ - long addTableEntry(Bmv2TableEntry entry) throws Bmv2RuntimeException; - - /** - * Modifies an existing entry at by updating its action. - * - * @param tableName a string value - * @param entryId a long value - * @param action an action - * @throws Bmv2RuntimeException if any error occurs - */ - void modifyTableEntry(String tableName, long entryId, Bmv2Action action) throws Bmv2RuntimeException; - - /** - * Deletes currently installed entry. - * - * @param tableName a string value - * @param entryId a long value - * @throws Bmv2RuntimeException if any error occurs - */ - void deleteTableEntry(String tableName, long entryId) throws Bmv2RuntimeException; - - /** - * Sets a default action for the given table. - * - * @param tableName a string value - * @param action an action value - * @throws Bmv2RuntimeException if any error occurs - */ - void setTableDefaultAction(String tableName, Bmv2Action action) throws Bmv2RuntimeException; - - /** - * Returns information on the ports currently configured in the switch. - * - * @return collection of port information - * @throws Bmv2RuntimeException if any error occurs - */ - Collection getPortsInfo() throws Bmv2RuntimeException; - - /** - * Returns a list of table entries installed in the given table. - * - * @param tableName a string value - * @return a list of parsed table entries - * @throws Bmv2RuntimeException if any error occurs - */ - List getTableEntries(String tableName) throws Bmv2RuntimeException; - - /** - * Requests the device to transmit a given packet over the given port. - * - * @param portNumber a port number - * @param packet a byte sequence - * @throws Bmv2RuntimeException - */ - void transmitPacket(int portNumber, ImmutableByteSequence packet) throws Bmv2RuntimeException; - - /** - * Resets the state of the switch. - * - * @throws Bmv2RuntimeException if any error occurs - */ - void resetState() throws Bmv2RuntimeException; - - /** - * Returns the JSON configuration currently used to process packets. - * - * @return a JSON-formatted string value - * @throws Bmv2RuntimeException if any error occurs - */ - String dumpJsonConfig() throws Bmv2RuntimeException; - - /** - * Returns the MD5 sum of the JSON-formatted configuration currently used to process packets. - * - * @return a string value - * @throws Bmv2RuntimeException if any error occurs - */ - String getJsonConfigMd5() throws Bmv2RuntimeException; - - /** - * Returns the counter values for a given table and entry. - * - * @param tableName a table name - * @param entryId an entry id - * @return a pair of long values, where the left value is the number of bytes and the right the number of packets - * @throws Bmv2RuntimeException if any error occurs - */ - Pair readTableEntryCounter(String tableName, long entryId) throws Bmv2RuntimeException; - - /** - * Returns the values of a given counter instance. - * - * @param counterName a counter name - * @param index an integer value - * @return a pair of long values, where the left value is the number of bytes and the right value is the number of - * packets - * @throws Bmv2RuntimeException if any error occurs - */ - Pair readCounter(String counterName, int index) throws Bmv2RuntimeException; - - /** - * Returns the ID of the current BMv2 process instance (used to distinguish between different executions of the - * same BMv2 device). - * - * @return an integer value - * @throws Bmv2RuntimeException if any error occurs - */ - int getProcessInstanceId() throws Bmv2RuntimeException; - - /** - * Uploads a new JSON configuration on the device. - * - * @param jsonString a string value - * @throws Bmv2RuntimeException if any error occurs - */ - void uploadNewJsonConfig(String jsonString) throws Bmv2RuntimeException; - - /** - * Triggers a configuration swap on the device. - * - * @throws Bmv2RuntimeException - */ - void swapJsonConfig() throws Bmv2RuntimeException; -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExactMatchParam.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExactMatchParam.java deleted file mode 100644 index 5b55d284a8..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExactMatchParam.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.runtime; - -import com.google.common.annotations.Beta; -import com.google.common.base.MoreObjects; -import com.google.common.base.Objects; -import org.onlab.util.ImmutableByteSequence; - -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * A BMv2 exact match parameter. - */ -@Beta -public final class Bmv2ExactMatchParam implements Bmv2MatchParam { - - private final ImmutableByteSequence value; - - /** - * Creates a new match parameter object that matches exactly on the - * given byte sequence. - * - * @param value a byte sequence value - */ - public Bmv2ExactMatchParam(ImmutableByteSequence value) { - this.value = checkNotNull(value, "value cannot be null"); - } - - @Override - public Type type() { - return Type.EXACT; - } - - /** - * Return the byte sequence matched by this parameter. - * - * @return an immutable byte buffer value - */ - public ImmutableByteSequence value() { - return this.value; - } - - @Override - public int hashCode() { - return Objects.hashCode(value); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2ExactMatchParam other = (Bmv2ExactMatchParam) obj; - return Objects.equal(this.value, other.value); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("value", value) - .toString(); - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExtensionSelector.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExtensionSelector.java deleted file mode 100644 index 1e357c4e1d..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExtensionSelector.java +++ /dev/null @@ -1,475 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.runtime; - -import com.google.common.annotations.Beta; -import com.google.common.base.MoreObjects; -import com.google.common.base.Objects; -import com.google.common.collect.Maps; -import org.apache.commons.lang3.tuple.Pair; -import org.onlab.util.KryoNamespace; -import org.onosproject.bmv2.api.context.Bmv2Configuration; -import org.onosproject.bmv2.api.context.Bmv2FieldTypeModel; -import org.onosproject.bmv2.api.context.Bmv2HeaderModel; -import org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils; -import org.onosproject.net.flow.AbstractExtension; -import org.onosproject.net.flow.criteria.ExtensionSelector; -import org.onosproject.net.flow.criteria.ExtensionSelectorType; -import org.onosproject.store.serializers.KryoNamespaces; - -import java.nio.ByteBuffer; -import java.util.Collections; -import java.util.Map; - -import static com.google.common.base.Preconditions.*; -import static org.onlab.util.ImmutableByteSequence.copyFrom; -import static org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils.fitByteSequence; - -/** - * Extension selector for BMv2 used as a wrapper for multiple BMv2 match parameters. Match parameters are - * encoded using a map where the keys are expected to be field names formatted as {@code headerName.fieldName} - * (e.g. {@code ethernet.dstAddr}). - */ -@Beta -public final class Bmv2ExtensionSelector extends AbstractExtension implements ExtensionSelector { - - private static final KryoNamespace APP_KRYO = new KryoNamespace.Builder() - .register(KryoNamespaces.API) - .register(Bmv2ExactMatchParam.class) - .register(Bmv2TernaryMatchParam.class) - .register(Bmv2LpmMatchParam.class) - .register(Bmv2ValidMatchParam.class) - .build(); - - private Map parameterMap; - - /** - * Creates a new BMv2 extension selector for the given match parameters map. - * - * @param paramMap a map - */ - private Bmv2ExtensionSelector(Map paramMap) { - this.parameterMap = paramMap; - } - - /** - * Returns the match parameters map of this selector. - * - * @return a match parameter map - */ - public Map parameterMap() { - return parameterMap; - } - - - @Override - public ExtensionSelectorType type() { - return ExtensionSelectorType.ExtensionSelectorTypes.BMV2_MATCH_PARAMS.type(); - } - - @Override - public byte[] serialize() { - return APP_KRYO.serialize(parameterMap); - } - - @Override - public void deserialize(byte[] data) { - this.parameterMap = APP_KRYO.deserialize(data); - } - - @Override - public int hashCode() { - return Objects.hashCode(parameterMap); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2ExtensionSelector other = (Bmv2ExtensionSelector) obj; - return Objects.equal(this.parameterMap, other.parameterMap); - } - - @Override - public String toString() { - MoreObjects.ToStringHelper helper = MoreObjects.toStringHelper(this); - parameterMap.forEach((name, param) -> { - switch (param.type()) { - case EXACT: - Bmv2ExactMatchParam e = (Bmv2ExactMatchParam) param; - helper.add(name, e.value()); - break; - case TERNARY: - Bmv2TernaryMatchParam t = (Bmv2TernaryMatchParam) param; - helper.add(name, t.value() + "&&&" + t.mask()); - break; - case LPM: - Bmv2LpmMatchParam l = (Bmv2LpmMatchParam) param; - helper.add(name, l.value() + "/" + String.valueOf(l.prefixLength())); - break; - case VALID: - Bmv2ValidMatchParam v = (Bmv2ValidMatchParam) param; - helper.add(name, v.flag() ? "VALID" : "NOT_VALID"); - break; - default: - helper.add(name, param); - break; - } - }); - return helper.toString(); - } - - /** - * Returns a new, empty BMv2 extension selector. - * - * @return a BMv2 extension treatment - */ - public static Bmv2ExtensionSelector empty() { - return new Bmv2ExtensionSelector(Collections.emptyMap()); - } - - /** - * Returns a new builder of BMv2 extension selectors. - * - * @return a builder - */ - public static Builder builder() { - return new Builder(); - } - - /** - * Builder of BMv2 extension selectors. - *

- * Match parameters are built from primitive data types ({@code short}, {@code int}, {@code long} or - * {@code byte[]}) and automatically casted to fixed-length byte sequences according to the given BMv2 - * configuration. - */ - public static final class Builder { - - private final Map, Bmv2MatchParam> parameterMap = Maps.newHashMap(); - private Bmv2Configuration configuration; - - private Builder() { - // ban constructor. - } - - /** - * Sets the BMv2 configuration to format the match parameters of the selector. - * - * @param config a BMv2 configuration - * @return this - */ - public Builder forConfiguration(Bmv2Configuration config) { - this.configuration = config; - return this; - } - - /** - * Adds an exact match parameter for the given header field and value. - * - * @param headerName a string value - * @param fieldName a string value - * @param value a short value - * @return this - */ - public Builder matchExact(String headerName, String fieldName, short value) { - parameterMap.put(Pair.of(checkNotNull(headerName, "header name cannot be null"), - checkNotNull(fieldName, "field name cannot be null")), - exact(value)); - return this; - } - - /** - * Adds an exact match parameter for the given header field and value. - * - * @param headerName a string value - * @param fieldName a string value - * @param value an integer value - * @return this - */ - public Builder matchExact(String headerName, String fieldName, int value) { - parameterMap.put(Pair.of(checkNotNull(headerName, "header name cannot be null"), - checkNotNull(fieldName, "field name cannot be null")), - exact(value)); - return this; - } - - /** - * Adds an exact match parameter for the given header field and value. - * - * @param headerName a string value - * @param fieldName a string value - * @param value a long value - * @return this - */ - public Builder matchExact(String headerName, String fieldName, long value) { - parameterMap.put(Pair.of(checkNotNull(headerName, "header name cannot be null"), - checkNotNull(fieldName, "field name cannot be null")), - exact(value)); - return this; - } - - /** - * Adds an exact match parameter for the given header field and value. - * - * @param headerName a string value - * @param fieldName a string value - * @param value a byte array - * @return this - */ - public Builder matchExact(String headerName, String fieldName, byte[] value) { - parameterMap.put(Pair.of(checkNotNull(headerName, "header name cannot be null"), - checkNotNull(fieldName, "field name cannot be null")), - exact(value)); - return this; - } - - /** - * Adds a ternary match parameter for the given header field, value and mask. - * - * @param headerName a string value - * @param fieldName a string value - * @param value a short value - * @param mask a short value - * @return this - */ - public Builder matchTernary(String headerName, String fieldName, short value, short mask) { - parameterMap.put(Pair.of(checkNotNull(headerName, "header name cannot be null"), - checkNotNull(fieldName, "field name cannot be null")), - ternary(value, mask)); - return this; - } - /** - * Adds a ternary match parameter for the given header field, value and mask. - * - * @param headerName a string value - * @param fieldName a string value - * @param value an integer value - * @param mask an integer value - * @return this - */ - public Builder matchTernary(String headerName, String fieldName, int value, int mask) { - parameterMap.put(Pair.of(checkNotNull(headerName, "header name cannot be null"), - checkNotNull(fieldName, "field name cannot be null")), - ternary(value, mask)); - return this; - } - /** - * Adds a ternary match parameter for the given header field, value and mask. - * - * @param headerName a string value - * @param fieldName a string value - * @param value a long value - * @param mask a long value - * @return this - */ - public Builder matchTernary(String headerName, String fieldName, long value, long mask) { - parameterMap.put(Pair.of(checkNotNull(headerName, "header name cannot be null"), - checkNotNull(fieldName, "field name cannot be null")), - ternary(value, mask)); - return this; - } - /** - * Adds a ternary match parameter for the given header field, value and mask. - * - * @param headerName a string value - * @param fieldName a string value - * @param value a byte array - * @param mask a byte array - * @return this - */ - public Builder matchTernary(String headerName, String fieldName, byte[] value, byte[] mask) { - parameterMap.put(Pair.of(checkNotNull(headerName, "header name cannot be null"), - checkNotNull(fieldName, "field name cannot be null")), - ternary(value, mask)); - return this; - } - - /** - * Adds a longest-prefix match (LPM) parameter for the given header field, value and prefix length. - * - * @param headerName a string value - * @param fieldName a string value - * @param value a short value - * @param prefixLength an integer value - * @return this - */ - public Builder matchLpm(String headerName, String fieldName, short value, int prefixLength) { - parameterMap.put(Pair.of(checkNotNull(headerName, "header name cannot be null"), - checkNotNull(fieldName, "field name cannot be null")), - lpm(value, prefixLength)); - return this; - } - /** - * Adds a longest-prefix match (LPM) parameter for the given header field, value and prefix length. - * - * @param headerName a string value - * @param fieldName a string value - * @param value an integer value - * @param prefixLength an integer value - * @return this - */ - public Builder matchLpm(String headerName, String fieldName, int value, int prefixLength) { - parameterMap.put(Pair.of(checkNotNull(headerName, "header name cannot be null"), - checkNotNull(fieldName, "field name cannot be null")), - lpm(value, prefixLength)); - return this; - } - /** - * Adds a longest-prefix match (LPM) parameter for the given header field, value and prefix length. - * - * @param headerName a string value - * @param fieldName a string value - * @param value a long value - * @param prefixLength an integer value - * @return this - */ - public Builder matchLpm(String headerName, String fieldName, long value, int prefixLength) { - parameterMap.put(Pair.of(checkNotNull(headerName, "header name cannot be null"), - checkNotNull(fieldName, "field name cannot be null")), - lpm(value, prefixLength)); - return this; - } - /** - * Adds a longest-prefix match (LPM) parameter for the given header field, value and prefix length. - * - * @param headerName a string value - * @param fieldName a string value - * @param value a byte array - * @param prefixLength an integer value - * @return this - */ - public Builder matchLpm(String headerName, String fieldName, byte[] value, int prefixLength) { - parameterMap.put(Pair.of(checkNotNull(headerName, "header name cannot be null"), - checkNotNull(fieldName, "field name cannot be null")), - lpm(value, prefixLength)); - return this; - } - - /** - * Adds a valid match parameter for the given header field. - * - * @param headerName a string value - * @param fieldName a string value - * @param flag a boolean value - * @return this - */ - public Builder matchValid(String headerName, String fieldName, boolean flag) { - parameterMap.put(Pair.of(checkNotNull(headerName, "header name cannot be null"), - checkNotNull(fieldName, "field name cannot be null")), - new Bmv2ValidMatchParam(flag)); - return this; - } - - /** - * Returns a new BMv2 extension selector. - * - * @return a BMv2 extension selector - * @throws NullPointerException if a given header or field name is not defined in the given configuration - * @throws IllegalArgumentException if a given parameter cannot be casted for the given configuration, e.g. - * when trying to fit an integer value into a smaller, fixed-length parameter - * produces overflow. - */ - public Bmv2ExtensionSelector build() { - checkNotNull(configuration, "configuration cannot be null"); - checkState(parameterMap.size() > 0, "parameter map cannot be empty"); - - final Map newParameterMap = Maps.newHashMap(); - - for (Pair key : parameterMap.keySet()) { - - String headerName = key.getLeft(); - String fieldName = key.getRight(); - - Bmv2HeaderModel headerModel = configuration.header(headerName); - checkNotNull(headerModel, "no such a header in configuration", headerName); - - Bmv2FieldTypeModel fieldModel = headerModel.type().field(fieldName); - checkNotNull(fieldModel, "no such a field in configuration", key); - - int bitWidth = fieldModel.bitWidth(); - - Bmv2MatchParam oldParam = parameterMap.get(key); - Bmv2MatchParam newParam = null; - - try { - switch (oldParam.type()) { - case EXACT: - Bmv2ExactMatchParam e = (Bmv2ExactMatchParam) oldParam; - newParam = new Bmv2ExactMatchParam(fitByteSequence(e.value(), bitWidth)); - break; - case TERNARY: - Bmv2TernaryMatchParam t = (Bmv2TernaryMatchParam) oldParam; - newParam = new Bmv2TernaryMatchParam(fitByteSequence(t.value(), bitWidth), - fitByteSequence(t.mask(), bitWidth)); - break; - case LPM: - Bmv2LpmMatchParam l = (Bmv2LpmMatchParam) oldParam; - checkArgument(l.prefixLength() <= bitWidth, "LPM parameter has prefix length too long", - key); - newParam = new Bmv2LpmMatchParam(fitByteSequence(l.value(), bitWidth), - l.prefixLength()); - break; - case VALID: - newParam = oldParam; - break; - default: - throw new RuntimeException("Match parameter type not supported: " + oldParam.type()); - } - } catch (Bmv2TranslatorUtils.ByteSequenceFitException e) { - throw new IllegalArgumentException(e.getMessage() + " [" + key + "]"); - } - // FIXME: should put the pair object instead of building a new string for the key. - newParameterMap.put(headerName + "." + fieldName, newParam); - } - - return new Bmv2ExtensionSelector(newParameterMap); - } - - private static Bmv2MatchParam exact(Object value) { - return new Bmv2ExactMatchParam(copyFrom(bb(value))); - } - - private static Bmv2MatchParam ternary(Object value, Object mask) { - return new Bmv2TernaryMatchParam(copyFrom(bb(value)), copyFrom(bb(mask))); - } - - private static Bmv2MatchParam lpm(Object value, int prefixLength) { - return new Bmv2LpmMatchParam(copyFrom(bb(value)), prefixLength); - } - - private static ByteBuffer bb(Object value) { - if (value instanceof Short) { - return ByteBuffer.allocate(Short.BYTES).putShort((short) value); - } else if (value instanceof Integer) { - return ByteBuffer.allocate(Integer.BYTES).putInt((int) value); - } else if (value instanceof Long) { - return ByteBuffer.allocate(Long.BYTES).putLong((long) value); - } else if (value instanceof byte[]) { - byte[] bytes = (byte[]) value; - return ByteBuffer.allocate(bytes.length).put(bytes); - } else { - // Never here. - return null; - } - } - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExtensionTreatment.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExtensionTreatment.java deleted file mode 100644 index 7062f41542..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ExtensionTreatment.java +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.runtime; - -import com.google.common.annotations.Beta; -import com.google.common.base.MoreObjects; -import com.google.common.base.Objects; -import com.google.common.collect.Maps; -import org.onlab.util.ImmutableByteSequence; -import org.onlab.util.KryoNamespace; -import org.onosproject.bmv2.api.context.Bmv2ActionModel; -import org.onosproject.bmv2.api.context.Bmv2Configuration; -import org.onosproject.bmv2.api.context.Bmv2RuntimeDataModel; -import org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils; -import org.onosproject.net.flow.AbstractExtension; -import org.onosproject.net.flow.instructions.ExtensionTreatment; -import org.onosproject.net.flow.instructions.ExtensionTreatmentType; -import org.onosproject.store.serializers.KryoNamespaces; - -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.StringJoiner; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static org.onlab.util.ImmutableByteSequence.copyFrom; -import static org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils.fitByteSequence; -import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.BMV2_ACTION; - -/** - * Extension treatment for BMv2 used as a wrapper for a {@link Bmv2Action}. - */ -@Beta -public final class Bmv2ExtensionTreatment extends AbstractExtension implements ExtensionTreatment { - - private static final KryoNamespace APP_KRYO = new KryoNamespace.Builder() - .register(KryoNamespaces.API) - .register(Bmv2ExtensionTreatment.class) - .register(Bmv2Action.class) - .build(); - - private List parameterNames; - private Bmv2Action action; - - /** - * Creates a new extension treatment for the given BMv2 action. - * The list of action parameters name is also required for visualization purposes (i.e. nicer toString()). - * - * @param action an action - * @param parameterNames a list of strings - */ - private Bmv2ExtensionTreatment(Bmv2Action action, List parameterNames) { - this.action = action; - this.parameterNames = parameterNames; - } - - /** - * Returns the action contained by this extension selector. - * - * @return an action - */ - public Bmv2Action action() { - return action; - } - - @Override - public ExtensionTreatmentType type() { - return BMV2_ACTION.type(); - } - - @Override - public byte[] serialize() { - return APP_KRYO.serialize(this); - } - - @Override - public void deserialize(byte[] data) { - Bmv2ExtensionTreatment other = APP_KRYO.deserialize(data); - action = other.action; - parameterNames = other.parameterNames; - } - - @Override - public int hashCode() { - return Objects.hashCode(action); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2ExtensionTreatment other = (Bmv2ExtensionTreatment) obj; - return Objects.equal(this.action, other.action); - } - - @Override - public String toString() { - StringJoiner stringJoiner = new StringJoiner(", ", "(", ")"); - for (int i = 0; i < parameterNames.size(); i++) { - stringJoiner.add(parameterNames.get(i) + "=" + action.parameters().get(i)); - } - return MoreObjects.toStringHelper(this) - .addValue(action.name() + stringJoiner.toString()) - .toString(); - } - - /** - * Returns a new, empty BMv2 extension treatment. - * - * @return a BMv2 extension treatment - */ - public static Bmv2ExtensionTreatment empty() { - return new Bmv2ExtensionTreatment(null, Collections.emptyList()); - } - - /** - * Returns a new BMv2 extension treatment builder. - * - * @return a builder - */ - public static Builder builder() { - return new Builder(); - } - - /** - * A builder of BMv2 extension treatments. - * - * BMv2 action parameters are built from primitive data types ({@code short}, {@code int}, {@code long} or - * {@code byte[]}) and automatically casted to fixed-length byte sequences according to the given BMv2 - * configuration. - */ - public static final class Builder { - private Bmv2Configuration configuration; - private String actionName; - private final Map parameters = Maps.newHashMap(); - - private Builder() { - // Ban constructor. - } - - /** - * Sets the BMv2 configuration to format the action parameters. - * - * @param config a BMv2 configuration - * @return this - */ - public Builder forConfiguration(Bmv2Configuration config) { - this.configuration = config; - return this; - } - - /** - * Sets the action name. - * - * @param actionName a string value - * @return this - */ - public Builder setActionName(String actionName) { - this.actionName = actionName; - return this; - } - - /** - * Adds an action parameter. - * - * @param parameterName a string value - * @param value a short value - * @return this - */ - public Builder addParameter(String parameterName, short value) { - this.parameters.put(parameterName, copyFrom(bb(value))); - return this; - } - - /** - * Adds an action parameter. - * - * @param parameterName a string value - * @param value an integer value - * @return this - */ - public Builder addParameter(String parameterName, int value) { - this.parameters.put(parameterName, copyFrom(bb(value))); - return this; - } - - /** - * Adds an action parameter. - * - * @param parameterName a string value - * @param value a long value - * @return this - */ - public Builder addParameter(String parameterName, long value) { - this.parameters.put(parameterName, copyFrom(bb(value))); - return this; - } - - /** - * Adds an action parameter. - * - * @param parameterName a string value - * @param value a byte array - * @return this - */ - public Builder addParameter(String parameterName, byte[] value) { - this.parameters.put(parameterName, copyFrom(bb(value))); - return this; - } - - /** - * Returns a new BMv2 extension treatment. - * - * @return a BMv2 extension treatment - * @throws NullPointerException if the given action or parameter names are not defined in the given - * configuration - * @throws IllegalArgumentException if a given parameter cannot be casted for the given configuration, e.g. - * when trying to fit an integer value into a smaller, fixed-length parameter - * produces overflow. - */ - public Bmv2ExtensionTreatment build() { - checkNotNull(configuration, "configuration cannot be null"); - checkNotNull(actionName, "action name cannot be null"); - - Bmv2ActionModel actionModel = configuration.action(actionName); - - checkNotNull(actionModel, "no such an action in configuration", actionName); - checkArgument(actionModel.runtimeDatas().size() == parameters.size(), - "invalid number of parameters", actionName); - - List newParameters = new ArrayList<>(parameters.size()); - List parameterNames = new ArrayList<>(parameters.size()); - - for (String parameterName : parameters.keySet()) { - Bmv2RuntimeDataModel runtimeData = actionModel.runtimeData(parameterName); - checkNotNull(runtimeData, "no such an action parameter in configuration", - actionName + "->" + runtimeData.name()); - int bitWidth = runtimeData.bitWidth(); - try { - ImmutableByteSequence newSequence = fitByteSequence(parameters.get(parameterName), bitWidth); - int idx = actionModel.runtimeDatas().indexOf(runtimeData); - newParameters.add(idx, newSequence); - parameterNames.add(idx, parameterName); - } catch (Bmv2TranslatorUtils.ByteSequenceFitException e) { - throw new IllegalArgumentException(e.getMessage() + - " [" + actionName + "->" + runtimeData.name() + "]"); - } - } - - return new Bmv2ExtensionTreatment(new Bmv2Action(actionName, newParameters), parameterNames); - } - - - - private static ByteBuffer bb(Object value) { - if (value instanceof Short) { - return ByteBuffer.allocate(Short.BYTES).putShort((short) value); - } else if (value instanceof Integer) { - return ByteBuffer.allocate(Integer.BYTES).putInt((int) value); - } else if (value instanceof Long) { - return ByteBuffer.allocate(Long.BYTES).putLong((long) value); - } else if (value instanceof byte[]) { - byte[] bytes = (byte[]) value; - return ByteBuffer.allocate(bytes.length).put(bytes); - } else { - // Never here. - return null; - } - } - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2FlowRuleWrapper.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2FlowRuleWrapper.java deleted file mode 100644 index e23059d162..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2FlowRuleWrapper.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.runtime; - -import com.google.common.annotations.Beta; -import com.google.common.base.Objects; -import org.onosproject.net.flow.FlowRule; - -/** - * A wrapper for a ONOS flow rule installed on a BMv2 device. - */ -@Beta -public final class Bmv2FlowRuleWrapper { - - private final FlowRule rule; - private final long entryId; - private final long installedOnMillis; - - /** - * Creates a new flow rule wrapper. - * - * @param rule a flow rule - * @param entryId a BMv2 table entry ID - * @param installedOnMillis the time (in milliseconds, since January 1, 1970 UTC) when the flow rule was installed - * on the device - */ - public Bmv2FlowRuleWrapper(FlowRule rule, long entryId, long installedOnMillis) { - this.rule = rule; - this.entryId = entryId; - this.installedOnMillis = installedOnMillis; - } - - /** - * Returns the flow rule contained by this wrapper. - * - * @return a flow rule - */ - public FlowRule rule() { - return rule; - } - - /** - * Return the number of seconds since when this flow rule was installed on the device. - * - * @return an integer value - */ - public long lifeInSeconds() { - return (System.currentTimeMillis() - installedOnMillis) / 1000; - } - - /** - * Returns the the time (in milliseconds, since January 1, 1970 UTC) when the flow rule was installed on - * the device. - * - * @return a long value - */ - public long installedOnMillis() { - return installedOnMillis; - } - - /** - * Returns the BMv2 entry ID of this flow rule. - * - * @return a long value - */ - public long entryId() { - return entryId; - } - - @Override - public int hashCode() { - return Objects.hashCode(rule, entryId, installedOnMillis); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2FlowRuleWrapper other = (Bmv2FlowRuleWrapper) obj; - return Objects.equal(this.rule, other.rule) - && Objects.equal(this.entryId, other.entryId) - && Objects.equal(this.installedOnMillis, other.installedOnMillis); - } - - @Override - public String toString() { - return installedOnMillis + "-" + rule.hashCode(); - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2LpmMatchParam.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2LpmMatchParam.java deleted file mode 100644 index 5f280b38c3..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2LpmMatchParam.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.runtime; - -import com.google.common.annotations.Beta; -import com.google.common.base.MoreObjects; -import com.google.common.base.Objects; -import org.onlab.util.ImmutableByteSequence; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * A BMv2 longest prefix match (LPM) parameter. - */ -@Beta -public final class Bmv2LpmMatchParam implements Bmv2MatchParam { - - private final ImmutableByteSequence value; - private final int prefixLength; - - /** - * Creates a new LPM parameter using the given byte sequence value and - * prefix length. - * - * @param value a byte sequence value - * @param prefixLength an integer value - */ - public Bmv2LpmMatchParam(ImmutableByteSequence value, int prefixLength) { - checkArgument(prefixLength >= 0, "prefix length cannot be negative"); - this.value = checkNotNull(value); - this.prefixLength = prefixLength; - } - - @Override - public Bmv2MatchParam.Type type() { - return Type.LPM; - } - - /** - * Returns the byte sequence value of this parameter. - * - * @return a byte sequence value - */ - public ImmutableByteSequence value() { - return this.value; - } - - /** - * Returns the prefix length of this parameter. - * - * @return an integer value - */ - public int prefixLength() { - return this.prefixLength; - } - - @Override - public int hashCode() { - return Objects.hashCode(value, prefixLength); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2LpmMatchParam other = (Bmv2LpmMatchParam) obj; - return Objects.equal(this.value, other.value) - && Objects.equal(this.prefixLength, other.prefixLength); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("value", value) - .add("prefixLength", prefixLength) - .toString(); - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2MatchKey.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2MatchKey.java deleted file mode 100644 index 34276aa869..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2MatchKey.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.runtime; - -import com.google.common.annotations.Beta; -import com.google.common.base.MoreObjects; -import com.google.common.collect.Lists; -import org.onlab.util.ImmutableByteSequence; - -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * A match key of a BMv2 match-action table entry. - */ -@Beta -public final class Bmv2MatchKey { - - private final List matchParams; - - private Bmv2MatchKey(List matchParams) { - // ban constructor - this.matchParams = matchParams; - } - - /** - * Returns a new match key builder. - * - * @return a match key builder - */ - public static Builder builder() { - return new Builder(); - } - - /** - * Returns the list of match parameters of this match key. - * - * @return list match parameters - */ - public final List matchParams() { - return Collections.unmodifiableList(matchParams); - } - - @Override - public final int hashCode() { - return Objects.hashCode(matchParams); - } - - @Override - public final boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2MatchKey other = (Bmv2MatchKey) obj; - - return Objects.equals(this.matchParams, other.matchParams); - } - - @Override - public final String toString() { - return MoreObjects.toStringHelper(this) - .addValue(matchParams) - .toString(); - } - - /** - * Builder of a BMv2 match key. - */ - public static final class Builder { - - private List matchParams; - - private Builder() { - this.matchParams = Lists.newArrayList(); - } - - /** - * Adds a match parameter to the match key. - * - * @param param a match parameter - * @return this - */ - public Builder add(Bmv2MatchParam param) { - this.matchParams.add(checkNotNull(param)); - return this; - } - - /** - * Adds a ternary match parameter where all bits are don't-care. - * - * @param byteLength length in bytes of the parameter - * @return this - */ - public Builder withWildcard(int byteLength) { - checkArgument(byteLength > 0, "length must be a positive integer"); - return add(new Bmv2TernaryMatchParam( - ImmutableByteSequence.ofZeros(byteLength), - ImmutableByteSequence.ofZeros(byteLength))); - } - - /** - * Builds a new match key object. - * - * @return match key - */ - public Bmv2MatchKey build() { - return new Bmv2MatchKey(this.matchParams); - } - } -} \ No newline at end of file diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2MatchParam.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2MatchParam.java deleted file mode 100644 index 5ff13168cc..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2MatchParam.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.runtime; - -import com.google.common.annotations.Beta; - -/** - * Representation of a BMv2 match parameter. - */ -@Beta -public interface Bmv2MatchParam { - - /** - * Returns the match type of this parameter. - * - * @return a match type value - */ - Type type(); - - /** - * BMv2 match types. - */ - enum Type { - /** - * Exact match type. - */ - EXACT, - /** - * Ternary match type. - */ - TERNARY, - /** - * Longest-prefix match type. - */ - LPM, - /** - * Valid match type. - */ - VALID - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ParsedTableEntry.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ParsedTableEntry.java deleted file mode 100644 index bf59cf46ee..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ParsedTableEntry.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.runtime; - -import com.google.common.annotations.Beta; -import com.google.common.base.MoreObjects; -import com.google.common.base.Objects; - -/** - * Representation of a table entry installed on a BMv2 device. - */ -@Beta -public final class Bmv2ParsedTableEntry { - private final long entryId; - private final Bmv2MatchKey matchKey; - private final Bmv2Action action; - private final int priority; - - /** - * Creates a new parsed table entry. - * - * @param entryId a long value - * @param matchKey a match key - * @param action an action - * @param priority an integer value - */ - public Bmv2ParsedTableEntry(long entryId, Bmv2MatchKey matchKey, Bmv2Action action, int priority) { - this.entryId = entryId; - this.matchKey = matchKey; - this.action = action; - this.priority = priority; - } - - /** - * Returns the entry ID. - * - * @return a long value - */ - public long entryId() { - return entryId; - } - - /** - * Returns the match key. - * - * @return a match key object - */ - public Bmv2MatchKey matchKey() { - return matchKey; - } - - /** - * Returns the action. - * - * @return an action object - */ - public Bmv2Action action() { - return action; - } - - /** - * Returns the priority. - * - * @return an integer value - */ - public int getPriority() { - return priority; - } - - @Override - public int hashCode() { - return Objects.hashCode(entryId, matchKey, action, priority); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2ParsedTableEntry other = (Bmv2ParsedTableEntry) obj; - return Objects.equal(this.entryId, other.entryId) - && Objects.equal(this.matchKey, other.matchKey) - && Objects.equal(this.action, other.action) - && Objects.equal(this.priority, other.priority); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("entryId", entryId) - .add("matchKey", matchKey) - .add("action", action) - .toString(); - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2PortInfo.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2PortInfo.java deleted file mode 100644 index 568d141ce1..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2PortInfo.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.runtime; - -import com.google.common.annotations.Beta; -import com.google.common.base.MoreObjects; -import com.google.common.base.Objects; - -/** - * Information of a port of a BMv2 device. - */ -@Beta -public final class Bmv2PortInfo { - - private final String ifaceName; - private final int number; - private final boolean isUp; - - /** - * Creates a new port description. - * - * @param ifaceName the common name of the network interface - * @param number a port number - * @param isUp interface status - */ - public Bmv2PortInfo(String ifaceName, int number, boolean isUp) { - this.ifaceName = ifaceName; - this.number = number; - this.isUp = isUp; - } - - /** - * Returns the common name the network interface used by this port. - * - * @return a string value - */ - public String ifaceName() { - return ifaceName; - } - - /** - * Returns the number of this port. - * - * @return an integer value - */ - public int number() { - return number; - } - - /** - * Returns true if the port is up, false otherwise. - * - * @return a boolean value - */ - public boolean isUp() { - return isUp; - } - - @Override - public int hashCode() { - return Objects.hashCode(ifaceName, number, isUp); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2PortInfo other = (Bmv2PortInfo) obj; - return Objects.equal(this.ifaceName, other.ifaceName) - && Objects.equal(this.number, other.number) - && Objects.equal(this.isUp, other.isUp); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("ifaceName", ifaceName) - .add("number", number) - .add("isUp", isUp) - .toString(); - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2RuntimeException.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2RuntimeException.java deleted file mode 100644 index 176e6f0aff..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2RuntimeException.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.runtime; - -import com.google.common.annotations.Beta; - -/** - * General exception of the BMv2 runtime APIs. - */ -@Beta -public final class Bmv2RuntimeException extends Exception { - - private final Code code; - private String codeString; - - public Bmv2RuntimeException(String message) { - super(message); - this.code = Code.OTHER; - this.codeString = message; - } - - public Bmv2RuntimeException(Throwable cause) { - super(cause); - this.code = Code.OTHER; - this.codeString = cause.toString(); - } - - public Bmv2RuntimeException(Code code) { - super(code.name()); - this.code = code; - } - - public Code getCode() { - return this.code; - } - - public String explain() { - return (codeString == null) ? code.name() : code.name() + " " + codeString; - } - - @Override - public String toString() { - return getClass().getSimpleName() + " " + explain(); - } - - public enum Code { - TABLE_FULL, - TABLE_INVALID_HANDLE, - TABLE_EXPIRED_HANDLE, - TABLE_COUNTERS_DISABLED, - TABLE_METERS_DISABLED, - TABLE_AGEING_DISABLED, - TABLE_INVALID_TABLE_NAME, - TABLE_INVALID_ACTION_NAME, - TABLE_WRONG_TABLE_TYPE, - TABLE_INVALID_MBR_HANDLE, - TABLE_MBR_STILL_USED, - TABLE_MBR_ALREADY_IN_GRP, - TABLE_MBR_NOT_IN_GRP, - TABLE_INVALID_GRP_HANDLE, - TABLE_GRP_STILL_USED, - TABLE_EMPTY_GRP, - TABLE_DUPLICATE_ENTRY, - TABLE_BAD_MATCH_KEY, - TABLE_INVALID_METER_OPERATION, - TABLE_DEFAULT_ACTION_IS_CONST, - TABLE_DEFAULT_ENTRY_IS_CONST, - TABLE_GENERAL_ERROR, - TABLE_UNKNOWN_ERROR, - - DEV_MGR_ERROR_GENERAL, - DEV_MGR_UNKNOWN, - - COUNTER_INVALID_NAME, - COUNTER_INVALID_INDEX, - COUNTER_ERROR_GENERAL, - COUNTER_ERROR_UNKNOWN, - - SWAP_CONFIG_DISABLED, - SWAP_ONGOING, - SWAP_NO_ONGOING, - SWAP_ERROR_UKNOWN, - - // TODO: add other codes based on autogenerated Thrift APIs - - OTHER - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TableEntry.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TableEntry.java deleted file mode 100644 index 6ea97e9090..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TableEntry.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.runtime; - -import com.google.common.annotations.Beta; - -import java.util.Objects; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * An entry of a match-action table in a BMv2 device. - */ -@Beta -public final class Bmv2TableEntry { - - private static final int NO_PRIORITY_VALUE = -1; - private static final int NO_TIMEOUT_VALUE = -1; - - private final String tableName; - private final Bmv2MatchKey matchKey; - private final Bmv2Action action; - private final int priority; - private final double timeout; - - private Bmv2TableEntry(String tableName, Bmv2MatchKey matchKey, - Bmv2Action action, int priority, double timeout) { - this.tableName = tableName; - this.matchKey = matchKey; - this.action = action; - this.priority = priority; - this.timeout = timeout; - } - - /** - * Returns a new BMv2 table entry builder. - * - * @return a new builder. - */ - public static Builder builder() { - return new Builder(); - } - - /** - * Returns the name of the table where this entry is installed. - * - * @return table name - */ - public final String tableName() { - return this.tableName; - } - - /** - * Returns the match key of this table entry. - * - * @return match key - */ - public final Bmv2MatchKey matchKey() { - return matchKey; - } - - /** - * Returns the action of this table entry. - * - * @return action - */ - public final Bmv2Action action() { - return action; - } - - /** - * Returns true is the entry has a valid priority. - * - * @return true if priority is set, false elsewhere - */ - public final boolean hasPriority() { - return this.priority != NO_PRIORITY_VALUE; - } - - /** - * Return the priority of this table entry. - * - * @return priority - */ - public final int priority() { - return priority; - } - - /** - * Returns true is this table entry has a valid timeout. - * - * @return true if timeout is set, false elsewhere - */ - public final boolean hasTimeout() { - return this.timeout != NO_PRIORITY_VALUE; - } - - /** - * Returns the timeout (in fractional seconds) of this table entry. - * - * @return a timeout vale (in fractional seconds) - */ - public final double timeout() { - return timeout; - } - - @Override - public final int hashCode() { - return Objects.hash(matchKey, action, priority, timeout); - } - - @Override - public final boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2TableEntry other = (Bmv2TableEntry) obj; - return Objects.equals(this.matchKey, other.matchKey) - && Objects.equals(this.action, other.action) - && Objects.equals(this.priority, other.priority) - && Objects.equals(this.timeout, other.timeout); - } - - @Override - public final String toString() { - return com.google.common.base.MoreObjects.toStringHelper(this) - .addValue(matchKey) - .addValue(action) - .add("priority", priority) - .add("timeout", timeout) - .toString(); - } - - public static final class Builder { - - private String tableName; - private Bmv2MatchKey matchKey; - private Bmv2Action action; - private int priority = NO_PRIORITY_VALUE; - private double timeout = NO_TIMEOUT_VALUE; - - private Builder() { - // hide constructor - } - - /** - * Sets the table name. - * - * @param tableName a string value - * @return this - */ - public Builder withTableName(String tableName) { - this.tableName = checkNotNull(tableName, "table name cannot be null"); - return this; - } - - /** - * Sets the match key. - * - * @param matchKey a match key value - * @return this - */ - public Builder withMatchKey(Bmv2MatchKey matchKey) { - this.matchKey = checkNotNull(matchKey, "match key cannot be null"); - return this; - } - - /** - * Sets the action. - * - * @param action an action value - * @return this - */ - public Builder withAction(Bmv2Action action) { - this.action = checkNotNull(action, "action cannot be null"); - return this; - } - - public Builder withPriority(int priority) { - checkArgument(priority >= 0, "priority cannot be negative"); - this.priority = priority; - return this; - } - - /** - * Sets the timeout. - * - * @param timeout a timeout value in fractional seconds - * @return this - */ - public Builder withTimeout(double timeout) { - checkArgument(timeout > 0, "timeout must be a positive non-zero value"); - this.timeout = timeout; - return this; - } - - /** - * Build the table entry. - * - * @return a new table entry object - */ - public Bmv2TableEntry build() { - return new Bmv2TableEntry(tableName, matchKey, action, priority, - timeout); - - } - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TableEntryReference.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TableEntryReference.java deleted file mode 100644 index 6283239e67..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TableEntryReference.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.runtime; - -import com.google.common.annotations.Beta; -import com.google.common.base.MoreObjects; -import com.google.common.base.Objects; -import org.onosproject.net.DeviceId; - -/** - * A reference to a table entry installed on a BMv2 device. - */ -@Beta -public final class Bmv2TableEntryReference { - - - private final DeviceId deviceId; - private final String tableName; - private final Bmv2MatchKey matchKey; - - /** - * Creates a new table entry reference. - * - * @param deviceId a device ID - * @param tableName a table name - * @param matchKey a match key - */ - public Bmv2TableEntryReference(DeviceId deviceId, String tableName, Bmv2MatchKey matchKey) { - this.deviceId = deviceId; - this.tableName = tableName; - this.matchKey = matchKey; - } - - /** - * Returns the device ID of this table entry reference. - * - * @return a device ID - */ - public DeviceId deviceId() { - return deviceId; - } - - /** - * Returns the name of the table of this table entry reference. - * - * @return a table name - */ - public String tableName() { - return tableName; - } - - /** - * Returns the match key of this table entry reference. - * - * @return a match key - */ - public Bmv2MatchKey matchKey() { - return matchKey; - } - - @Override - public int hashCode() { - return Objects.hashCode(deviceId, tableName, matchKey); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2TableEntryReference other = (Bmv2TableEntryReference) obj; - return Objects.equal(this.deviceId, other.deviceId) - && Objects.equal(this.tableName, other.tableName) - && Objects.equal(this.matchKey, other.matchKey); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("deviceId", deviceId) - .add("tableName", tableName) - .add("matchKey", matchKey) - .toString(); - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TernaryMatchParam.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TernaryMatchParam.java deleted file mode 100644 index 713d5325b7..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2TernaryMatchParam.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.runtime; - -import com.google.common.annotations.Beta; -import com.google.common.base.MoreObjects; -import com.google.common.base.Objects; -import org.onlab.util.ImmutableByteSequence; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -/** - * Representation of a BMv2 ternary match parameter. - */ -@Beta -public final class Bmv2TernaryMatchParam implements Bmv2MatchParam { - - private final ImmutableByteSequence value; - private final ImmutableByteSequence mask; - - /** - * Creates a new ternary match parameter using the given byte sequences of - * value and mask. - * - * @param value a byte sequence value - * @param mask a byte sequence value - */ - public Bmv2TernaryMatchParam(ImmutableByteSequence value, - ImmutableByteSequence mask) { - this.value = checkNotNull(value, "value cannot be null"); - this.mask = checkNotNull(mask, "value cannot be null"); - checkState(value.size() == mask.size(), - "value and mask must have equal size"); - } - - @Override - public Type type() { - return Type.TERNARY; - } - - /** - * Returns the byte sequence value of by this parameter. - * - * @return a byte sequence value - */ - public ImmutableByteSequence value() { - return this.value; - } - - /** - * Returns the byte sequence mask of by this parameter. - * - * @return a byte sequence value - */ - public ImmutableByteSequence mask() { - return this.mask; - } - - @Override - public int hashCode() { - return Objects.hashCode(value, mask); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2TernaryMatchParam other = (Bmv2TernaryMatchParam) obj; - return Objects.equal(this.value, other.value) - && Objects.equal(this.mask, other.mask); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("value", value) - .add("mask", mask) - .toString(); - } -} \ No newline at end of file diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ValidMatchParam.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ValidMatchParam.java deleted file mode 100644 index 9312b56fb8..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/Bmv2ValidMatchParam.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.runtime; - - -import com.google.common.annotations.Beta; -import com.google.common.base.MoreObjects; - -import java.util.Objects; - -/** - * Representation of a BMv2 valid match parameter. - */ -@Beta -public final class Bmv2ValidMatchParam implements Bmv2MatchParam { - - private final boolean flag; - - /** - * Creates a new valid match parameter using the given boolean flag. - * - * @param flag a boolean value - */ - public Bmv2ValidMatchParam(boolean flag) { - this.flag = flag; - } - - @Override - public Type type() { - return Type.VALID; - } - - /** - * Returns the boolean flag of this parameter. - * - * @return a boolean value - */ - public boolean flag() { - return flag; - } - - @Override - public int hashCode() { - return Objects.hashCode(flag); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - final Bmv2ValidMatchParam other = (Bmv2ValidMatchParam) obj; - return this.flag == other.flag; - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("flag", flag) - .toString(); - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/package-info.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/package-info.java deleted file mode 100644 index d4b1279e25..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/runtime/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * BMv2 runtime API. - */ -package org.onosproject.bmv2.api.runtime; \ No newline at end of file diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2Controller.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2Controller.java deleted file mode 100644 index 22ba01605b..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2Controller.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.service; - -import com.google.common.annotations.Beta; -import org.onosproject.bmv2.api.runtime.Bmv2DeviceAgent; -import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException; -import org.onosproject.net.DeviceId; - -/** - * A controller of BMv2 devices. - */ -@Beta -public interface Bmv2Controller { - - /** - * Default port. - */ - int DEFAULT_PORT = 40123; - - /** - * Return an agent to operate on the given device. - * - * @param deviceId a device ID - * @return a BMv2 agent - * @throws Bmv2RuntimeException if the agent is not available - */ - Bmv2DeviceAgent getAgent(DeviceId deviceId) throws Bmv2RuntimeException; - - /** - * Returns true if the given device is reachable from this controller, false otherwise. - * - * @param deviceId a device ID - * @return a boolean value - */ - boolean isReacheable(DeviceId deviceId); - - /** - * Register the given device listener. - * - * @param listener a device listener - */ - void addDeviceListener(Bmv2DeviceListener listener); - - /** - * Unregister the given device listener. - * - * @param listener a device listener - */ - void removeDeviceListener(Bmv2DeviceListener listener); - - /** - * Register the given packet listener. - * - * @param listener a packet listener - */ - void addPacketListener(Bmv2PacketListener listener); - - /** - * Unregister the given packet listener. - * - * @param listener a packet listener - */ - void removePacketListener(Bmv2PacketListener listener); -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2DeviceContextService.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2DeviceContextService.java deleted file mode 100644 index ed15134cb3..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2DeviceContextService.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.service; - -import com.google.common.annotations.Beta; -import org.onosproject.bmv2.api.context.Bmv2DeviceContext; -import org.onosproject.bmv2.api.context.Bmv2Interpreter; -import org.onosproject.net.DeviceId; - -/** - * A service for managing BMv2 device contexts. - */ -@Beta -public interface Bmv2DeviceContextService { - - /** - * Returns the context of the given device, null if no context has been previously set. - * - * @param deviceId a device ID - * @return a BMv2 device context - */ - Bmv2DeviceContext getContext(DeviceId deviceId); - - /** - * Sets the context for the given device. - * - * @param deviceId a device ID - * @param context a BMv2 device context - */ - void setContext(DeviceId deviceId, Bmv2DeviceContext context); - - /** - * Binds the given interpreter with the given class loader so that other ONOS instances in the cluster can properly - * load the interpreter. - * - * @param interpreterClass an interpreter class - * @param loader a class loader - */ - void registerInterpreterClassLoader(Class interpreterClass, ClassLoader loader); - - /** - * Returns the default context. - * - * @return a BMv2 device context - */ - Bmv2DeviceContext defaultContext(); - - /** - * Sets the default context for the given device. - */ - void setDefaultContext(DeviceId deviceId); -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2DeviceListener.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2DeviceListener.java deleted file mode 100644 index cb8c4444e2..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2DeviceListener.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.service; - -import com.google.common.annotations.Beta; -import org.onosproject.bmv2.api.runtime.Bmv2Device; - -/** - * A listener of BMv2 device events. - */ -@Beta -public interface Bmv2DeviceListener { - - /** - * Handles a hello message. - * - * @param device the BMv2 device that originated the message - * @param instanceId the ID of the BMv2 process instance - * @param jsonConfigMd5 the MD5 sum of the JSON configuration currently running on the device - */ - void handleHello(Bmv2Device device, int instanceId, String jsonConfigMd5); -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2PacketListener.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2PacketListener.java deleted file mode 100644 index 32629eb81a..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2PacketListener.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.service; - -import com.google.common.annotations.Beta; -import org.onlab.util.ImmutableByteSequence; -import org.onosproject.bmv2.api.runtime.Bmv2Device; - -/** - * A listener of BMv2 packet events. - */ -@Beta -public interface Bmv2PacketListener { - - /** - * Handles a packet-in message. - * - * @param device the BMv2 device that originated the message - * @param inputPort the device port where the packet was received - * @param packet the packet raw data - */ - void handlePacketIn(Bmv2Device device, int inputPort, ImmutableByteSequence packet); -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2TableEntryService.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2TableEntryService.java deleted file mode 100644 index 5c5ee38cdd..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/Bmv2TableEntryService.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.service; - - -import com.google.common.annotations.Beta; -import org.onosproject.bmv2.api.context.Bmv2FlowRuleTranslator; -import org.onosproject.bmv2.api.runtime.Bmv2FlowRuleWrapper; -import org.onosproject.bmv2.api.runtime.Bmv2TableEntryReference; -import org.onosproject.net.DeviceId; - -/** - * A service for managing BMv2 table entries. - */ -@Beta -public interface Bmv2TableEntryService { - - /** - * Returns a flow rule translator. - * - * @return a flow rule translator - */ - Bmv2FlowRuleTranslator getFlowRuleTranslator(); - - /** - * Binds the given ONOS flow rule with a BMv2 table entry reference. - * - * @param entryRef a table entry reference - * @param rule a BMv2 flow rule wrapper - */ - void bind(Bmv2TableEntryReference entryRef, Bmv2FlowRuleWrapper rule); - - /** - * Returns the ONOS flow rule associated with the given BMv2 table entry reference, or null if there's no such a - * mapping. - * - * @param entryRef a table entry reference - * @return a BMv2 flow rule wrapper - */ - Bmv2FlowRuleWrapper lookup(Bmv2TableEntryReference entryRef); - - /** - * Removes any flow rule previously bound with a given BMv2 table entry reference. - * - * @param entryRef a table entry reference - */ - void unbind(Bmv2TableEntryReference entryRef); - - /** - * Removes all bindings for a given device. - * - * @param deviceId a device ID - */ - void unbindAll(DeviceId deviceId); -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/package-info.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/package-info.java deleted file mode 100644 index 07bb1a0da9..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/service/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * BMv2 service API. - */ -package org.onosproject.bmv2.api.service; \ No newline at end of file diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/utils/Bmv2TranslatorUtils.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/utils/Bmv2TranslatorUtils.java deleted file mode 100644 index 0cc102ba26..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/utils/Bmv2TranslatorUtils.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.utils; - -import com.google.common.annotations.Beta; -import org.onlab.util.HexString; -import org.onlab.util.ImmutableByteSequence; - -import java.util.Arrays; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * Collection of utility methods to deal with flow rule translation. - */ -@Beta -public final class Bmv2TranslatorUtils { - - private Bmv2TranslatorUtils() { - // Ban constructor. - } - - /** - * Returns the number of bytes necessary to contain the given bit-width. - * - * @param bitWidth an integer value - * @return an integer value - */ - public static int roundToBytes(int bitWidth) { - return (int) Math.ceil((double) bitWidth / 8); - } - - /** - * Trims or expands the given byte sequence so to fit a given bit-width. - * - * @param original a byte sequence - * @param bitWidth an integer value - * @return a new byte sequence - * @throws ByteSequenceFitException if the byte sequence cannot be fitted in the given bit-width - */ - public static ImmutableByteSequence fitByteSequence(ImmutableByteSequence original, int bitWidth) - throws ByteSequenceFitException { - - checkNotNull(original, "byte sequence cannot be null"); - checkArgument(bitWidth > 0, "byte width must a non-zero positive integer"); - - int newByteWidth = roundToBytes(bitWidth); - - if (original.size() == newByteWidth) { - // nothing to do - return original; - } - - byte[] originalBytes = original.asArray(); - - if (newByteWidth > original.size()) { - // pad missing bytes with zeros - return ImmutableByteSequence.copyFrom(Arrays.copyOf(originalBytes, newByteWidth)); - } - - byte[] newBytes = new byte[newByteWidth]; - // ImmutableByteSequence is always big-endian, hence check the array in reverse order - int diff = originalBytes.length - newByteWidth; - for (int i = originalBytes.length - 1; i > 0; i--) { - byte ob = originalBytes[i]; // original byte - byte nb; // new byte - if (i > diff) { - // no need to truncate, copy as is - nb = ob; - } else if (i == diff) { - // truncate this byte, check if we're loosing something - byte mask = (byte) ((1 >> ((bitWidth % 8) + 1)) - 1); - if ((ob & ~mask) != 0) { - throw new ByteSequenceFitException(originalBytes, bitWidth); - } else { - nb = (byte) (ob & mask); - } - } else { - // drop this byte, check if we're loosing something - if (originalBytes[i] != 0) { - throw new ByteSequenceFitException(originalBytes, bitWidth); - } else { - continue; - } - } - newBytes[i - diff] = nb; - } - - return ImmutableByteSequence.copyFrom(newBytes); - } - - /** - * A byte sequence fit exception. - */ - public static class ByteSequenceFitException extends Exception { - public ByteSequenceFitException(byte[] bytes, int bitWidth) { - super("cannot fit " + HexString.toHexString(bytes) + " into a " + bitWidth + " bits value"); - } - } -} diff --git a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/utils/package-info.java b/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/utils/package-info.java deleted file mode 100644 index bdae0392bf..0000000000 --- a/protocols/bmv2/api/src/main/java/org/onosproject/bmv2/api/utils/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * BMv2 utils. - */ -package org.onosproject.bmv2.api.utils; \ No newline at end of file diff --git a/protocols/bmv2/api/src/test/java/org/onosproject/bmv2/api/context/Bmv2ConfigurationTest.java b/protocols/bmv2/api/src/test/java/org/onosproject/bmv2/api/context/Bmv2ConfigurationTest.java deleted file mode 100644 index bc1659d4b5..0000000000 --- a/protocols/bmv2/api/src/test/java/org/onosproject/bmv2/api/context/Bmv2ConfigurationTest.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.context; - -import com.eclipsesource.json.Json; -import com.eclipsesource.json.JsonObject; -import com.google.common.testing.EqualsTester; -import org.hamcrest.collection.IsIterableContainingInOrder; -import org.junit.Before; -import org.junit.Test; -import org.onosproject.bmv2.api.runtime.Bmv2MatchParam; - -import java.io.BufferedReader; -import java.io.InputStreamReader; - -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.core.IsEqual.equalTo; - -/** - * BMv2 JSON configuration parser test. - */ -public class Bmv2ConfigurationTest { - - private JsonObject json; - private JsonObject json2; - - @Before - public void setUp() throws Exception { - json = Json.parse(new BufferedReader(new InputStreamReader( - this.getClass().getResourceAsStream("/simple.json")))).asObject(); - json2 = Json.parse(new BufferedReader(new InputStreamReader( - this.getClass().getResourceAsStream("/simple.json")))).asObject(); - } - - @Test - public void testParse() throws Exception { - Bmv2Configuration config = Bmv2DefaultConfiguration.parse(json); - Bmv2Configuration config2 = Bmv2DefaultConfiguration.parse(json2); - - new EqualsTester() - .addEqualityGroup(config, config2) - .testEquals(); - - /* Check header types */ - Bmv2HeaderTypeModel stdMetaT = config.headerType("standard_metadata_t"); - Bmv2HeaderTypeModel ethernetT = config.headerType("ethernet_t"); - Bmv2HeaderTypeModel intrinsicMetaT = config.headerType("intrinsic_metadata_t"); - - Bmv2HeaderTypeModel stdMetaT2 = config2.headerType("standard_metadata_t"); - Bmv2HeaderTypeModel ethernetT2 = config2.headerType("ethernet_t"); - Bmv2HeaderTypeModel intrinsicMetaT2 = config2.headerType("intrinsic_metadata_t"); - - new EqualsTester() - .addEqualityGroup(stdMetaT, stdMetaT2) - .addEqualityGroup(ethernetT, ethernetT2) - .addEqualityGroup(intrinsicMetaT, intrinsicMetaT2) - .testEquals(); - - // existence - assertThat("Json parsed value is null", stdMetaT, notNullValue()); - assertThat("Json parsed value is null", ethernetT, notNullValue()); - assertThat("Json parsed value is null", intrinsicMetaT, notNullValue()); - - // fields size - assertThat("Incorrect size for header type fields", - stdMetaT.fields(), hasSize(8)); - assertThat("Incorrect size for header type fields", - ethernetT.fields(), hasSize(3)); - assertThat("Incorrect size for header type fields", - intrinsicMetaT.fields(), hasSize(4)); - - // check that fields are in order - assertThat("Incorrect order for header type fields", - stdMetaT.fields(), IsIterableContainingInOrder.contains( - stdMetaT.field("ingress_port"), - stdMetaT.field("packet_length"), - stdMetaT.field("egress_spec"), - stdMetaT.field("egress_port"), - stdMetaT.field("egress_instance"), - stdMetaT.field("instance_type"), - stdMetaT.field("clone_spec"), - stdMetaT.field("_padding"))); - - /* Check actions */ - Bmv2ActionModel floodAction = config.action("flood"); - Bmv2ActionModel dropAction = config.action("_drop"); - Bmv2ActionModel fwdAction = config.action("set_egress_port"); - - Bmv2ActionModel floodAction2 = config2.action("flood"); - Bmv2ActionModel dropAction2 = config2.action("_drop"); - Bmv2ActionModel fwdAction2 = config2.action("set_egress_port"); - - new EqualsTester() - .addEqualityGroup(floodAction, floodAction2) - .addEqualityGroup(dropAction, dropAction2) - .addEqualityGroup(fwdAction, fwdAction2) - .testEquals(); - - // existence - assertThat("Json parsed value is null", floodAction, notNullValue()); - assertThat("Json parsed value is null", dropAction, notNullValue()); - assertThat("Json parsed value is null", fwdAction, notNullValue()); - - // runtime data size - assertThat("Incorrect size for action runtime data", - floodAction.runtimeDatas().size(), is(equalTo(0))); - assertThat("Incorrect size for action runtime data", - dropAction.runtimeDatas().size(), is(equalTo(0))); - assertThat("Incorrect size for action runtime data", - fwdAction.runtimeDatas().size(), is(equalTo(1))); - - // runtime data existence and parsing - assertThat("Parsed Json value is null", - fwdAction.runtimeData("port"), notNullValue()); - assertThat("Incorrect value for action runtime data bitwidth", - fwdAction.runtimeData("port").bitWidth(), is(equalTo(9))); - - /* Check tables */ - Bmv2TableModel table0 = config.table(0); - Bmv2TableModel table02 = config2.table(0); - - new EqualsTester() - .addEqualityGroup(table0, table02) - .testEquals(); - - // existence - assertThat("Parsed Json value is null", table0, notNullValue()); - - // id and name correspondence - assertThat("Incorrect value for table name", - table0.name(), is(equalTo("table0"))); - - // keys size - assertThat("Incorrect size for table keys", - table0.keys().size(), is(equalTo(4))); - - // key match type - assertThat("Incorrect value for table key match type", - table0.keys().get(0).matchType(), is(equalTo(Bmv2MatchParam.Type.TERNARY))); - - // header type - assertThat("Incorrect value for table key header type", - table0.keys().get(0).field().header().type(), is(equalTo(stdMetaT))); - } -} \ No newline at end of file diff --git a/protocols/bmv2/api/src/test/java/org/onosproject/bmv2/api/runtime/Bmv2ExtensionsTest.java b/protocols/bmv2/api/src/test/java/org/onosproject/bmv2/api/runtime/Bmv2ExtensionsTest.java deleted file mode 100644 index d3ffbddf49..0000000000 --- a/protocols/bmv2/api/src/test/java/org/onosproject/bmv2/api/runtime/Bmv2ExtensionsTest.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.api.runtime; - -import com.eclipsesource.json.Json; -import com.eclipsesource.json.JsonObject; -import com.google.common.testing.EqualsTester; -import org.junit.Before; -import org.junit.Test; -import org.onlab.packet.MacAddress; -import org.onosproject.bmv2.api.context.Bmv2Configuration; -import org.onosproject.bmv2.api.context.Bmv2DefaultConfiguration; - -import java.io.BufferedReader; -import java.io.InputStreamReader; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; - -public class Bmv2ExtensionsTest { - - private Bmv2Configuration config; - - @Before - public void setUp() throws Exception { - JsonObject json = Json.parse(new BufferedReader(new InputStreamReader( - this.getClass().getResourceAsStream("/simple.json")))).asObject(); - config = Bmv2DefaultConfiguration.parse(json); - } - - @Test - public void testExtensionSelectorBuilder() throws Exception { - - Bmv2ExtensionSelector extSelectorExact = Bmv2ExtensionSelector.builder() - .forConfiguration(config) - .matchExact("standard_metadata", "ingress_port", (short) 255) - .matchExact("ethernet", "etherType", 512) - .matchExact("ethernet", "dstAddr", 1024L) - .matchExact("ethernet", "srcAddr", MacAddress.BROADCAST.toBytes()) - .build(); - - Bmv2ExtensionSelector extSelectorTernary = Bmv2ExtensionSelector.builder() - .forConfiguration(config) - .matchTernary("standard_metadata", "ingress_port", (short) 255, (short) 255) - .matchTernary("ethernet", "etherType", 512, 512) - .matchTernary("ethernet", "dstAddr", 1024L, 1024L) - .matchTernary("ethernet", "srcAddr", MacAddress.BROADCAST.toBytes(), MacAddress.NONE.toBytes()) - .build(); - - Bmv2ExtensionSelector extSelectorLpm = Bmv2ExtensionSelector.builder() - .forConfiguration(config) - .matchLpm("standard_metadata", "ingress_port", (short) 255, 1) - .matchLpm("ethernet", "etherType", 512, 2) - .matchLpm("ethernet", "dstAddr", 1024L, 3) - .matchLpm("ethernet", "srcAddr", MacAddress.BROADCAST.toBytes(), 4) - .build(); - - Bmv2ExtensionSelector extSelectorValid = Bmv2ExtensionSelector.builder() - .forConfiguration(config) - .matchValid("standard_metadata", "ingress_port", true) - .matchValid("ethernet", "etherType", true) - .matchValid("ethernet", "dstAddr", false) - .matchValid("ethernet", "srcAddr", false) - .build(); - - assertThat(extSelectorExact.parameterMap().size(), is(4)); - assertThat(extSelectorTernary.parameterMap().size(), is(4)); - assertThat(extSelectorLpm.parameterMap().size(), is(4)); - assertThat(extSelectorValid.parameterMap().size(), is(4)); - - // TODO add more tests, e.g. check for byte sequences content and size. - } - - @Test - public void testExtensionTreatmentBuilder() throws Exception { - - Bmv2ExtensionTreatment treatment = Bmv2ExtensionTreatment.builder() - .forConfiguration(config) - .setActionName("set_egress_port") - .addParameter("port", 1) - .build(); - - assertThat(treatment.action().parameters().size(), is(1)); - - // TODO add more tests, e.g. check for byte sequences content and size. - } - - @Test - public void testExtensionSelectorSerialization() throws Exception { - - Bmv2ExtensionSelector original = Bmv2ExtensionSelector.builder() - .forConfiguration(config) - .matchExact("standard_metadata", "ingress_port", (short) 255) - .matchLpm("ethernet", "etherType", 512, 4) - .matchTernary("ethernet", "dstAddr", 1024L, 512L) - .matchValid("ethernet", "srcAddr", true) - .build(); - - Bmv2ExtensionSelector other = Bmv2ExtensionSelector.empty(); - other.deserialize(original.serialize()); - - new EqualsTester() - .addEqualityGroup(original, other) - .testEquals(); - } - - @Test - public void testExtensionTreatmentSerialization() throws Exception { - - Bmv2ExtensionTreatment original = Bmv2ExtensionTreatment.builder() - .forConfiguration(config) - .setActionName("set_egress_port") - .addParameter("port", 1) - .build(); - - Bmv2ExtensionTreatment other = Bmv2ExtensionTreatment.empty(); - other.deserialize(original.serialize()); - - new EqualsTester() - .addEqualityGroup(original, other) - .testEquals(); - } -} \ No newline at end of file diff --git a/protocols/bmv2/api/src/test/resources/simple.json b/protocols/bmv2/api/src/test/resources/simple.json deleted file mode 100644 index 9be7b890b8..0000000000 --- a/protocols/bmv2/api/src/test/resources/simple.json +++ /dev/null @@ -1,397 +0,0 @@ -{ - "header_types": [ - { - "name": "standard_metadata_t", - "id": 0, - "fields": [ - [ - "ingress_port", - 9 - ], - [ - "packet_length", - 32 - ], - [ - "egress_spec", - 9 - ], - [ - "egress_port", - 9 - ], - [ - "egress_instance", - 32 - ], - [ - "instance_type", - 32 - ], - [ - "clone_spec", - 32 - ], - [ - "_padding", - 5 - ] - ], - "length_exp": null, - "max_length": null - }, - { - "name": "ethernet_t", - "id": 1, - "fields": [ - [ - "dstAddr", - 48 - ], - [ - "srcAddr", - 48 - ], - [ - "etherType", - 16 - ] - ], - "length_exp": null, - "max_length": null - }, - { - "name": "intrinsic_metadata_t", - "id": 2, - "fields": [ - [ - "ingress_global_timestamp", - 32 - ], - [ - "lf_field_list", - 32 - ], - [ - "mcast_grp", - 16 - ], - [ - "egress_rid", - 16 - ] - ], - "length_exp": null, - "max_length": null - } - ], - "headers": [ - { - "name": "standard_metadata", - "id": 0, - "header_type": "standard_metadata_t", - "metadata": true - }, - { - "name": "ethernet", - "id": 1, - "header_type": "ethernet_t", - "metadata": false - }, - { - "name": "intrinsic_metadata", - "id": 2, - "header_type": "intrinsic_metadata_t", - "metadata": true - } - ], - "header_stacks": [], - "parsers": [ - { - "name": "parser", - "id": 0, - "init_state": "start", - "parse_states": [ - { - "name": "start", - "id": 0, - "parser_ops": [], - "transition_key": [], - "transitions": [ - { - "value": "default", - "mask": null, - "next_state": "parse_ethernet" - } - ] - }, - { - "name": "parse_ethernet", - "id": 1, - "parser_ops": [ - { - "op": "extract", - "parameters": [ - { - "type": "regular", - "value": "ethernet" - } - ] - } - ], - "transition_key": [], - "transitions": [ - { - "value": "default", - "mask": null, - "next_state": null - } - ] - } - ] - } - ], - "deparsers": [ - { - "name": "deparser", - "id": 0, - "order": [ - "ethernet" - ] - } - ], - "meter_arrays": [], - "actions": [ - { - "name": "set_egress_port", - "id": 0, - "runtime_data": [ - { - "name": "port", - "bitwidth": 9 - } - ], - "primitives": [ - { - "op": "modify_field", - "parameters": [ - { - "type": "field", - "value": [ - "standard_metadata", - "egress_spec" - ] - }, - { - "type": "runtime_data", - "value": 0 - } - ] - } - ] - }, - { - "name": "_drop", - "id": 1, - "runtime_data": [], - "primitives": [ - { - "op": "modify_field", - "parameters": [ - { - "type": "field", - "value": [ - "standard_metadata", - "egress_spec" - ] - }, - { - "type": "hexstr", - "value": "0x1ff" - } - ] - } - ] - }, - { - "name": "flood", - "id": 2, - "runtime_data": [], - "primitives": [ - { - "op": "modify_field", - "parameters": [ - { - "type": "field", - "value": [ - "intrinsic_metadata", - "mcast_grp" - ] - }, - { - "type": "field", - "value": [ - "standard_metadata", - "ingress_port" - ] - } - ] - } - ] - }, - { - "name": "send_to_cpu", - "id": 3, - "runtime_data": [], - "primitives": [ - { - "op": "modify_field", - "parameters": [ - { - "type": "field", - "value": [ - "standard_metadata", - "egress_spec" - ] - }, - { - "type": "hexstr", - "value": "0xff" - } - ] - } - ] - } - ], - "pipelines": [ - { - "name": "ingress", - "id": 0, - "init_table": "table0", - "tables": [ - { - "name": "table0", - "id": 0, - "match_type": "ternary", - "type": "simple", - "max_size": 16384, - "with_counters": false, - "direct_meters": null, - "support_timeout": false, - "key": [ - { - "match_type": "ternary", - "target": [ - "standard_metadata", - "ingress_port" - ], - "mask": null - }, - { - "match_type": "ternary", - "target": [ - "ethernet", - "dstAddr" - ], - "mask": null - }, - { - "match_type": "ternary", - "target": [ - "ethernet", - "srcAddr" - ], - "mask": null - }, - { - "match_type": "ternary", - "target": [ - "ethernet", - "etherType" - ], - "mask": null - } - ], - "actions": [ - "set_egress_port", - "flood", - "send_to_cpu", - "_drop" - ], - "next_tables": { - "set_egress_port": null, - "flood": null, - "send_to_cpu": null, - "_drop": null - }, - "default_action": null, - "base_default_next": null - } - ], - "conditionals": [] - }, - { - "name": "egress", - "id": 1, - "init_table": null, - "tables": [], - "conditionals": [] - } - ], - "calculations": [], - "checksums": [], - "learn_lists": [], - "field_lists": [], - "counter_arrays": [], - "register_arrays": [], - "force_arith": [ - [ - "standard_metadata", - "ingress_port" - ], - [ - "standard_metadata", - "packet_length" - ], - [ - "standard_metadata", - "egress_spec" - ], - [ - "standard_metadata", - "egress_port" - ], - [ - "standard_metadata", - "egress_instance" - ], - [ - "standard_metadata", - "instance_type" - ], - [ - "standard_metadata", - "clone_spec" - ], - [ - "standard_metadata", - "_padding" - ], - [ - "intrinsic_metadata", - "ingress_global_timestamp" - ], - [ - "intrinsic_metadata", - "lf_field_list" - ], - [ - "intrinsic_metadata", - "mcast_grp" - ], - [ - "intrinsic_metadata", - "egress_rid" - ] - ] -} \ No newline at end of file diff --git a/protocols/bmv2/ctl/pom.xml b/protocols/bmv2/ctl/pom.xml deleted file mode 100644 index 5909909183..0000000000 --- a/protocols/bmv2/ctl/pom.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - onos-bmv2-protocol - org.onosproject - 1.11.0-SNAPSHOT - - 4.0.0 - - onos-bmv2-protocol-ctl - - bundle - - - - org.apache.thrift - libthrift - 0.9.3 - - - org.onosproject - onos-bmv2-protocol-api - ${project.version} - - - org.onosproject - onos-bmv2-protocol-thrift-api - ${project.version} - - - org.apache.felix - org.apache.felix.scr.annotations - - - org.onosproject - onos-core-serializers - ${project.version} - - - - - - - org.apache.felix - maven-scr-plugin - - - org.onosproject - onos-maven-plugin - - - - - - \ No newline at end of file diff --git a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2ControlPlaneThriftServer.java b/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2ControlPlaneThriftServer.java deleted file mode 100644 index bf444236da..0000000000 --- a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2ControlPlaneThriftServer.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.ctl; - -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import org.apache.thrift.TProcessor; -import org.apache.thrift.server.TThreadedSelectorServer; -import org.apache.thrift.transport.TFramedTransport; -import org.apache.thrift.transport.TNonblockingServerSocket; -import org.apache.thrift.transport.TNonblockingServerTransport; -import org.apache.thrift.transport.TNonblockingSocket; -import org.apache.thrift.transport.TNonblockingTransport; -import org.apache.thrift.transport.TTransport; -import org.apache.thrift.transport.TTransportException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.nio.channels.SelectionKey; -import java.nio.channels.SocketChannel; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ExecutorService; - -/** - * A Thrift TThreadedSelectorServer that keeps track of the clients' IP address. - */ -final class Bmv2ControlPlaneThriftServer extends TThreadedSelectorServer { - - private static final int MAX_WORKER_THREADS = 20; - private static final int MAX_SELECTOR_THREADS = 4; - private static final int ACCEPT_QUEUE_LEN = 8; - - private final Map clientAddresses = Maps.newConcurrentMap(); - private final Set selectorThreads = Sets.newHashSet(); - - private AcceptThread acceptThread; - - private final Logger log = LoggerFactory.getLogger(this.getClass()); - - /** - * Creates a new server. - * - * @param port a listening port - * @param processor a processor - * @param executorService an executor service - * @throws TTransportException - */ - public Bmv2ControlPlaneThriftServer(int port, TProcessor processor, ExecutorService executorService) - throws TTransportException { - super(new TThreadedSelectorServer.Args(new TNonblockingServerSocket(port)) - .workerThreads(MAX_WORKER_THREADS) - .selectorThreads(MAX_SELECTOR_THREADS) - .acceptQueueSizePerThread(ACCEPT_QUEUE_LEN) - .executorService(executorService) - .processor(processor)); - } - - /** - * Returns the IP address of the client associated with the given input framed transport. - * - * @param inputTransport a framed transport instance - * @return the IP address of the client or null - */ - InetAddress getClientAddress(TFramedTransport inputTransport) { - return clientAddresses.get(inputTransport); - } - - @Override - protected boolean startThreads() { - try { - for (int i = 0; i < MAX_SELECTOR_THREADS; ++i) { - selectorThreads.add(new TrackingSelectorThread(ACCEPT_QUEUE_LEN)); - } - acceptThread = new AcceptThread((TNonblockingServerTransport) serverTransport_, - createSelectorThreadLoadBalancer(selectorThreads)); - selectorThreads.forEach(Thread::start); - acceptThread.start(); - return true; - } catch (IOException e) { - log.error("Failed to start threads!", e); - return false; - } - } - - @Override - protected void joinThreads() throws InterruptedException { - // Wait until the io threads exit. - acceptThread.join(); - for (TThreadedSelectorServer.SelectorThread thread : selectorThreads) { - thread.join(); - } - } - - @Override - public void stop() { - stopped_ = true; - // Stop queuing connect attempts asap. - stopListening(); - if (acceptThread != null) { - acceptThread.wakeupSelector(); - } - if (selectorThreads != null) { - selectorThreads.stream() - .filter(thread -> thread != null) - .forEach(TrackingSelectorThread::wakeupSelector); - } - } - - private class TrackingSelectorThread extends TThreadedSelectorServer.SelectorThread { - - TrackingSelectorThread(int maxPendingAccepts) throws IOException { - super(maxPendingAccepts); - } - - @Override - protected FrameBuffer createFrameBuffer(TNonblockingTransport trans, SelectionKey selectionKey, - AbstractSelectThread selectThread) { - TrackingFrameBuffer frameBuffer = new TrackingFrameBuffer(trans, selectionKey, selectThread); - if (trans instanceof TNonblockingSocket) { - try { - SocketChannel socketChannel = ((TNonblockingSocket) trans).getSocketChannel(); - InetAddress addr = ((InetSocketAddress) socketChannel.getRemoteAddress()).getAddress(); - clientAddresses.put(frameBuffer.getInputFramedTransport(), addr); - } catch (IOException e) { - log.warn("Exception while tracking client address", e); - clientAddresses.remove(frameBuffer.getInputFramedTransport()); - } - } else { - log.warn("Unknown TNonblockingTransport instance: {}", trans.getClass().getName()); - clientAddresses.remove(frameBuffer.getInputFramedTransport()); - } - return frameBuffer; - } - } - - private class TrackingFrameBuffer extends FrameBuffer { - - TrackingFrameBuffer(TNonblockingTransport trans, SelectionKey selectionKey, - AbstractSelectThread selectThread) { - super(trans, selectionKey, selectThread); - } - - TTransport getInputFramedTransport() { - return this.inTrans_; - } - } -} diff --git a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2ControllerImpl.java b/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2ControllerImpl.java deleted file mode 100644 index 4a63d21a36..0000000000 --- a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2ControllerImpl.java +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.ctl; - -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.common.cache.RemovalListener; -import com.google.common.cache.RemovalNotification; -import com.google.common.collect.Maps; -import org.apache.commons.lang3.tuple.Pair; -import org.apache.felix.scr.annotations.Activate; -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.Deactivate; -import org.apache.felix.scr.annotations.Reference; -import org.apache.felix.scr.annotations.ReferenceCardinality; -import org.apache.felix.scr.annotations.Service; -import org.apache.thrift.TException; -import org.apache.thrift.TProcessor; -import org.apache.thrift.protocol.TBinaryProtocol; -import org.apache.thrift.protocol.TMultiplexedProtocol; -import org.apache.thrift.protocol.TProtocol; -import org.apache.thrift.transport.TFramedTransport; -import org.apache.thrift.transport.TSocket; -import org.apache.thrift.transport.TTransport; -import org.apache.thrift.transport.TTransportException; -import org.onlab.util.ImmutableByteSequence; -import org.onosproject.bmv2.api.runtime.Bmv2Device; -import org.onosproject.bmv2.api.runtime.Bmv2DeviceAgent; -import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException; -import org.onosproject.bmv2.api.service.Bmv2Controller; -import org.onosproject.bmv2.api.service.Bmv2DeviceListener; -import org.onosproject.bmv2.api.service.Bmv2PacketListener; -import org.onosproject.bmv2.thriftapi.BmConfig; -import org.onosproject.bmv2.thriftapi.ControlPlaneService; -import org.onosproject.bmv2.thriftapi.SimpleSwitch; -import org.onosproject.bmv2.thriftapi.Standard; -import org.onosproject.core.CoreService; -import org.onosproject.net.DeviceId; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.net.InetAddress; -import java.nio.ByteBuffer; -import java.util.List; -import java.util.Set; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.CopyOnWriteArraySet; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - -import static com.google.common.base.Preconditions.checkNotNull; -import static org.onlab.util.Tools.groupedThreads; -import static org.onosproject.bmv2.thriftapi.ControlPlaneService.Processor; - -/** - * Default implementation of a BMv2 controller. - */ -@Component(immediate = true) -@Service -public class Bmv2ControllerImpl implements Bmv2Controller { - - private static final String APP_ID = "org.onosproject.bmv2"; - - // Seconds after a client is expired (and connection closed) in the cache. - private static final int CLIENT_CACHE_TIMEOUT = 60; - // Number of connection retries after a network error. - private static final int NUM_CONNECTION_RETRIES = 2; - // Time between retries in milliseconds. - private static final int TIME_BETWEEN_RETRIES = 10; - - private final Logger log = LoggerFactory.getLogger(this.getClass()); - - // Cache where clients are removed after a predefined timeout. - private final LoadingCache> agentCache = - CacheBuilder.newBuilder() - .expireAfterAccess(CLIENT_CACHE_TIMEOUT, TimeUnit.SECONDS) - .removalListener(new ClientRemovalListener()) - .build(new ClientLoader()); - - private final TProcessor trackingProcessor = new TrackingProcessor(); - - private final ExecutorService executorService = Executors - .newFixedThreadPool(32, groupedThreads("onos/bmv2", "controller", log)); - - private final Set deviceListeners = new CopyOnWriteArraySet<>(); - private final Set packetListeners = new CopyOnWriteArraySet<>(); - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected CoreService coreService; - - private Bmv2ControlPlaneThriftServer server; - - // TODO: make it configurable trough component config - private int serverPort = DEFAULT_PORT; - - @Activate - public void activate() { - coreService.registerApplication(APP_ID); - startServer(serverPort); - log.info("Activated"); - } - - @Deactivate - public void deactivate() { - stopServer(); - log.info("Deactivated"); - } - - private void startServer(int port) { - try { - log.info("Starting server on port {}...", port); - this.server = new Bmv2ControlPlaneThriftServer(port, trackingProcessor, executorService); - executorService.execute(server::serve); - } catch (TTransportException e) { - log.error("Unable to start server", e); - } - } - - private void stopServer() { - // Stop the server if running... - if (server != null && !server.isServing()) { - server.setShouldStop(true); - server.stop(); - } - try { - executorService.shutdown(); - executorService.awaitTermination(5, TimeUnit.SECONDS); - } catch (InterruptedException e) { - List runningTasks = executorService.shutdownNow(); - log.warn("Unable to stop server threads: {}", runningTasks); - } - } - - @Override - public Bmv2DeviceAgent getAgent(DeviceId deviceId) throws Bmv2RuntimeException { - try { - checkNotNull(deviceId, "deviceId cannot be null"); - return agentCache.get(deviceId).getRight(); - } catch (ExecutionException e) { - throw new Bmv2RuntimeException(e); - } - } - - @Override - public boolean isReacheable(DeviceId deviceId) { - try { - Bmv2DeviceThriftClient client = (Bmv2DeviceThriftClient) getAgent(deviceId); - BmConfig config = client.standardClient.bm_mgmt_get_info(); - // The BMv2 instance running at this thrift IP and port might have a different BMv2 internal ID. - return config.getDevice_id() == Integer.valueOf(deviceId.uri().getFragment()); - } catch (Bmv2RuntimeException | TException e) { - return false; - } - } - - @Override - public void addDeviceListener(Bmv2DeviceListener listener) { - if (!deviceListeners.contains(listener)) { - deviceListeners.add(listener); - } - } - - @Override - public void removeDeviceListener(Bmv2DeviceListener listener) { - deviceListeners.remove(listener); - } - - @Override - public void addPacketListener(Bmv2PacketListener listener) { - if (!packetListeners.contains(listener)) { - packetListeners.add(listener); - } - } - - @Override - public void removePacketListener(Bmv2PacketListener listener) { - packetListeners.remove(listener); - } - - /** - * Client cache removal listener. Close the connection on cache removal. - */ - private static class ClientRemovalListener implements - RemovalListener> { - - @Override - public void onRemoval(RemovalNotification> notification) { - // close the transport connection - Bmv2DeviceThriftClient client = notification.getValue().getRight(); - TTransport transport = notification.getValue().getLeft(); - // Locking here is ugly, but needed (see SafeThriftClient). - synchronized (transport) { - if (transport.isOpen()) { - transport.close(); - } - } - } - } - - /** - * Handles requests from BMv2 devices using the registered listeners. - */ - private final class ServiceHandler implements ControlPlaneService.Iface { - - private final InetAddress clientAddress; - private Bmv2Device remoteDevice; - - ServiceHandler(InetAddress clientAddress) { - this.clientAddress = clientAddress; - } - - @Override - public boolean ping() { - return true; - } - - @Override - public void hello(int thriftServerPort, int deviceId, int instanceId, String jsonConfigMd5) { - // Store a reference to the remote device for future uses. - String host = clientAddress.getHostAddress(); - remoteDevice = new Bmv2Device(host, thriftServerPort, deviceId); - - if (deviceListeners.size() == 0) { - log.debug("Received hello, but there's no listener registered."); - } else { - deviceListeners.forEach(l -> l.handleHello(remoteDevice, instanceId, jsonConfigMd5)); - } - } - - @Override - public void packet_in(int port, ByteBuffer data, int dataLength) { - if (remoteDevice == null) { - log.debug("Received packet-in, but the remote device is still unknown. Need a hello first..."); - return; - } - - if (packetListeners.size() == 0) { - log.debug("Received packet-in, but there's no listener registered."); - } else { - byte[] bytes = new byte[dataLength]; - data.get(bytes); - ImmutableByteSequence pkt = ImmutableByteSequence.copyFrom(bytes); - packetListeners.forEach(l -> l.handlePacketIn(remoteDevice, port, pkt)); - } - } - } - - /** - * Decorator of a Thrift processor needed in order to keep track of the client's IP address that originated the - * request. - */ - private final class TrackingProcessor implements TProcessor { - - // Map transports to processors. - private final ConcurrentMap> processors = Maps.newConcurrentMap(); - - @Override - public boolean process(final TProtocol in, final TProtocol out) throws TException { - // Get the client address for this request. - InetAddress clientAddress = server.getClientAddress((TFramedTransport) in.getTransport()); - if (clientAddress != null) { - // Get or create a processor for this input transport, i.e. the client on the other side. - Processor processor = processors.computeIfAbsent( - in.getTransport(), t -> new Processor<>(new ServiceHandler(clientAddress))); - // Delegate to the processor we are decorating. - return processor.process(in, out); - } else { - log.warn("Unable to retrieve client IP address of incoming request"); - return false; - } - } - } - - /** - * Cache loader of BMv2 Thrift clients. - */ - private class ClientLoader extends CacheLoader> { - - private final SafeThriftClient.Options options = new SafeThriftClient.Options(NUM_CONNECTION_RETRIES, - TIME_BETWEEN_RETRIES); - - @Override - public Pair load(DeviceId deviceId) - throws TTransportException { - log.debug("Instantiating new client... > deviceId={}", deviceId); - // Make the expensive call - Bmv2Device device = Bmv2Device.of(deviceId); - TTransport transport = new TSocket(device.thriftServerHost(), device.thriftServerPort()); - TProtocol protocol = new TBinaryProtocol(transport); - // Our BMv2 device implements multiple Thrift services, create a client for each one on the same transport. - Standard.Client standardClient = new Standard.Client( - new TMultiplexedProtocol(protocol, "standard")); - SimpleSwitch.Client simpleSwitch = new SimpleSwitch.Client( - new TMultiplexedProtocol(protocol, "simple_switch")); - // Wrap clients so to automatically have synchronization and resiliency to connectivity errors - Standard.Iface safeStandardClient = SafeThriftClient.wrap(standardClient, - Standard.Iface.class, - options); - SimpleSwitch.Iface safeSimpleSwitchClient = SafeThriftClient.wrap(simpleSwitch, - SimpleSwitch.Iface.class, - options); - Bmv2DeviceThriftClient client = new Bmv2DeviceThriftClient(deviceId, - transport, - safeStandardClient, - safeSimpleSwitchClient); - return Pair.of(transport, client); - } - } -} diff --git a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2DefaultInterpreterImpl.java b/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2DefaultInterpreterImpl.java deleted file mode 100644 index 55bf60c653..0000000000 --- a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2DefaultInterpreterImpl.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.ctl; - -import com.google.common.collect.ImmutableBiMap; -import org.onlab.util.ImmutableByteSequence; -import org.onosproject.bmv2.api.context.Bmv2Configuration; -import org.onosproject.bmv2.api.context.Bmv2Interpreter; -import org.onosproject.bmv2.api.context.Bmv2InterpreterException; -import org.onosproject.bmv2.api.runtime.Bmv2Action; -import org.onosproject.net.PortNumber; -import org.onosproject.net.flow.TrafficTreatment; -import org.onosproject.net.flow.criteria.Criterion; -import org.onosproject.net.flow.instructions.Instruction; - -import static org.onlab.util.ImmutableByteSequence.copyFrom; -import static org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils.ByteSequenceFitException; -import static org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils.fitByteSequence; -import static org.onosproject.net.PortNumber.CONTROLLER; -import static org.onosproject.net.flow.instructions.Instructions.OutputInstruction; - -/** - * Implementation of a BMv2 interpreter for the BMv2 default.json configuration. - */ -public final class Bmv2DefaultInterpreterImpl implements Bmv2Interpreter { - - public static final String TABLE0 = "table0"; - public static final String SEND_TO_CPU = "send_to_cpu"; - public static final String PORT = "port"; - public static final String DROP = "_drop"; - public static final String SET_EGRESS_PORT = "set_egress_port"; - - private static final ImmutableBiMap CRITERION_MAP = ImmutableBiMap.of( - Criterion.Type.IN_PORT, "standard_metadata.ingress_port", - Criterion.Type.ETH_DST, "ethernet.dstAddr", - Criterion.Type.ETH_SRC, "ethernet.srcAddr", - Criterion.Type.ETH_TYPE, "ethernet.etherType"); - - private static final ImmutableBiMap TABLE_MAP = ImmutableBiMap.of( - 0, TABLE0); - - @Override - public ImmutableBiMap criterionTypeMap() { - return CRITERION_MAP; - } - - @Override - public ImmutableBiMap tableIdMap() { - return TABLE_MAP; - } - - @Override - public Bmv2Action mapTreatment(TrafficTreatment treatment, Bmv2Configuration configuration) - throws Bmv2InterpreterException { - - if (treatment.allInstructions().size() == 0) { - // No instructions means drop for us. - return actionWithName(DROP); - } else if (treatment.allInstructions().size() > 1) { - // Otherwise, we understand treatments with only 1 instruction. - throw new Bmv2InterpreterException("Treatment has multiple instructions"); - } - - Instruction instruction = treatment.allInstructions().get(0); - - switch (instruction.type()) { - case OUTPUT: - OutputInstruction outInstruction = (OutputInstruction) instruction; - PortNumber port = outInstruction.port(); - if (!port.isLogical()) { - return buildEgressAction(port, configuration); - } else if (port.equals(CONTROLLER)) { - return actionWithName(SEND_TO_CPU); - } else { - throw new Bmv2InterpreterException("Egress on logical port not supported: " + port); - } - case NOACTION: - return actionWithName(DROP); - default: - throw new Bmv2InterpreterException("Instruction type not supported: " + instruction.type().name()); - } - } - - private Bmv2Action buildEgressAction(PortNumber port, Bmv2Configuration configuration) - throws Bmv2InterpreterException { - - int portBitWidth = configuration.action(SET_EGRESS_PORT).runtimeData(PORT).bitWidth(); - - try { - ImmutableByteSequence portBs = fitByteSequence(copyFrom(port.toLong()), portBitWidth); - return Bmv2Action.builder() - .withName(SET_EGRESS_PORT) - .addParameter(portBs) - .build(); - } catch (ByteSequenceFitException e) { - throw new Bmv2InterpreterException(e.getMessage()); - } - } - - private Bmv2Action actionWithName(String name) { - return Bmv2Action.builder().withName(name).build(); - } -} diff --git a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2DeviceContextServiceImpl.java b/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2DeviceContextServiceImpl.java deleted file mode 100644 index e077b6d062..0000000000 --- a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2DeviceContextServiceImpl.java +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.ctl; - -import com.eclipsesource.json.Json; -import com.eclipsesource.json.JsonObject; -import com.esotericsoftware.kryo.Kryo; -import com.esotericsoftware.kryo.io.Input; -import com.esotericsoftware.kryo.io.Output; -import com.google.common.collect.Maps; -import org.apache.felix.scr.annotations.Activate; -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.Deactivate; -import org.apache.felix.scr.annotations.Reference; -import org.apache.felix.scr.annotations.ReferenceCardinality; -import org.apache.felix.scr.annotations.Service; -import org.onlab.util.KryoNamespace; -import org.onlab.util.SharedScheduledExecutors; -import org.onosproject.bmv2.api.context.Bmv2Configuration; -import org.onosproject.bmv2.api.context.Bmv2DefaultConfiguration; -import org.onosproject.bmv2.api.context.Bmv2DeviceContext; -import org.onosproject.bmv2.api.context.Bmv2Interpreter; -import org.onosproject.bmv2.api.runtime.Bmv2DeviceAgent; -import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException; -import org.onosproject.bmv2.api.service.Bmv2Controller; -import org.onosproject.bmv2.api.service.Bmv2DeviceContextService; -import org.onosproject.mastership.MastershipService; -import org.onosproject.net.DeviceId; -import org.onosproject.net.device.DeviceService; -import org.onosproject.store.serializers.KryoNamespaces; -import org.onosproject.store.service.ConsistentMap; -import org.onosproject.store.service.ConsistentMapException; -import org.onosproject.store.service.MapEvent; -import org.onosproject.store.service.MapEventListener; -import org.onosproject.store.service.Serializer; -import org.onosproject.store.service.StorageService; -import org.onosproject.store.service.Versioned; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.Map; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -import static com.google.common.base.Preconditions.checkNotNull; -import static org.onosproject.bmv2.api.context.Bmv2DefaultConfiguration.parse; -import static org.onosproject.store.service.MapEvent.Type.INSERT; -import static org.onosproject.store.service.MapEvent.Type.UPDATE; - -@Component(immediate = true) -@Service -public class Bmv2DeviceContextServiceImpl implements Bmv2DeviceContextService { - - private static final String JSON_DEFAULT_CONFIG_PATH = "/default.json"; - private static final long CHECK_INTERVAL = 5_000; // milliseconds - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - private StorageService storageService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - private DeviceService deviceService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - private MastershipService mastershipService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - private Bmv2Controller controller; - - private final ScheduledExecutorService scheduledExecutor = SharedScheduledExecutors.getPoolThreadExecutor(); - private final MapEventListener contextListener = new ContextMapEventListener(); - private final ConcurrentMap deviceLocks = Maps.newConcurrentMap(); - - private ConsistentMap contexts; - private Map interpreterClassLoaders; - private Bmv2DeviceContext defaultContext; - private ScheduledFuture configChecker = null; - - private final Logger log = LoggerFactory.getLogger(getClass()); - - @Activate - public void activate() { - KryoNamespace kryo = new KryoNamespace.Builder() - .register(KryoNamespaces.API) - .register(new BmvDeviceContextSerializer(), Bmv2DeviceContext.class) - .build(); - - this.contexts = storageService.consistentMapBuilder() - .withSerializer(Serializer.using(kryo)) - .withName("onos-bmv2-contexts") - .build(); - - Bmv2Configuration defaultConfiguration = loadDefaultConfiguration(); - Bmv2Interpreter defaultInterpreter = new Bmv2DefaultInterpreterImpl(); - defaultContext = new Bmv2DeviceContext(defaultConfiguration, defaultInterpreter); - - interpreterClassLoaders = Maps.newConcurrentMap(); - registerInterpreterClassLoader(defaultInterpreter.getClass(), this.getClass().getClassLoader()); - - contexts.addListener(contextListener, scheduledExecutor); - - if (configChecker != null && configChecker.isCancelled()) { - configChecker.cancel(false); - } - configChecker = scheduledExecutor.scheduleAtFixedRate(this::checkDevices, 0, CHECK_INTERVAL, - TimeUnit.MILLISECONDS); - - log.info("Started"); - } - - @Deactivate - public void deactivate() { - contexts.removeListener(contextListener); - if (configChecker != null) { - configChecker.cancel(false); - } - log.info("Stopped"); - } - - @Override - public Bmv2DeviceContext getContext(DeviceId deviceId) { - checkNotNull(deviceId, "device id cannot be null"); - Versioned versionedContext = contexts.get(deviceId); - return (versionedContext == null) ? null : versionedContext.value(); - } - - @Override - public void setContext(DeviceId deviceId, Bmv2DeviceContext context) { - checkNotNull(deviceId, "device id cannot be null"); - checkNotNull(context, "context cannot be null"); - if (!interpreterClassLoaders.containsKey(context.interpreter().getClass().getName())) { - log.error("Unable to set context, missing class loader for interpreter '{}'. " + - "Please register it with registerInterpreterClassLoader()", - context.interpreter().getClass().getName()); - } else { - try { - contexts.put(deviceId, context); - } catch (ConsistentMapException.ConcurrentModification e) { - log.error("Detected concurrent modification on context map"); - } - } - } - - @Override - public void registerInterpreterClassLoader(Class interpreterClass, ClassLoader loader) { - interpreterClassLoaders.put(interpreterClass.getName(), loader); - } - - @Override - public Bmv2DeviceContext defaultContext() { - return defaultContext; - } - - @Override - public void setDefaultContext(DeviceId deviceId) { - Versioned previous = contexts.put(deviceId, defaultContext); - if (mastershipService.getMasterFor(deviceId) == null) { - // Checking for who is the master here is ugly but necessary, as this method is called by Bmv2DeviceProvider - // prior to master election. A solution could be to use a separate leadership contest instead of the - // mastership service. - triggerConfigCheck(deviceId, defaultContext); - } - } - - private void configCheck(DeviceId deviceId, Bmv2DeviceContext storedContext) { - if (storedContext == null) { - return; - } - // Synchronize executions over the same deviceId. - Lock lock = deviceLocks.computeIfAbsent(deviceId, did -> new ReentrantLock()); - lock.lock(); - try { - log.trace("Executing configuration check on {}...", deviceId); - - try { - // FIXME: JSON dump is heavy, can we use the JSON MD5 to check the running configuration? - String jsonString = controller.getAgent(deviceId).dumpJsonConfig(); - Bmv2Configuration deviceConfiguration = parse(Json.parse(jsonString).asObject()); - - if (!storedContext.configuration().equals(deviceConfiguration)) { - log.info("Triggering configuration swap on {}...", deviceId); - try { - Bmv2DeviceAgent agent = controller.getAgent(deviceId); - String newJsonString = storedContext.configuration().json().toString(); - agent.uploadNewJsonConfig(newJsonString); - agent.swapJsonConfig(); - } catch (Bmv2RuntimeException e) { - log.error("Unable to swap configuration on {}: {}", deviceId, e.explain()); - } - } - } catch (Bmv2RuntimeException e) { - log.warn("Unable to dump JSON configuration from {}: {}", deviceId, e.explain()); - } - } finally { - lock.unlock(); - } - } - - private void triggerConfigCheck(DeviceId deviceId, Bmv2DeviceContext context) { - scheduledExecutor.schedule(() -> configCheck(deviceId, context), 0, TimeUnit.SECONDS); - } - - private void checkDevices() { - deviceService.getAvailableDevices().forEach(device -> { - if (mastershipService.isLocalMaster(device.id())) { - triggerConfigCheck(device.id(), getContext(device.id())); - } - }); - } - - protected static Bmv2DefaultConfiguration loadDefaultConfiguration() { - try { - JsonObject json = Json.parse(new BufferedReader(new InputStreamReader( - Bmv2DeviceContextServiceImpl.class.getResourceAsStream(JSON_DEFAULT_CONFIG_PATH)))).asObject(); - return parse(json); - } catch (IOException e) { - throw new RuntimeException("Unable to load default configuration", e); - } - } - - /** - * Listener of context changes that immediately triggers config checks (to swap the config if necessary). - */ - private class ContextMapEventListener implements MapEventListener { - @Override - public void event(MapEvent event) { - DeviceId deviceId = event.key(); - if (event.type().equals(INSERT) || event.type().equals(UPDATE)) { - if (mastershipService.isLocalMaster(deviceId)) { - log.trace("Context {} for {}", event.type().name(), deviceId); - triggerConfigCheck(deviceId, event.newValue().value()); - } - } - } - } - - /** - * Context serializer. - */ - private class BmvDeviceContextSerializer extends com.esotericsoftware.kryo.Serializer { - - @Override - public void write(Kryo kryo, Output output, Bmv2DeviceContext context) { - kryo.writeObject(output, context.configuration().json().toString()); - kryo.writeObject(output, context.interpreter().getClass().getName()); - } - - @Override - public Bmv2DeviceContext read(Kryo kryo, Input input, Class type) { - String jsonStr = kryo.readObject(input, String.class); - String interpreterClassName = kryo.readObject(input, String.class); - Bmv2Configuration configuration = parse(Json.parse(jsonStr).asObject()); - ClassLoader loader = interpreterClassLoaders.get(interpreterClassName); - if (loader == null) { - throw new IllegalStateException("No class loader registered for interpreter: " + interpreterClassName); - } - try { - Bmv2Interpreter interpreter = (Bmv2Interpreter) loader.loadClass(interpreterClassName).newInstance(); - return new Bmv2DeviceContext(configuration, interpreter); - } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { - throw new RuntimeException("Unable to load interpreter class", e); - } - } - } -} diff --git a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2DeviceThriftClient.java b/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2DeviceThriftClient.java deleted file mode 100644 index 5bd5228f62..0000000000 --- a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2DeviceThriftClient.java +++ /dev/null @@ -1,486 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.ctl; - -import com.google.common.collect.Lists; -import org.apache.commons.lang3.tuple.Pair; -import org.apache.thrift.TException; -import org.apache.thrift.transport.TTransport; -import org.onlab.util.ImmutableByteSequence; -import org.onosproject.bmv2.api.runtime.Bmv2Action; -import org.onosproject.bmv2.api.runtime.Bmv2DeviceAgent; -import org.onosproject.bmv2.api.runtime.Bmv2ExactMatchParam; -import org.onosproject.bmv2.api.runtime.Bmv2LpmMatchParam; -import org.onosproject.bmv2.api.runtime.Bmv2MatchKey; -import org.onosproject.bmv2.api.runtime.Bmv2MatchParam; -import org.onosproject.bmv2.api.runtime.Bmv2ParsedTableEntry; -import org.onosproject.bmv2.api.runtime.Bmv2PortInfo; -import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException; -import org.onosproject.bmv2.api.runtime.Bmv2TableEntry; -import org.onosproject.bmv2.api.runtime.Bmv2TernaryMatchParam; -import org.onosproject.bmv2.api.runtime.Bmv2ValidMatchParam; -import org.onosproject.bmv2.thriftapi.BmActionEntry; -import org.onosproject.bmv2.thriftapi.BmAddEntryOptions; -import org.onosproject.bmv2.thriftapi.BmCounterValue; -import org.onosproject.bmv2.thriftapi.BmMatchParam; -import org.onosproject.bmv2.thriftapi.BmMatchParamExact; -import org.onosproject.bmv2.thriftapi.BmMatchParamLPM; -import org.onosproject.bmv2.thriftapi.BmMatchParamTernary; -import org.onosproject.bmv2.thriftapi.BmMatchParamType; -import org.onosproject.bmv2.thriftapi.BmMatchParamValid; -import org.onosproject.bmv2.thriftapi.BmMtEntry; -import org.onosproject.bmv2.thriftapi.SimpleSwitch; -import org.onosproject.bmv2.thriftapi.Standard; -import org.onosproject.net.DeviceId; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.nio.ByteBuffer; -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; - -import static org.onlab.util.ImmutableByteSequence.copyFrom; -import static org.onosproject.bmv2.ctl.Bmv2TExceptionParser.parseTException; - -/** - * Implementation of a Thrift client to control a BMv2 device. - */ -public final class Bmv2DeviceThriftClient implements Bmv2DeviceAgent { - - private final Logger log = LoggerFactory.getLogger(this.getClass()); - - // FIXME: make context_id arbitrary for each call - // See: https://github.com/p4lang/behavioral-model/blob/master/modules/bm_sim/include/bm_sim/context.h - private static final int CONTEXT_ID = 0; - - protected final Standard.Iface standardClient; - private final SimpleSwitch.Iface simpleSwitchClient; - private final TTransport transport; - private final DeviceId deviceId; - - // ban constructor - protected Bmv2DeviceThriftClient(DeviceId deviceId, TTransport transport, Standard.Iface standardClient, - SimpleSwitch.Iface simpleSwitchClient) { - this.deviceId = deviceId; - this.transport = transport; - this.standardClient = standardClient; - this.simpleSwitchClient = simpleSwitchClient; - } - - @Override - public DeviceId deviceId() { - return deviceId; - } - - @Override - public boolean ping() { - try { - return this.simpleSwitchClient.ping(); - } catch (TException e) { - return false; - } - } - - @Override - public final long addTableEntry(Bmv2TableEntry entry) throws Bmv2RuntimeException { - - log.debug("Adding table entry... > deviceId={}, entry={}", deviceId, entry); - - long entryId = -1; - - try { - BmAddEntryOptions options = new BmAddEntryOptions(); - - if (entry.hasPriority()) { - options.setPriority(entry.priority()); - } - - entryId = standardClient.bm_mt_add_entry( - CONTEXT_ID, - entry.tableName(), - buildMatchParamsList(entry.matchKey()), - entry.action().name(), - buildActionParamsList(entry.action()), - options); - - if (entry.hasTimeout()) { - /* bmv2 accepts timeouts in milliseconds */ - int msTimeout = (int) Math.round(entry.timeout() * 1_000); - standardClient.bm_mt_set_entry_ttl( - CONTEXT_ID, entry.tableName(), entryId, msTimeout); - } - - log.debug("Table entry added! > deviceId={}, entryId={}/{}", deviceId, entry.tableName(), entryId); - - return entryId; - - } catch (TException e) { - log.debug("Exception while adding table entry: {} > deviceId={}, tableName={}", - e, deviceId, entry.tableName()); - if (entryId != -1) { - // entry is in inconsistent state (unable to add timeout), remove it - try { - deleteTableEntry(entry.tableName(), entryId); - } catch (Bmv2RuntimeException e1) { - log.debug("Unable to remove failed table entry: {} > deviceId={}, tableName={}", - e1, deviceId, entry.tableName()); - } - } - throw parseTException(e); - } - } - - @Override - public final void modifyTableEntry(String tableName, - long entryId, Bmv2Action action) - throws Bmv2RuntimeException { - - log.debug("Modifying table entry... > deviceId={}, entryId={}/{}", deviceId, tableName, entryId); - - try { - standardClient.bm_mt_modify_entry( - CONTEXT_ID, - tableName, - entryId, - action.name(), - buildActionParamsList(action)); - log.debug("Table entry modified! > deviceId={}, entryId={}/{}", deviceId, tableName, entryId); - } catch (TException e) { - log.debug("Exception while modifying table entry: {} > deviceId={}, entryId={}/{}", - e, deviceId, tableName, entryId); - throw parseTException(e); - } - } - - @Override - public final void deleteTableEntry(String tableName, - long entryId) throws Bmv2RuntimeException { - - log.debug("Deleting table entry... > deviceId={}, entryId={}/{}", deviceId, tableName, entryId); - - try { - standardClient.bm_mt_delete_entry(CONTEXT_ID, tableName, entryId); - log.debug("Table entry deleted! > deviceId={}, entryId={}/{}", deviceId, tableName, entryId); - } catch (TException e) { - log.debug("Exception while deleting table entry: {} > deviceId={}, entryId={}/{}", - e, deviceId, tableName, entryId); - throw parseTException(e); - } - } - - @Override - public final void setTableDefaultAction(String tableName, Bmv2Action action) - throws Bmv2RuntimeException { - - log.debug("Setting table default... > deviceId={}, tableName={}, action={}", deviceId, tableName, action); - - try { - standardClient.bm_mt_set_default_action( - CONTEXT_ID, - tableName, - action.name(), - buildActionParamsList(action)); - log.debug("Table default set! > deviceId={}, tableName={}, action={}", deviceId, tableName, action); - } catch (TException e) { - log.debug("Exception while setting table default : {} > deviceId={}, tableName={}, action={}", - e, deviceId, tableName, action); - throw parseTException(e); - } - } - - @Override - public Collection getPortsInfo() throws Bmv2RuntimeException { - - log.debug("Retrieving port info... > deviceId={}", deviceId); - - try { - return standardClient.bm_dev_mgr_show_ports().stream() - .map(p -> new Bmv2PortInfo(p.getIface_name(), p.getPort_num(), p.isIs_up())) - .collect(Collectors.toList()); - } catch (TException e) { - log.debug("Exception while retrieving port info: {} > deviceId={}", e, deviceId); - throw parseTException(e); - } - } - - @Override - public List getTableEntries(String tableName) throws Bmv2RuntimeException { - - log.debug("Retrieving table entries... > deviceId={}, tableName={}", deviceId, tableName); - - List bmEntries; - try { - bmEntries = standardClient.bm_mt_get_entries(CONTEXT_ID, tableName); - } catch (TException e) { - log.debug("Exception while retrieving table entries: {} > deviceId={}, tableName={}", - e, deviceId, tableName); - throw parseTException(e); - } - - List parsedEntries = Lists.newArrayList(); - - entryLoop: - for (BmMtEntry bmEntry : bmEntries) { - - Bmv2MatchKey.Builder matchKeyBuilder = Bmv2MatchKey.builder(); - for (BmMatchParam bmParam : bmEntry.getMatch_key()) { - Bmv2MatchParam param; - switch (bmParam.getType()) { - case EXACT: - param = new Bmv2ExactMatchParam(copyFrom(bmParam.getExact().getKey())); - break; - case LPM: - param = new Bmv2LpmMatchParam(copyFrom(bmParam.getLpm().getKey()), - bmParam.getLpm().getPrefix_length()); - break; - case TERNARY: - param = new Bmv2TernaryMatchParam(copyFrom(bmParam.getTernary().getKey()), - copyFrom(bmParam.getTernary().getMask())); - break; - case VALID: - param = new Bmv2ValidMatchParam(bmParam.getValid().isKey()); - break; - default: - log.warn("Parsing of match type {} unsupported, skipping table entry.", - bmParam.getType().name()); - continue entryLoop; - } - matchKeyBuilder.add(param); - } - - Bmv2Action.Builder actionBuilder = Bmv2Action.builder(); - BmActionEntry bmActionEntry = bmEntry.getAction_entry(); - switch (bmActionEntry.getAction_type()) { - case ACTION_DATA: - actionBuilder.withName(bmActionEntry.getAction_name()); - bmActionEntry.getAction_data() - .stream() - .map(ImmutableByteSequence::copyFrom) - .forEach(actionBuilder::addParameter); - break; - default: - log.warn("Parsing of action action type {} unsupported, skipping table entry.", - bmActionEntry.getAction_type().name()); - continue entryLoop; - } - - parsedEntries.add(new Bmv2ParsedTableEntry(bmEntry.getEntry_handle(), matchKeyBuilder.build(), - actionBuilder.build(), bmEntry.getOptions().getPriority())); - } - - return parsedEntries; - } - - @Override - public void transmitPacket(int portNumber, ImmutableByteSequence packet) throws Bmv2RuntimeException { - - log.debug("Requesting packet transmission... > portNumber={}, packetSize={}", portNumber, packet.size()); - - try { - - simpleSwitchClient.packet_out(portNumber, ByteBuffer.wrap(packet.asArray())); - log.debug("Packet transmission requested! > portNumber={}, packetSize={}", portNumber, packet.size()); - } catch (TException e) { - log.debug("Exception while requesting packet transmission: {} > portNumber={}, packetSize={}", - e, portNumber, packet.size()); - throw parseTException(e); - } - } - - @Override - public void resetState() throws Bmv2RuntimeException { - - log.debug("Resetting device state... > deviceId={}", deviceId); - - try { - standardClient.bm_reset_state(); - log.debug("Device state reset! > deviceId={}", deviceId); - } catch (TException e) { - log.debug("Exception while resetting device state: {} > deviceId={}", e, deviceId); - throw parseTException(e); - } - } - - @Override - public String dumpJsonConfig() throws Bmv2RuntimeException { - - log.debug("Dumping device config... > deviceId={}", deviceId); - - try { - String config = standardClient.bm_get_config(); - log.debug("Device config dumped! > deviceId={}, configLength={}", deviceId, config.length()); - return config; - } catch (TException e) { - log.debug("Exception while dumping device config: {} > deviceId={}", e, deviceId); - throw parseTException(e); - } - } - - @Override - public Pair readTableEntryCounter(String tableName, long entryId) throws Bmv2RuntimeException { - - log.debug("Reading table entry counters... > deviceId={}, tableName={}, entryId={}", - deviceId, tableName, entryId); - - try { - BmCounterValue counterValue = standardClient.bm_mt_read_counter(CONTEXT_ID, tableName, entryId); - log.debug("Table entry counters retrieved! > deviceId={}, tableName={}, entryId={}, bytes={}, packets={}", - deviceId, tableName, entryId, counterValue.bytes, counterValue.packets); - return Pair.of(counterValue.bytes, counterValue.packets); - } catch (TException e) { - log.debug("Exception while reading table counters: {} > deviceId={}, tableName={}, entryId={}", - e.toString(), deviceId); - throw parseTException(e); - } - } - - @Override - public Pair readCounter(String counterName, int index) throws Bmv2RuntimeException { - - log.debug("Reading table entry counters... > deviceId={}, counterName={}, index={}", - deviceId, counterName, index); - - try { - BmCounterValue counterValue = standardClient.bm_counter_read(CONTEXT_ID, counterName, index); - log.debug("Table entry counters retrieved! >deviceId={}, counterName={}, index={}, bytes={}, packets={}", - deviceId, counterName, index, counterValue.bytes, counterValue.packets); - return Pair.of(counterValue.bytes, counterValue.packets); - } catch (TException e) { - log.debug("Exception while reading table counters: {} > deviceId={}, counterName={}, index={}", - e.toString(), deviceId); - throw parseTException(e); - } - } - - @Override - public int getProcessInstanceId() throws Bmv2RuntimeException { - log.debug("Getting process instance ID... > deviceId={}", deviceId); - try { - int instanceId = simpleSwitchClient.get_process_instance_id(); - log.debug("TProcess instance ID retrieved! > deviceId={}, instanceId={}", - deviceId, instanceId); - return instanceId; - } catch (TException e) { - log.debug("Exception while getting process instance ID: {} > deviceId={}", e.toString(), deviceId); - throw parseTException(e); - } - } - - @Override - public String getJsonConfigMd5() throws Bmv2RuntimeException { - - log.debug("Getting device config md5... > deviceId={}", deviceId); - - try { - String md5 = standardClient.bm_get_config_md5(); - log.debug("Device config md5 received! > deviceId={}, configMd5={}", deviceId, md5); - return md5; - } catch (TException e) { - log.debug("Exception while getting device config md5: {} > deviceId={}", e, deviceId); - throw parseTException(e); - } - } - - @Override - public void uploadNewJsonConfig(String jsonString) throws Bmv2RuntimeException { - - log.debug("Loading new JSON config on device... > deviceId={}, jsonStringLength={}", - deviceId, jsonString.length()); - - try { - standardClient.bm_load_new_config(jsonString); - log.debug("JSON config loaded! > deviceId={}", deviceId); - } catch (TException e) { - log.debug("Exception while loading JSON config: {} > deviceId={}", e, deviceId); - throw parseTException(e); - } - } - - @Override - public void swapJsonConfig() throws Bmv2RuntimeException { - - log.debug("Swapping JSON config on device... > deviceId={}", deviceId); - - try { - standardClient.bm_swap_configs(); - simpleSwitchClient.force_swap(); - log.debug("JSON config swapped! > deviceId={}", deviceId); - } catch (TException e) { - log.debug("Exception while swapping JSON config: {} > deviceId={}", e, deviceId); - throw parseTException(e); - } - } - - /** - * Builds a list of Bmv2/Thrift compatible match parameters. - * - * @param matchKey a bmv2 matchKey - * @return list of thrift-compatible bm match parameters - */ - private static List buildMatchParamsList(Bmv2MatchKey matchKey) { - List paramsList = Lists.newArrayList(); - matchKey.matchParams().forEach(x -> { - ByteBuffer value; - ByteBuffer mask; - switch (x.type()) { - case EXACT: - value = ByteBuffer.wrap(((Bmv2ExactMatchParam) x).value().asArray()); - paramsList.add( - new BmMatchParam(BmMatchParamType.EXACT) - .setExact(new BmMatchParamExact(value))); - break; - case TERNARY: - value = ByteBuffer.wrap(((Bmv2TernaryMatchParam) x).value().asArray()); - mask = ByteBuffer.wrap(((Bmv2TernaryMatchParam) x).mask().asArray()); - paramsList.add( - new BmMatchParam(BmMatchParamType.TERNARY) - .setTernary(new BmMatchParamTernary(value, mask))); - break; - case LPM: - value = ByteBuffer.wrap(((Bmv2LpmMatchParam) x).value().asArray()); - int prefixLength = ((Bmv2LpmMatchParam) x).prefixLength(); - paramsList.add( - new BmMatchParam(BmMatchParamType.LPM) - .setLpm(new BmMatchParamLPM(value, prefixLength))); - break; - case VALID: - boolean flag = ((Bmv2ValidMatchParam) x).flag(); - paramsList.add( - new BmMatchParam(BmMatchParamType.VALID) - .setValid(new BmMatchParamValid(flag))); - break; - default: - // should never be here - throw new RuntimeException("Unknown match param type " + x.type().name()); - } - }); - return paramsList; - } - - /** - * Build a list of Bmv2/Thrift compatible action parameters. - * - * @param action an action object - * @return list of ByteBuffers - */ - private static List buildActionParamsList(Bmv2Action action) { - List buffers = Lists.newArrayList(); - action.parameters().forEach(p -> buffers.add(ByteBuffer.wrap(p.asArray()))); - return buffers; - } -} diff --git a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2FlowRuleTranslatorImpl.java b/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2FlowRuleTranslatorImpl.java deleted file mode 100644 index ef9427e207..0000000000 --- a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2FlowRuleTranslatorImpl.java +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.ctl; - -import com.google.common.annotations.Beta; -import com.google.common.collect.Sets; -import org.onlab.util.ImmutableByteSequence; -import org.onosproject.bmv2.api.context.Bmv2ActionModel; -import org.onosproject.bmv2.api.context.Bmv2Configuration; -import org.onosproject.bmv2.api.context.Bmv2DeviceContext; -import org.onosproject.bmv2.api.context.Bmv2FieldModel; -import org.onosproject.bmv2.api.context.Bmv2FlowRuleTranslator; -import org.onosproject.bmv2.api.context.Bmv2FlowRuleTranslatorException; -import org.onosproject.bmv2.api.context.Bmv2Interpreter; -import org.onosproject.bmv2.api.context.Bmv2InterpreterException; -import org.onosproject.bmv2.api.context.Bmv2RuntimeDataModel; -import org.onosproject.bmv2.api.context.Bmv2TableKeyModel; -import org.onosproject.bmv2.api.context.Bmv2TableModel; -import org.onosproject.bmv2.api.runtime.Bmv2Action; -import org.onosproject.bmv2.api.runtime.Bmv2ExactMatchParam; -import org.onosproject.bmv2.api.runtime.Bmv2ExtensionSelector; -import org.onosproject.bmv2.api.runtime.Bmv2ExtensionTreatment; -import org.onosproject.bmv2.api.runtime.Bmv2LpmMatchParam; -import org.onosproject.bmv2.api.runtime.Bmv2MatchKey; -import org.onosproject.bmv2.api.runtime.Bmv2MatchParam; -import org.onosproject.bmv2.api.runtime.Bmv2TableEntry; -import org.onosproject.bmv2.api.runtime.Bmv2TernaryMatchParam; -import org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils; -import org.onosproject.net.flow.FlowRule; -import org.onosproject.net.flow.TrafficSelector; -import org.onosproject.net.flow.TrafficTreatment; -import org.onosproject.net.flow.criteria.Criterion; -import org.onosproject.net.flow.criteria.EthCriterion; -import org.onosproject.net.flow.criteria.EthTypeCriterion; -import org.onosproject.net.flow.criteria.ExtensionCriterion; -import org.onosproject.net.flow.criteria.PortCriterion; -import org.onosproject.net.flow.instructions.ExtensionTreatment; -import org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes; -import org.onosproject.net.flow.instructions.Instruction; -import org.onosproject.net.flow.instructions.Instructions; -import org.onosproject.net.flow.instructions.Instructions.ExtensionInstructionWrapper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Collections; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -import static org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils.roundToBytes; -import static org.onosproject.net.flow.criteria.Criterion.Type.EXTENSION; -import static org.onosproject.net.flow.criteria.ExtensionSelectorType.ExtensionSelectorTypes.BMV2_MATCH_PARAMS; - -/** - * Default implementation of a BMv2 flow rule translator. - */ -@Beta -public class Bmv2FlowRuleTranslatorImpl implements Bmv2FlowRuleTranslator { - - private final Logger log = LoggerFactory.getLogger(this.getClass()); - - @Override - public Bmv2TableEntry translate(FlowRule rule, Bmv2DeviceContext context) - throws Bmv2FlowRuleTranslatorException { - - Bmv2Configuration configuration = context.configuration(); - Bmv2Interpreter interpreter = context.interpreter(); - - int tableId = rule.tableId(); - String tableName = interpreter.tableIdMap().get(tableId); - - Bmv2TableModel table = (tableName == null) ? configuration.table(tableId) : configuration.table(tableName); - - if (table == null) { - throw new Bmv2FlowRuleTranslatorException("Unknown table ID: " + tableId); - } - - /* Translate selector */ - Bmv2MatchKey bmv2MatchKey = buildMatchKey(interpreter, rule.selector(), table); - - /* Translate treatment */ - TrafficTreatment treatment = rule.treatment(); - Bmv2Action bmv2Action = null; - // If treatment has only 1 instruction of type extension, use that - for (Instruction inst : treatment.allInstructions()) { - if (inst.type() == Instruction.Type.EXTENSION) { - if (treatment.allInstructions().size() == 1) { - bmv2Action = getActionFromExtension((ExtensionInstructionWrapper) inst); - } else { - throw new Bmv2FlowRuleTranslatorException("Unable to translate traffic treatment, found multiple " + - "instructions of which one is an extension: " + - treatment.toString()); - } - } - } - - if (bmv2Action == null) { - // No extension, use interpreter to build action. - try { - bmv2Action = interpreter.mapTreatment(treatment, configuration); - } catch (Bmv2InterpreterException e) { - throw new Bmv2FlowRuleTranslatorException("Unable to translate treatment. " + e.toString()); - } - } - - if (bmv2Action == null) { - // Interpreter returned null. - throw new Bmv2FlowRuleTranslatorException("Unable to translate treatment"); - } - - // Check action - Bmv2ActionModel actionModel = configuration.action(bmv2Action.name()); - if (actionModel == null) { - throw new Bmv2FlowRuleTranslatorException("Unknown action " + bmv2Action.name()); - } - if (!table.actions().contains(actionModel)) { - throw new Bmv2FlowRuleTranslatorException("Action " + bmv2Action.name() - + " is not defined for table " + tableName); - } - if (actionModel.runtimeDatas().size() != bmv2Action.parameters().size()) { - throw new Bmv2FlowRuleTranslatorException("Wrong number of parameters for action " - + actionModel.name() + ", expected " - + actionModel.runtimeDatas().size() + ", but found " - + bmv2Action.parameters().size()); - } - for (int i = 0; i < actionModel.runtimeDatas().size(); i++) { - Bmv2RuntimeDataModel data = actionModel.runtimeDatas().get(i); - ImmutableByteSequence param = bmv2Action.parameters().get(i); - if (param.size() != roundToBytes(data.bitWidth())) { - throw new Bmv2FlowRuleTranslatorException("Wrong byte-width for parameter " + data.name() - + " of action " + actionModel.name() - + ", expected " + roundToBytes(data.bitWidth()) - + " bytes, but found " + param.size()); - } - } - - Bmv2TableEntry.Builder tableEntryBuilder = Bmv2TableEntry.builder(); - - // In BMv2 0 is the highest priority. - int newPriority = Integer.MAX_VALUE - rule.priority(); - - tableEntryBuilder - .withTableName(table.name()) - .withPriority(newPriority) - .withMatchKey(bmv2MatchKey) - .withAction(bmv2Action); - - if (!rule.isPermanent()) { - if (table.hasTimeouts()) { - tableEntryBuilder.withTimeout((double) rule.timeout()); - } else { - log.warn("Flow rule is temporary but table {} doesn't support timeouts, translating to permanent", - table.name()); - } - - } - - return tableEntryBuilder.build(); - } - - private Bmv2TernaryMatchParam buildTernaryParam(Bmv2FieldModel field, Criterion criterion, int bitWidth) - throws Bmv2FlowRuleTranslatorException { - - // Value and mask will be filled according to criterion type - ImmutableByteSequence value; - ImmutableByteSequence mask = null; - - int byteWidth = roundToBytes(bitWidth); - - switch (criterion.type()) { - case IN_PORT: - long port = ((PortCriterion) criterion).port().toLong(); - value = ImmutableByteSequence.copyFrom(port); - break; - case ETH_DST: - EthCriterion c = (EthCriterion) criterion; - value = ImmutableByteSequence.copyFrom(c.mac().toBytes()); - if (c.mask() != null) { - mask = ImmutableByteSequence.copyFrom(c.mask().toBytes()); - } - break; - case ETH_SRC: - EthCriterion c2 = (EthCriterion) criterion; - value = ImmutableByteSequence.copyFrom(c2.mac().toBytes()); - if (c2.mask() != null) { - mask = ImmutableByteSequence.copyFrom(c2.mask().toBytes()); - } - break; - case ETH_TYPE: - short ethType = ((EthTypeCriterion) criterion).ethType().toShort(); - value = ImmutableByteSequence.copyFrom(ethType); - break; - // TODO: implement building for other criterion types (easy with DefaultCriterion of ONOS-4034) - default: - throw new Bmv2FlowRuleTranslatorException("Feature not implemented, ternary builder for criterion" + - "type: " + criterion.type().name()); - } - - // Fit byte sequence in field model bit-width. - try { - value = Bmv2TranslatorUtils.fitByteSequence(value, bitWidth); - } catch (Bmv2TranslatorUtils.ByteSequenceFitException e) { - throw new Bmv2FlowRuleTranslatorException( - "Fit exception for criterion " + criterion.type().name() + " value, " + e.getMessage()); - } - - if (mask == null) { - // no mask, all ones - mask = ImmutableByteSequence.ofOnes(byteWidth); - } else { - try { - mask = Bmv2TranslatorUtils.fitByteSequence(mask, bitWidth); - } catch (Bmv2TranslatorUtils.ByteSequenceFitException e) { - throw new Bmv2FlowRuleTranslatorException( - "Fit exception for criterion " + criterion.type().name() + " mask, " + e.getMessage()); - } - } - - return new Bmv2TernaryMatchParam(value, mask); - } - - private Bmv2Action getActionFromExtension(Instructions.ExtensionInstructionWrapper inst) - throws Bmv2FlowRuleTranslatorException { - - ExtensionTreatment extTreatment = inst.extensionInstruction(); - - if (extTreatment.type() == ExtensionTreatmentTypes.BMV2_ACTION.type()) { - if (extTreatment instanceof Bmv2ExtensionTreatment) { - return ((Bmv2ExtensionTreatment) extTreatment).action(); - } else { - throw new Bmv2FlowRuleTranslatorException("Unable to decode treatment extension: " + extTreatment); - } - } else { - throw new Bmv2FlowRuleTranslatorException("Unsupported treatment extension type: " + extTreatment.type()); - } - } - - private Bmv2MatchKey buildMatchKey(Bmv2Interpreter interpreter, TrafficSelector selector, Bmv2TableModel tableModel) - throws Bmv2FlowRuleTranslatorException { - - // Find a bmv2 extension selector (if any) and get the parameter map. - Optional extSelector = selector.criteria().stream() - .filter(c -> c.type().equals(EXTENSION)) - .map(c -> (ExtensionCriterion) c) - .map(ExtensionCriterion::extensionSelector) - .filter(c -> c.type().equals(BMV2_MATCH_PARAMS.type())) - .map(c -> (Bmv2ExtensionSelector) c) - .findFirst(); - Map extParamMap = - (extSelector.isPresent()) ? extSelector.get().parameterMap() : Collections.emptyMap(); - - Set translatedCriteria = Sets.newHashSet(); - Set usedExtParams = Sets.newHashSet(); - - Bmv2MatchKey.Builder matchKeyBuilder = Bmv2MatchKey.builder(); - - keysLoop: - for (Bmv2TableKeyModel keyModel : tableModel.keys()) { - - // use fieldName dot notation (e.g. ethernet.dstAddr) - String fieldName = keyModel.field().header().name() + "." + keyModel.field().type().name(); - - int bitWidth = keyModel.field().type().bitWidth(); - int byteWidth = roundToBytes(bitWidth); - - Criterion.Type criterionType = interpreter.criterionTypeMap().inverse().get(fieldName); - - if (!extParamMap.containsKey(fieldName) && - (criterionType == null || selector.getCriterion(criterionType) == null)) { - // Neither an extension nor a mapping / criterion is available for this field. - switch (keyModel.matchType()) { - case TERNARY: - // Wildcard field - matchKeyBuilder.withWildcard(byteWidth); - break; - case LPM: - // LPM with prefix 0 - matchKeyBuilder.add(new Bmv2LpmMatchParam(ImmutableByteSequence.ofZeros(byteWidth), 0)); - break; - default: - throw new Bmv2FlowRuleTranslatorException("No value found for required match field " - + fieldName); - } - // Next key - continue keysLoop; - } - - Bmv2MatchParam matchParam; - - if (extParamMap.containsKey(fieldName)) { - // Parameter found in extension - if (criterionType != null && selector.getCriterion(criterionType) != null) { - // Found also a criterion that can be mapped. This is bad. - throw new Bmv2FlowRuleTranslatorException("Both an extension and a criterion mapping are defined " + - "for match field " + fieldName); - } - - matchParam = extParamMap.get(fieldName); - usedExtParams.add(fieldName); - - // Check parameter type and size - if (!keyModel.matchType().equals(matchParam.type())) { - throw new Bmv2FlowRuleTranslatorException("Wrong match type for parameter " + fieldName - + ", expected " + keyModel.matchType().name() - + ", but found " + matchParam.type().name()); - } - int foundByteWidth; - switch (keyModel.matchType()) { - case EXACT: - Bmv2ExactMatchParam m1 = (Bmv2ExactMatchParam) matchParam; - foundByteWidth = m1.value().size(); - break; - case TERNARY: - Bmv2TernaryMatchParam m2 = (Bmv2TernaryMatchParam) matchParam; - foundByteWidth = m2.value().size(); - break; - case LPM: - Bmv2LpmMatchParam m3 = (Bmv2LpmMatchParam) matchParam; - foundByteWidth = m3.value().size(); - break; - case VALID: - foundByteWidth = -1; - break; - default: - // should never be her - throw new RuntimeException("Unrecognized match type " + keyModel.matchType().name()); - } - if (foundByteWidth != -1 && foundByteWidth != byteWidth) { - throw new Bmv2FlowRuleTranslatorException("Wrong byte-width for match parameter " + fieldName - + ", expected " + byteWidth + ", but found " - + foundByteWidth); - } - - } else { - // A criterion mapping is available for this key - Criterion criterion = selector.getCriterion(criterionType); - translatedCriteria.add(criterion); - switch (keyModel.matchType()) { - case TERNARY: - matchParam = buildTernaryParam(keyModel.field(), criterion, bitWidth); - break; - default: - // TODO: implement other match param builders (exact, LPM, etc.) - throw new Bmv2FlowRuleTranslatorException("Feature not yet implemented, match param builder: " - + keyModel.matchType().name()); - } - } - - matchKeyBuilder.add(matchParam); - } - - // Check if all criteria have been translated - Set ignoredCriteria = selector.criteria() - .stream() - .filter(c -> !c.type().equals(EXTENSION)) - .filter(c -> !translatedCriteria.contains(c)) - .collect(Collectors.toSet()); - - if (ignoredCriteria.size() > 0) { - throw new Bmv2FlowRuleTranslatorException("The following criteria cannot be translated for table " - + tableModel.name() + ": " + ignoredCriteria.toString()); - } - - // Check is all extension parameters have been used - Set ignoredExtParams = extParamMap.keySet() - .stream() - .filter(k -> !usedExtParams.contains(k)) - .collect(Collectors.toSet()); - - if (ignoredExtParams.size() > 0) { - throw new Bmv2FlowRuleTranslatorException("The following extension match parameters cannot be used for " + - "table " + tableModel.name() + ": " - + ignoredExtParams.toString()); - } - - return matchKeyBuilder.build(); - } - -} diff --git a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2TExceptionParser.java b/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2TExceptionParser.java deleted file mode 100644 index 6ce3fbdfa1..0000000000 --- a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2TExceptionParser.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.ctl; - - -import org.apache.thrift.TException; -import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException; -import org.onosproject.bmv2.thriftapi.InvalidCounterOperation; -import org.onosproject.bmv2.thriftapi.InvalidDevMgrOperation; -import org.onosproject.bmv2.thriftapi.InvalidLearnOperation; -import org.onosproject.bmv2.thriftapi.InvalidMcOperation; -import org.onosproject.bmv2.thriftapi.InvalidMeterOperation; -import org.onosproject.bmv2.thriftapi.InvalidRegisterOperation; -import org.onosproject.bmv2.thriftapi.InvalidSwapOperation; -import org.onosproject.bmv2.thriftapi.InvalidTableOperation; - -import static org.onosproject.bmv2.api.runtime.Bmv2RuntimeException.Code; - -/** - * Utility class to translate a Thrift exception into a Bmv2RuntimeException. - */ -final class Bmv2TExceptionParser { - - private Bmv2TExceptionParser() { - // ban constructor. - } - - static Bmv2RuntimeException parseTException(TException cause) { - try { - return new Bmv2RuntimeException(getCode(cause)); - } catch (ParserException e) { - return new Bmv2RuntimeException(e.codeString); - } - } - - private static Code getCode(TException e) throws ParserException { - if (e instanceof InvalidTableOperation) { - InvalidTableOperation t = (InvalidTableOperation) e; - switch (t.getCode()) { - case TABLE_FULL: - return Code.TABLE_FULL; - case INVALID_HANDLE: - return Code.TABLE_INVALID_HANDLE; - case EXPIRED_HANDLE: - return Code.TABLE_EXPIRED_HANDLE; - case COUNTERS_DISABLED: - return Code.TABLE_COUNTERS_DISABLED; - case METERS_DISABLED: - return Code.TABLE_METERS_DISABLED; - case AGEING_DISABLED: - return Code.TABLE_AGEING_DISABLED; - case INVALID_TABLE_NAME: - return Code.TABLE_INVALID_TABLE_NAME; - case INVALID_ACTION_NAME: - return Code.TABLE_INVALID_ACTION_NAME; - case WRONG_TABLE_TYPE: - return Code.TABLE_WRONG_TABLE_TYPE; - case INVALID_MBR_HANDLE: - return Code.TABLE_INVALID_MBR_HANDLE; - case MBR_STILL_USED: - return Code.TABLE_MBR_STILL_USED; - case MBR_ALREADY_IN_GRP: - return Code.TABLE_MBR_ALREADY_IN_GRP; - case MBR_NOT_IN_GRP: - return Code.TABLE_MBR_NOT_IN_GRP; - case INVALID_GRP_HANDLE: - return Code.TABLE_INVALID_GRP_HANDLE; - case GRP_STILL_USED: - return Code.TABLE_GRP_STILL_USED; - case EMPTY_GRP: - return Code.TABLE_EMPTY_GRP; - case DUPLICATE_ENTRY: - return Code.TABLE_DUPLICATE_ENTRY; - case BAD_MATCH_KEY: - return Code.TABLE_BAD_MATCH_KEY; - case INVALID_METER_OPERATION: - return Code.TABLE_INVALID_METER_OPERATION; - case DEFAULT_ACTION_IS_CONST: - return Code.TABLE_DEFAULT_ACTION_IS_CONST; - case DEFAULT_ENTRY_IS_CONST: - return Code.TABLE_DEFAULT_ENTRY_IS_CONST; - case ERROR: - return Code.TABLE_GENERAL_ERROR; - default: - return Code.TABLE_UNKNOWN_ERROR; - } - } else if (e instanceof InvalidCounterOperation) { - InvalidCounterOperation t = (InvalidCounterOperation) e; - switch (t.getCode()) { - case INVALID_COUNTER_NAME: - return Code.COUNTER_INVALID_NAME; - case INVALID_INDEX: - return Code.COUNTER_INVALID_INDEX; - case ERROR: - return Code.COUNTER_ERROR_GENERAL; - default: - return Code.COUNTER_ERROR_UNKNOWN; - } - } else if (e instanceof InvalidDevMgrOperation) { - InvalidDevMgrOperation t = (InvalidDevMgrOperation) e; - switch (t.getCode()) { - case ERROR: - return Code.DEV_MGR_ERROR_GENERAL; - default: - return Code.DEV_MGR_UNKNOWN; - } - } else if (e instanceof InvalidSwapOperation) { - InvalidSwapOperation t = (InvalidSwapOperation) e; - switch (t.getCode()) { - case CONFIG_SWAP_DISABLED: - return Code.SWAP_CONFIG_DISABLED; - case ONGOING_SWAP: - return Code.SWAP_ONGOING; - case NO_ONGOING_SWAP: - return Code.SWAP_NO_ONGOING; - default: - return Code.SWAP_ERROR_UKNOWN; - } - } else if (e instanceof InvalidMeterOperation) { - // TODO - throw new ParserException(e.toString()); - } else if (e instanceof InvalidRegisterOperation) { - // TODO - throw new ParserException(e.toString()); - } else if (e instanceof InvalidLearnOperation) { - // TODO - throw new ParserException(e.toString()); - } else if (e instanceof InvalidMcOperation) { - // TODO - throw new ParserException(e.toString()); - } else { - throw new ParserException(e.toString()); - } - } - - private static class ParserException extends Exception { - - private String codeString; - - public ParserException(String codeString) { - this.codeString = codeString; - } - } -} diff --git a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2TableEntryServiceImpl.java b/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2TableEntryServiceImpl.java deleted file mode 100644 index 38f627da00..0000000000 --- a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/Bmv2TableEntryServiceImpl.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.ctl; - -import org.apache.felix.scr.annotations.Activate; -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.Deactivate; -import org.apache.felix.scr.annotations.Reference; -import org.apache.felix.scr.annotations.ReferenceCardinality; -import org.apache.felix.scr.annotations.Service; -import org.onlab.util.KryoNamespace; -import org.onosproject.bmv2.api.context.Bmv2FlowRuleTranslator; -import org.onosproject.bmv2.api.runtime.Bmv2ExactMatchParam; -import org.onosproject.bmv2.api.runtime.Bmv2FlowRuleWrapper; -import org.onosproject.bmv2.api.runtime.Bmv2LpmMatchParam; -import org.onosproject.bmv2.api.runtime.Bmv2MatchKey; -import org.onosproject.bmv2.api.runtime.Bmv2TableEntryReference; -import org.onosproject.bmv2.api.runtime.Bmv2TernaryMatchParam; -import org.onosproject.bmv2.api.runtime.Bmv2ValidMatchParam; -import org.onosproject.bmv2.api.service.Bmv2Controller; -import org.onosproject.bmv2.api.service.Bmv2DeviceContextService; -import org.onosproject.bmv2.api.service.Bmv2TableEntryService; -import org.onosproject.net.DeviceId; -import org.onosproject.store.serializers.KryoNamespaces; -import org.onosproject.store.service.EventuallyConsistentMap; -import org.onosproject.store.service.StorageService; -import org.onosproject.store.service.WallClockTimestamp; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * Implementation of the Bmv2TableEntryService. - */ -@Component(immediate = true) -@Service -public class Bmv2TableEntryServiceImpl implements Bmv2TableEntryService { - - private final Logger log = LoggerFactory.getLogger(this.getClass()); - - private final Bmv2FlowRuleTranslator translator = new Bmv2FlowRuleTranslatorImpl(); - - private EventuallyConsistentMap flowRules; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected StorageService storageService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected Bmv2Controller controller; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected Bmv2DeviceContextService contextService; - - - @Activate - public void activate() { - KryoNamespace kryo = new KryoNamespace.Builder() - .register(KryoNamespaces.API) - .register(Bmv2TableEntryReference.class) - .register(Bmv2MatchKey.class) - .register(Bmv2ExactMatchParam.class) - .register(Bmv2TernaryMatchParam.class) - .register(Bmv2LpmMatchParam.class) - .register(Bmv2ValidMatchParam.class) - .register(Bmv2FlowRuleWrapper.class) - .build(); - - flowRules = storageService.eventuallyConsistentMapBuilder() - .withSerializer(kryo) - .withTimestampProvider((k, v) -> new WallClockTimestamp()) - .withName("onos-bmv2-flowrules") - .build(); - - log.info("Started"); - } - - @Deactivate - public void deactivate() { - log.info("Stopped"); - } - - @Override - public Bmv2FlowRuleTranslator getFlowRuleTranslator() { - return translator; - } - - @Override - public Bmv2FlowRuleWrapper lookup(Bmv2TableEntryReference entryRef) { - checkNotNull(entryRef, "table entry reference cannot be null"); - return flowRules.get(entryRef); - } - - @Override - public void bind(Bmv2TableEntryReference entryRef, Bmv2FlowRuleWrapper rule) { - checkNotNull(entryRef, "table entry reference cannot be null"); - checkNotNull(rule, "bmv2 flow rule cannot be null"); - flowRules.put(entryRef, rule); - } - - @Override - public void unbind(Bmv2TableEntryReference entryRef) { - checkNotNull(entryRef, "table entry reference cannot be null"); - flowRules.remove(entryRef); - } - - @Override - public void unbindAll(DeviceId deviceId) { - flowRules.keySet() - .stream() - .filter(entryRef -> entryRef.deviceId().equals(deviceId)) - .forEach(flowRules::remove); - } -} diff --git a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/SafeThriftClient.java b/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/SafeThriftClient.java deleted file mode 100644 index f6e4813356..0000000000 --- a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/SafeThriftClient.java +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Most of the code of this class was copied from: - * http://liveramp.com/engineering/reconnecting-thrift-client/ - */ - -package org.onosproject.bmv2.ctl; - -import com.google.common.collect.ImmutableSet; -import org.apache.thrift.TServiceClient; -import org.apache.thrift.transport.TTransport; -import org.apache.thrift.transport.TTransportException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.Set; - -/** - * Thrift client wrapper that attempts a few reconnects before giving up a method call execution. It also provides - * synchronization between calls over the same transport. - */ -public final class SafeThriftClient { - - private static final Logger LOG = LoggerFactory.getLogger(SafeThriftClient.class); - - /** - * List of causes which suggest a restart might fix things (defined as constants in {@link TTransportException}). - */ - private static final Set RESTARTABLE_CAUSES = ImmutableSet.of(TTransportException.NOT_OPEN, - TTransportException.END_OF_FILE, - TTransportException.TIMED_OUT, - TTransportException.UNKNOWN); - - private SafeThriftClient() { - // ban constructor. - } - - /** - * Reflectively wraps an already existing Thrift client. - * - * @param baseClient the client to wrap - * @param clientInterface the interface that the client implements - * @param options options that control behavior of the reconnecting client - * @param - * @param - * @return - */ - public static C wrap(T baseClient, Class clientInterface, Options options) { - Object proxyObject = Proxy.newProxyInstance(clientInterface.getClassLoader(), - new Class[]{clientInterface}, - new ReconnectingClientProxy(baseClient, - options.getNumRetries(), - options.getTimeBetweenRetries())); - - return (C) proxyObject; - } - - /** - * Reflectively wraps an already existing Thrift client. - * - * @param baseClient the client to wrap - * @param options options that control behavior of the reconnecting client - * @param - * @param - * @return - */ - public static C wrap(T baseClient, Options options) { - Class[] interfaces = baseClient.getClass().getInterfaces(); - - for (Class iface : interfaces) { - if (iface.getSimpleName().equals("Iface") - && iface.getEnclosingClass().equals(baseClient.getClass().getEnclosingClass())) { - return (C) wrap(baseClient, iface, options); - } - } - - throw new RuntimeException("Class needs to implement Iface directly. Use wrap(TServiceClient, Class) instead."); - } - - /** - * Reflectively wraps an already existing Thrift client. - * - * @param baseClient the client to wrap - * @param clientInterface the interface that the client implements - * @param - * @param - * @return - */ - public static C wrap(T baseClient, Class clientInterface) { - return wrap(baseClient, clientInterface, Options.defaults()); - } - - /** - * Reflectively wraps an already existing Thrift client. - * - * @param baseClient the client to wrap - * @param - * @param - * @return - */ - public static C wrap(T baseClient) { - return wrap(baseClient, Options.defaults()); - } - - /** - * Reconnection options for {@link SafeThriftClient}. - */ - public static class Options { - private int numRetries; - private long timeBetweenRetries; - - /** - * Creates new options with the given parameters. - * - * @param numRetries the maximum number of times to try reconnecting before giving up and throwing an - * exception - * @param timeBetweenRetries the number of milliseconds to wait in between reconnection attempts. - */ - public Options(int numRetries, long timeBetweenRetries) { - this.numRetries = numRetries; - this.timeBetweenRetries = timeBetweenRetries; - } - - private static Options defaults() { - return new Options(5, 10000L); - } - - private int getNumRetries() { - return numRetries; - } - - private long getTimeBetweenRetries() { - return timeBetweenRetries; - } - } - - /** - * Helper proxy class. Attempts to call method on proxy object wrapped in try/catch. If it fails, it attempts a - * reconnect and tries the method again. - * - * @param - */ - private static class ReconnectingClientProxy implements InvocationHandler { - private final T baseClient; - private final TTransport transport; - private final int maxRetries; - private final long timeBetweenRetries; - - public ReconnectingClientProxy(T baseClient, int maxRetries, long timeBetweenRetries) { - this.baseClient = baseClient; - this.transport = baseClient.getInputProtocol().getTransport(); - this.maxRetries = maxRetries; - this.timeBetweenRetries = timeBetweenRetries; - } - - private void reconnectOrThrowException() - throws TTransportException { - int errors = 0; - try { - if (transport.isOpen()) { - transport.close(); - } - } catch (Exception e) { - // Thrift seems to have a bug where if the transport is already closed a SocketException is thrown. - // However, such an exception is not advertised by .close(), hence the general-purpose catch. - LOG.debug("Exception while closing transport", e); - } - - while (errors < maxRetries) { - try { - LOG.debug("Attempting to reconnect..."); - transport.open(); - LOG.debug("Reconnection successful"); - break; - } catch (TTransportException e) { - LOG.debug("Error while reconnecting:", e); - errors++; - - if (errors < maxRetries) { - try { - LOG.debug("Sleeping for {} milliseconds before retrying", timeBetweenRetries); - Thread.sleep(timeBetweenRetries); - } catch (InterruptedException e2) { - Thread.currentThread().interrupt(); - throw new RuntimeException(e); - } - } - } - } - - if (errors >= maxRetries) { - throw new TTransportException("Failed to reconnect"); - } - } - - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - - // Thrift transport layer is not thread-safe (it's a wrapper on a socket), hence we need locking. - synchronized (transport) { - - LOG.debug("Invoking method... > fromThread={}, method={}, args={}", - Thread.currentThread().getId(), method.getName(), args); - - try { - - return method.invoke(baseClient, args); - } catch (InvocationTargetException e) { - if (e.getTargetException() instanceof TTransportException) { - TTransportException cause = (TTransportException) e.getTargetException(); - - if (RESTARTABLE_CAUSES.contains(cause.getType())) { - // Try to reconnect. If fail, a TTransportException will be thrown. - reconnectOrThrowException(); - try { - // If here, transport has been successfully open, hence new exceptions will be thrown. - return method.invoke(baseClient, args); - } catch (InvocationTargetException e1) { - LOG.debug("Exception: {}", e1.getTargetException()); - throw e1.getTargetException(); - } - } - } - // Target exception is neither a TTransportException nor a restartable cause. - LOG.debug("Exception: {}", e.getTargetException()); - throw e.getTargetException(); - } - } - } - } -} diff --git a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/package-info.java b/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/package-info.java deleted file mode 100644 index dcd9a28936..0000000000 --- a/protocols/bmv2/ctl/src/main/java/org/onosproject/bmv2/ctl/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * BMv2 Thrift client implementation. - */ -package org.onosproject.bmv2.ctl; \ No newline at end of file diff --git a/protocols/bmv2/ctl/src/main/resources/default.json b/protocols/bmv2/ctl/src/main/resources/default.json deleted file mode 100644 index abc04525f7..0000000000 --- a/protocols/bmv2/ctl/src/main/resources/default.json +++ /dev/null @@ -1,730 +0,0 @@ -{ - "header_types": [ - { - "name": "standard_metadata_t", - "id": 0, - "fields": [ - [ - "ingress_port", - 9 - ], - [ - "packet_length", - 32 - ], - [ - "egress_spec", - 9 - ], - [ - "egress_port", - 9 - ], - [ - "egress_instance", - 32 - ], - [ - "instance_type", - 32 - ], - [ - "clone_spec", - 32 - ], - [ - "_padding", - 5 - ] - ], - "length_exp": null, - "max_length": null - }, - { - "name": "intrinsic_metadata_t", - "id": 1, - "fields": [ - [ - "ingress_global_timestamp", - 32 - ], - [ - "lf_field_list", - 32 - ], - [ - "mcast_grp", - 16 - ], - [ - "egress_rid", - 16 - ] - ], - "length_exp": null, - "max_length": null - }, - { - "name": "ethernet_t", - "id": 2, - "fields": [ - [ - "dstAddr", - 48 - ], - [ - "srcAddr", - 48 - ], - [ - "etherType", - 16 - ] - ], - "length_exp": null, - "max_length": null - }, - { - "name": "ipv4_t", - "id": 3, - "fields": [ - [ - "version", - 4 - ], - [ - "ihl", - 4 - ], - [ - "diffserv", - 8 - ], - [ - "totalLen", - 16 - ], - [ - "identification", - 16 - ], - [ - "flags", - 3 - ], - [ - "fragOffset", - 13 - ], - [ - "ttl", - 8 - ], - [ - "protocol", - 8 - ], - [ - "hdrChecksum", - 16 - ], - [ - "srcAddr", - 32 - ], - [ - "dstAddr", - 32 - ] - ], - "length_exp": null, - "max_length": null - }, - { - "name": "tcp_t", - "id": 4, - "fields": [ - [ - "srcPort", - 16 - ], - [ - "dstPort", - 16 - ], - [ - "seqNo", - 32 - ], - [ - "ackNo", - 32 - ], - [ - "dataOffset", - 4 - ], - [ - "res", - 3 - ], - [ - "ecn", - 3 - ], - [ - "ctrl", - 6 - ], - [ - "window", - 16 - ], - [ - "checksum", - 16 - ], - [ - "urgentPtr", - 16 - ] - ], - "length_exp": null, - "max_length": null - }, - { - "name": "udp_t", - "id": 5, - "fields": [ - [ - "srcPort", - 16 - ], - [ - "dstPort", - 16 - ], - [ - "length_", - 16 - ], - [ - "checksum", - 16 - ] - ], - "length_exp": null, - "max_length": null - } - ], - "headers": [ - { - "name": "standard_metadata", - "id": 0, - "header_type": "standard_metadata_t", - "metadata": true - }, - { - "name": "intrinsic_metadata", - "id": 1, - "header_type": "intrinsic_metadata_t", - "metadata": true - }, - { - "name": "ethernet", - "id": 2, - "header_type": "ethernet_t", - "metadata": false - }, - { - "name": "ipv4", - "id": 3, - "header_type": "ipv4_t", - "metadata": false - }, - { - "name": "tcp", - "id": 4, - "header_type": "tcp_t", - "metadata": false - }, - { - "name": "udp", - "id": 5, - "header_type": "udp_t", - "metadata": false - } - ], - "header_stacks": [], - "parsers": [ - { - "name": "parser", - "id": 0, - "init_state": "start", - "parse_states": [ - { - "name": "start", - "id": 0, - "parser_ops": [], - "transition_key": [], - "transitions": [ - { - "value": "default", - "mask": null, - "next_state": "parse_ethernet" - } - ] - }, - { - "name": "parse_ethernet", - "id": 1, - "parser_ops": [ - { - "op": "extract", - "parameters": [ - { - "type": "regular", - "value": "ethernet" - } - ] - } - ], - "transition_key": [ - { - "type": "field", - "value": [ - "ethernet", - "etherType" - ] - } - ], - "transitions": [ - { - "value": "0x0800", - "mask": null, - "next_state": "parse_ipv4" - }, - { - "value": "default", - "mask": null, - "next_state": null - } - ] - }, - { - "name": "parse_ipv4", - "id": 2, - "parser_ops": [ - { - "op": "extract", - "parameters": [ - { - "type": "regular", - "value": "ipv4" - } - ] - } - ], - "transition_key": [ - { - "type": "field", - "value": [ - "ipv4", - "fragOffset" - ] - }, - { - "type": "field", - "value": [ - "ipv4", - "protocol" - ] - } - ], - "transitions": [ - { - "value": "0x000006", - "mask": null, - "next_state": "parse_tcp" - }, - { - "value": "0x000011", - "mask": null, - "next_state": "parse_udp" - }, - { - "value": "default", - "mask": null, - "next_state": null - } - ] - }, - { - "name": "parse_tcp", - "id": 3, - "parser_ops": [ - { - "op": "extract", - "parameters": [ - { - "type": "regular", - "value": "tcp" - } - ] - } - ], - "transition_key": [], - "transitions": [ - { - "value": "default", - "mask": null, - "next_state": null - } - ] - }, - { - "name": "parse_udp", - "id": 4, - "parser_ops": [ - { - "op": "extract", - "parameters": [ - { - "type": "regular", - "value": "udp" - } - ] - } - ], - "transition_key": [], - "transitions": [ - { - "value": "default", - "mask": null, - "next_state": null - } - ] - } - ] - } - ], - "deparsers": [ - { - "name": "deparser", - "id": 0, - "order": [ - "ethernet", - "ipv4", - "udp", - "tcp" - ] - } - ], - "meter_arrays": [], - "actions": [ - { - "name": "_drop", - "id": 0, - "runtime_data": [], - "primitives": [ - { - "op": "modify_field", - "parameters": [ - { - "type": "field", - "value": [ - "standard_metadata", - "egress_spec" - ] - }, - { - "type": "hexstr", - "value": "0x1ff" - } - ] - } - ] - }, - { - "name": "count_packet", - "id": 1, - "runtime_data": [], - "primitives": [ - { - "op": "count", - "parameters": [ - { - "type": "counter_array", - "value": "ingress_port_counter" - }, - { - "type": "field", - "value": [ - "standard_metadata", - "ingress_port" - ] - } - ] - }, - { - "op": "count", - "parameters": [ - { - "type": "counter_array", - "value": "egress_port_counter" - }, - { - "type": "field", - "value": [ - "standard_metadata", - "egress_spec" - ] - } - ] - } - ] - }, - { - "name": "send_to_cpu", - "id": 2, - "runtime_data": [], - "primitives": [ - { - "op": "modify_field", - "parameters": [ - { - "type": "field", - "value": [ - "standard_metadata", - "egress_spec" - ] - }, - { - "type": "hexstr", - "value": "0xff" - } - ] - } - ] - }, - { - "name": "set_egress_port", - "id": 3, - "runtime_data": [ - { - "name": "port", - "bitwidth": 9 - } - ], - "primitives": [ - { - "op": "modify_field", - "parameters": [ - { - "type": "field", - "value": [ - "standard_metadata", - "egress_spec" - ] - }, - { - "type": "runtime_data", - "value": 0 - } - ] - } - ] - } - ], - "pipelines": [ - { - "name": "ingress", - "id": 0, - "init_table": "table0", - "tables": [ - { - "name": "port_count_table", - "id": 0, - "match_type": "exact", - "type": "simple", - "max_size": 16384, - "with_counters": false, - "direct_meters": null, - "support_timeout": false, - "key": [], - "actions": [ - "count_packet" - ], - "next_tables": { - "count_packet": null - }, - "default_action": null, - "base_default_next": null - }, - { - "name": "table0", - "id": 1, - "match_type": "ternary", - "type": "simple", - "max_size": 16384, - "with_counters": true, - "direct_meters": null, - "support_timeout": true, - "key": [ - { - "match_type": "ternary", - "target": [ - "standard_metadata", - "ingress_port" - ], - "mask": null - }, - { - "match_type": "ternary", - "target": [ - "ethernet", - "dstAddr" - ], - "mask": null - }, - { - "match_type": "ternary", - "target": [ - "ethernet", - "srcAddr" - ], - "mask": null - }, - { - "match_type": "ternary", - "target": [ - "ethernet", - "etherType" - ], - "mask": null - } - ], - "actions": [ - "set_egress_port", - "send_to_cpu", - "_drop" - ], - "next_tables": { - "set_egress_port": "_condition_0", - "send_to_cpu": "_condition_0", - "_drop": "_condition_0" - }, - "default_action": null, - "base_default_next": "_condition_0" - } - ], - "conditionals": [ - { - "name": "_condition_0", - "id": 0, - "expression": { - "type": "expression", - "value": { - "op": "<", - "left": { - "type": "field", - "value": [ - "standard_metadata", - "egress_spec" - ] - }, - "right": { - "type": "hexstr", - "value": "0xfe" - } - } - }, - "true_next": "port_count_table", - "false_next": null - } - ] - }, - { - "name": "egress", - "id": 1, - "init_table": null, - "tables": [], - "conditionals": [] - } - ], - "calculations": [], - "checksums": [], - "learn_lists": [], - "field_lists": [], - "counter_arrays": [ - { - "name": "ingress_port_counter", - "id": 0, - "is_direct": false, - "size": 254 - }, - { - "name": "egress_port_counter", - "id": 1, - "is_direct": false, - "size": 254 - }, - { - "name": "table0_counter", - "id": 2, - "is_direct": true, - "binding": "table0" - } - ], - "register_arrays": [], - "force_arith": [ - [ - "standard_metadata", - "ingress_port" - ], - [ - "standard_metadata", - "packet_length" - ], - [ - "standard_metadata", - "egress_spec" - ], - [ - "standard_metadata", - "egress_port" - ], - [ - "standard_metadata", - "egress_instance" - ], - [ - "standard_metadata", - "instance_type" - ], - [ - "standard_metadata", - "clone_spec" - ], - [ - "standard_metadata", - "_padding" - ], - [ - "intrinsic_metadata", - "ingress_global_timestamp" - ], - [ - "intrinsic_metadata", - "lf_field_list" - ], - [ - "intrinsic_metadata", - "mcast_grp" - ], - [ - "intrinsic_metadata", - "egress_rid" - ] - ] -} \ No newline at end of file diff --git a/protocols/bmv2/ctl/src/test/java/org/onosproject/bmv2/ctl/Bmv2FlowRuleTranslatorImplTest.java b/protocols/bmv2/ctl/src/test/java/org/onosproject/bmv2/ctl/Bmv2FlowRuleTranslatorImplTest.java deleted file mode 100644 index 41a774ff7a..0000000000 --- a/protocols/bmv2/ctl/src/test/java/org/onosproject/bmv2/ctl/Bmv2FlowRuleTranslatorImplTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.bmv2.ctl; - -import com.google.common.testing.EqualsTester; -import org.junit.Test; -import org.onlab.packet.MacAddress; -import org.onosproject.bmv2.api.context.Bmv2Configuration; -import org.onosproject.bmv2.api.context.Bmv2DeviceContext; -import org.onosproject.bmv2.api.context.Bmv2FlowRuleTranslator; -import org.onosproject.bmv2.api.context.Bmv2Interpreter; -import org.onosproject.bmv2.api.runtime.Bmv2TableEntry; -import org.onosproject.bmv2.api.runtime.Bmv2TernaryMatchParam; -import org.onosproject.core.ApplicationId; -import org.onosproject.core.DefaultApplicationId; -import org.onosproject.net.DeviceId; -import org.onosproject.net.PortNumber; -import org.onosproject.net.flow.DefaultFlowRule; -import org.onosproject.net.flow.DefaultTrafficSelector; -import org.onosproject.net.flow.DefaultTrafficTreatment; -import org.onosproject.net.flow.FlowRule; -import org.onosproject.net.flow.TrafficSelector; -import org.onosproject.net.flow.TrafficTreatment; - -import java.util.Random; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.onosproject.bmv2.ctl.Bmv2DefaultInterpreterImpl.TABLE0; - -/** - * Tests for {@link Bmv2FlowRuleTranslatorImpl}. - */ -public class Bmv2FlowRuleTranslatorImplTest { - - private Random random = new Random(); - private Bmv2Configuration configuration = Bmv2DeviceContextServiceImpl.loadDefaultConfiguration(); - private Bmv2Interpreter interpreter = new Bmv2DefaultInterpreterImpl(); - private Bmv2DeviceContext context = new Bmv2DeviceContext(configuration, interpreter); - private Bmv2FlowRuleTranslator translator = new Bmv2FlowRuleTranslatorImpl(); - - @Test - public void testTranslate() throws Exception { - - DeviceId deviceId = DeviceId.NONE; - ApplicationId appId = new DefaultApplicationId(1, "test"); - int tableId = 0; - MacAddress ethDstMac = MacAddress.valueOf(random.nextLong()); - MacAddress ethSrcMac = MacAddress.valueOf(random.nextLong()); - short ethType = (short) (0x0000FFFF & random.nextInt()); - short outPort = (short) random.nextInt(65); - short inPort = (short) random.nextInt(65); - int timeout = random.nextInt(100); - int priority = random.nextInt(100); - - TrafficSelector matchInPort1 = DefaultTrafficSelector - .builder() - .matchInPort(PortNumber.portNumber(inPort)) - .matchEthDst(ethDstMac) - .matchEthSrc(ethSrcMac) - .matchEthType(ethType) - .build(); - - TrafficTreatment outPort2 = DefaultTrafficTreatment - .builder() - .setOutput(PortNumber.portNumber(outPort)) - .build(); - - FlowRule rule1 = DefaultFlowRule.builder() - .forDevice(deviceId) - .forTable(tableId) - .fromApp(appId) - .withSelector(matchInPort1) - .withTreatment(outPort2) - .makeTemporary(timeout) - .withPriority(priority) - .build(); - - FlowRule rule2 = DefaultFlowRule.builder() - .forDevice(deviceId) - .forTable(tableId) - .fromApp(appId) - .withSelector(matchInPort1) - .withTreatment(outPort2) - .makeTemporary(timeout) - .withPriority(priority) - .build(); - - Bmv2TableEntry entry1 = translator.translate(rule1, context); - Bmv2TableEntry entry2 = translator.translate(rule1, context); - - // check equality, i.e. same rules must produce same entries - new EqualsTester() - .addEqualityGroup(rule1, rule2) - .addEqualityGroup(entry1, entry2) - .testEquals(); - - int numMatchParams = configuration.table(TABLE0).keys().size(); - // parse values stored in entry1 - Bmv2TernaryMatchParam inPortParam = (Bmv2TernaryMatchParam) entry1.matchKey().matchParams().get(0); - Bmv2TernaryMatchParam ethDstParam = (Bmv2TernaryMatchParam) entry1.matchKey().matchParams().get(1); - Bmv2TernaryMatchParam ethSrcParam = (Bmv2TernaryMatchParam) entry1.matchKey().matchParams().get(2); - Bmv2TernaryMatchParam ethTypeParam = (Bmv2TernaryMatchParam) entry1.matchKey().matchParams().get(3); - double expectedTimeout = (double) (configuration.table(TABLE0).hasTimeouts() ? rule1.timeout() : -1); - - // check that the number of parameters in the entry is the same as the number of table keys - assertThat("Incorrect number of match parameters", - entry1.matchKey().matchParams().size(), is(equalTo(numMatchParams))); - - // check that values stored in entry are the same used for the flow rule - assertThat("Incorrect inPort match param value", - inPortParam.value().asReadOnlyBuffer().getShort(), is(equalTo(inPort))); - assertThat("Incorrect ethDestMac match param value", - ethDstParam.value().asArray(), is(equalTo(ethDstMac.toBytes()))); - assertThat("Incorrect ethSrcMac match param value", - ethSrcParam.value().asArray(), is(equalTo(ethSrcMac.toBytes()))); - assertThat("Incorrect ethType match param value", - ethTypeParam.value().asReadOnlyBuffer().getShort(), is(equalTo(ethType))); - assertThat("Incorrect priority value", - entry1.priority(), is(equalTo(Integer.MAX_VALUE - rule1.priority()))); - assertThat("Incorrect timeout value", - entry1.timeout(), is(equalTo(expectedTimeout))); - - } -} \ No newline at end of file diff --git a/protocols/bmv2/pom.xml b/protocols/bmv2/pom.xml deleted file mode 100644 index 23b4acddf9..0000000000 --- a/protocols/bmv2/pom.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - onos-protocols - org.onosproject - 1.11.0-SNAPSHOT - - 4.0.0 - - onos-bmv2-protocol - - - api - ctl - thrift-api - - - pom - - BMv2 protocol subsystem - - \ No newline at end of file diff --git a/protocols/bmv2/thrift-api/pom.xml b/protocols/bmv2/thrift-api/pom.xml deleted file mode 100644 index 3514bed403..0000000000 --- a/protocols/bmv2/thrift-api/pom.xml +++ /dev/null @@ -1,239 +0,0 @@ - - - - - - onos-bmv2-protocol - org.onosproject - 1.11.0-SNAPSHOT - - - 4.0.0 - - onos-bmv2-protocol-thrift-api - - bundle - - - - 8f675d0284e9e014f1b8ed502ba54e61d68108cf - 0.9.3 - https://cdn.rawgit.com/opennetworkinglab/onos-bmv2/${bmv2.commit} - org.onosproject.bmv2.thriftapi - ${project.build.directory}/thrift-sources/${bmv2.commit}/ - ${project.build.directory}/thrift-compiler/ - thrift-${os.detected.classifier}.exe - - - - - org.apache.thrift - libthrift - 0.9.3 - - - - - - - jitpack.io - https://jitpack.io - - - - - - - kr.motd.maven - os-maven-plugin - 1.4.0.Final - - - - - - - com.googlecode.maven-download-plugin - download-maven-plugin - 1.3.0 - - - download-bmv2-thrift-standard - initialize - - wget - - - ${bmv2.baseurl}/thrift_src/standard.thrift - ${bmv2.thrift.srcdir} - - - - download-bmv2-thrift-simple_pre - initialize - - wget - - - ${bmv2.baseurl}/thrift_src/simple_pre.thrift - ${bmv2.thrift.srcdir} - - - - download-bmv2-thrift-simple_pre_lag - initialize - - wget - - - ${bmv2.baseurl}/thrift_src/simple_pre_lag.thrift - ${bmv2.thrift.srcdir} - - - - download-bmv2-thrift-simple_switch - initialize - - wget - - - ${bmv2.baseurl}/targets/simple_switch/thrift/simple_switch.thrift - ${bmv2.thrift.srcdir} - - - - download-bmv2-thrift-simple_switch-cpservice - initialize - - wget - - - ${bmv2.baseurl}/targets/simple_switch/thrift/control_plane.thrift - ${bmv2.thrift.srcdir} - - - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - unpack - initialize - - unpack - - - - - com.github.ccascone - mvn-thrift-compiler - 1.1_${bmv2.thrift.version} - jar - ${thrift.exefilename} - ${project.build.directory}/thrift-compiler - - - - - - - - - org.codehaus.mojo - exec-maven-plugin - 1.4.0 - - - add-bmv2-thrift-java-namespace - initialize - - exec - - - ${project.basedir}/src/patch.sh - - ${bmv2.thrift.srcdir} - ${bmv2.thrift.javanamespace} - - - - - set-thrift-compiler-permissions - initialize - - exec - - - chmod - - +x - ${thrift.exedir}/${thrift.exefilename} - - - - - - - - org.apache.thrift.tools - maven-thrift-plugin - 0.1.11 - - ${bmv2.thrift.srcdir} - ${thrift.exedir}/${thrift.exefilename} - ${project.build.directory}/generated-sources - - - - thrift-sources - initialize - - compile - - - - - - - org.codehaus.mojo - build-helper-maven-plugin - 1.4 - - - add-thrift-sources-to-path - generate-sources - - add-source - - - - - ${project.build.directory}/generated-sources - - - - - - - - - \ No newline at end of file diff --git a/protocols/bmv2/thrift-api/src/patch.sh b/protocols/bmv2/thrift-api/src/patch.sh deleted file mode 100755 index 7f7ffb9903..0000000000 --- a/protocols/bmv2/thrift-api/src/patch.sh +++ /dev/null @@ -1,29 +0,0 @@ -#! /bin/bash -# -# Copyright 2014-2016 Open Networking Laboratory -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# exit on errors -set -e - -srcdir=$1 -ns=$2 - -# add java namespace at beginning of file -for f in ${srcdir}/*.thrift -do - if ! grep -q ${ns} ${f}; then - echo "namespace java ${ns}" | cat - ${f} > temp && mv temp ${f} - fi -done \ No newline at end of file diff --git a/protocols/pom.xml b/protocols/pom.xml index 8d40b53501..b823f9c9f8 100644 --- a/protocols/pom.xml +++ b/protocols/pom.xml @@ -40,7 +40,6 @@ ospf isis snmp - bmv2 lisp restconf tl1 diff --git a/providers/bmv2/app/features.xml b/providers/bmv2/app/features.xml deleted file mode 100644 index 76c36e670b..0000000000 --- a/providers/bmv2/app/features.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - onos-drivers-bmv2 - mvn:${project.groupId}/${project.artifactId}/${project.version} - mvn:${project.groupId}/onos-bmv2-provider-device/${project.version} - mvn:${project.groupId}/onos-bmv2-provider-packet/${project.version} - mvn:org.apache.thrift/libthrift/0.9.3 - mvn:${project.groupId}/onos-bmv2-protocol-api/${project.version} - mvn:${project.groupId}/onos-bmv2-protocol-ctl/${project.version} - mvn:${project.groupId}/onos-bmv2-protocol-thrift-api/${project.version} - - - diff --git a/providers/bmv2/app/pom.xml b/providers/bmv2/app/pom.xml deleted file mode 100644 index 25f1cd6acb..0000000000 --- a/providers/bmv2/app/pom.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - onos-bmv2-providers - org.onosproject - 1.11.0-SNAPSHOT - - - 4.0.0 - - onos-bmv2-app - bundle - - ONOS BMv2 southbound providers - - - org.onosproject.bmv2 - BMv2 Providers - Provider - - - - - org.onosproject - onos-bmv2-provider-device - ${project.version} - - - org.onosproject - onos-bmv2-provider-packet - ${project.version} - - - - \ No newline at end of file diff --git a/providers/bmv2/device/pom.xml b/providers/bmv2/device/pom.xml deleted file mode 100644 index ba62b49f32..0000000000 --- a/providers/bmv2/device/pom.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - onos-bmv2-providers - org.onosproject - 1.11.0-SNAPSHOT - - 4.0.0 - - onos-bmv2-provider-device - bundle - - ONOS BMv2 device provider - - - - org.onosproject - onos-core-common - - - org.onosproject - onos-bmv2-protocol-api - ${project.version} - - - \ No newline at end of file diff --git a/providers/bmv2/device/src/main/java/org/onosproject/provider/bmv2/device/impl/Bmv2DeviceProvider.java b/providers/bmv2/device/src/main/java/org/onosproject/provider/bmv2/device/impl/Bmv2DeviceProvider.java deleted file mode 100644 index 53f8c5bc52..0000000000 --- a/providers/bmv2/device/src/main/java/org/onosproject/provider/bmv2/device/impl/Bmv2DeviceProvider.java +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.provider.bmv2.device.impl; - -import com.google.common.collect.Maps; -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.Reference; -import org.apache.felix.scr.annotations.ReferenceCardinality; -import org.onlab.util.SharedScheduledExecutors; -import org.onosproject.bmv2.api.runtime.Bmv2Device; -import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException; -import org.onosproject.bmv2.api.service.Bmv2Controller; -import org.onosproject.bmv2.api.service.Bmv2DeviceContextService; -import org.onosproject.bmv2.api.service.Bmv2DeviceListener; -import org.onosproject.bmv2.api.service.Bmv2TableEntryService; -import org.onosproject.common.net.AbstractDeviceProvider; -import org.onosproject.core.ApplicationId; -import org.onosproject.core.CoreService; -import org.onosproject.incubator.net.config.basics.ConfigException; -import org.onosproject.mastership.MastershipService; -import org.onosproject.net.Device; -import org.onosproject.net.DeviceId; -import org.onosproject.net.MastershipRole; -import org.onosproject.net.PortNumber; -import org.onosproject.net.config.ConfigFactory; -import org.onosproject.net.config.NetworkConfigEvent; -import org.onosproject.net.config.NetworkConfigListener; -import org.onosproject.net.config.NetworkConfigRegistry; -import org.onosproject.net.device.DeviceDescription; -import org.onosproject.net.device.DeviceDescriptionDiscovery; -import org.onosproject.net.device.DeviceService; -import org.onosproject.net.device.PortDescription; -import org.onosproject.net.device.PortStatistics; -import org.onosproject.net.driver.DefaultDriverData; -import org.onosproject.net.driver.DefaultDriverHandler; -import org.onosproject.net.driver.Driver; -import org.onosproject.net.provider.ProviderId; -import org.slf4j.Logger; - -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static org.onlab.util.Tools.groupedThreads; -import static org.onosproject.bmv2.api.runtime.Bmv2Device.*; -import static org.onosproject.net.Device.Type.SWITCH; -import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY; -import static org.onosproject.provider.bmv2.device.impl.Bmv2PortStatisticsGetter.getPortStatistics; -import static org.onosproject.provider.bmv2.device.impl.Bmv2PortStatisticsGetter.initCounters; -import static org.slf4j.LoggerFactory.getLogger; - -/** - * BMv2 device provider. - */ -@Component(immediate = true) -public class Bmv2DeviceProvider extends AbstractDeviceProvider { - - private static final String APP_NAME = "org.onosproject.bmv2"; - - private static final int POLL_PERIOD = 5_000; // milliseconds - - private final Logger log = getLogger(this.getClass()); - - private final ExecutorService executorService = Executors - .newFixedThreadPool(16, groupedThreads("onos/bmv2", "device-discovery", log)); - - private final ScheduledExecutorService scheduledExecutorService = SharedScheduledExecutors.getPoolThreadExecutor(); - - private final NetworkConfigListener cfgListener = new InternalNetworkConfigListener(); - - private final ConfigFactory cfgFactory = new InternalConfigFactory(); - - private final Map lastDescriptions = Maps.newHashMap(); - - private final ConcurrentMap deviceLocks = Maps.newConcurrentMap(); - - private final InternalDeviceListener deviceListener = new InternalDeviceListener(); - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected NetworkConfigRegistry netCfgService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected CoreService coreService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected DeviceService deviceService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected MastershipService mastershipService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected Bmv2Controller controller; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected Bmv2DeviceContextService contextService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected Bmv2TableEntryService tableEntryService; - - private ApplicationId appId; - private ScheduledFuture poller; - - /** - * Creates a Bmv2 device provider with the supplied identifier. - */ - public Bmv2DeviceProvider() { - super(new ProviderId("bmv2", "org.onosproject.provider.device")); - } - - @Override - protected void activate() { - appId = coreService.registerApplication(APP_NAME); - netCfgService.registerConfigFactory(cfgFactory); - netCfgService.addListener(cfgListener); - controller.addDeviceListener(deviceListener); - if (poller != null) { - poller.cancel(false); - } - poller = scheduledExecutorService.scheduleAtFixedRate(this::pollDevices, 1_000, POLL_PERIOD, MILLISECONDS); - super.activate(); - } - - @Override - protected void deactivate() { - if (poller != null) { - poller.cancel(false); - } - controller.removeDeviceListener(deviceListener); - try { - lastDescriptions.forEach((did, value) -> { - executorService.execute(() -> disconnectDevice(did)); - }); - executorService.awaitTermination(1000, MILLISECONDS); - } catch (InterruptedException e) { - log.error("Device discovery threads did not terminate"); - } - executorService.shutdownNow(); - netCfgService.unregisterConfigFactory(cfgFactory); - netCfgService.removeListener(cfgListener); - super.deactivate(); - } - - @Override - public void triggerProbe(DeviceId deviceId) { - // Asynchronously trigger probe task. - executorService.execute(() -> executeProbe(deviceId)); - } - - private void executeProbe(DeviceId did) { - boolean reachable = isReachable(did); - log.debug("Probed device: id={}, reachable={}", did.toString(), reachable); - if (reachable) { - discoverDevice(did); - } else { - disconnectDevice(did); - } - } - - @Override - public void roleChanged(DeviceId deviceId, MastershipRole newRole) { - log.debug("roleChanged() is not yet implemented"); - // TODO: implement mastership handling - } - - @Override - public boolean isReachable(DeviceId deviceId) { - return controller.isReacheable(deviceId); - } - - @Override - public void changePortState(DeviceId deviceId, PortNumber portNumber, boolean enable) { - log.warn("changePortState() not supported"); - } - - private void discoverDevice(DeviceId did) { - // Serialize discovery for the same device. - Lock lock = deviceLocks.computeIfAbsent(did, k -> new ReentrantLock()); - lock.lock(); - try { - log.debug("Starting device discovery... deviceId={}", did); - - if (contextService.getContext(did) == null) { - // Device is a first timer. - log.info("Setting DEFAULT context for {}", did); - // It is important to do this before creating the device in the core - // so other services won't find a null context. - contextService.setDefaultContext(did); - // Abort discovery, we'll receive a new hello once the swap has been performed. - return; - } - - DeviceDescription lastDescription = lastDescriptions.get(did); - DeviceDescription thisDescription = getDeviceDescription(did); - - if (thisDescription != null) { - boolean descriptionChanged = lastDescription == null || - (!Objects.equals(thisDescription, lastDescription) || - !Objects.equals(thisDescription.annotations(), lastDescription.annotations())); - if (descriptionChanged || !deviceService.isAvailable(did)) { - resetDeviceState(did); - initPortCounters(did); - providerService.deviceConnected(did, thisDescription); - updatePortsAndStats(did); - } - lastDescriptions.put(did, thisDescription); - } else { - log.warn("Unable to get device description for {}", did); - lastDescriptions.put(did, lastDescription); - } - } finally { - lock.unlock(); - } - } - - private DeviceDescription getDeviceDescription(DeviceId did) { - Device device = deviceService.getDevice(did); - DeviceDescriptionDiscovery discovery = null; - if (device == null) { - // Device not yet in the core. Manually get a driver. - Driver driver = driverService.getDriver(MANUFACTURER, HW_VERSION, SW_VERSION); - if (driver.hasBehaviour(DeviceDescriptionDiscovery.class)) { - discovery = driver.createBehaviour(new DefaultDriverHandler(new DefaultDriverData(driver, did)), - DeviceDescriptionDiscovery.class); - } - } else if (device.is(DeviceDescriptionDiscovery.class)) { - discovery = device.as(DeviceDescriptionDiscovery.class); - } - if (discovery == null) { - log.warn("No DeviceDescriptionDiscovery behavior for device {}", did); - return null; - } else { - return discovery.discoverDeviceDetails(); - } - } - - private void resetDeviceState(DeviceId did) { - try { - controller.getAgent(did).resetState(); - // Tables emptied. Reset all bindings. - tableEntryService.unbindAll(did); - } catch (Bmv2RuntimeException e) { - log.warn("Unable to reset {}: {}", did, e.toString()); - } - } - - private void initPortCounters(DeviceId did) { - try { - initCounters(controller.getAgent(did)); - } catch (Bmv2RuntimeException e) { - log.warn("Unable to init counter on {}: {}", did, e.explain()); - } - } - - private void updatePortsAndStats(DeviceId did) { - Device device = deviceService.getDevice(did); - if (device.is(DeviceDescriptionDiscovery.class)) { - DeviceDescriptionDiscovery discovery = device.as(DeviceDescriptionDiscovery.class); - List portDescriptions = discovery.discoverPortDetails(); - if (portDescriptions != null) { - providerService.updatePorts(did, portDescriptions); - } - } else { - log.warn("No DeviceDescriptionDiscovery behavior for device {}", did); - } - try { - Collection portStats = getPortStatistics(controller.getAgent(did), - deviceService.getPorts(did)); - providerService.updatePortStatistics(did, portStats); - } catch (Bmv2RuntimeException e) { - log.warn("Unable to get port statistics for {}: {}", did, e.explain()); - } - } - - private void disconnectDevice(DeviceId did) { - log.debug("Disconnecting device from core... deviceId={}", did); - providerService.deviceDisconnected(did); - lastDescriptions.remove(did); - } - - private void pollDevices() { - for (Device device: deviceService.getAvailableDevices(SWITCH)) { - if (device.id().uri().getScheme().equals(SCHEME) && - mastershipService.isLocalMaster(device.id())) { - executorService.execute(() -> pollingTask(device.id())); - } - } - } - - private void pollingTask(DeviceId deviceId) { - log.debug("Polling device {}...", deviceId); - if (isReachable(deviceId)) { - updatePortsAndStats(deviceId); - } else { - disconnectDevice(deviceId); - } - } - - /** - * Internal net-cfg config factory. - */ - private class InternalConfigFactory extends ConfigFactory { - - InternalConfigFactory() { - super(APP_SUBJECT_FACTORY, Bmv2ProviderConfig.class, "devices", true); - } - - @Override - public Bmv2ProviderConfig createConfig() { - return new Bmv2ProviderConfig(); - } - } - - /** - * Internal net-cfg event listener. - */ - private class InternalNetworkConfigListener implements NetworkConfigListener { - - @Override - public void event(NetworkConfigEvent event) { - Bmv2ProviderConfig cfg = netCfgService.getConfig(appId, Bmv2ProviderConfig.class); - if (cfg != null) { - try { - cfg.getDevicesInfo().stream().forEach(info -> { - // FIXME: require also bmv2 internal device id from net-cfg (now is default 0) - Bmv2Device bmv2Device = new Bmv2Device(info.ip().toString(), info.port(), 0); - triggerProbe(bmv2Device.asDeviceId()); - }); - } catch (ConfigException e) { - log.error("Unable to read config: " + e); - } - } else { - log.error("Unable to read config (was null)"); - } - } - - @Override - public boolean isRelevant(NetworkConfigEvent event) { - return event.configClass().equals(Bmv2ProviderConfig.class) && - (event.type() == NetworkConfigEvent.Type.CONFIG_ADDED || - event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED); - } - } - - /** - * Listener triggered by the BMv2 controller each time a hello message is received. - */ - private class InternalDeviceListener implements Bmv2DeviceListener { - @Override - public void handleHello(Bmv2Device device, int instanceId, String jsonConfigMd5) { - log.debug("Received hello from {}", device); - triggerProbe(device.asDeviceId()); - } - } -} diff --git a/providers/bmv2/device/src/main/java/org/onosproject/provider/bmv2/device/impl/Bmv2PortStatisticsGetter.java b/providers/bmv2/device/src/main/java/org/onosproject/provider/bmv2/device/impl/Bmv2PortStatisticsGetter.java deleted file mode 100644 index ff94ab03a1..0000000000 --- a/providers/bmv2/device/src/main/java/org/onosproject/provider/bmv2/device/impl/Bmv2PortStatisticsGetter.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.provider.bmv2.device.impl; - -import com.google.common.collect.Lists; -import org.apache.commons.lang3.tuple.Pair; -import org.onosproject.bmv2.api.runtime.Bmv2Action; -import org.onosproject.bmv2.api.runtime.Bmv2DeviceAgent; -import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException; -import org.onosproject.net.Port; -import org.onosproject.net.device.DefaultPortStatistics; -import org.onosproject.net.device.PortStatistics; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Collection; -import java.util.List; - -/** - * Utility class to read port statistics from a BMv2 device. - */ -final class Bmv2PortStatisticsGetter { - - // TODO: make counters configuration dependent - - private static final String TABLE_NAME = "port_count_table"; - private static final String ACTION_NAME = "count_packet"; - private static final String EGRESS_COUNTER = "egress_port_counter"; - private static final String INGRESS_COUNTER = "ingress_port_counter"; - - private static final Logger log = LoggerFactory.getLogger(Bmv2PortStatisticsGetter.class); - - private Bmv2PortStatisticsGetter() { - // ban constructor. - } - - /** - * Returns a collection of port statistics for given ports using the given BMv2 device agent. - * - * @param deviceAgent a device agent - * @param ports a collection of ports - * @return a collection of port statistics - */ - static Collection getPortStatistics(Bmv2DeviceAgent deviceAgent, Collection ports) { - - List ps = Lists.newArrayList(); - - for (Port port : ports) { - int portNumber = (int) port.number().toLong(); - try { - Pair egressCounter = deviceAgent.readCounter(EGRESS_COUNTER, portNumber); - Pair ingressCounter = deviceAgent.readCounter(INGRESS_COUNTER, portNumber); - ps.add(DefaultPortStatistics.builder() - .setPort(portNumber) - .setBytesSent(egressCounter.getLeft()) - .setPacketsSent(egressCounter.getRight()) - .setBytesReceived(ingressCounter.getLeft()) - .setPacketsReceived(ingressCounter.getRight()) - .build()); - } catch (Bmv2RuntimeException e) { - log.info("Unable to read port statistics from {}: {}", port, e.explain()); - } - } - - return ps; - } - - /** - * Initialize port counters on the given device agent. - * - * @param deviceAgent a device agent. - */ - static void initCounters(Bmv2DeviceAgent deviceAgent) { - try { - deviceAgent.setTableDefaultAction(TABLE_NAME, Bmv2Action.builder().withName(ACTION_NAME).build()); - } catch (Bmv2RuntimeException e) { - log.debug("Failed to provision counters on {}: {}", deviceAgent.deviceId(), e.explain()); - } - } -} - diff --git a/providers/bmv2/device/src/main/java/org/onosproject/provider/bmv2/device/impl/Bmv2ProviderConfig.java b/providers/bmv2/device/src/main/java/org/onosproject/provider/bmv2/device/impl/Bmv2ProviderConfig.java deleted file mode 100644 index 0accf9b460..0000000000 --- a/providers/bmv2/device/src/main/java/org/onosproject/provider/bmv2/device/impl/Bmv2ProviderConfig.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.provider.bmv2.device.impl; - -import com.fasterxml.jackson.databind.JsonNode; -import com.google.common.annotations.Beta; -import com.google.common.collect.Sets; -import org.onlab.packet.IpAddress; -import org.onosproject.core.ApplicationId; -import org.onosproject.incubator.net.config.basics.ConfigException; -import org.onosproject.net.config.Config; - -import java.util.Set; - -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * Configuration decoder for Bmv2 provider. - */ -@Beta -public class Bmv2ProviderConfig extends Config { - public static final String CONFIG_VALUE_ERROR = "Error parsing config value"; - private static final String IP = "ip"; - private static final int DEFAULT_THRIFT_PORT = 9090; - private static final String PORT = "port"; - - /** - * Retrieves a set of Bmv2DeviceInfo containing all the device - * configuration pertaining to the Bmv2 device provider. - * - * @return set of device configurations. - * @throws ConfigException if configuration can't be read - */ - public Set getDevicesInfo() throws ConfigException { - Set deviceInfos = Sets.newHashSet(); - - try { - for (JsonNode node : array) { - String ip = node.path(IP).asText(); - IpAddress ipAddr = ip.isEmpty() ? null : IpAddress.valueOf(ip); - int port = node.path(PORT).asInt(DEFAULT_THRIFT_PORT); - deviceInfos.add(new Bmv2DeviceInfo(ipAddr, port)); - - } - } catch (IllegalArgumentException e) { - throw new ConfigException(CONFIG_VALUE_ERROR, e); - } - - return deviceInfos; - } - - /** - * Contains information about a Bmv2 device retrieved from the net-cfg - * subsystem. - */ - public static class Bmv2DeviceInfo { - private final IpAddress ip; - private final int port; - - /** - * Build an information object containing the given device specifics. - * - * @param ip ip - * @param port port - */ - public Bmv2DeviceInfo(IpAddress ip, int port) { - // TODO use generalized host string instead of IP address - this.ip = checkNotNull(ip, "ip cannot be null"); - this.port = checkNotNull(port, "port cannot be null"); - } - - /** - * Returns IpAddress of the device. - * - * @return ip - */ - public IpAddress ip() { - return ip; - } - - /** - * Returns port of the device. - * - * @return port - */ - public int port() { - return port; - } - } - -} diff --git a/providers/bmv2/device/src/main/java/org/onosproject/provider/bmv2/device/impl/package-info.java b/providers/bmv2/device/src/main/java/org/onosproject/provider/bmv2/device/impl/package-info.java deleted file mode 100644 index 1607b3c081..0000000000 --- a/providers/bmv2/device/src/main/java/org/onosproject/provider/bmv2/device/impl/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Provider that use BMv2 Thrift RPCs as a mean of infrastructure device discovery. - */ -package org.onosproject.provider.bmv2.device.impl; \ No newline at end of file diff --git a/providers/bmv2/packet/pom.xml b/providers/bmv2/packet/pom.xml deleted file mode 100644 index cb4fe23f3d..0000000000 --- a/providers/bmv2/packet/pom.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - onos-bmv2-providers - org.onosproject - 1.11.0-SNAPSHOT - - 4.0.0 - - onos-bmv2-provider-packet - - bundle - - ONOS BMv2 packet provider - - - - org.onosproject - onos-core-common - - - org.onosproject - onos-bmv2-protocol-api - ${project.version} - - - \ No newline at end of file diff --git a/providers/bmv2/packet/src/main/java/org/onosproject/provider/bmv2/packet/impl/Bmv2PacketProvider.java b/providers/bmv2/packet/src/main/java/org/onosproject/provider/bmv2/packet/impl/Bmv2PacketProvider.java deleted file mode 100644 index c6945f94cf..0000000000 --- a/providers/bmv2/packet/src/main/java/org/onosproject/provider/bmv2/packet/impl/Bmv2PacketProvider.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.provider.bmv2.packet.impl; - -import org.apache.felix.scr.annotations.Activate; -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.Deactivate; -import org.apache.felix.scr.annotations.Reference; -import org.apache.felix.scr.annotations.ReferenceCardinality; -import org.onlab.packet.Ethernet; -import org.onlab.util.ImmutableByteSequence; -import org.onosproject.bmv2.api.runtime.Bmv2Device; -import org.onosproject.bmv2.api.service.Bmv2Controller; -import org.onosproject.bmv2.api.service.Bmv2PacketListener; -import org.onosproject.core.CoreService; -import org.onosproject.net.ConnectPoint; -import org.onosproject.net.Device; -import org.onosproject.net.DeviceId; -import org.onosproject.net.Port; -import org.onosproject.net.PortNumber; -import org.onosproject.net.device.DeviceService; -import org.onosproject.net.flow.DefaultTrafficTreatment; -import org.onosproject.net.flow.TrafficTreatment; -import org.onosproject.net.packet.DefaultInboundPacket; -import org.onosproject.net.packet.DefaultOutboundPacket; -import org.onosproject.net.packet.DefaultPacketContext; -import org.onosproject.net.packet.InboundPacket; -import org.onosproject.net.packet.OutboundPacket; -import org.onosproject.net.packet.PacketContext; -import org.onosproject.net.packet.PacketProgrammable; -import org.onosproject.net.packet.PacketProvider; -import org.onosproject.net.packet.PacketProviderRegistry; -import org.onosproject.net.packet.PacketProviderService; -import org.onosproject.net.provider.AbstractProvider; -import org.onosproject.net.provider.ProviderId; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.nio.ByteBuffer; -import java.util.Optional; - -import static org.onosproject.net.PortNumber.FLOOD; -import static org.onosproject.net.flow.DefaultTrafficTreatment.emptyTreatment; -import static org.onosproject.net.flow.instructions.Instruction.Type.OUTPUT; -import static org.onosproject.net.flow.instructions.Instructions.OutputInstruction; - -/** - * Implementation of a packet provider for BMv2. - */ -@Component(immediate = true) -public class Bmv2PacketProvider extends AbstractProvider implements PacketProvider { - - private final Logger log = LoggerFactory.getLogger(Bmv2PacketProvider.class); - private static final String APP_NAME = "org.onosproject.bmv2"; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected Bmv2Controller controller; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected CoreService coreService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected PacketProviderRegistry providerRegistry; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected DeviceService deviceService; - - private PacketProviderService providerService; - - private InternalPacketListener packetListener = new InternalPacketListener(); - - /** - * Creates a new BMv2 packet provider. - */ - public Bmv2PacketProvider() { - super(new ProviderId("bmv2", "org.onosproject.provider.packet")); - } - - @Activate - protected void activate() { - providerService = providerRegistry.register(this); - coreService.registerApplication(APP_NAME); - controller.addPacketListener(packetListener); - log.info("Started"); - } - - @Deactivate - public void deactivate() { - controller.removePacketListener(packetListener); - providerRegistry.unregister(this); - providerService = null; - log.info("Stopped"); - } - - @Override - public void emit(OutboundPacket packet) { - if (packet != null) { - DeviceId deviceId = packet.sendThrough(); - Device device = deviceService.getDevice(deviceId); - if (device.is(PacketProgrammable.class)) { - PacketProgrammable packetProgrammable = device.as(PacketProgrammable.class); - packetProgrammable.emit(packet); - } else { - log.info("No PacketProgrammable behavior for device {}", deviceId); - } - } - } - - /** - * Internal packet context implementation. - */ - private class Bmv2PacketContext extends DefaultPacketContext { - - Bmv2PacketContext(long time, InboundPacket inPkt, OutboundPacket outPkt, boolean block) { - super(time, inPkt, outPkt, block); - } - - @Override - public void send() { - - if (this.block()) { - log.info("Unable to send, packet context not blocked"); - return; - } - - DeviceId deviceId = outPacket().sendThrough(); - ByteBuffer rawData = outPacket().data(); - - TrafficTreatment treatment; - if (outPacket().treatment() == null) { - treatment = (treatmentBuilder() == null) ? emptyTreatment() : treatmentBuilder().build(); - } else { - treatment = outPacket().treatment(); - } - - // BMv2 doesn't support FLOOD for packet-outs. - // Workaround here is to perform multiple emits, one for each device port != packet inPort. - Optional floodInst = treatment.allInstructions() - .stream() - .filter(i -> i.type().equals(OUTPUT)) - .map(i -> (OutputInstruction) i) - .filter(i -> i.port().equals(FLOOD)) - .findAny(); - - if (floodInst.isPresent() && treatment.allInstructions().size() == 1) { - // Only one instruction and is FLOOD. Do the trick. - PortNumber inPort = inPacket().receivedFrom().port(); - deviceService.getPorts(outPacket().sendThrough()) - .stream() - .map(Port::number) - .filter(port -> !port.equals(inPort)) - .map(outPort -> DefaultTrafficTreatment.builder().setOutput(outPort).build()) - .map(outTreatment -> new DefaultOutboundPacket(deviceId, outTreatment, rawData)) - .forEach(Bmv2PacketProvider.this::emit); - } else { - // Not FLOOD treatment, what to do is up to driver. - emit(new DefaultOutboundPacket(deviceId, treatment, rawData)); - } - } - } - - /** - * Internal packet listener to handle packet-in events received from the BMv2 controller. - */ - private class InternalPacketListener implements Bmv2PacketListener { - - @Override - public void handlePacketIn(Bmv2Device device, int inputPort, ImmutableByteSequence packet) { - Ethernet ethPkt = new Ethernet(); - ethPkt.deserialize(packet.asArray(), 0, packet.size()); - - DeviceId deviceId = device.asDeviceId(); - ConnectPoint receivedFrom = new ConnectPoint(deviceId, PortNumber.portNumber(inputPort)); - - ByteBuffer rawData = ByteBuffer.wrap(packet.asArray()); - - InboundPacket inPkt = new DefaultInboundPacket(receivedFrom, ethPkt, rawData); - OutboundPacket outPkt = new DefaultOutboundPacket(deviceId, null, rawData); - - PacketContext pktCtx = new Bmv2PacketContext(System.currentTimeMillis(), inPkt, outPkt, false); - - providerService.processPacket(pktCtx); - } - } -} diff --git a/providers/bmv2/packet/src/main/java/org/onosproject/provider/bmv2/packet/impl/package-info.java b/providers/bmv2/packet/src/main/java/org/onosproject/provider/bmv2/packet/impl/package-info.java deleted file mode 100644 index 3d83eadbfc..0000000000 --- a/providers/bmv2/packet/src/main/java/org/onosproject/provider/bmv2/packet/impl/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2016-present Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Provider that use Thrift as a mean of listening for packet-ins and emitting packet-outs. - */ -package org.onosproject.provider.bmv2.packet.impl; \ No newline at end of file diff --git a/providers/bmv2/pom.xml b/providers/bmv2/pom.xml deleted file mode 100644 index ef5a3b379d..0000000000 --- a/providers/bmv2/pom.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - onos-providers - org.onosproject - 1.11.0-SNAPSHOT - - - 4.0.0 - - onos-bmv2-providers - pom - - ONOS BMv2 providers - - - app - device - packet - - - \ No newline at end of file diff --git a/providers/pom.xml b/providers/pom.xml index 639c123619..ea912909e2 100644 --- a/providers/pom.xml +++ b/providers/pom.xml @@ -45,7 +45,6 @@ lldpcommon lldp netcfglinks - bmv2 isis lisp ospf diff --git a/tools/build/conf/src/main/resources/onos/suppressions.xml b/tools/build/conf/src/main/resources/onos/suppressions.xml index c2922fb921..a40ce9cc63 100644 --- a/tools/build/conf/src/main/resources/onos/suppressions.xml +++ b/tools/build/conf/src/main/resources/onos/suppressions.xml @@ -46,9 +46,6 @@ - - diff --git a/tools/build/onos-validate-change-version.excludes b/tools/build/onos-validate-change-version.excludes index 88bf63f270..a064421e3e 100755 --- a/tools/build/onos-validate-change-version.excludes +++ b/tools/build/onos-validate-change-version.excludes @@ -31,9 +31,7 @@ \./protocols/snmp/ \./protocols/restconf \./providers/snmp/ -\./providers/bmv2/ \./providers/ietfte/ -\./drivers/bmv2/ \./apps/kafka-integration/ \./pom.xml.versionsBackup \./tools/build/buck-publish-api