WIP: Initial implementation of filterObjectives using driver subsystem.
Incomplete implementation
Change-Id: I3745d481027659d4ca44b72139e5461c02e8c3ef
diff --git a/apps/bgprouter/src/main/java/org/onosproject/bgprouter/BgpRouter.java b/apps/bgprouter/src/main/java/org/onosproject/bgprouter/BgpRouter.java
index 9a4ecba..58e796f 100644
--- a/apps/bgprouter/src/main/java/org/onosproject/bgprouter/BgpRouter.java
+++ b/apps/bgprouter/src/main/java/org/onosproject/bgprouter/BgpRouter.java
@@ -15,14 +15,11 @@
*/
package org.onosproject.bgprouter;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
+import com.google.common.collect.ConcurrentHashMultiset;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multiset;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -45,12 +42,14 @@
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.FlowRule.Type;
import org.onosproject.net.flow.FlowRuleOperations;
-import org.onosproject.net.flow.FlowRuleOperationsContext;
import org.onosproject.net.flow.FlowRuleService;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flowobjective.DefaultFilteringObjective;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
import org.onosproject.net.group.DefaultGroupBucket;
import org.onosproject.net.group.DefaultGroupDescription;
import org.onosproject.net.group.DefaultGroupKey;
@@ -73,11 +72,13 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.collect.ConcurrentHashMultiset;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Multiset;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
/**
* BgpRouter component.
@@ -156,6 +157,10 @@
.register(NextHopGroupKey.class)
.build();
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected FlowObjectiveService flowObjectiveService;
+
@Activate
protected void activate() {
appId = coreService.registerApplication(BGP_ROUTER_APP);
@@ -377,336 +382,28 @@
private class InternalTableHandler {
- private static final int CONTROLLER_PRIORITY = 255;
- private static final int DROP_PRIORITY = 0;
- private static final int HIGHEST_PRIORITY = 0xffff;
private Set<InterfaceIpAddress> intfIps = new HashSet<InterfaceIpAddress>();
private Set<MacAddress> intfMacs = new HashSet<MacAddress>();
private Map<PortNumber, VlanId> portVlanPair = Maps.newHashMap();
public void provision(boolean install, Set<Interface> intfs) {
getInterfaceConfig(intfs);
- processTableZero(install);
- processTableOne(install);
- processTableTwo(install);
- processTableFour(install);
- processTableFive(install);
- processTableSix(install);
- processTableNine(install);
}
private void getInterfaceConfig(Set<Interface> intfs) {
log.info("Processing {} router interfaces", intfs.size());
for (Interface intf : intfs) {
+ FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
+ flowObjectiveService.filter(deviceId, Collections.singletonList(
+ fob.addCondition(Criteria.matchEthDst(intf.mac()))
+ .fromApp(appId).permit().add()));
intfIps.addAll(intf.ipAddresses());
intfMacs.add(intf.mac());
portVlanPair.put(intf.connectPoint().port(), intf.vlan());
}
}
- private void processTableZero(boolean install) {
- TrafficSelector.Builder selector;
- TrafficTreatment.Builder treatment;
-
- // Bcast rule
- selector = DefaultTrafficSelector.builder();
- treatment = DefaultTrafficTreatment.builder();
-
- selector.matchEthDst(MacAddress.BROADCAST);
- treatment.transition(FlowRule.Type.VLAN_MPLS);
-
- FlowRule rule = new DefaultFlowRule(deviceId, selector.build(),
- treatment.build(),
- CONTROLLER_PRIORITY, appId, 0,
- true, FlowRule.Type.FIRST);
-
- FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
-
- ops = install ? ops.add(rule) : ops.remove(rule);
-
- // Interface MACs
- for (MacAddress mac : intfMacs) {
- log.debug("adding rule for MAC: {}", mac);
- selector = DefaultTrafficSelector.builder();
- treatment = DefaultTrafficTreatment.builder();
-
- selector.matchEthDst(mac);
- treatment.transition(FlowRule.Type.VLAN_MPLS);
-
- rule = new DefaultFlowRule(deviceId, selector.build(),
- treatment.build(),
- CONTROLLER_PRIORITY, appId, 0,
- true, FlowRule.Type.FIRST);
-
- ops = install ? ops.add(rule) : ops.remove(rule);
- }
-
- //Drop rule
- selector = DefaultTrafficSelector.builder();
- treatment = DefaultTrafficTreatment.builder();
-
- treatment.drop();
-
- rule = new DefaultFlowRule(deviceId, selector.build(),
- treatment.build(), DROP_PRIORITY, appId,
- 0, true, FlowRule.Type.FIRST);
-
- ops = install ? ops.add(rule) : ops.remove(rule);
-
- flowService.apply(ops.build(new FlowRuleOperationsContext() {
- @Override
- public void onSuccess(FlowRuleOperations ops) {
- log.info("Provisioned default table for bgp router");
- }
-
- @Override
- public void onError(FlowRuleOperations ops) {
- log.info("Failed to provision default table for bgp router");
- }
- }));
-
- }
-
- private void processTableOne(boolean install) {
- TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
- TrafficTreatment.Builder treatment = DefaultTrafficTreatment
- .builder();
- FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
- FlowRule rule;
-
- selector.matchVlanId(VlanId.ANY);
- treatment.transition(FlowRule.Type.VLAN);
-
- rule = new DefaultFlowRule(deviceId, selector.build(),
- treatment.build(), CONTROLLER_PRIORITY,
- appId, 0, true, FlowRule.Type.VLAN_MPLS);
-
- ops = install ? ops.add(rule) : ops.remove(rule);
-
- flowService.apply(ops.build(new FlowRuleOperationsContext() {
- @Override
- public void onSuccess(FlowRuleOperations ops) {
- log.info("Provisioned vlan/mpls table for bgp router");
- }
-
- @Override
- public void onError(FlowRuleOperations ops) {
- log.info(
- "Failed to provision vlan/mpls table for bgp router");
- }
- }));
-
- }
-
- private void processTableTwo(boolean install) {
- TrafficSelector.Builder selector;
- TrafficTreatment.Builder treatment;
- FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
- FlowRule rule;
-
- //Interface Vlans
- for (Map.Entry<PortNumber, VlanId> portVlan : portVlanPair.entrySet()) {
- log.debug("adding rule for VLAN: {}", portVlan);
- selector = DefaultTrafficSelector.builder();
- treatment = DefaultTrafficTreatment.builder();
-
- selector.matchVlanId(portVlan.getValue());
- selector.matchInPort(portVlan.getKey());
- treatment.transition(Type.ETHER);
- treatment.deferred().popVlan();
-
- rule = new DefaultFlowRule(deviceId, selector.build(),
- treatment.build(), CONTROLLER_PRIORITY, appId,
- 0, true, FlowRule.Type.VLAN);
-
- ops = install ? ops.add(rule) : ops.remove(rule);
- }
-
- //Drop rule
- selector = DefaultTrafficSelector.builder();
- treatment = DefaultTrafficTreatment.builder();
-
- treatment.drop();
-
- rule = new DefaultFlowRule(deviceId, selector.build(),
- treatment.build(), DROP_PRIORITY, appId,
- 0, true, FlowRule.Type.VLAN);
-
- ops = install ? ops.add(rule) : ops.remove(rule);
-
- flowService.apply(ops.build(new FlowRuleOperationsContext() {
- @Override
- public void onSuccess(FlowRuleOperations ops) {
- log.info("Provisioned vlan table for bgp router");
- }
-
- @Override
- public void onError(FlowRuleOperations ops) {
- log.info("Failed to provision vlan table for bgp router");
- }
- }));
- }
-
- private void processTableFour(boolean install) {
- TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
- TrafficTreatment.Builder treatment = DefaultTrafficTreatment
- .builder();
- FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
- FlowRule rule;
-
- selector.matchEthType(Ethernet.TYPE_ARP);
- treatment.punt();
-
- rule = new DefaultFlowRule(deviceId, selector.build(),
- treatment.build(), CONTROLLER_PRIORITY,
- appId, 0, true, FlowRule.Type.ETHER);
-
- ops = install ? ops.add(rule) : ops.remove(rule);
-
- selector = DefaultTrafficSelector.builder();
- treatment = DefaultTrafficTreatment.builder();
-
- selector.matchEthType(Ethernet.TYPE_IPV4);
- treatment.transition(FlowRule.Type.COS);
-
- rule = new DefaultFlowRule(deviceId, selector.build(),
- treatment.build(), CONTROLLER_PRIORITY,
- appId, 0, true, FlowRule.Type.ETHER);
-
- ops = install ? ops.add(rule) : ops.remove(rule);
-
- //Drop rule
- selector = DefaultTrafficSelector.builder();
- treatment = DefaultTrafficTreatment.builder();
-
- treatment.drop();
-
- rule = new DefaultFlowRule(deviceId, selector.build(),
- treatment.build(), DROP_PRIORITY, appId,
- 0, true, FlowRule.Type.ETHER);
-
- ops = install ? ops.add(rule) : ops.remove(rule);
-
- flowService.apply(ops.build(new FlowRuleOperationsContext() {
- @Override
- public void onSuccess(FlowRuleOperations ops) {
- log.info("Provisioned ether table for bgp router");
- }
-
- @Override
- public void onError(FlowRuleOperations ops) {
- log.info("Failed to provision ether table for bgp router");
- }
- }));
-
- }
-
- private void processTableFive(boolean install) {
- TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
- TrafficTreatment.Builder treatment = DefaultTrafficTreatment
- .builder();
- FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
- FlowRule rule;
-
- treatment.transition(FlowRule.Type.IP);
-
- rule = new DefaultFlowRule(deviceId, selector.build(),
- treatment.build(), DROP_PRIORITY, appId,
- 0, true, FlowRule.Type.COS);
-
- ops = install ? ops.add(rule) : ops.remove(rule);
-
- flowService.apply(ops.build(new FlowRuleOperationsContext() {
- @Override
- public void onSuccess(FlowRuleOperations ops) {
- log.info("Provisioned cos table for bgp router");
- }
-
- @Override
- public void onError(FlowRuleOperations ops) {
- log.info("Failed to provision cos table for bgp router");
- }
- }));
-
- }
-
- private void processTableSix(boolean install) {
- TrafficSelector.Builder selector;
- TrafficTreatment.Builder treatment;
- FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
- FlowRule rule;
-
-
- //Interface IPs
- for (InterfaceIpAddress ipAddr : intfIps) {
- log.debug("adding rule for IPs: {}", ipAddr.ipAddress());
- selector = DefaultTrafficSelector.builder();
- treatment = DefaultTrafficTreatment.builder();
-
- selector.matchEthType(Ethernet.TYPE_IPV4);
- selector.matchIPDst(IpPrefix.valueOf(ipAddr.ipAddress(), 32));
- treatment.transition(Type.ACL);
-
- rule = new DefaultFlowRule(deviceId, selector.build(),
- treatment.build(), HIGHEST_PRIORITY, appId,
- 0, true, FlowRule.Type.IP);
-
- ops = install ? ops.add(rule) : ops.remove(rule);
- }
-
-
- //Drop rule
- selector = DefaultTrafficSelector.builder();
- treatment = DefaultTrafficTreatment.builder();
-
- treatment.drop();
-
- rule = new DefaultFlowRule(deviceId, selector.build(),
- treatment.build(), DROP_PRIORITY, appId,
- 0, true, FlowRule.Type.IP);
-
- ops = install ? ops.add(rule) : ops.remove(rule);
-
- flowService.apply(ops.build(new FlowRuleOperationsContext() {
- @Override
- public void onSuccess(FlowRuleOperations ops) {
- log.info("Provisioned FIB table for bgp router");
- }
-
- @Override
- public void onError(FlowRuleOperations ops) {
- log.info("Failed to provision FIB table for bgp router");
- }
- }));
- }
-
- private void processTableNine(boolean install) {
- TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
- TrafficTreatment.Builder treatment = DefaultTrafficTreatment
- .builder();
- FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
- FlowRule rule;
-
- treatment.punt();
-
- rule = new DefaultFlowRule(deviceId, selector.build(),
- treatment.build(), CONTROLLER_PRIORITY,
- appId, 0, true, FlowRule.Type.DEFAULT);
-
- ops = install ? ops.add(rule) : ops.remove(rule);
-
- flowService.apply(ops.build(new FlowRuleOperationsContext() {
- @Override
- public void onSuccess(FlowRuleOperations ops) {
- log.info("Provisioned Local table for bgp router");
- }
- @Override
- public void onError(FlowRuleOperations ops) {
- log.info("Failed to provision Local table for bgp router");
- }
- }));
- }
}
private class InternalGroupListener implements GroupListener {
diff --git a/core/api/src/main/java/org/onosproject/net/driver/AbstractBehaviour.java b/core/api/src/main/java/org/onosproject/net/driver/AbstractBehaviour.java
index eb6a302..001c490 100644
--- a/core/api/src/main/java/org/onosproject/net/driver/AbstractBehaviour.java
+++ b/core/api/src/main/java/org/onosproject/net/driver/AbstractBehaviour.java
@@ -26,4 +26,9 @@
public void setData(DriverData data) {
this.data = data;
}
+
+ @Override
+ public DriverData data() {
+ return data;
+ }
}
diff --git a/core/api/src/main/java/org/onosproject/net/driver/Behaviour.java b/core/api/src/main/java/org/onosproject/net/driver/Behaviour.java
index 7257eed..208eef7 100644
--- a/core/api/src/main/java/org/onosproject/net/driver/Behaviour.java
+++ b/core/api/src/main/java/org/onosproject/net/driver/Behaviour.java
@@ -29,4 +29,11 @@
*/
void setData(DriverData data);
+ /**
+ * Obtains the driver data.
+ *
+ * @return driver data
+ */
+ DriverData data();
+
}
diff --git a/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultFilteringObjective.java b/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultFilteringObjective.java
index 4c1b71f..da92b80 100644
--- a/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultFilteringObjective.java
+++ b/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultFilteringObjective.java
@@ -32,7 +32,7 @@
public final class DefaultFilteringObjective implements FilteringObjective {
- private final Criterion key;
+ private final Type type;
private final boolean permanent;
private final int timeout;
private final ApplicationId appId;
@@ -41,10 +41,10 @@
private final int id;
private final Operation op;
- private DefaultFilteringObjective(Criterion key, boolean permanent, int timeout,
+ private DefaultFilteringObjective(Type type, boolean permanent, int timeout,
ApplicationId appId, int priority,
List<Criterion> conditions, Operation op) {
- this.key = key;
+ this.type = type;
this.permanent = permanent;
this.timeout = timeout;
this.appId = appId;
@@ -52,14 +52,13 @@
this.conditions = conditions;
this.op = op;
- this.id = Objects.hash(key, conditions, permanent,
+ this.id = Objects.hash(type, conditions, permanent,
timeout, appId, priority);
}
-
@Override
- public Criterion key() {
- return key;
+ public Type type() {
+ return this.type;
}
@Override
@@ -111,7 +110,7 @@
private final ImmutableList.Builder<Criterion> listBuilder
= ImmutableList.builder();
- private Criterion key;
+ private Type type;
private boolean permanent = DEFAULT_PERMANENT;
private int timeout = DEFAULT_TIMEOUT;
private ApplicationId appId;
@@ -124,8 +123,14 @@
}
@Override
- public Builder withKey(Criterion criterion) {
- key = criterion;
+ public Builder permit() {
+ this.type = Type.PERMIT;
+ return this;
+ }
+
+ @Override
+ public Builder deny() {
+ this.type = Type.DENY;
return this;
}
@@ -157,11 +162,11 @@
@Override
public FilteringObjective add() {
List<Criterion> conditions = listBuilder.build();
- checkNotNull(key, "Must have a key.");
+ checkNotNull(type, "Must have a type.");
checkArgument(!conditions.isEmpty(), "Must have at least one condition.");
checkNotNull(appId, "Must supply an application id");
- return new DefaultFilteringObjective(key, permanent, timeout,
+ return new DefaultFilteringObjective(type, permanent, timeout,
appId, priority, conditions,
Operation.ADD);
@@ -170,11 +175,11 @@
@Override
public FilteringObjective remove() {
List<Criterion> conditions = listBuilder.build();
- checkNotNull(key, "Must have a key.");
+ checkNotNull(type, "Must have a type.");
checkArgument(!conditions.isEmpty(), "Must have at least one condition.");
checkNotNull(appId, "Must supply an application id");
- return new DefaultFilteringObjective(key, permanent, timeout,
+ return new DefaultFilteringObjective(type, permanent, timeout,
appId, priority, conditions,
Operation.REMOVE);
diff --git a/core/api/src/main/java/org/onosproject/net/flowobjective/FilteringObjective.java b/core/api/src/main/java/org/onosproject/net/flowobjective/FilteringObjective.java
index 93f62ac9..24ca2dc 100644
--- a/core/api/src/main/java/org/onosproject/net/flowobjective/FilteringObjective.java
+++ b/core/api/src/main/java/org/onosproject/net/flowobjective/FilteringObjective.java
@@ -15,6 +15,7 @@
*/
package org.onosproject.net.flowobjective;
+import org.onosproject.core.ApplicationId;
import org.onosproject.net.flow.criteria.Criterion;
import java.util.Collection;
@@ -27,12 +28,23 @@
*/
public interface FilteringObjective extends Objective {
+ enum Type {
+ /**
+ * Enables the filtering condition.
+ */
+ PERMIT,
+
+ /**
+ * Disables the filtering condition.
+ */
+ DENY
+ }
+
/**
- * Represents filtering key used in this filter.
- *
- * @return a criterion
+ * Obtain this filtering type.
+ * @return the type
*/
- Criterion key();
+ public Type type();
/**
* The set of conditions the filter must provision at the device.
@@ -55,12 +67,23 @@
public Builder addCondition(Criterion criterion);
/**
- * Add a filtering key.
- *
- * @param criterion new criterion
- * @return a filtering builder.
+ * Permit this filtering condition set.
+ * @return a filtering builder
*/
- public Builder withKey(Criterion criterion);
+ public Builder permit();
+
+ /**
+ * Deny this filtering condition set.
+ * @return a filtering builder
+ */
+ public Builder deny();
+
+ /**
+ * Assigns an application id.
+ * @param appId an application id
+ * @return a filtering builder
+ */
+ public Builder fromApp(ApplicationId appId);
/**
* Builds the filtering objective that will be added.
diff --git a/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java
index 3c1ec35..29e5857 100644
--- a/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java
+++ b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java
@@ -15,7 +15,9 @@
*/
package org.onosproject.net.flowobjective.impl;
+import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import com.google.common.util.concurrent.Futures;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -43,11 +45,13 @@
import org.onosproject.net.flowobjective.FlowObjectiveService;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.flowobjective.Objective;
import org.onosproject.net.group.GroupService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
+import java.util.Collections;
import java.util.Map;
import java.util.concurrent.Future;
@@ -87,12 +91,16 @@
private final Map<DeviceId, DriverHandler> driverHandlers = Maps.newConcurrentMap();
+ private final Map<DeviceId, Pipeliner> pipeliners = Maps.newConcurrentMap();
private final PipelinerContext context = new InnerPipelineContext();
private final MastershipListener mastershipListener = new InnerMastershipListener();
private final DeviceListener deviceListener = new InnerDeviceListener();
protected ServiceDirectory serviceDirectory = new DefaultServiceDirectory();
+
+ private final Map<DeviceId, Collection<Objective>> pendingObjectives =
+ Maps.newConcurrentMap();
private NodeId localNode;
@Activate
@@ -114,26 +122,51 @@
@Override
public Future<Boolean> filter(DeviceId deviceId,
Collection<FilteringObjective> filteringObjectives) {
- return getDevicePipeliner(deviceId).filter(filteringObjectives);
+ if (deviceService.isAvailable(deviceId)) {
+ return getDevicePipeliner(deviceId).filter(filteringObjectives);
+ } else {
+ filteringObjectives.forEach(obj -> updatePendingMap(deviceId, obj));
+ }
+ return Futures.immediateFuture(true);
}
+
+
@Override
public Future<Boolean> forward(DeviceId deviceId,
Collection<ForwardingObjective> forwardingObjectives) {
- return getDevicePipeliner(deviceId).forward(forwardingObjectives);
+ if (deviceService.isAvailable(deviceId)) {
+ return getDevicePipeliner(deviceId).forward(forwardingObjectives);
+ } else {
+ forwardingObjectives.forEach(obj -> updatePendingMap(deviceId, obj));
+ }
+ return Futures.immediateFuture(true);
}
@Override
public Future<Boolean> next(DeviceId deviceId,
Collection<NextObjective> nextObjectives) {
- return getDevicePipeliner(deviceId).next(nextObjectives);
+ if (deviceService.isAvailable(deviceId)) {
+ return getDevicePipeliner(deviceId).next(nextObjectives);
+ } else {
+ nextObjectives.forEach(obj -> updatePendingMap(deviceId, obj));
+ }
+ return Futures.immediateFuture(true);
}
- // Retrieves the device handler pipeline behaviour from the cache.
+ private void updatePendingMap(DeviceId deviceId, Objective pending) {
+ if (pendingObjectives.putIfAbsent(deviceId, Lists.newArrayList(pending)) != null) {
+ Collection<Objective> objectives = pendingObjectives.get(deviceId);
+ objectives.add(pending);
+ }
+
+ }
+
+ // Retrieves the device pipeline behaviour from the cache.
private Pipeliner getDevicePipeliner(DeviceId deviceId) {
- DriverHandler handler = driverHandlers.get(deviceId);
- checkState(handler != null, NOT_INITIALIZED);
- return handler != null ? handler.behaviour(Pipeliner.class) : null;
+ Pipeliner pipeliner = pipeliners.get(deviceId);
+ checkState(pipeliner != null, NOT_INITIALIZED);
+ return pipeliner;
}
@@ -164,6 +197,7 @@
case DEVICE_AVAILABILITY_CHANGED:
if (deviceService.isAvailable(event.subject().id())) {
setupPipelineHandler(event.subject().id());
+ processPendingObjectives(event.subject().id());
}
break;
case DEVICE_UPDATED:
@@ -182,6 +216,21 @@
break;
}
}
+
+ private void processPendingObjectives(DeviceId deviceId) {
+ pendingObjectives.get(deviceId).forEach(obj -> {
+ if (obj instanceof NextObjective) {
+ getDevicePipeliner(deviceId)
+ .next(Collections.singletonList((NextObjective) obj));
+ } else if (obj instanceof ForwardingObjective) {
+ getDevicePipeliner(deviceId)
+ .forward(Collections.singletonList((ForwardingObjective) obj));
+ } else {
+ getDevicePipeliner(deviceId)
+ .filter(Collections.singletonList((FilteringObjective) obj));
+ }
+ });
+ }
}
private void setupPipelineHandler(DeviceId deviceId) {
@@ -205,7 +254,9 @@
}
// Always (re)initialize the pipeline behaviour
- handler.behaviour(Pipeliner.class).init(deviceId, context);
+ Pipeliner pipeliner = handler.behaviour(Pipeliner.class);
+ pipeliner.init(deviceId, context);
+ pipeliners.putIfAbsent(deviceId, pipeliner);
log.info("Driver {} bound to device {}", handler.driver().name(), deviceId);
}
}
diff --git a/drivers/src/main/java/org/onosproject/driver/pipeline/OVSCorsaPipeline.java b/drivers/src/main/java/org/onosproject/driver/pipeline/OVSCorsaPipeline.java
index 3da786a..5af2563 100644
--- a/drivers/src/main/java/org/onosproject/driver/pipeline/OVSCorsaPipeline.java
+++ b/drivers/src/main/java/org/onosproject/driver/pipeline/OVSCorsaPipeline.java
@@ -15,6 +15,8 @@
*/
package org.onosproject.driver.pipeline;
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.SettableFuture;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.packet.Ethernet;
import org.onlab.packet.MacAddress;
@@ -34,9 +36,12 @@
import org.onosproject.net.flow.FlowRuleService;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flowobjective.FilteringObjective;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.flowobjective.Objective;
import org.slf4j.Logger;
import java.util.Collection;
@@ -79,7 +84,54 @@
@Override
public Future<Boolean> filter(Collection<FilteringObjective> filteringObjectives) {
- return null;
+ Collection<Future<Boolean>> results =
+ Sets.newHashSet();
+ filteringObjectives.stream()
+ .filter(obj -> obj.type() == FilteringObjective.Type.PERMIT)
+ .forEach(obj -> obj.conditions()
+ .forEach(condition ->
+ results.add(processCondition(condition,
+ obj.op() == Objective.Operation.ADD,
+ obj.appId()))
+ ));
+
+ //TODO: return something more helpful/sensible in the future (no pun intended)
+ return results.iterator().next();
+
+ }
+
+ private Future<Boolean> processCondition(Criterion c, boolean install,
+ ApplicationId applicationId) {
+ SettableFuture<Boolean> result = SettableFuture.create();
+ if (c.type() == Criterion.Type.ETH_DST) {
+ Criteria.EthCriterion e = (Criteria.EthCriterion) c;
+ log.debug("adding rule for MAC: {}", e.mac());
+
+ TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+ TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+ selector.matchEthDst(e.mac());
+ treatment.transition(FlowRule.Type.VLAN_MPLS);
+ FlowRule rule = new DefaultFlowRule(deviceId, selector.build(),
+ treatment.build(),
+ CONTROLLER_PRIORITY, applicationId, 0,
+ true, FlowRule.Type.FIRST);
+ FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
+ ops = install ? ops.add(rule) : ops.remove(rule);
+ flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
+ @Override
+ public void onSuccess(FlowRuleOperations ops) {
+ result.set(true);
+ log.info("Provisioned default table for bgp router");
+ }
+
+ @Override
+ public void onError(FlowRuleOperations ops) {
+ result.set(false);
+ log.info("Failed to provision default table for bgp router");
+ }
+ }));
+ }
+ return result;
}
@Override