CNlucius
Committed by Gerrit Code Review

ONOS-2724

Fix bug of apply flowrule and remove flowrule

Change-Id: Ia7dec83206c3f5e24f912f111bd87dab6eab4610
......@@ -33,6 +33,8 @@ 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.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.BridgeDescription;
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.criteria.Criteria;
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 @@ public class VTNManager implements VTNService {
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 @@ public class VTNManager implements VTNService {
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 @@ public class VTNManager implements VTNService {
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 @@ public class VTNManager implements VTNService {
DriverHandler handler1 = driverService
.createHandler(d.id());
applyTunnelConfig(ip1, ip, handler1);
});
}
......@@ -221,30 +232,6 @@ public class VTNManager implements VTNService {
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 @@ public class VTNManager implements VTNService {
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 @@ public class VTNManager implements VTNService {
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 @@ public class VTNManager implements VTNService {
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 @@ public class VTNManager implements VTNService {
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 @@ public class VTNManager implements VTNService {
.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 @@ public class VTNManager implements VTNService {
.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 @@ public class VTNManager implements VTNService {
.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 @@ public class VTNManager implements VTNService {
.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 @@ public class VTNManager implements VTNService {
.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 @@ public class VTNManager implements VTNService {
.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 @@ public class VTNManager implements VTNService {
.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 @@ public class VTNManager implements VTNService {
.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 @@ public class VTNManager implements VTNService {
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;
}
}
}
......
/*
* 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);
}
......
......@@ -153,8 +153,8 @@ public class DefaultDriver implements Driver {
// 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);
......
......@@ -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 @@ public class OvsdbBridgeConfig extends AbstractHandlerBehaviour
)
.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;
}
}
......
......@@ -26,7 +26,6 @@ import org.onosproject.net.DeviceId;
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 @@ import org.slf4j.Logger;
/**
* 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 @@ public class OpenVSwitchPipeline extends AbstractHandlerBehaviour
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 @@ public class OpenVSwitchPipeline extends AbstractHandlerBehaviour
@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 @@ public class OpenVSwitchPipeline extends AbstractHandlerBehaviour
@Override
public void next(NextObjective nextObjective) {
// TODO Auto-generated method stub
super.next(nextObjective);
}
private Collection<FlowRule> processForward(ForwardingObjective fwd) {
......@@ -148,18 +150,16 @@ public class OpenVSwitchPipeline extends AbstractHandlerBehaviour
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);
......
......@@ -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>
......
......@@ -212,7 +212,7 @@ public interface OvsdbClientService extends OvsdbRPC {
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 @@ public interface OvsdbClientService extends OvsdbRPC {
*/
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);
}
......
......@@ -46,6 +46,7 @@ import org.onosproject.ovsdb.rfc.message.OperationResult;
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.fasterxml.jackson.databind.JsonNode;
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 @@ public class DefaultOvsdbClient
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;
}
}
......
......@@ -220,7 +220,6 @@ public class OvsdbControllerImpl implements OvsdbController {
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 @@ public class OvsdbControllerImpl implements OvsdbController {
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 @@ public class OvsdbControllerImpl implements OvsdbController {
* @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;
}
......