CNlucius
Committed by Gerrit Code Review

ONOS-2724

Fix bug of apply flowrule and remove flowrule

Change-Id: Ia7dec83206c3f5e24f912f111bd87dab6eab4610
/*
* 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;
}
......