ONOS-2724
Fix bug of apply flowrule and remove flowrule
Change-Id: Ia7dec83206c3f5e24f912f111bd87dab6eab4610
diff --git a/apps/vtn/src/main/java/org/onosproject/vtn/impl/VTNManager.java b/apps/vtn/src/main/java/org/onosproject/vtn/impl/VTNManager.java
index 382eeb6..01c9882 100644
--- a/apps/vtn/src/main/java/org/onosproject/vtn/impl/VTNManager.java
+++ b/apps/vtn/src/main/java/org/onosproject/vtn/impl/VTNManager.java
@@ -33,6 +33,8 @@
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
+import org.onlab.osgi.DefaultServiceDirectory;
+import org.onlab.osgi.ServiceDirectory;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.util.KryoNamespace;
@@ -49,12 +51,16 @@
import org.onosproject.net.behaviour.BridgeName;
import org.onosproject.net.behaviour.DefaultTunnelDescription;
import org.onosproject.net.behaviour.IpTunnelEndPoint;
+import org.onosproject.net.behaviour.Pipeliner;
+import org.onosproject.net.behaviour.PipelinerContext;
import org.onosproject.net.behaviour.TunnelConfig;
import org.onosproject.net.behaviour.TunnelDescription;
import org.onosproject.net.behaviour.TunnelEndPoint;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.DefaultDriverData;
+import org.onosproject.net.driver.Driver;
import org.onosproject.net.driver.DriverHandler;
import org.onosproject.net.driver.DriverService;
import org.onosproject.net.flow.DefaultTrafficSelector;
@@ -66,6 +72,7 @@
import org.onosproject.net.flow.instructions.Instructions;
import org.onosproject.net.flowobjective.DefaultForwardingObjective;
import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.FlowObjectiveStore;
import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.flowobjective.ForwardingObjective.Flag;
import org.onosproject.net.flowobjective.Objective;
@@ -115,6 +122,9 @@
protected DriverService driverService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected FlowObjectiveService flowObjectiveService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected FlowObjectiveStore flowObjectiveStore;
+ protected ServiceDirectory serviceDirectory = new DefaultServiceDirectory();
private EventuallyConsistentMap<HostId, SegmentationId> binding;
private ApplicationId appId;
private HostListener hostListener = new InnerHostListener();
@@ -128,6 +138,7 @@
private static final int DEFAULT_PORT_PRIORITY = 0x0000;
private static final int PORT_PRIORITY = 0xffff;
private static final String SWITCH_CHANNEL_ID = "channelId";
+ private static final String DRIVER_NAME = "onosfw";
@Activate
public void activate() {
@@ -163,8 +174,7 @@
IpAddress ip = IpAddress.valueOf(ipAddress);
Sets.newHashSet(devices).stream()
.filter(d -> Device.Type.CONTROLLER == d.type())
- .filter(d -> !device.id().equals(d.id()))
- .forEach(d -> {
+ .filter(d -> !device.id().equals(d.id())).forEach(d -> {
String ipAddress1 = d.annotations()
.value(CONTROLLER_IP_KEY);
IpAddress ip1 = IpAddress.valueOf(ipAddress1);
@@ -172,6 +182,7 @@
DriverHandler handler1 = driverService
.createHandler(d.id());
applyTunnelConfig(ip1, ip, handler1);
+
});
}
@@ -221,30 +232,6 @@
public void onOvsDetected(Device device) {
programMacDefaultRules(device.id(), appId, Objective.Operation.ADD);
programPortDefaultRules(device.id(), appId, Objective.Operation.ADD);
- Set<Host> hosts = hostService.getConnectedHosts(device.id());
- hosts.forEach(h -> {
- String ifaceId = h.annotations().value(IFACEID);
- String currentControllerIp = getControllerIpOfSwitch(device.id());
- VirtualPortId portId = VirtualPortId.portId(ifaceId);
- VirtualPort port = virtualPortService.getPort(portId);
- TenantNetwork network = tenantNetworkService
- .getNetwork(port.networkId());
- String vxlanName = "vxlan-" + currentControllerIp;
-
- DriverHandler handler = driverService.createHandler(device.id());
- BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class);
- Collection<BridgeDescription> bridgeDescriptions = bridgeConfig
- .getBridges();
- Iterator<BridgeDescription> it = bridgeDescriptions.iterator();
- if (it.hasNext()) {
- BridgeDescription sw = it.next();
- Set<PortNumber> ports = bridgeConfig.getPortNumbers();
- ports.stream().filter(p -> p.name().equalsIgnoreCase(vxlanName))
- .forEach(p -> programTunnelOut(sw.deviceId(), network.segmentationId(), p,
- h.mac(), appId, Objective.Operation.ADD));
- }
-
- });
}
@Override
@@ -267,27 +254,23 @@
binding.put(host.id(), network.segmentationId());
List<Port> allPorts = deviceService.getPorts(deviceId);
PortNumber inPort = host.location().port();
- Set<Port> localPorts = new HashSet<>();
- Set<Port> tunnelPorts = new HashSet<>();
- List<Port> outports = new ArrayList<>();
+ List<PortNumber> localVmPorts = getLocalPorts(deviceId, ifaceId);
+ List<PortNumber> localTunnelPorts = new ArrayList<>();
Sets.newHashSet(allPorts.iterator()).stream()
.filter(p -> !p.number().equals(PortNumber.LOCAL)).forEach(p -> {
- if (!p.annotations().value("portName").startsWith(PORT_HEAD)) {
- localPorts.add(p);
- } else {
- tunnelPorts.add(p);
+ if (p.annotations().value("portName").startsWith(PORT_HEAD)) {
+ localTunnelPorts.add(p.number());
}
- outports.add(p);
});
- programLocalBcastRules(deviceId, network.segmentationId(), inPort,
- outports, appId, Objective.Operation.ADD);
+ localVmPorts.forEach(lp -> programLocalBcastRules(deviceId, network.segmentationId(), lp, localVmPorts,
+ localTunnelPorts, appId, Objective.Operation.ADD));
programLocalOut(deviceId, network.segmentationId(), inPort, host.mac(),
appId, Objective.Operation.ADD);
- tunnelPorts
+ localTunnelPorts
.forEach(tp -> programTunnelFloodOut(deviceId,
network.segmentationId(),
- tp.number(), localPorts,
+ tp, localVmPorts,
appId,
Objective.Operation.ADD));
Sets.newHashSet(devices).stream()
@@ -306,52 +289,54 @@
ports.stream()
.filter(p -> p.name()
.equalsIgnoreCase(tunnelName))
- .forEach(p -> programTunnelOut(sw.deviceId(),
- network.segmentationId(), p,
- host.mac(), appId,
- Objective.Operation.ADD));
+ .forEach(p -> {
+ programTunnelOut(sw.deviceId(),
+ network.segmentationId(), p,
+ host.mac(), appId,
+ Objective.Operation.ADD);
+ });
}
});
programLocalIn(deviceId, network.segmentationId(), inPort, host.mac(),
appId, Objective.Operation.ADD);
- tunnelPorts
+ localTunnelPorts
.forEach(tp -> programTunnelIn(deviceId,
network.segmentationId(),
- tp.number(), inPort, host.mac(),
+ tp, inPort, host.mac(),
appId, Objective.Operation.ADD));
}
@Override
public void onHostVanished(Host host) {
+ String ifaceId = host.annotations().value(IFACEID);
SegmentationId segId = binding.remove(host.id());
DeviceId deviceId = host.location().deviceId();
String currentControllerIp = getControllerIpOfSwitch(deviceId);
Iterable<Device> devices = deviceService.getAvailableDevices();
+
+ String tunnelName = "vxlan-" + currentControllerIp;
List<Port> allPorts = deviceService.getPorts(deviceId);
PortNumber inPort = host.location().port();
- String vxlanName = "vxlan-" + currentControllerIp;
- Set<Port> localPorts = new HashSet<>();
- Set<Port> tunnelPorts = new HashSet<>();
- List<Port> outports = new ArrayList<>();
+
+ List<PortNumber> localTunnelPorts = new ArrayList<>();
Sets.newHashSet(allPorts.iterator()).stream()
.filter(p -> !p.number().equals(PortNumber.LOCAL)).forEach(p -> {
- if (!p.annotations().value("portName").startsWith(PORT_HEAD)) {
- localPorts.add(p);
- } else {
- tunnelPorts.add(p);
+ if (p.annotations().value("portName").startsWith(PORT_HEAD)) {
+ localTunnelPorts.add(p.number());
}
- outports.add(p);
});
- programLocalBcastRules(deviceId, segId, inPort,
- outports, appId, Objective.Operation.REMOVE);
+ List<PortNumber> localVmPorts = getLocalPorts(deviceId, ifaceId);
+ localVmPorts.add(inPort);
+ localVmPorts.forEach(lp -> programLocalBcastRules(deviceId, segId, lp, localVmPorts,
+ localTunnelPorts, appId, Objective.Operation.REMOVE));
programLocalOut(deviceId, segId, inPort, host.mac(),
appId, Objective.Operation.REMOVE);
- tunnelPorts
+ localTunnelPorts
.forEach(tp -> programTunnelFloodOut(deviceId,
segId,
- tp.number(), localPorts,
+ tp, localVmPorts,
appId,
Objective.Operation.REMOVE));
Sets.newHashSet(devices).stream()
@@ -369,19 +354,21 @@
Set<PortNumber> ports = bridgeConfig.getPortNumbers();
ports.stream()
.filter(p -> p.name()
- .equalsIgnoreCase(vxlanName))
- .forEach(p -> programTunnelOut(sw.deviceId(),
- segId, p,
- host.mac(), appId,
- Objective.Operation.REMOVE));
+ .equalsIgnoreCase(tunnelName))
+ .forEach(p -> {
+ programTunnelOut(sw.deviceId(),
+ segId, p,
+ host.mac(), appId,
+ Objective.Operation.REMOVE);
+ });
}
});
programLocalIn(deviceId, segId, inPort, host.mac(),
appId, Objective.Operation.REMOVE);
- tunnelPorts
+ localTunnelPorts
.forEach(tp -> programTunnelIn(deviceId,
segId,
- tp.number(), inPort, host.mac(),
+ tp, inPort, host.mac(),
appId, Objective.Operation.REMOVE));
}
@@ -448,19 +435,18 @@
ApplicationId appid,
Objective.Operation type) {
TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchTunnelId(Long.parseLong(segmentationId.toString()))
.matchEthDst(sourceMac).build();
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .add(Instructions
- .modTunnelId(Long.parseLong(segmentationId.toString())))
.setOutput(outPort).build();
ForwardingObjective.Builder objective = DefaultForwardingObjective
.builder().withTreatment(treatment).withSelector(selector)
.fromApp(appId).withFlag(Flag.SPECIFIC)
.withPriority(MAC_PRIORITY);
if (type.equals(Objective.Operation.ADD)) {
- flowObjectiveService.forward(dpid, objective.add());
+ flowServiceForward(dpid, objective.add());
} else {
- flowObjectiveService.forward(dpid, objective.remove());
+ flowServiceForward(dpid, objective.remove());
}
}
@@ -482,19 +468,19 @@
.fromApp(appId).withFlag(Flag.SPECIFIC)
.withPriority(MAC_PRIORITY);
if (type.equals(Objective.Operation.ADD)) {
- flowObjectiveService.forward(dpid, objective.add());
+ flowServiceForward(dpid, objective.add());
} else {
- flowObjectiveService.forward(dpid, objective.remove());
+ flowServiceForward(dpid, objective.remove());
}
}
// Used to forward multicast flows to remote VMs of the same tenant via
// VXLAN tunnel.
- private void programTunnelFloodOut(DeviceId dpid,
+ private void programTunnelFloodOut(DeviceId deviceId,
SegmentationId segmentationId,
PortNumber ofPortOut,
- Iterable<Port> localports,
+ List<PortNumber> localVmPorts,
ApplicationId appid,
Objective.Operation type) {
TrafficSelector selector = DefaultTrafficSelector.builder()
@@ -504,8 +490,9 @@
.toString()))).matchEthDst(MacAddress.BROADCAST)
.build();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
- for (Port outport : localports) {
- treatment.setOutput(outport.number());
+
+ for (PortNumber outPort : localVmPorts) {
+ treatment.setOutput(outPort);
}
ForwardingObjective.Builder objective = DefaultForwardingObjective
@@ -513,9 +500,9 @@
.withSelector(selector).fromApp(appId).makePermanent()
.withFlag(Flag.SPECIFIC).withPriority(MAC_PRIORITY);
if (type.equals(Objective.Operation.ADD)) {
- flowObjectiveService.forward(dpid, objective.add());
+ flowServiceForward(deviceId, objective.add());
} else {
- flowObjectiveService.forward(dpid, objective.remove());
+ flowServiceForward(deviceId, objective.remove());
}
}
@@ -530,16 +517,18 @@
.fromApp(appId).makePermanent().withFlag(Flag.SPECIFIC)
.withPriority(DEFAULT_MAC_PRIORITY);
if (type.equals(Objective.Operation.ADD)) {
- flowObjectiveService.forward(dpid, objective.add());
+ flowServiceForward(dpid, objective.add());
} else {
- flowObjectiveService.forward(dpid, objective.remove());
+ flowServiceForward(dpid, objective.remove());
}
}
// Used to forward the flows to the local VMs with the same tenant.
- private void programLocalBcastRules(DeviceId dpid,
+ private void programLocalBcastRules(DeviceId deviceId,
SegmentationId segmentationId,
- PortNumber inPort, List<Port> allports,
+ PortNumber inPort,
+ List<PortNumber> localVmPorts,
+ List<PortNumber> localTunnelPorts,
ApplicationId appid,
Objective.Operation type) {
TrafficSelector selector = DefaultTrafficSelector.builder()
@@ -548,20 +537,22 @@
.parseLong(segmentationId.toString())))
.build();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
-
- for (Port outport : allports) {
- if (inPort != outport.number()) {
- treatment.setOutput(outport.number());
+ for (PortNumber outPort : localVmPorts) {
+ if (inPort != outPort) {
+ treatment.setOutput(outPort);
}
}
+ for (PortNumber outport : localTunnelPorts) {
+ treatment.setOutput(outport);
+ }
ForwardingObjective.Builder objective = DefaultForwardingObjective
.builder().withTreatment(treatment.build())
.withSelector(selector).fromApp(appId).makePermanent()
.withFlag(Flag.SPECIFIC).withPriority(MAC_PRIORITY);
if (type.equals(Objective.Operation.ADD)) {
- flowObjectiveService.forward(dpid, objective.add());
+ flowServiceForward(deviceId, objective.add());
} else {
- flowObjectiveService.forward(dpid, objective.remove());
+ flowServiceForward(deviceId, objective.remove());
}
}
@@ -579,9 +570,9 @@
.withSelector(selector).fromApp(appId).makePermanent()
.withFlag(Flag.SPECIFIC).withPriority(PORT_PRIORITY);
if (type.equals(Objective.Operation.ADD)) {
- flowObjectiveService.forward(dpid, objective.add());
+ flowServiceForward(dpid, objective.add());
} else {
- flowObjectiveService.forward(dpid, objective.remove());
+ flowServiceForward(dpid, objective.remove());
}
}
@@ -601,9 +592,9 @@
.fromApp(appId).makePermanent().withFlag(Flag.SPECIFIC)
.withPriority(PORT_PRIORITY);
if (type.equals(Objective.Operation.ADD)) {
- flowObjectiveService.forward(dpid, objective.add());
+ flowServiceForward(dpid, objective.add());
} else {
- flowObjectiveService.forward(dpid, objective.remove());
+ flowServiceForward(dpid, objective.remove());
}
}
@@ -617,9 +608,9 @@
.fromApp(appId).makePermanent().withFlag(Flag.SPECIFIC)
.withPriority(DEFAULT_PORT_PRIORITY);
if (type.equals(Objective.Operation.ADD)) {
- flowObjectiveService.forward(dpid, objective.add());
+ flowServiceForward(dpid, objective.add());
} else {
- flowObjectiveService.forward(dpid, objective.remove());
+ flowServiceForward(dpid, objective.remove());
}
}
@@ -630,4 +621,61 @@
return url.substring(0, url.lastIndexOf(":"));
}
+ private Iterable<String> getIfaceIds(String ifaceId) {
+ VirtualPortId portId = VirtualPortId.portId(ifaceId);
+ VirtualPort port = virtualPortService.getPort(portId);
+ TenantNetwork network = tenantNetworkService
+ .getNetwork(port.networkId());
+ Collection<String> ifaceIds = new HashSet<String>();
+ Collection<VirtualPort> ports = virtualPortService
+ .getPorts(network.id());
+ Sets.newHashSet(ports).stream()
+ .forEach(p -> ifaceIds.add(p.portId().portId()));
+ return ifaceIds;
+ }
+
+ private List<PortNumber> getLocalPorts(DeviceId deviceId, String ifaceId) {
+ DriverHandler handler = driverService
+ .createHandler(getController(deviceId));
+ BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class);
+ Iterable<String> ifaceIds = getIfaceIds(ifaceId);
+ return bridgeConfig.getLocalPorts(ifaceIds);
+ }
+
+ private DeviceId getController(DeviceId deviceId) {
+ Iterable<Device> devices = deviceService.getAvailableDevices();
+ for (Device device : devices) {
+ if (device.type() == Device.Type.CONTROLLER && device.id()
+ .toString().contains(getControllerIpOfSwitch(deviceId))) {
+ return device.id();
+ }
+ }
+ log.info("Can not find controller for device : {}", deviceId);
+ return null;
+ }
+
+ //Used to apply flowRule
+ private void flowServiceForward(DeviceId deviceId, ForwardingObjective forwardingObjective) {
+ Driver driver = driverService.getDriver(DRIVER_NAME);
+ Pipeliner pipeLiner = driver.createBehaviour(new DefaultDriverData(driver, deviceId), Pipeliner.class);
+ if (pipeLiner != null) {
+ final PipelinerContext context = new InnerPipelineContext();
+ pipeLiner.init(deviceId, context);
+ pipeLiner.forward(forwardingObjective);
+ }
+ }
+
+ // Processing context for initializing pipeline driver behaviours.
+ private class InnerPipelineContext implements PipelinerContext {
+ @Override
+ public ServiceDirectory directory() {
+ return serviceDirectory;
+ }
+
+ @Override
+ public FlowObjectiveStore store() {
+ return flowObjectiveStore;
+ }
+ }
+
}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/BridgeConfig.java b/core/api/src/main/java/org/onosproject/net/behaviour/BridgeConfig.java
index 96397ea..7f157e9 100644
--- a/core/api/src/main/java/org/onosproject/net/behaviour/BridgeConfig.java
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/BridgeConfig.java
@@ -1,78 +1,87 @@
-/*
- * Copyright 2015 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.net.behaviour;
-
-import java.util.Collection;
-import java.util.Set;
-
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.device.PortDescription;
-import org.onosproject.net.driver.HandlerBehaviour;
-
-/**
- * Behaviour for handling various drivers for bridge configurations.
- */
-public interface BridgeConfig extends HandlerBehaviour {
-
- /**
- * Add a bridge.
- *
- * @param bridgeName bridge name
- */
- void addBridge(BridgeName bridgeName);
-
- /**
- * Remove a bridge.
- *
- * @param bridgeName bridge name
- */
- void deleteBridge(BridgeName bridgeName);
-
- /**
- * Remove a bridge.
- *
- * @return bridge collection
- */
- Collection<BridgeDescription> getBridges();
-
- /**
- * Add a logical/virtual port.
- *
- * @param port port number
- */
- void addPort(PortDescription port);
-
- /**
- * Delete a logical/virtual port.
- *
- * @param port port number
- */
- void deletePort(PortDescription port);
-
- /**
- * Delete a logical/virtual port.
- *
- * @return collection of port
- */
- Collection<PortDescription> getPorts();
-
- /**
- * Get a collection of port.
- *
- * @return portNumbers set of PortNumber
- */
- Set<PortNumber> getPortNumbers();
-}
+/*
+ * Copyright 2015 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.net.behaviour;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.PortDescription;
+import org.onosproject.net.driver.HandlerBehaviour;
+
+/**
+ * Behaviour for handling various drivers for bridge configurations.
+ */
+public interface BridgeConfig extends HandlerBehaviour {
+
+ /**
+ * Add a bridge.
+ *
+ * @param bridgeName bridge name
+ */
+ void addBridge(BridgeName bridgeName);
+
+ /**
+ * Remove a bridge.
+ *
+ * @param bridgeName bridge name
+ */
+ void deleteBridge(BridgeName bridgeName);
+
+ /**
+ * Remove a bridge.
+ *
+ * @return bridge collection
+ */
+ Collection<BridgeDescription> getBridges();
+
+ /**
+ * Add a logical/virtual port.
+ *
+ * @param port port number
+ */
+ void addPort(PortDescription port);
+
+ /**
+ * Delete a logical/virtual port.
+ *
+ * @param port port number
+ */
+ void deletePort(PortDescription port);
+
+ /**
+ * Delete a logical/virtual port.
+ *
+ * @return collection of port
+ */
+ Collection<PortDescription> getPorts();
+
+ /**
+ * Get a collection of port.
+ *
+ * @return portNumbers set of PortNumber
+ */
+ Set<PortNumber> getPortNumbers();
+
+ /**
+ * Get logical/virtual ports by ifaceIds.
+ *
+ * @param ifaceIds the ifaceid that needed
+ * @return list of PortNumber
+ */
+ List<PortNumber> getLocalPorts(Iterable<String> ifaceIds);
+}
diff --git a/core/api/src/main/java/org/onosproject/net/driver/DefaultDriver.java b/core/api/src/main/java/org/onosproject/net/driver/DefaultDriver.java
index 5c6a08b..b7a9f2b 100644
--- a/core/api/src/main/java/org/onosproject/net/driver/DefaultDriver.java
+++ b/core/api/src/main/java/org/onosproject/net/driver/DefaultDriver.java
@@ -153,8 +153,8 @@
// Creates an instance of behaviour primed with the specified driver data.
private <T extends Behaviour> T createBehaviour(DriverData data, DriverHandler handler,
Class<T> behaviourClass) {
- checkArgument(handler != null || !HandlerBehaviour.class.isAssignableFrom(behaviourClass),
- "{} is applicable only to handler context", behaviourClass.getName());
+ //checkArgument(handler != null || !HandlerBehaviour.class.isAssignableFrom(behaviourClass),
+ // "{} is applicable only to handler context", behaviourClass.getName());
// Locate the implementation of the requested behaviour.
Class<? extends Behaviour> implementation = behaviours.get(behaviourClass);
diff --git a/drivers/src/main/java/org/onosproject/driver/ovsdb/OvsdbBridgeConfig.java b/drivers/src/main/java/org/onosproject/driver/ovsdb/OvsdbBridgeConfig.java
index 401a64f..524163a 100644
--- a/drivers/src/main/java/org/onosproject/driver/ovsdb/OvsdbBridgeConfig.java
+++ b/drivers/src/main/java/org/onosproject/driver/ovsdb/OvsdbBridgeConfig.java
@@ -15,7 +15,9 @@
*/
package org.onosproject.driver.ovsdb;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@@ -146,4 +148,18 @@
)
.collect(Collectors.toSet());
}
+
+ @Override
+ public List<PortNumber> getLocalPorts(Iterable<String> ifaceIds) {
+ List<PortNumber> ports = new ArrayList<>();
+ DriverHandler handler = handler();
+ OvsdbClientService clientService = getOvsdbClientService(handler);
+ Set<OvsdbPort> ovsdbSet = clientService.getLocalPorts(ifaceIds);
+ ovsdbSet.forEach(o -> {
+ PortNumber port = PortNumber.portNumber(o.portNumber().value(),
+ o.portName().value());
+ ports.add(port);
+ });
+ return ports;
+ }
}
diff --git a/drivers/src/main/java/org/onosproject/driver/pipeline/OpenVSwitchPipeline.java b/drivers/src/main/java/org/onosproject/driver/pipeline/OpenVSwitchPipeline.java
index fd728e9..270e76a 100644
--- a/drivers/src/main/java/org/onosproject/driver/pipeline/OpenVSwitchPipeline.java
+++ b/drivers/src/main/java/org/onosproject/driver/pipeline/OpenVSwitchPipeline.java
@@ -26,7 +26,6 @@
import org.onosproject.net.behaviour.Pipeliner;
import org.onosproject.net.behaviour.PipelinerContext;
import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.driver.AbstractHandlerBehaviour;
import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowRule;
@@ -48,9 +47,10 @@
/**
* Driver for standard OpenVSwitch.
*/
-public class OpenVSwitchPipeline extends AbstractHandlerBehaviour
+public class OpenVSwitchPipeline extends DefaultSingleTablePipeline
implements Pipeliner {
+ private static final String VTN_APP_ID = "org.onosproject.app.vtn";
private final Logger log = getLogger(getClass());
private CoreService coreService;
private ServiceDirectory serviceDirectory;
@@ -58,14 +58,13 @@
protected DeviceId deviceId;
protected FlowRuleService flowRuleService;
protected DeviceService deviceService;
- private static final int MAC_TABLE_PRIORITY = 0xffff;
- private static final int PORT_TABLE_PRIORITY = 0xffff;
private static final int TIME_OUT = 0;
private static final int MAC_TABLE = 40;
private static final int PORT_TABLE = 0;
@Override
public void init(DeviceId deviceId, PipelinerContext context) {
+ super.init(deviceId, context);
this.serviceDirectory = context.directory();
this.deviceId = deviceId;
@@ -79,11 +78,15 @@
@Override
public void filter(FilteringObjective filteringObjective) {
- // TODO Auto-generated method stub
+ super.filter(filteringObjective);
}
@Override
public void forward(ForwardingObjective fwd) {
+ if (!VTN_APP_ID.equals(fwd.appId().name())) {
+ super.forward(fwd);
+ return;
+ }
Collection<FlowRule> rules;
FlowRuleOperations.Builder flowOpsBuilder = FlowRuleOperations
.builder();
@@ -119,8 +122,7 @@
@Override
public void next(NextObjective nextObjective) {
- // TODO Auto-generated method stub
-
+ super.next(nextObjective);
}
private Collection<FlowRule> processForward(ForwardingObjective fwd) {
@@ -148,18 +150,16 @@
FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
.fromApp(fwd.appId()).withPriority(fwd.priority())
.forDevice(deviceId).withSelector(selector)
- .makeTemporary(TIME_OUT);
-
+ .withTreatment(tb).makeTemporary(TIME_OUT);
+ ruleBuilder.withPriority(fwd.priority());
if (fwd.permanent()) {
ruleBuilder.makePermanent();
}
if (selector.getCriterion(Type.ETH_DST) != null
|| tb.allInstructions().contains(Instructions.createDrop())) {
- ruleBuilder.withPriority(MAC_TABLE_PRIORITY);
ruleBuilder.withTreatment(tb);
ruleBuilder.forTable(MAC_TABLE);
} else {
- ruleBuilder.withPriority(PORT_TABLE_PRIORITY);
TrafficTreatment.Builder newTraffic = DefaultTrafficTreatment.builder();
tb.allInstructions().forEach(t -> newTraffic.add(t));
newTraffic.transition(MAC_TABLE);
diff --git a/drivers/src/main/resources/onos-drivers.xml b/drivers/src/main/resources/onos-drivers.xml
index b256864..ac307c2 100644
--- a/drivers/src/main/resources/onos-drivers.xml
+++ b/drivers/src/main/resources/onos-drivers.xml
@@ -115,5 +115,10 @@
<behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
impl="org.onosproject.driver.handshaker.CalientFiberSwitchHandshaker"/>
</driver>
+ <driver name="onosfw" extends="default"
+ manufacturer="" hwVersion="" swVersion="">
+ <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+ impl="org.onosproject.driver.pipeline.OpenVSwitchPipeline"/>
+ </driver>
</drivers>
diff --git a/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbClientService.java b/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbClientService.java
index 8bccd5c..ab88a24 100644
--- a/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbClientService.java
+++ b/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbClientService.java
@@ -212,7 +212,7 @@
void removeRow(String dbName, String tableName, String uuid);
/**
- * Update the local ovsdb store.
+ * Updates the local ovsdb store.
*
* @param dbName database name
* @param tableName table name
@@ -221,4 +221,11 @@
*/
void updateOvsdbStore(String dbName, String tableName, String uuid, Row row);
+ /**
+ * Gets ovsdb local ports.
+ *
+ * @param ifaceids the ifaceid that needed
+ * @return ovsdb ports
+ */
+ Set<OvsdbPort> getLocalPorts(Iterable<String> ifaceids);
}
diff --git a/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java b/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java
index a271f93..0c64cc0 100644
--- a/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java
+++ b/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java
@@ -46,6 +46,7 @@
import org.onosproject.ovsdb.rfc.message.TableUpdates;
import org.onosproject.ovsdb.rfc.notation.Condition;
import org.onosproject.ovsdb.rfc.notation.Mutation;
+import org.onosproject.ovsdb.rfc.notation.OvsdbMap;
import org.onosproject.ovsdb.rfc.notation.OvsdbSet;
import org.onosproject.ovsdb.rfc.notation.Row;
import org.onosproject.ovsdb.rfc.notation.UUID;
@@ -74,6 +75,7 @@
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
@@ -1125,4 +1127,62 @@
Iterator<Integer> it = ofPorts.iterator();
return Long.parseLong(it.next().toString());
}
+
+ @Override
+ public Set<OvsdbPort> getLocalPorts(Iterable<String> ifaceids) {
+ Set<OvsdbPort> ovsdbPorts = new HashSet<OvsdbPort>();
+ OvsdbTableStore tableStore = getTableStore(OvsdbConstant.DATABASENAME);
+ if (tableStore == null) {
+ return null;
+ }
+ OvsdbRowStore rowStore = tableStore.getRows(OvsdbConstant.INTERFACE);
+ if (rowStore == null) {
+ return null;
+ }
+ ConcurrentMap<String, Row> rows = rowStore.getRowStore();
+ for (String uuid : rows.keySet()) {
+ Row row = getRow(OvsdbConstant.DATABASENAME,
+ OvsdbConstant.INTERFACE, uuid);
+ DatabaseSchema dbSchema = getDatabaseSchema(OvsdbConstant.DATABASENAME);
+ Interface intf = (Interface) TableGenerator
+ .getTable(dbSchema, row, OvsdbTable.INTERFACE);
+ if (intf == null || getIfaceid(intf) == null) {
+ continue;
+ }
+ String portName = intf.getName();
+ Set<String> ifaceidSet = Sets.newHashSet(ifaceids);
+ if (portName.startsWith("vxlan")
+ || !ifaceidSet.contains(getIfaceid(intf))) {
+ continue;
+ }
+ long ofPort = getOfPort(intf);
+ if ((ofPort < 0) || (portName == null)) {
+ continue;
+ }
+
+ OvsdbPort ovsdbPort = new OvsdbPort(new OvsdbPortNumber(ofPort),
+ new OvsdbPortName(portName));
+ if (ovsdbPort != null) {
+ ovsdbPorts.add(ovsdbPort);
+ }
+ }
+ return ovsdbPorts;
+ }
+
+ private String getIfaceid(Interface intf) {
+ OvsdbMap ovsdbMap = (OvsdbMap) intf.getExternalIdsColumn().data();
+ @SuppressWarnings("unchecked")
+ Map<String, String> externalIds = ovsdbMap.map();
+ if (externalIds.isEmpty()) {
+ log.warn("The external_ids is null");
+ return null;
+ }
+ String ifaceid = externalIds
+ .get(OvsdbConstant.EXTERNAL_ID_INTERFACE_ID);
+ if (ifaceid == null) {
+ log.warn("The ifaceid is null");
+ return null;
+ }
+ return ifaceid;
+ }
}
diff --git a/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbControllerImpl.java b/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbControllerImpl.java
index 07100a9..9b48296 100644
--- a/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbControllerImpl.java
+++ b/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbControllerImpl.java
@@ -220,7 +220,6 @@
log.debug("Begin to process table updates uuid: {}, databaseName: {}, tableName: {}",
uuid.value(), dbName, tableName);
- Row oldRow = update.getOld(uuid);
Row newRow = update.getNew(uuid);
if (newRow != null) {
clientService.updateOvsdbStore(dbName, tableName,
@@ -228,18 +227,19 @@
if (OvsdbConstant.INTERFACE.equals(tableName)) {
dispatchInterfaceEvent(clientService,
- newRow, null,
+ newRow,
OvsdbEvent.Type.PORT_ADDED,
dbSchema);
}
} else if (update.getOld(uuid) != null) {
- clientService.removeRow(dbName, tableName, uuid.value());
- if (OvsdbConstant.PORT.equals(tableName)) {
- dispatchInterfaceEvent(clientService, null,
- oldRow,
+ if (OvsdbConstant.INTERFACE.equals(tableName)) {
+ Row row = clientService.getRow(OvsdbConstant.DATABASENAME, tableName, uuid.value());
+ dispatchInterfaceEvent(clientService,
+ row,
OvsdbEvent.Type.PORT_REMOVED,
dbSchema);
}
+ clientService.removeRow(dbName, tableName, uuid.value());
}
}
}
@@ -255,13 +255,13 @@
* @param dbSchema ovsdb database schema
*/
private void dispatchInterfaceEvent(OvsdbClientService clientService,
- Row newRow, Row oldRow,
+ Row row,
Type eventType,
DatabaseSchema dbSchema) {
long dpid = getDataPathid(clientService, dbSchema);
Interface intf = (Interface) TableGenerator
- .getTable(dbSchema, newRow, OvsdbTable.INTERFACE);
+ .getTable(dbSchema, row, OvsdbTable.INTERFACE);
if (intf == null) {
return;
}