initial flows for corsa pipeline v39
- initial flows configuration
- moved to a dedicated folder
- refactoring super classes
Change-Id: Ie7452aed35d7947ca5f7246dd06fcbb87b2971b5
diff --git a/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/CorsaPipelineV3.java b/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/CorsaPipelineV3.java
new file mode 100644
index 0000000..581a734
--- /dev/null
+++ b/drivers/corsa/src/main/java/org/onosproject/drivers/corsa/CorsaPipelineV3.java
@@ -0,0 +1,369 @@
+/*
+ * Copyright 2016-present 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.drivers.corsa;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+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.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.EthCriterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.meter.Band;
+import org.onosproject.net.meter.DefaultBand;
+import org.onosproject.net.meter.DefaultMeterRequest;
+import org.onosproject.net.meter.Meter;
+import org.onosproject.net.meter.MeterId;
+import org.onosproject.net.meter.MeterRequest;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import static org.onosproject.net.flow.FlowRule.Builder;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Implementation of the Corsa pipeline handler for pipeline version 3.
+ */
+public class CorsaPipelineV3 extends AbstractCorsaPipeline {
+
+ private final Logger log = getLogger(getClass());
+
+ protected static final int PORT_BASED_PROTO_TABLE = 0;
+ protected static final int VLAN_CHECK_TABLE = 1;
+ protected static final int VLAN_MAC_XLATE_TABLE = 2;
+ protected static final int VLAN_CIRCUIT_TABLE = 3;
+ protected static final int PRIORITY_MAP_TABLE = 4;
+ protected static final int L3_IF_MAC_DA_TABLE = 5;
+ protected static final int ETHER_TABLE = 6;
+ protected static final int FIB_TABLE = 7;
+ protected static final int LOCAL_TABLE = 9;
+
+ protected static final byte MAX_VLAN_PCP = 7;
+
+ protected MeterId defaultMeterId = null;
+
+ @Override
+ protected TrafficTreatment processNextTreatment(TrafficTreatment treatment) {
+ TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder();
+
+ treatment.immediate().stream()
+ .filter(i -> {
+ switch (i.type()) {
+ case L2MODIFICATION:
+ L2ModificationInstruction l2i = (L2ModificationInstruction) i;
+ if (l2i instanceof L2ModificationInstruction.ModVlanIdInstruction ||
+ l2i instanceof L2ModificationInstruction.ModEtherInstruction) {
+ return true;
+ }
+ case OUTPUT:
+ return true;
+ default:
+ return false;
+ }
+ }).forEach(i -> tb.add(i));
+ return tb.build();
+ }
+
+ @Override
+ protected TrafficTreatment.Builder processSpecificRoutingTreatment() {
+ return DefaultTrafficTreatment.builder().deferred();
+ }
+
+ @Override
+ protected Builder processSpecificRoutingRule(Builder rb) {
+ return rb.forTable(FIB_TABLE);
+ }
+
+ @Override
+ protected Collection<FlowRule> processSpecificSwitch(ForwardingObjective fwd) {
+ TrafficSelector filteredSelector =
+ DefaultTrafficSelector.builder()
+ .matchInPort(
+ ((PortCriterion) fwd.selector().getCriterion(Criterion.Type.IN_PORT)).port())
+ .matchVlanId(
+ ((VlanIdCriterion) fwd.selector().getCriterion(Criterion.Type.VLAN_VID)).vlanId())
+ .build();
+
+ Builder ruleBuilder = DefaultFlowRule.builder()
+ .fromApp(fwd.appId())
+ .withPriority(fwd.priority())
+ .forDevice(deviceId)
+ .withSelector(filteredSelector)
+ .withTreatment(fwd.treatment())
+ .forTable(VLAN_CIRCUIT_TABLE);
+
+ if (fwd.permanent()) {
+ ruleBuilder.makePermanent();
+ } else {
+ ruleBuilder.makeTemporary(fwd.timeout());
+ }
+
+ return Collections.singletonList(ruleBuilder.build());
+ }
+
+ @Override
+ protected Collection<FlowRule> processArpTraffic(ForwardingObjective fwd, Builder rule) {
+ //TODO
+ return Collections.emptyList();
+ }
+
+ @Override
+ protected Collection<FlowRule> processLinkDiscovery(ForwardingObjective fwd, Builder rule) {
+ //TODO
+ return Collections.emptyList();
+ }
+
+ @Override
+ protected Collection<FlowRule> processIpTraffic(ForwardingObjective fwd, Builder rule) {
+ //TODO
+ return Collections.emptyList();
+ }
+
+ @Override
+ protected Builder processEthFiler(FilteringObjective filt, EthCriterion eth, PortCriterion port) {
+ log.debug("adding rule for MAC: {}", eth.mac());
+ TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+ TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+ selector.matchEthDst(eth.mac());
+ selector.matchInPort(port.port());
+ treatment.transition(ETHER_TABLE);
+ return DefaultFlowRule.builder()
+ .withSelector(selector.build())
+ .withTreatment(treatment.build())
+ .withPriority(CONTROLLER_PRIORITY)
+ .makePermanent()
+ .forTable(L3_IF_MAC_DA_TABLE);
+ }
+
+ @Override
+ protected Builder processVlanFiler(FilteringObjective filt, VlanIdCriterion vlan, PortCriterion port) {
+ log.debug("adding rule for VLAN: {}", vlan.vlanId());
+ TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+ TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+ selector.matchVlanId(vlan.vlanId());
+ selector.matchInPort(port.port());
+ /* Static treatment for VLAN_CIRCUIT_TABLE */
+ treatment.setVlanPcp(MAX_VLAN_PCP);
+ treatment.setQueue(0);
+ treatment.meter(MeterId.meterId(defaultMeterId.id())); /* use default meter (Green) */
+ treatment.transition(L3_IF_MAC_DA_TABLE);
+ return DefaultFlowRule.builder()
+ .withSelector(selector.build())
+ .withTreatment(treatment.build())
+ .withPriority(CONTROLLER_PRIORITY)
+ .makePermanent()
+ .forTable(VLAN_CIRCUIT_TABLE);
+ }
+
+ @Override
+ protected Builder processIpFilter(FilteringObjective filt, IPCriterion ip, PortCriterion port) {
+ 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(LOCAL_TABLE);
+ return DefaultFlowRule.builder()
+ .withSelector(selector.build())
+ .withTreatment(treatment.build())
+ .withPriority(HIGHEST_PRIORITY)
+ .makePermanent()
+ .forTable(FIB_TABLE);
+ }
+
+ @Override
+ public void initializePipeline() {
+ processMeterTable(true);
+ processPortBasedProtoTable(true); /* Table 0 */
+ processVlanCheckTable(true); /* Table 1 */
+ processVlanMacXlateTable(true); /* Table 2 */
+ processVlanCircuitTable(true); /* Table 3 */
+ processPriorityMapTable(true); /* Table 4 */
+ processL3IFMacDATable(true); /* Table 5 */
+ processEtherTable(true); /* Table 6 */
+ processFibTable(true); /* Table 7 */
+ processLocalTable(true); /* Table 9 */
+ }
+
+ protected void processMeterTable(boolean install) {
+ //Green meter : Pass all traffic
+ Band dropBand = DefaultBand.builder()
+ .ofType(Band.Type.DROP)
+ .withRate(0xFFFFFFFF) /* Max Rate */
+ .build();
+ MeterRequest.Builder ops = DefaultMeterRequest.builder()
+ .forDevice(deviceId)
+ .withBands(Collections.singletonList(dropBand))
+ .fromApp(appId);
+
+ Meter meter = meterService.submit(install ? ops.add() : ops.remove());
+ defaultMeterId = meter.id();
+ }
+
+ protected void processPortBasedProtoTable(boolean install) {
+ /* Default action */
+ processTableMissGoTo(install, PORT_BASED_PROTO_TABLE, VLAN_CHECK_TABLE, "Provisioned port-based table");
+ }
+
+ protected void processVlanCheckTable(boolean install) {
+
+ /* Default action */
+ processTableMissDrop(install, VLAN_CHECK_TABLE, "Provisioned vlantable drop");
+
+ processTaggedPackets(install);
+
+ }
+
+ /* Tagged packets to VLAN_MAC_XLATE */
+ protected void processTaggedPackets(boolean install) {
+ TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+ selector.matchVlanId(VlanId.ANY);
+
+ TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+ treatment.transition(VLAN_MAC_XLATE_TABLE);
+
+ FlowRule rule = DefaultFlowRule.builder()
+ .forDevice(deviceId)
+ .withSelector(selector.build())
+ .withTreatment(treatment.build())
+ .withPriority(CONTROLLER_PRIORITY)
+ .fromApp(appId)
+ .makePermanent()
+ .forTable(VLAN_CHECK_TABLE).build();
+ processFlowRule(install, rule, "Provisioned vlan table tagged packets");
+ }
+
+ protected void processVlanMacXlateTable(boolean install) {
+ /* Default action */
+ processTableMissGoTo(install, VLAN_MAC_XLATE_TABLE, VLAN_CIRCUIT_TABLE, "Provisioned vlan mac table");
+ }
+
+ protected void processVlanCircuitTable(boolean install) {
+ /* Default action */
+ processTableMissDrop(install, VLAN_CIRCUIT_TABLE, "Provisioned vlan circuit");
+ }
+
+ private void processPriorityMapTable(boolean install) {
+ /* Not required currently */
+ }
+
+ protected void processL3IFMacDATable(boolean install) {
+ int table = L3_IF_MAC_DA_TABLE;
+
+ /* Default action */
+ processTableMissDrop(install, table, "Provisioned l3 table drop");
+
+ /* Allow MAC broadcast frames on all ports */
+ TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+ selector.matchEthDst(MacAddress.BROADCAST);
+
+ TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+ treatment.transition(ETHER_TABLE);
+
+ FlowRule rule = DefaultFlowRule.builder()
+ .forDevice(deviceId)
+ .withSelector(selector.build())
+ .withTreatment(treatment.build())
+ .withPriority(CONTROLLER_PRIORITY)
+ .fromApp(appId)
+ .makePermanent()
+ .forTable(table).build();
+ processFlowRule(install, rule, "Provisioned l3 table");
+ }
+
+
+ protected void processEtherTable(boolean install) {
+ int table = ETHER_TABLE;
+
+ /* Default action */
+ processTableMissDrop(install, table, "Provisioned ether type table drop");
+
+ /* Arp to controller */
+ TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+ selector.matchEthType(Ethernet.TYPE_ARP);
+
+ TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+ treatment.punt();
+
+ FlowRule rule = DefaultFlowRule.builder()
+ .forDevice(deviceId)
+ .withSelector(selector.build())
+ .withTreatment(treatment.build())
+ .withPriority(CONTROLLER_PRIORITY)
+ .fromApp(appId)
+ .makePermanent()
+ .forTable(table).build();
+ processFlowRule(install, rule, "Provisioned ether type table arp");
+
+ /* IP to FIB_TABLE */
+ selector = DefaultTrafficSelector.builder();
+ selector.matchEthType(Ethernet.TYPE_IPV4);
+
+ treatment = DefaultTrafficTreatment.builder();
+ treatment.transition(FIB_TABLE);
+
+ rule = DefaultFlowRule.builder()
+ .forDevice(deviceId)
+ .withSelector(selector.build())
+ .withTreatment(treatment.build())
+ .withPriority(CONTROLLER_PRIORITY)
+ .fromApp(appId)
+ .makePermanent()
+ .forTable(table).build();
+ processFlowRule(install, rule, "Provisioned ether type table ip");
+ }
+
+ private void processFibTable(boolean install) {
+ /* Default action */
+ processTableMissDrop(install, FIB_TABLE, "Provisioned fib drop");
+ }
+
+ private void processLocalTable(boolean install) {
+ int table = LOCAL_TABLE;
+ /* Default action */
+ processTableMissDrop(install, table, "Provisioned local table drop");
+
+ /* Send all protocols to controller */
+ TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+
+ TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+ treatment.punt();
+
+ FlowRule rule = DefaultFlowRule.builder()
+ .forDevice(deviceId)
+ .withSelector(selector.build())
+ .withTreatment(treatment.build())
+ .withPriority(CONTROLLER_PRIORITY)
+ .fromApp(appId)
+ .makePermanent()
+ .forTable(table).build();
+ processFlowRule(install, rule, "Provisioned ether type table to controller");
+ }
+
+
+}