Saurav Das

Improvements for the ofdpa driver.

New driver for ofdpa emulation with cpqd switch.

Change-Id: I5221069e07abe57538d4e988cdb7190b50c595f7
package org.onosproject.driver.pipeline;
import static org.slf4j.LoggerFactory.getLogger;
import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.FlowRuleOperations;
import org.onosproject.net.flow.FlowRuleOperationsContext;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.slf4j.Logger;
/**
* Driver for software switch emulation of the OFDPA 1.0 pipeline.
* The software switch is the CPqD OF 1.3 switch.
*/
public class CpqdOFDPA1Pipeline extends OFDPA1Pipeline {
private final Logger log = getLogger(getClass());
@Override
protected void initializePipeline() {
processPortTable();
//processVlanTable();
processTmacTable();
processIpTable();
//processMcastTable();
processBridgingTable();
//processAclTable();
//processGroupTable();
}
@Override
protected void processPortTable() {
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
treatment.transition(VLAN_TABLE);
FlowRule tmisse = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(LOWEST_PRIORITY)
.fromApp(driverId)
.makePermanent()
.forTable(PORT_TABLE).build();
ops = ops.add(tmisse);
flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
log.info("Initialized port table");
}
@Override
public void onError(FlowRuleOperations ops) {
log.info("Failed to initialize port table");
}
}));
}
@Override
protected void processTmacTable() {
//table miss entry
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
selector = DefaultTrafficSelector.builder();
treatment = DefaultTrafficTreatment.builder();
treatment.transition(BRIDGING_TABLE);
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(LOWEST_PRIORITY)
.fromApp(driverId)
.makePermanent()
.forTable(TMAC_TABLE).build();
ops = ops.add(rule);
flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
log.info("Initialized tmac table");
}
@Override
public void onError(FlowRuleOperations ops) {
log.info("Failed to initialize tmac table");
}
}));
}
@Override
protected void processIpTable() {
//table miss entry
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
selector = DefaultTrafficSelector.builder();
treatment = DefaultTrafficTreatment.builder();
treatment.transition(ACL_TABLE);
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(LOWEST_PRIORITY)
.fromApp(driverId)
.makePermanent()
.forTable(UNICAST_ROUTING_TABLE).build();
ops = ops.add(rule);
flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
log.info("Initialized IP table");
}
@Override
public void onError(FlowRuleOperations ops) {
log.info("Failed to initialize unicast IP table");
}
}));
}
private void processBridgingTable() {
//table miss entry
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
selector = DefaultTrafficSelector.builder();
treatment = DefaultTrafficTreatment.builder();
treatment.transition(ACL_TABLE);
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(LOWEST_PRIORITY)
.fromApp(driverId)
.makePermanent()
.forTable(BRIDGING_TABLE).build();
ops = ops.add(rule);
flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
log.info("Initialized Bridging table");
}
@Override
public void onError(FlowRuleOperations ops) {
log.info("Failed to initialize Bridging table");
}
}));
}
}
......@@ -105,7 +105,7 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline
private static final int HIGHEST_PRIORITY = 0xffff;
private static final int DEFAULT_PRIORITY = 0x8000;
private static final int LOWEST_PRIORITY = 0x0;
protected static final int LOWEST_PRIORITY = 0x0;
/*
* Group keys are normally generated by using the next Objective id. In the
......@@ -130,12 +130,12 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline
private final Logger log = getLogger(getClass());
private ServiceDirectory serviceDirectory;
private FlowRuleService flowRuleService;
protected FlowRuleService flowRuleService;
private CoreService coreService;
private GroupService groupService;
private FlowObjectiveStore flowObjectiveStore;
private DeviceId deviceId;
private ApplicationId driverId;
protected DeviceId deviceId;
protected ApplicationId driverId;
private KryoNamespace appKryo = new KryoNamespace.Builder()
.register(KryoNamespaces.API)
......@@ -610,7 +610,7 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline
}
private void initializePipeline() {
protected void initializePipeline() {
processPortTable();
processVlanTable();
processTmacTable();
......@@ -621,7 +621,7 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline
//processGroupTable();
}
private void processPortTable() {
protected void processPortTable() {
//XXX is table miss entry enough or do we need to do the maskable in-port 0?
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
......@@ -653,56 +653,12 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline
}
private void processVlanTable() {
// make these up for now - should really be filtering rules
/*FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
selector.matchInPort(PortNumber.portNumber(10));
selector.matchVlanId(VlanId.vlanId((short) 100));
treatment.transition(TMAC_TABLE);
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(DEFAULT_PRIORITY)
.fromApp(appId)
.makePermanent()
.forTable(VLAN_TABLE).build();
ops = ops.add(rule);
flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
log.info("Initialized vlan table");
}
@Override
public void onError(FlowRuleOperations ops) {
log.info("Failed to initialize vlan table");
}
}));*/
// Table miss entry is not required as ofdpa default is to drop
// In OF terms, the absence of a t.m.e. also implies drop
}
private void processTmacTable() {
// this is made up as well -- should be a filtering rule
/*selector.matchInPort(PortNumber.portNumber(10));
selector.matchVlanId(VlanId.vlanId((short) 100));
selector.matchEthType(Ethernet.TYPE_IPV4);
selector.matchEthDst(MacAddress.valueOf("00:00:00:ba:ba:00"));
treatment.transition(UNICAST_ROUTING_TABLE);
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(DEFAULT_PRIORITY)
.fromApp(appId)
.makePermanent()
.forTable(TMAC_TABLE).build();
ops = ops.add(rule);*/
protected void processTmacTable() {
//table miss entry
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
......@@ -732,7 +688,7 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline
}));*/
}
private void processIpTable() {
protected void processIpTable() {
//table miss entry
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
......@@ -762,72 +718,16 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline
}));*/
}
@SuppressWarnings("unused")
private void processGroupTable() {
// Creating a dummy L2 group as per OFDPA requirements
/* TrafficTreatment treatment = DefaultTrafficTreatment.builder()
.setOutput(PortNumber.portNumber(10))
.build();
NextObjective nextObjective = DefaultNextObjective.builder()
.addTreatment(treatment)
.fromApp(appId)
.withId(678) // dummy next objective id
.withType(NextObjective.Type.SIMPLE)
.add();
Integer l2groupId = 0x0064000a;
GroupBucket bucket =
DefaultGroupBucket.createIndirectGroupBucket(treatment);
final GroupKey key = new DefaultGroupKey(appKryo.serialize(678));
GroupDescription groupDescriptionl2
= new DefaultGroupDescription(deviceId,
GroupDescription.Type.INDIRECT,
new GroupBuckets(Collections
.singletonList(bucket)),
key,
l2groupId,
appId);
groupService.addGroup(groupDescriptionl2);*/
//pendingNextObjectives.put(key, nextObjective);
}
@SuppressWarnings("unused")
private void tryGroupChain() {
//Create a dummy L3 group as per OFDPA requirements
/*TrafficTreatment treatment2 = DefaultTrafficTreatment.builder()
.setEthDst(MacAddress.valueOf("00:00:00:aa:aa:aa"))
.setEthSrc(MacAddress.valueOf("00:00:00:dd:dd:dd"))
.setVlanId(VlanId.vlanId((short) 100))
.group(new DefaultGroupId(0x0064000a))
.build();
NextObjective nextObjective2 = DefaultNextObjective.builder()
.addTreatment(treatment2)
.fromApp(appId)
.withId(67800) // another dummy next objective id
.withType(NextObjective.Type.SIMPLE)
.add();
Integer l3groupId = 0x2000000a;
GroupBucket bucket2 = DefaultGroupBucket.createIndirectGroupBucket(treatment2);
final GroupKey key2 = new DefaultGroupKey(appKryo.serialize(67800));
GroupDescription groupDescriptionl3
= new DefaultGroupDescription(deviceId,
GroupDescription.Type.INDIRECT,
new GroupBuckets(Collections
.singletonList(bucket2)),
key2,
l3groupId,
appId);
groupService.addGroup(groupDescriptionl3);
pendingNextObjectives.put(key2, nextObjective2);
*/
}
private class GroupChecker implements Runnable {
@Override
public void run() {
Set<GroupKey> keys = pendingGroups.keySet().stream()
.filter(key -> groupService.getGroup(deviceId, key) != null)
.collect(Collectors.toSet());
Set<GroupKey> otherkeys = pendingNextObjectives.asMap().keySet().stream()
.filter(otherkey -> groupService.getGroup(deviceId, otherkey) != null)
.collect(Collectors.toSet());
keys.addAll(otherkeys);
keys.stream().forEach(key -> {
//first check for group chain
......@@ -856,7 +756,7 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline
private class InnerGroupListener implements GroupListener {
@Override
public void event(GroupEvent event) {
log.info("received group event of type {}", event.type());
log.debug("received group event of type {}", event.type());
if (event.type() == GroupEvent.Type.GROUP_ADDED) {
GroupKey key = event.subject().appCookie();
// first check for group chain
......
......@@ -63,9 +63,10 @@
impl="org.onosproject.driver.pipeline.OFDPA1Pipeline"/>
</driver>
<!-- The SoftRouter driver is meant to be used by any software/NPU based
~ switch that wishes to implement a simple 2-table router. ONOS needs to
~ be configured with the dpid of such a device to attach this driver
~ to the device.
~ switch that wishes to implement a simple 2-table router. To use this
~ driver, configure ONOS with the dpid of the device, or extend the
~ driver declaration with the manufacturer/hwVersion/swVersion of the
~ device (see 'noviflow' example).
-->
<driver name="softrouter" extends="default"
manufacturer="Various" hwVersion="various" swVersion="0.0.0">
......@@ -85,5 +86,14 @@
<driver name="noviflow" extends="softrouter"
manufacturer="NoviFlow Inc" hwVersion="NS1132" swVersion="NW250.4.4">
</driver>
<!-- Emulation of the ofdpa pipeline using a CPqD OF 1.3 software switch.
~ To use this driver, configure ONOS with the dpid of the device.
-->
<driver name="ofdpa-cpqd" extends="default"
manufacturer="ONF"
hwVersion="OF1.3 Software Switch from CPqD" swVersion="for Group Chaining">
<behaviour api="org.onosproject.net.behaviour.Pipeliner"
impl="org.onosproject.driver.pipeline.CpqdOFDPA1Pipeline"/>
</driver>
</drivers>
......