Saurav Das
Committed by Gerrit Code Review

CORD-48 First checkin for enabling OF-DPA driver to support the SR app.

Filtering Objective support added. Driver renamed from OFDPA1 to OFDPA2.
Code refactored within driver to reflect test-code which will be used by
static flow-pusher app in the future.

Change-Id: I7132d8b8eaf28df7c11646c5a35035f258c65af4
......@@ -112,7 +112,7 @@ public class ArpHandler {
private boolean isArpReqForRouter(DeviceId deviceId, ARP arpRequest) {
List<Ip4Address> gatewayIpAddresses = config.getSubnetGatewayIps(deviceId);
List<Ip4Address> gatewayIpAddresses = config.getPortIPs(deviceId);
if (gatewayIpAddresses != null) {
Ip4Address targetProtocolAddress = Ip4Address.valueOf(arpRequest
.getTargetProtocolAddress());
......
......@@ -499,14 +499,13 @@ public class DefaultRoutingHandler {
}
/**
* Populates table miss entries for all tables, and pipeline rules for VLAN
* and TCAM tables. XXX rename/rethink
* Populates filtering rules for permitting Router DstMac and VLAN.
*
* @param deviceId Switch ID to set the rules
*/
public void populateTtpRules(DeviceId deviceId) {
rulePopulator.populateTableVlan(deviceId);
rulePopulator.populateTableTMac(deviceId);
public void populatePortAddressingRules(DeviceId deviceId) {
rulePopulator.populateRouterMacVlanFilters(deviceId);
rulePopulator.populateRouterIpPunts(deviceId);
}
/**
......
......@@ -126,7 +126,7 @@ public class DeviceConfiguration implements DeviceProperties {
}
/**
* Returns the segment id of a segment router.
* Returns the Node segment id of a segment router.
*
* @param deviceId device identifier
* @return segment id
......@@ -147,7 +147,7 @@ public class DeviceConfiguration implements DeviceProperties {
}
/**
* Returns the segment id of a segment router given its mac address.
* Returns the Node segment id of a segment router given its Router mac address.
*
* @param routerMac router mac address
* @return segment id
......@@ -164,7 +164,7 @@ public class DeviceConfiguration implements DeviceProperties {
}
/**
* Returns the segment id of a segment router given its router ip address.
* Returns the Node segment id of a segment router given its Router ip address.
*
* @param routerAddress router ip address
* @return segment id
......@@ -223,7 +223,7 @@ public class DeviceConfiguration implements DeviceProperties {
/**
* Indicates if the segment router is a edge router or
* a transit/back bone router.
* a core/backbone router.
*
* @param deviceId device identifier
* @return boolean
......@@ -244,9 +244,9 @@ public class DeviceConfiguration implements DeviceProperties {
}
/**
* Returns the segment ids of all configured segment routers.
* Returns the node segment ids of all configured segment routers.
*
* @return list of segment ids
* @return list of node segment ids
*/
@Override
public List<Integer> getAllDeviceSegmentIds() {
......@@ -290,12 +290,14 @@ public class DeviceConfiguration implements DeviceProperties {
}
/**
* Returns the configured subnet gateway ip addresses for a segment router.
* Returns the configured port ip addresses for a segment router.
* These addresses serve as gateway IP addresses for the subnets configured
* on those ports.
*
* @param deviceId device identifier
* @return list of ip addresses
* @return list of ip addresses configured on the ports
*/
public List<Ip4Address> getSubnetGatewayIps(DeviceId deviceId) {
public List<Ip4Address> getPortIPs(DeviceId deviceId) {
if (deviceConfigMap.get(deviceId) != null) {
log.trace("getSubnetGatewayIps for device{} is {}",
deviceId,
......@@ -307,6 +309,20 @@ public class DeviceConfiguration implements DeviceProperties {
}
/**
* Returns the configured IP addresses per port
* for a segment router.
*
* @param deviceId device identifier
* @return map of port to gateway IP addresses
*/
public Map<PortNumber, Ip4Address> getPortIPMap(DeviceId deviceId) {
if (deviceConfigMap.get(deviceId) != null) {
return deviceConfigMap.get(deviceId).gatewayIps;
}
return null;
}
/**
* Returns the configured subnet prefixes for a segment router.
*
* @param deviceId device identifier
......
......@@ -70,7 +70,7 @@ public class IcmpHandler {
DeviceId deviceId = connectPoint.deviceId();
Ip4Address destinationAddress =
Ip4Address.valueOf(ipv4.getDestinationAddress());
List<Ip4Address> gatewayIpAddresses = config.getSubnetGatewayIps(deviceId);
List<Ip4Address> gatewayIpAddresses = config.getPortIPs(deviceId);
Ip4Address routerIp = config.getRouterIp(deviceId);
IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH);
Ip4Address routerIpAddress = routerIpPrefix.getIp4Prefix().address();
......
......@@ -38,6 +38,7 @@ import org.onosproject.net.flowobjective.ForwardingObjective;
import org.onosproject.net.flowobjective.Objective;
import org.onosproject.net.flowobjective.ObjectiveError;
import org.onosproject.net.flowobjective.ForwardingObjective.Builder;
import org.onosproject.net.flowobjective.ForwardingObjective.Flag;
import org.onosproject.net.flowobjective.ObjectiveContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -57,6 +58,9 @@ public class RoutingRulePopulator {
private AtomicLong rulePopulationCounter;
private SegmentRoutingManager srManager;
private DeviceConfiguration config;
private static final int HIGHEST_PRIORITY = 0xffff;
/**
* Creates a RoutingRulePopulator object.
*
......@@ -98,7 +102,7 @@ public class RoutingRulePopulator {
TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
sbuilder.matchIPDst(IpPrefix.valueOf(hostIp, 32));
sbuilder.matchIPDst(IpPrefix.valueOf(hostIp, IpPrefix.MAX_INET_MASK_LENGTH));
sbuilder.matchEthType(Ethernet.TYPE_IPV4);
tbuilder.deferred()
......@@ -350,16 +354,22 @@ public class RoutingRulePopulator {
}
/**
* Populates VLAN flows rules. All packets are forwarded to TMAC table.
* Creates a filtering objective to permit all untagged packets with a
* dstMac corresponding to the router's MAC address.
*
* @param deviceId switch ID to set the rules
* @param deviceId the switch dpid for the router
*/
public void populateTableVlan(DeviceId deviceId) {
public void populateRouterMacVlanFilters(DeviceId deviceId) {
FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
fob.withKey(Criteria.matchInPort(PortNumber.ALL))
.addCondition(Criteria.matchVlanId(VlanId.NONE));
.addCondition(Criteria.matchEthDst(config.getDeviceMac(deviceId)))
.addCondition(Criteria.matchVlanId(VlanId.NONE))
.addCondition(Criteria.matchIPDst(
IpPrefix.valueOf(config.getRouterIp(deviceId),
IpPrefix.MAX_INET_MASK_LENGTH)));
fob.permit().fromApp(srManager.appId);
log.debug("populateTableVlan: Installing filtering objective for untagged packets");
log.debug("Installing filtering objective for untagged packets");
srManager.flowObjectiveService.
filter(deviceId,
fob.add(new SRObjectiveContext(deviceId,
......@@ -367,23 +377,35 @@ public class RoutingRulePopulator {
}
/**
* Populates TMAC table rules. IP packets are forwarded to IP table. MPLS
* packets are forwarded to MPLS table.
* Creates a forwarding objective to punt all IP packets, destined to the
* router's port IP addresses, to the controller. Note that it the input
* port should not be matched on, as these packets can come from any input.
*
* @param deviceId switch ID to set the rules
* @param deviceId the switch dpid for the router
*/
public void populateTableTMac(DeviceId deviceId) {
FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
fob.withKey(Criteria.matchInPort(PortNumber.ALL))
.addCondition(Criteria.matchEthDst(config
.getDeviceMac(deviceId)));
fob.permit().fromApp(srManager.appId);
log.debug("populateTableTMac: Installing filtering objective for router mac");
srManager.flowObjectiveService.
filter(deviceId,
fob.add(new SRObjectiveContext(deviceId,
SRObjectiveContext.ObjectiveType.FILTER)));
public void populateRouterIpPunts(DeviceId deviceId) {
ForwardingObjective.Builder puntIp = DefaultForwardingObjective.builder();
List<Ip4Address> gws = config.getPortIPs(deviceId);
for (Ip4Address ipaddr : gws) {
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
selector.matchEthType(Ethernet.TYPE_IPV4);
selector.matchIPDst(IpPrefix.valueOf(ipaddr,
IpPrefix.MAX_INET_MASK_LENGTH));
treatment.setOutput(PortNumber.CONTROLLER);
puntIp.withSelector(selector.build());
puntIp.withTreatment(treatment.build());
puntIp.withFlag(Flag.VERSATILE)
.withPriority(HIGHEST_PRIORITY)
.makePermanent()
.fromApp(srManager.appId);
log.debug("Installing forwarding objective to punt port IP addresses");
srManager.flowObjectiveService.
forward(deviceId,
puntIp.add(new SRObjectiveContext(deviceId,
SRObjectiveContext.ObjectiveType.FORWARDING)));
}
}
private PortNumber selectOnePort(DeviceId srcId, Set<DeviceId> destIds) {
......
......@@ -497,7 +497,7 @@ public class SegmentRoutingManager implements SegmentRoutingService {
flowObjectiveService,
nsNextObjStore);
groupHandlerMap.put(device.id(), dgh);
defaultRoutingHandler.populateTtpRules(device.id());
defaultRoutingHandler.populatePortAddressingRules(device.id());
}
private void processPortRemoved(Device device, Port port) {
......@@ -542,7 +542,7 @@ public class SegmentRoutingManager implements SegmentRoutingService {
flowObjectiveService,
nsNextObjStore);
groupHandlerMap.put(device.id(), groupHandler);
defaultRoutingHandler.populateTtpRules(device.id());
defaultRoutingHandler.populatePortAddressingRules(device.id());
}
defaultRoutingHandler.startPopulationProcess();
......
......@@ -29,22 +29,23 @@ import org.slf4j.Logger;
/**
* Driver for software switch emulation of the OFDPA 1.0 pipeline.
* Driver for software switch emulation of the OFDPA 2.0 pipeline.
* The software switch is the CPqD OF 1.3 switch.
*/
public class CpqdOFDPA1Pipeline extends OFDPA1Pipeline {
public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline {
private final Logger log = getLogger(getClass());
@Override
protected void initializePipeline() {
processPortTable();
//processVlanTable();
processTmacTable();
processIpTable();
//processMcastTable();
processBridgingTable();
processAclTable();
// XXX implement table miss entries and default groups
//processVlanTable();
//processMPLSTable();
//processGroupTable();
}
......@@ -169,6 +170,7 @@ public class CpqdOFDPA1Pipeline extends OFDPA1Pipeline {
}));
}
@Override
protected void processAclTable() {
//table miss entry - catch all to executed action-set
FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
......
......@@ -53,6 +53,7 @@ import org.onosproject.net.flow.criteria.MplsCriterion;
import org.onosproject.net.flow.criteria.PortCriterion;
import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
import org.onosproject.net.flowobjective.FilteringObjective;
import org.onosproject.net.flowobjective.FlowObjectiveStore;
import org.onosproject.net.flowobjective.ForwardingObjective;
......@@ -383,7 +384,7 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
private Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
log.debug("Processing versatile forwarding objective");
TrafficSelector selector = fwd.selector();
TrafficTreatment treatment = null;
EthTypeCriterion ethType =
(EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
if (ethType == null) {
......@@ -410,15 +411,26 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
return Collections.emptySet();
}
treatmentBuilder.deferred().group(group.id());
treatment = treatmentBuilder.build();
log.debug("Adding OUTGROUP action");
}
} else if (fwd.treatment() != null) {
if (fwd.treatment().allInstructions().size() == 1 &&
fwd.treatment().allInstructions().get(0).type() == Instruction.Type.OUTPUT) {
OutputInstruction o = (OutputInstruction) fwd.treatment().allInstructions().get(0);
if (o.port() == PortNumber.CONTROLLER) {
log.warn("Punts to the controller are handled by misses in"
+ " the TMAC, IP and MPLS tables.");
return Collections.emptySet();
}
}
treatment = fwd.treatment();
} else {
log.warn("VERSATILE forwarding objective need next objective ID.");
log.warn("VERSATILE forwarding objective needs next objective ID "
+ "or treatment.");
return Collections.emptySet();
}
TrafficTreatment treatment = treatmentBuilder.build();
FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
.fromApp(fwd.appId()).withPriority(fwd.priority())
.forDevice(deviceId).withSelector(fwd.selector())
......@@ -616,21 +628,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
ops = install ? ops.add(rule) : ops.remove(rule);
}
} else if (c.type() == Criterion.Type.IPV4_DST) {
IPCriterion ip = (IPCriterion) c;
log.debug("adding rule for IP: {}", ip.ip());
TrafficSelector.Builder selector = DefaultTrafficSelector
.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment
.builder();
selector.matchEthType(Ethernet.TYPE_IPV4);
selector.matchIPDst(ip.ip());
treatment.transition(aclTableId);
FlowRule rule = DefaultFlowRule.builder().forDevice(deviceId)
.withSelector(selector.build())
.withTreatment(treatment.build())
.withPriority(filt.priority()).fromApp(applicationId)
.makePermanent().forTable(ipv4UnicastTableId).build();
ops = install ? ops.add(rule) : ops.remove(rule);
log.debug("driver does not process IP filtering rules as it " +
"sends all misses in the IP table to the controller");
} else {
log.warn("Driver does not currently process filtering condition"
+ " of type: {}", c.type());
......@@ -762,6 +761,7 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
this.key = key;
}
@SuppressWarnings("unused")
public GroupKey key() {
return key;
}
......
......@@ -38,6 +38,9 @@
<behaviour api="org.onosproject.net.behaviour.Pipeliner"
impl="org.onosproject.driver.pipeline.OVSCorsaPipeline"/>
</driver>
<!-- Emulation of the spring-open pipeline using a CPqD OF 1.3 software switch.
~ This driver is the default driver assigned to the CPqD switch.
-->
<driver name="spring-open-cpqd" extends="default"
manufacturer="Stanford University, Ericsson Research and CPqD Research"
hwVersion="OpenFlow 1.3 Reference Userspace Switch" swVersion=".*">
......@@ -66,7 +69,7 @@
<driver name="ofdpa" extends="default"
manufacturer="Broadcom Corp." hwVersion="OF-DPA.*" swVersion="OF-DPA.*">
<behaviour api="org.onosproject.net.behaviour.Pipeliner"
impl="org.onosproject.driver.pipeline.OFDPA1Pipeline"/>
impl="org.onosproject.driver.pipeline.OFDPA2Pipeline"/>
</driver>
<driver name="pmc-olt" extends="default"
manufacturer="Big Switch Networks" hwVersion="ivs 0.5" swVersion="ivs 0.5">
......@@ -109,7 +112,7 @@
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"/>
impl="org.onosproject.driver.pipeline.CpqdOFDPA2Pipeline"/>
</driver>
<driver name="calient" extends="default"
manufacturer="calient inc" hwVersion="calient hardware"
......