Committed by
Gerrit Code Review
initial flows for corsa pipeline v39
- initial flows configuration - moved to a dedicated folder - refactoring super classes Change-Id: Ie7452aed35d7947ca5f7246dd06fcbb87b2971b5
Showing
12 changed files
with
1060 additions
and
799 deletions
drivers/corsa/pom.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<!-- | ||
| 3 | + ~ Copyright 2014-2016 Open Networking Laboratory | ||
| 4 | + ~ | ||
| 5 | + ~ Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | + ~ you may not use this file except in compliance with the License. | ||
| 7 | + ~ You may obtain a copy of the License at | ||
| 8 | + ~ | ||
| 9 | + ~ http://www.apache.org/licenses/LICENSE-2.0 | ||
| 10 | + ~ | ||
| 11 | + ~ Unless required by applicable law or agreed to in writing, software | ||
| 12 | + ~ distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | + ~ See the License for the specific language governing permissions and | ||
| 15 | + ~ limitations under the License. | ||
| 16 | + --> | ||
| 17 | + | ||
| 18 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| 19 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 20 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| 21 | + <parent> | ||
| 22 | + <artifactId>onos-drivers-general</artifactId> | ||
| 23 | + <groupId>org.onosproject</groupId> | ||
| 24 | + <version>1.6.0-SNAPSHOT</version> | ||
| 25 | + </parent> | ||
| 26 | + <modelVersion>4.0.0</modelVersion> | ||
| 27 | + | ||
| 28 | + <artifactId>onos-drivers-corsa</artifactId> | ||
| 29 | + <packaging>bundle</packaging> | ||
| 30 | + | ||
| 31 | + <description>Corsa device drivers</description> | ||
| 32 | + | ||
| 33 | + <properties> | ||
| 34 | + <onos.app.name>org.onosproject.drivers.corsa</onos.app.name> | ||
| 35 | + <onos.app.origin>ON.Lab</onos.app.origin> | ||
| 36 | + <onos.app.title>Corsa Device Drivers</onos.app.title> | ||
| 37 | + <onos.app.category>Drivers</onos.app.category> | ||
| 38 | + <onos.app.url>http://onosproject.org</onos.app.url> | ||
| 39 | + <onos.app.requires> | ||
| 40 | + org.onosproject.openflow | ||
| 41 | + </onos.app.requires> | ||
| 42 | + </properties> | ||
| 43 | + | ||
| 44 | + <dependencies> | ||
| 45 | + <dependency> | ||
| 46 | + <groupId>org.onosproject</groupId> | ||
| 47 | + <artifactId>onos-of-api</artifactId> | ||
| 48 | + </dependency> | ||
| 49 | + <dependency> | ||
| 50 | + <groupId>org.onosproject</groupId> | ||
| 51 | + <artifactId>openflowj</artifactId> | ||
| 52 | + </dependency> | ||
| 53 | + </dependencies> | ||
| 54 | + | ||
| 55 | +</project> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| ... | @@ -13,18 +13,15 @@ | ... | @@ -13,18 +13,15 @@ |
| 13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. | 14 | * limitations under the License. |
| 15 | */ | 15 | */ |
| 16 | -package org.onosproject.driver.pipeline; | 16 | + |
| 17 | +package org.onosproject.drivers.corsa; | ||
| 17 | 18 | ||
| 18 | import com.google.common.cache.Cache; | 19 | import com.google.common.cache.Cache; |
| 19 | import com.google.common.cache.CacheBuilder; | 20 | import com.google.common.cache.CacheBuilder; |
| 20 | import com.google.common.cache.RemovalCause; | 21 | import com.google.common.cache.RemovalCause; |
| 21 | import com.google.common.cache.RemovalNotification; | 22 | import com.google.common.cache.RemovalNotification; |
| 22 | - | ||
| 23 | import org.onlab.osgi.ServiceDirectory; | 23 | import org.onlab.osgi.ServiceDirectory; |
| 24 | import org.onlab.packet.Ethernet; | 24 | import org.onlab.packet.Ethernet; |
| 25 | -import org.onlab.packet.IPv4; | ||
| 26 | -import org.onlab.packet.MacAddress; | ||
| 27 | -import org.onlab.packet.VlanId; | ||
| 28 | import org.onlab.util.KryoNamespace; | 25 | import org.onlab.util.KryoNamespace; |
| 29 | import org.onosproject.core.ApplicationId; | 26 | import org.onosproject.core.ApplicationId; |
| 30 | import org.onosproject.core.CoreService; | 27 | import org.onosproject.core.CoreService; |
| ... | @@ -32,6 +29,7 @@ import org.onosproject.net.DeviceId; | ... | @@ -32,6 +29,7 @@ import org.onosproject.net.DeviceId; |
| 32 | import org.onosproject.net.behaviour.NextGroup; | 29 | import org.onosproject.net.behaviour.NextGroup; |
| 33 | import org.onosproject.net.behaviour.Pipeliner; | 30 | import org.onosproject.net.behaviour.Pipeliner; |
| 34 | import org.onosproject.net.behaviour.PipelinerContext; | 31 | import org.onosproject.net.behaviour.PipelinerContext; |
| 32 | +import org.onosproject.net.device.DeviceService; | ||
| 35 | import org.onosproject.net.driver.AbstractHandlerBehaviour; | 33 | import org.onosproject.net.driver.AbstractHandlerBehaviour; |
| 36 | import org.onosproject.net.flow.DefaultFlowRule; | 34 | import org.onosproject.net.flow.DefaultFlowRule; |
| 37 | import org.onosproject.net.flow.DefaultTrafficSelector; | 35 | import org.onosproject.net.flow.DefaultTrafficSelector; |
| ... | @@ -47,7 +45,6 @@ import org.onosproject.net.flow.criteria.Criterion; | ... | @@ -47,7 +45,6 @@ import org.onosproject.net.flow.criteria.Criterion; |
| 47 | import org.onosproject.net.flow.criteria.EthCriterion; | 45 | import org.onosproject.net.flow.criteria.EthCriterion; |
| 48 | import org.onosproject.net.flow.criteria.EthTypeCriterion; | 46 | import org.onosproject.net.flow.criteria.EthTypeCriterion; |
| 49 | import org.onosproject.net.flow.criteria.IPCriterion; | 47 | import org.onosproject.net.flow.criteria.IPCriterion; |
| 50 | -import org.onosproject.net.flow.criteria.IPProtocolCriterion; | ||
| 51 | import org.onosproject.net.flow.criteria.PortCriterion; | 48 | import org.onosproject.net.flow.criteria.PortCriterion; |
| 52 | import org.onosproject.net.flow.criteria.VlanIdCriterion; | 49 | import org.onosproject.net.flow.criteria.VlanIdCriterion; |
| 53 | import org.onosproject.net.flowobjective.FilteringObjective; | 50 | import org.onosproject.net.flowobjective.FilteringObjective; |
| ... | @@ -81,26 +78,14 @@ import java.util.concurrent.TimeUnit; | ... | @@ -81,26 +78,14 @@ import java.util.concurrent.TimeUnit; |
| 81 | import java.util.stream.Collectors; | 78 | import java.util.stream.Collectors; |
| 82 | 79 | ||
| 83 | import static org.onlab.util.Tools.groupedThreads; | 80 | import static org.onlab.util.Tools.groupedThreads; |
| 81 | +import static org.onosproject.net.flow.FlowRule.Builder; | ||
| 84 | import static org.slf4j.LoggerFactory.getLogger; | 82 | import static org.slf4j.LoggerFactory.getLogger; |
| 85 | 83 | ||
| 86 | /** | 84 | /** |
| 87 | - * OpenvSwitch emulation of the Corsa pipeline handler. | 85 | + * Abstraction of the Corsa pipeline handler. |
| 88 | */ | 86 | */ |
| 89 | -public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeliner { | 87 | +public abstract class AbstractCorsaPipeline extends AbstractHandlerBehaviour implements Pipeliner { |
| 90 | - | ||
| 91 | - protected static final int MAC_TABLE = 0; | ||
| 92 | - protected static final int VLAN_MPLS_TABLE = 1; | ||
| 93 | - protected static final int VLAN_TABLE = 2; | ||
| 94 | - //protected static final int MPLS_TABLE = 3; | ||
| 95 | - protected static final int ETHER_TABLE = 4; | ||
| 96 | - protected static final int COS_MAP_TABLE = 5; | ||
| 97 | - protected static final int FIB_TABLE = 6; | ||
| 98 | - protected static final int LOCAL_TABLE = 9; | ||
| 99 | - | ||
| 100 | 88 | ||
| 101 | - protected static final int CONTROLLER_PRIORITY = 255; | ||
| 102 | - protected static final int DROP_PRIORITY = 0; | ||
| 103 | - protected static final int HIGHEST_PRIORITY = 0xffff; | ||
| 104 | 89 | ||
| 105 | private final Logger log = getLogger(getClass()); | 90 | private final Logger log = getLogger(getClass()); |
| 106 | 91 | ||
| ... | @@ -112,6 +97,7 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli | ... | @@ -112,6 +97,7 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli |
| 112 | private FlowObjectiveStore flowObjectiveStore; | 97 | private FlowObjectiveStore flowObjectiveStore; |
| 113 | protected DeviceId deviceId; | 98 | protected DeviceId deviceId; |
| 114 | protected ApplicationId appId; | 99 | protected ApplicationId appId; |
| 100 | + protected DeviceService deviceService; | ||
| 115 | 101 | ||
| 116 | private KryoNamespace appKryo = new KryoNamespace.Builder() | 102 | private KryoNamespace appKryo = new KryoNamespace.Builder() |
| 117 | .register(GroupKey.class) | 103 | .register(GroupKey.class) |
| ... | @@ -124,8 +110,12 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli | ... | @@ -124,8 +110,12 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli |
| 124 | 110 | ||
| 125 | private ScheduledExecutorService groupChecker = | 111 | private ScheduledExecutorService groupChecker = |
| 126 | Executors.newScheduledThreadPool(2, groupedThreads("onos/pipeliner", | 112 | Executors.newScheduledThreadPool(2, groupedThreads("onos/pipeliner", |
| 127 | - "ovs-corsa-%d", | 113 | + "ovs-corsa-%d")); |
| 128 | - log)); | 114 | + |
| 115 | + protected static final int CONTROLLER_PRIORITY = 255; | ||
| 116 | + protected static final int DROP_PRIORITY = 0; | ||
| 117 | + protected static final int HIGHEST_PRIORITY = 0xffff; | ||
| 118 | + protected static final String APPID = "org.onosproject.drivers.corsa.CorsaPipeline"; | ||
| 129 | 119 | ||
| 130 | @Override | 120 | @Override |
| 131 | public void init(DeviceId deviceId, PipelinerContext context) { | 121 | public void init(DeviceId deviceId, PipelinerContext context) { |
| ... | @@ -146,27 +136,171 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli | ... | @@ -146,27 +136,171 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli |
| 146 | flowRuleService = serviceDirectory.get(FlowRuleService.class); | 136 | flowRuleService = serviceDirectory.get(FlowRuleService.class); |
| 147 | groupService = serviceDirectory.get(GroupService.class); | 137 | groupService = serviceDirectory.get(GroupService.class); |
| 148 | meterService = serviceDirectory.get(MeterService.class); | 138 | meterService = serviceDirectory.get(MeterService.class); |
| 139 | + deviceService = serviceDirectory.get(DeviceService.class); | ||
| 149 | flowObjectiveStore = context.store(); | 140 | flowObjectiveStore = context.store(); |
| 150 | 141 | ||
| 151 | groupService.addListener(new InnerGroupListener()); | 142 | groupService.addListener(new InnerGroupListener()); |
| 152 | 143 | ||
| 153 | - appId = coreService.registerApplication( | 144 | + appId = coreService.registerApplication(APPID); |
| 154 | - "org.onosproject.driver.OVSCorsaPipeline"); | ||
| 155 | 145 | ||
| 156 | initializePipeline(); | 146 | initializePipeline(); |
| 157 | } | 147 | } |
| 158 | 148 | ||
| 149 | + protected abstract void initializePipeline(); | ||
| 150 | + | ||
| 151 | + protected void pass(Objective obj) { | ||
| 152 | + obj.context().ifPresent(context -> context.onSuccess(obj)); | ||
| 153 | + } | ||
| 154 | + | ||
| 155 | + protected void fail(Objective obj, ObjectiveError error) { | ||
| 156 | + obj.context().ifPresent(context -> context.onError(obj, error)); | ||
| 157 | + } | ||
| 158 | + | ||
| 159 | + private class GroupChecker implements Runnable { | ||
| 160 | + | ||
| 161 | + @Override | ||
| 162 | + public void run() { | ||
| 163 | + Set<GroupKey> keys = pendingGroups.asMap().keySet().stream() | ||
| 164 | + .filter(key -> groupService.getGroup(deviceId, key) != null) | ||
| 165 | + .collect(Collectors.toSet()); | ||
| 166 | + | ||
| 167 | + keys.stream().forEach(key -> { | ||
| 168 | + NextObjective obj = pendingGroups.getIfPresent(key); | ||
| 169 | + if (obj == null) { | ||
| 170 | + return; | ||
| 171 | + } | ||
| 172 | + pass(obj); | ||
| 173 | + pendingGroups.invalidate(key); | ||
| 174 | + log.info("Heard back from group service for group {}. " | ||
| 175 | + + "Applying pending forwarding objectives", obj.id()); | ||
| 176 | + flowObjectiveStore.putNextGroup(obj.id(), new CorsaGroup(key)); | ||
| 177 | + }); | ||
| 178 | + } | ||
| 179 | + } | ||
| 180 | + | ||
| 181 | + private class CorsaGroup implements NextGroup { | ||
| 182 | + | ||
| 183 | + private final GroupKey key; | ||
| 184 | + | ||
| 185 | + public CorsaGroup(GroupKey key) { | ||
| 186 | + this.key = key; | ||
| 187 | + } | ||
| 188 | + | ||
| 189 | + public GroupKey key() { | ||
| 190 | + return key; | ||
| 191 | + } | ||
| 192 | + | ||
| 193 | + @Override | ||
| 194 | + public byte[] data() { | ||
| 195 | + return appKryo.serialize(key); | ||
| 196 | + } | ||
| 197 | + | ||
| 198 | + } | ||
| 199 | + | ||
| 200 | + @Override | ||
| 201 | + public List<String> getNextMappings(NextGroup nextGroup) { | ||
| 202 | + //TODO: to be implemented | ||
| 203 | + return Collections.emptyList(); | ||
| 204 | + } | ||
| 205 | + | ||
| 206 | + private class InnerGroupListener implements GroupListener { | ||
| 207 | + @Override | ||
| 208 | + public void event(GroupEvent event) { | ||
| 209 | + if (event.type() == GroupEvent.Type.GROUP_ADDED) { | ||
| 210 | + GroupKey key = event.subject().appCookie(); | ||
| 211 | + | ||
| 212 | + NextObjective obj = pendingGroups.getIfPresent(key); | ||
| 213 | + if (obj != null) { | ||
| 214 | + flowObjectiveStore.putNextGroup(obj.id(), new CorsaGroup(key)); | ||
| 215 | + pass(obj); | ||
| 216 | + pendingGroups.invalidate(key); | ||
| 217 | + } | ||
| 218 | + } | ||
| 219 | + } | ||
| 220 | + } | ||
| 221 | + | ||
| 222 | + | ||
| 159 | @Override | 223 | @Override |
| 160 | public void filter(FilteringObjective filteringObjective) { | 224 | public void filter(FilteringObjective filteringObjective) { |
| 161 | if (filteringObjective.type() == FilteringObjective.Type.PERMIT) { | 225 | if (filteringObjective.type() == FilteringObjective.Type.PERMIT) { |
| 162 | processFilter(filteringObjective, | 226 | processFilter(filteringObjective, |
| 163 | - filteringObjective.op() == Objective.Operation.ADD, | 227 | + filteringObjective.op() == Objective.Operation.ADD, |
| 164 | - filteringObjective.appId()); | 228 | + filteringObjective.appId()); |
| 165 | } else { | 229 | } else { |
| 166 | fail(filteringObjective, ObjectiveError.UNSUPPORTED); | 230 | fail(filteringObjective, ObjectiveError.UNSUPPORTED); |
| 167 | } | 231 | } |
| 168 | } | 232 | } |
| 169 | 233 | ||
| 234 | + private void processFilter(FilteringObjective filt, boolean install, | ||
| 235 | + ApplicationId applicationId) { | ||
| 236 | + // This driver only processes filtering criteria defined with switch | ||
| 237 | + // ports as the key | ||
| 238 | + PortCriterion port; | ||
| 239 | + if (!filt.key().equals(Criteria.dummy()) && | ||
| 240 | + filt.key().type() == Criterion.Type.IN_PORT) { | ||
| 241 | + port = (PortCriterion) filt.key(); | ||
| 242 | + } else { | ||
| 243 | + log.warn("No key defined in filtering objective from app: {}. Not" | ||
| 244 | + + "processing filtering objective", applicationId); | ||
| 245 | + fail(filt, ObjectiveError.UNKNOWN); | ||
| 246 | + return; | ||
| 247 | + } | ||
| 248 | + // convert filtering conditions for switch-intfs into flowrules | ||
| 249 | + FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | ||
| 250 | + for (Criterion c : filt.conditions()) { | ||
| 251 | + if (c.type() == Criterion.Type.ETH_DST) { | ||
| 252 | + EthCriterion eth = (EthCriterion) c; | ||
| 253 | + FlowRule.Builder rule = processEthFiler(filt, eth, port); | ||
| 254 | + rule.forDevice(deviceId) | ||
| 255 | + .fromApp(applicationId); | ||
| 256 | + ops = install ? ops.add(rule.build()) : ops.remove(rule.build()); | ||
| 257 | + | ||
| 258 | + } else if (c.type() == Criterion.Type.VLAN_VID) { | ||
| 259 | + VlanIdCriterion vlan = (VlanIdCriterion) c; | ||
| 260 | + FlowRule.Builder rule = processVlanFiler(filt, vlan, port); | ||
| 261 | + rule.forDevice(deviceId) | ||
| 262 | + .fromApp(applicationId); | ||
| 263 | + ops = install ? ops.add(rule.build()) : ops.remove(rule.build()); | ||
| 264 | + | ||
| 265 | + } else if (c.type() == Criterion.Type.IPV4_DST) { | ||
| 266 | + IPCriterion ip = (IPCriterion) c; | ||
| 267 | + FlowRule.Builder rule = processIpFilter(filt, ip, port); | ||
| 268 | + rule.forDevice(deviceId) | ||
| 269 | + .fromApp(applicationId); | ||
| 270 | + ops = install ? ops.add(rule.build()) : ops.remove(rule.build()); | ||
| 271 | + | ||
| 272 | + } else { | ||
| 273 | + log.warn("Driver does not currently process filtering condition" | ||
| 274 | + + " of type: {}", c.type()); | ||
| 275 | + fail(filt, ObjectiveError.UNSUPPORTED); | ||
| 276 | + } | ||
| 277 | + } | ||
| 278 | + // apply filtering flow rules | ||
| 279 | + flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { | ||
| 280 | + @Override | ||
| 281 | + public void onSuccess(FlowRuleOperations ops) { | ||
| 282 | + pass(filt); | ||
| 283 | + log.info("Applied filtering rules"); | ||
| 284 | + } | ||
| 285 | + | ||
| 286 | + @Override | ||
| 287 | + public void onError(FlowRuleOperations ops) { | ||
| 288 | + fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED); | ||
| 289 | + log.info("Failed to apply filtering rules"); | ||
| 290 | + } | ||
| 291 | + })); | ||
| 292 | + } | ||
| 293 | + | ||
| 294 | + protected abstract Builder processEthFiler(FilteringObjective filt, | ||
| 295 | + EthCriterion eth, PortCriterion port); | ||
| 296 | + | ||
| 297 | + protected abstract Builder processVlanFiler(FilteringObjective filt, | ||
| 298 | + VlanIdCriterion vlan, PortCriterion port); | ||
| 299 | + | ||
| 300 | + protected abstract Builder processIpFilter(FilteringObjective filt, | ||
| 301 | + IPCriterion ip, PortCriterion port); | ||
| 302 | + | ||
| 303 | + | ||
| 170 | @Override | 304 | @Override |
| 171 | public void forward(ForwardingObjective fwd) { | 305 | public void forward(ForwardingObjective fwd) { |
| 172 | Collection<FlowRule> rules; | 306 | Collection<FlowRule> rules; |
| ... | @@ -189,7 +323,6 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli | ... | @@ -189,7 +323,6 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli |
| 189 | log.warn("Unknown forwarding type {}", fwd.op()); | 323 | log.warn("Unknown forwarding type {}", fwd.op()); |
| 190 | } | 324 | } |
| 191 | 325 | ||
| 192 | - | ||
| 193 | flowRuleService.apply(flowBuilder.build(new FlowRuleOperationsContext() { | 326 | flowRuleService.apply(flowBuilder.build(new FlowRuleOperationsContext() { |
| 194 | @Override | 327 | @Override |
| 195 | public void onSuccess(FlowRuleOperations ops) { | 328 | public void onSuccess(FlowRuleOperations ops) { |
| ... | @@ -204,47 +337,6 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli | ... | @@ -204,47 +337,6 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli |
| 204 | 337 | ||
| 205 | } | 338 | } |
| 206 | 339 | ||
| 207 | - @Override | ||
| 208 | - public void next(NextObjective nextObjective) { | ||
| 209 | - switch (nextObjective.type()) { | ||
| 210 | - case SIMPLE: | ||
| 211 | - Collection<TrafficTreatment> treatments = nextObjective.next(); | ||
| 212 | - if (treatments.size() == 1) { | ||
| 213 | - TrafficTreatment treatment = treatments.iterator().next(); | ||
| 214 | - treatment = processNextTreatment(treatment); | ||
| 215 | - GroupBucket bucket = | ||
| 216 | - DefaultGroupBucket.createIndirectGroupBucket(treatment); | ||
| 217 | - final GroupKey key = new DefaultGroupKey(appKryo.serialize(nextObjective.id())); | ||
| 218 | - GroupDescription groupDescription | ||
| 219 | - = new DefaultGroupDescription(deviceId, | ||
| 220 | - GroupDescription.Type.INDIRECT, | ||
| 221 | - new GroupBuckets(Collections | ||
| 222 | - .singletonList(bucket)), | ||
| 223 | - key, | ||
| 224 | - null, // let group service determine group id | ||
| 225 | - nextObjective.appId()); | ||
| 226 | - groupService.addGroup(groupDescription); | ||
| 227 | - pendingGroups.put(key, nextObjective); | ||
| 228 | - } | ||
| 229 | - break; | ||
| 230 | - case HASHED: | ||
| 231 | - case BROADCAST: | ||
| 232 | - case FAILOVER: | ||
| 233 | - fail(nextObjective, ObjectiveError.UNSUPPORTED); | ||
| 234 | - log.warn("Unsupported next objective type {}", nextObjective.type()); | ||
| 235 | - break; | ||
| 236 | - default: | ||
| 237 | - fail(nextObjective, ObjectiveError.UNKNOWN); | ||
| 238 | - log.warn("Unknown next objective type {}", nextObjective.type()); | ||
| 239 | - } | ||
| 240 | - | ||
| 241 | - } | ||
| 242 | - | ||
| 243 | - /* Hook for altering the NextObjective treatment */ | ||
| 244 | - protected TrafficTreatment processNextTreatment(TrafficTreatment treatment) { | ||
| 245 | - return treatment; /* Keep treatment as is for OVSCorsaPipeline */ | ||
| 246 | - } | ||
| 247 | - | ||
| 248 | private Collection<FlowRule> processForward(ForwardingObjective fwd) { | 340 | private Collection<FlowRule> processForward(ForwardingObjective fwd) { |
| 249 | switch (fwd.flag()) { | 341 | switch (fwd.flag()) { |
| 250 | case SPECIFIC: | 342 | case SPECIFIC: |
| ... | @@ -258,8 +350,34 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli | ... | @@ -258,8 +350,34 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli |
| 258 | return Collections.emptySet(); | 350 | return Collections.emptySet(); |
| 259 | } | 351 | } |
| 260 | 352 | ||
| 353 | + private Collection<FlowRule> processSpecific(ForwardingObjective fwd) { | ||
| 354 | + log.debug("Processing specific forwarding objective"); | ||
| 355 | + TrafficSelector selector = fwd.selector(); | ||
| 356 | + EthTypeCriterion ethType = | ||
| 357 | + (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE); | ||
| 358 | + if (ethType != null) { | ||
| 359 | + short et = ethType.ethType().toShort(); | ||
| 360 | + if (et == Ethernet.TYPE_IPV4) { | ||
| 361 | + return processSpecificRoute(fwd); | ||
| 362 | + } else if (et == Ethernet.TYPE_VLAN) { | ||
| 363 | + /* The ForwardingObjective must specify VLAN ethtype in order to use the Transit Circuit */ | ||
| 364 | + return processSpecificSwitch(fwd); | ||
| 365 | + } | ||
| 366 | + } | ||
| 367 | + | ||
| 368 | + fail(fwd, ObjectiveError.UNSUPPORTED); | ||
| 369 | + return Collections.emptySet(); | ||
| 370 | + } | ||
| 371 | + | ||
| 372 | + protected Collection<FlowRule> processSpecificSwitch(ForwardingObjective fwd) { | ||
| 373 | + /* Not supported by until CorsaPipelineV3 */ | ||
| 374 | + log.warn("Vlan switching not supported in ovs-corsa driver"); | ||
| 375 | + fail(fwd, ObjectiveError.UNSUPPORTED); | ||
| 376 | + return Collections.emptySet(); | ||
| 377 | + } | ||
| 378 | + | ||
| 261 | private Collection<FlowRule> processVersatile(ForwardingObjective fwd) { | 379 | private Collection<FlowRule> processVersatile(ForwardingObjective fwd) { |
| 262 | - log.debug("Processing versatile forwarding objective"); | 380 | + log.debug("Processing vesatile forwarding objective"); |
| 263 | TrafficSelector selector = fwd.selector(); | 381 | TrafficSelector selector = fwd.selector(); |
| 264 | 382 | ||
| 265 | EthTypeCriterion ethType = | 383 | EthTypeCriterion ethType = |
| ... | @@ -269,66 +387,31 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli | ... | @@ -269,66 +387,31 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli |
| 269 | fail(fwd, ObjectiveError.UNKNOWN); | 387 | fail(fwd, ObjectiveError.UNKNOWN); |
| 270 | return Collections.emptySet(); | 388 | return Collections.emptySet(); |
| 271 | } | 389 | } |
| 390 | + Builder rule = DefaultFlowRule.builder() | ||
| 391 | + .forDevice(deviceId) | ||
| 392 | + .withSelector(fwd.selector()) | ||
| 393 | + .withTreatment(fwd.treatment()) | ||
| 394 | + .withPriority(fwd.priority()) | ||
| 395 | + .fromApp(fwd.appId()) | ||
| 396 | + .makePermanent(); | ||
| 272 | if (ethType.ethType().toShort() == Ethernet.TYPE_ARP) { | 397 | if (ethType.ethType().toShort() == Ethernet.TYPE_ARP) { |
| 273 | - log.warn("Driver automatically handles ARP packets by punting to controller " | 398 | + return processArpTraffic(fwd, rule); |
| 274 | - + " from ETHER table"); | ||
| 275 | - pass(fwd); | ||
| 276 | - return Collections.emptySet(); | ||
| 277 | } else if (ethType.ethType().toShort() == Ethernet.TYPE_LLDP || | 399 | } else if (ethType.ethType().toShort() == Ethernet.TYPE_LLDP || |
| 278 | ethType.ethType().toShort() == Ethernet.TYPE_BSN) { | 400 | ethType.ethType().toShort() == Ethernet.TYPE_BSN) { |
| 279 | - log.warn("Driver currently does not currently handle LLDP packets"); | 401 | + return processLinkDiscovery(fwd, rule); |
| 280 | - fail(fwd, ObjectiveError.UNSUPPORTED); | ||
| 281 | - return Collections.emptySet(); | ||
| 282 | } else if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) { | 402 | } else if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) { |
| 283 | - IPCriterion ipSrc = (IPCriterion) selector | 403 | + return processIpTraffic(fwd, rule); |
| 284 | - .getCriterion(Criterion.Type.IPV4_SRC); | ||
| 285 | - IPCriterion ipDst = (IPCriterion) selector | ||
| 286 | - .getCriterion(Criterion.Type.IPV4_DST); | ||
| 287 | - IPProtocolCriterion ipProto = (IPProtocolCriterion) selector | ||
| 288 | - .getCriterion(Criterion.Type.IP_PROTO); | ||
| 289 | - if (ipSrc != null) { | ||
| 290 | - log.warn("Driver does not currently handle matching Src IP"); | ||
| 291 | - fail(fwd, ObjectiveError.UNSUPPORTED); | ||
| 292 | - return Collections.emptySet(); | ||
| 293 | - } | ||
| 294 | - if (ipDst != null) { | ||
| 295 | - log.error("Driver handles Dst IP matching as specific forwarding " | ||
| 296 | - + "objective, not versatile"); | ||
| 297 | - fail(fwd, ObjectiveError.UNSUPPORTED); | ||
| 298 | - return Collections.emptySet(); | ||
| 299 | - } | ||
| 300 | - if (ipProto != null && ipProto.protocol() == IPv4.PROTOCOL_TCP) { | ||
| 301 | - log.warn("Driver automatically punts all packets reaching the " | ||
| 302 | - + "LOCAL table to the controller"); | ||
| 303 | - pass(fwd); | ||
| 304 | - return Collections.emptySet(); | ||
| 305 | - } | ||
| 306 | } | 404 | } |
| 307 | - | ||
| 308 | log.warn("Driver does not support given versatile forwarding objective"); | 405 | log.warn("Driver does not support given versatile forwarding objective"); |
| 309 | fail(fwd, ObjectiveError.UNSUPPORTED); | 406 | fail(fwd, ObjectiveError.UNSUPPORTED); |
| 310 | return Collections.emptySet(); | 407 | return Collections.emptySet(); |
| 311 | } | 408 | } |
| 312 | 409 | ||
| 313 | - private Collection<FlowRule> processSpecific(ForwardingObjective fwd) { | 410 | + protected abstract Collection<FlowRule> processArpTraffic(ForwardingObjective fwd, Builder rule); |
| 314 | - log.debug("Processing specific forwarding objective"); | ||
| 315 | - TrafficSelector selector = fwd.selector(); | ||
| 316 | 411 | ||
| 317 | - EthTypeCriterion ethType = | 412 | + protected abstract Collection<FlowRule> processLinkDiscovery(ForwardingObjective fwd, Builder rule); |
| 318 | - (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE); | ||
| 319 | - if (ethType != null) { | ||
| 320 | - short et = ethType.ethType().toShort(); | ||
| 321 | - if (et == Ethernet.TYPE_IPV4) { | ||
| 322 | - return processSpecificRoute(fwd); | ||
| 323 | - } else if (et == Ethernet.TYPE_VLAN) { | ||
| 324 | - /* The ForwardingObjective must specify VLAN ethtype in order to use the Transit Circuit */ | ||
| 325 | - return processSpecificSwitch(fwd); | ||
| 326 | - } | ||
| 327 | - } | ||
| 328 | 413 | ||
| 329 | - fail(fwd, ObjectiveError.UNSUPPORTED); | 414 | + protected abstract Collection<FlowRule> processIpTraffic(ForwardingObjective fwd, Builder rule); |
| 330 | - return Collections.emptySet(); | ||
| 331 | - } | ||
| 332 | 415 | ||
| 333 | private Collection<FlowRule> processSpecificRoute(ForwardingObjective fwd) { | 416 | private Collection<FlowRule> processSpecificRoute(ForwardingObjective fwd) { |
| 334 | TrafficSelector filteredSelector = | 417 | TrafficSelector filteredSelector = |
| ... | @@ -351,8 +434,7 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli | ... | @@ -351,8 +434,7 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli |
| 351 | } | 434 | } |
| 352 | tb.group(group.id()); | 435 | tb.group(group.id()); |
| 353 | } | 436 | } |
| 354 | - | 437 | + Builder ruleBuilder = DefaultFlowRule.builder() |
| 355 | - FlowRule.Builder ruleBuilder = DefaultFlowRule.builder() | ||
| 356 | .fromApp(fwd.appId()) | 438 | .fromApp(fwd.appId()) |
| 357 | .withPriority(fwd.priority()) | 439 | .withPriority(fwd.priority()) |
| 358 | .forDevice(deviceId) | 440 | .forDevice(deviceId) |
| ... | @@ -366,503 +448,111 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli | ... | @@ -366,503 +448,111 @@ public class OVSCorsaPipeline extends AbstractHandlerBehaviour implements Pipeli |
| 366 | } else { | 448 | } else { |
| 367 | ruleBuilder.makeTemporary(fwd.timeout()); | 449 | ruleBuilder.makeTemporary(fwd.timeout()); |
| 368 | } | 450 | } |
| 369 | - | ||
| 370 | return Collections.singletonList(ruleBuilder.build()); | 451 | return Collections.singletonList(ruleBuilder.build()); |
| 371 | } | 452 | } |
| 372 | 453 | ||
| 373 | - /* Hook for modifying Route traffic treatment */ | 454 | + //Hook for modifying Route traffic treatment |
| 374 | protected TrafficTreatment.Builder processSpecificRoutingTreatment() { | 455 | protected TrafficTreatment.Builder processSpecificRoutingTreatment() { |
| 375 | return DefaultTrafficTreatment.builder(); | 456 | return DefaultTrafficTreatment.builder(); |
| 376 | } | 457 | } |
| 377 | 458 | ||
| 378 | - /* Hook for modifying Route flow rule */ | 459 | + //Hook for modifying Route flow rule |
| 379 | - protected FlowRule.Builder processSpecificRoutingRule(FlowRule.Builder rb) { | 460 | + protected abstract Builder processSpecificRoutingRule(Builder rb); |
| 380 | - return rb.forTable(FIB_TABLE); | 461 | + |
| 462 | + @Override | ||
| 463 | + public void next(NextObjective nextObjective) { | ||
| 464 | + switch (nextObjective.type()) { | ||
| 465 | + case SIMPLE: | ||
| 466 | + Collection<TrafficTreatment> treatments = nextObjective.next(); | ||
| 467 | + if (treatments.size() == 1) { | ||
| 468 | + TrafficTreatment treatment = treatments.iterator().next(); | ||
| 469 | + treatment = processNextTreatment(treatment); | ||
| 470 | + GroupBucket bucket = | ||
| 471 | + DefaultGroupBucket.createIndirectGroupBucket(treatment); | ||
| 472 | + final GroupKey key = new DefaultGroupKey(appKryo.serialize(nextObjective.id())); | ||
| 473 | + GroupDescription groupDescription | ||
| 474 | + = new DefaultGroupDescription(deviceId, | ||
| 475 | + GroupDescription.Type.INDIRECT, | ||
| 476 | + new GroupBuckets(Collections | ||
| 477 | + .singletonList(bucket)), | ||
| 478 | + key, | ||
| 479 | + null, // let group service determine group id | ||
| 480 | + nextObjective.appId()); | ||
| 481 | + groupService.addGroup(groupDescription); | ||
| 482 | + pendingGroups.put(key, nextObjective); | ||
| 483 | + } | ||
| 484 | + break; | ||
| 485 | + case HASHED: | ||
| 486 | + case BROADCAST: | ||
| 487 | + case FAILOVER: | ||
| 488 | + fail(nextObjective, ObjectiveError.UNSUPPORTED); | ||
| 489 | + log.warn("Unsupported next objective type {}", nextObjective.type()); | ||
| 490 | + break; | ||
| 491 | + default: | ||
| 492 | + fail(nextObjective, ObjectiveError.UNKNOWN); | ||
| 493 | + log.warn("Unknown next objective type {}", nextObjective.type()); | ||
| 494 | + } | ||
| 495 | + | ||
| 381 | } | 496 | } |
| 382 | 497 | ||
| 383 | - protected Collection<FlowRule> processSpecificSwitch(ForwardingObjective fwd) { | 498 | + //Hook for altering the NextObjective treatment |
| 384 | - /* Not supported by until CorsaPipelineV3 */ | 499 | + protected TrafficTreatment processNextTreatment(TrafficTreatment treatment) { |
| 385 | - log.warn("Vlan switching not supported in ovs-corsa driver"); | 500 | + return treatment; |
| 386 | - fail(fwd, ObjectiveError.UNSUPPORTED); | ||
| 387 | - return Collections.emptySet(); | ||
| 388 | } | 501 | } |
| 389 | 502 | ||
| 390 | - protected void processFilter(FilteringObjective filt, boolean install, | 503 | + //Init helper: Table Miss = Drop |
| 391 | - ApplicationId applicationId) { | 504 | + protected void processTableMissDrop(boolean install, int table, String description) { |
| 392 | - // This driver only processes filtering criteria defined with switch | ||
| 393 | - // ports as the key | ||
| 394 | - PortCriterion p; | ||
| 395 | - if (!filt.key().equals(Criteria.dummy()) && | ||
| 396 | - filt.key().type() == Criterion.Type.IN_PORT) { | ||
| 397 | - p = (PortCriterion) filt.key(); | ||
| 398 | - } else { | ||
| 399 | - log.warn("No key defined in filtering objective from app: {}. Not" | ||
| 400 | - + "processing filtering objective", applicationId); | ||
| 401 | - fail(filt, ObjectiveError.UNKNOWN); | ||
| 402 | - return; | ||
| 403 | - } | ||
| 404 | - // convert filtering conditions for switch-intfs into flowrules | ||
| 405 | - FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | ||
| 406 | - for (Criterion c : filt.conditions()) { | ||
| 407 | - if (c.type() == Criterion.Type.ETH_DST) { | ||
| 408 | - EthCriterion e = (EthCriterion) c; | ||
| 409 | - log.debug("adding rule for MAC: {}", e.mac()); | ||
| 410 | - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
| 411 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
| 412 | - selector.matchEthDst(e.mac()); | ||
| 413 | - treatment.transition(VLAN_MPLS_TABLE); | ||
| 414 | - FlowRule rule = DefaultFlowRule.builder() | ||
| 415 | - .forDevice(deviceId) | ||
| 416 | - .withSelector(selector.build()) | ||
| 417 | - .withTreatment(treatment.build()) | ||
| 418 | - .withPriority(CONTROLLER_PRIORITY) | ||
| 419 | - .fromApp(applicationId) | ||
| 420 | - .makePermanent() | ||
| 421 | - .forTable(MAC_TABLE).build(); | ||
| 422 | - ops = install ? ops.add(rule) : ops.remove(rule); | ||
| 423 | - } else if (c.type() == Criterion.Type.VLAN_VID) { | ||
| 424 | - VlanIdCriterion v = (VlanIdCriterion) c; | ||
| 425 | - log.debug("adding rule for VLAN: {}", v.vlanId()); | ||
| 426 | - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
| 427 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
| 428 | - selector.matchVlanId(v.vlanId()); | ||
| 429 | - selector.matchInPort(p.port()); | ||
| 430 | - treatment.transition(ETHER_TABLE); | ||
| 431 | - treatment.deferred().popVlan(); | ||
| 432 | - FlowRule rule = DefaultFlowRule.builder() | ||
| 433 | - .forDevice(deviceId) | ||
| 434 | - .withSelector(selector.build()) | ||
| 435 | - .withTreatment(treatment.build()) | ||
| 436 | - .withPriority(CONTROLLER_PRIORITY) | ||
| 437 | - .fromApp(applicationId) | ||
| 438 | - .makePermanent() | ||
| 439 | - .forTable(VLAN_TABLE).build(); | ||
| 440 | - ops = install ? ops.add(rule) : ops.remove(rule); | ||
| 441 | - } else if (c.type() == Criterion.Type.IPV4_DST) { | ||
| 442 | - IPCriterion ip = (IPCriterion) c; | ||
| 443 | - log.debug("adding rule for IP: {}", ip.ip()); | ||
| 444 | - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
| 445 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
| 446 | - selector.matchEthType(Ethernet.TYPE_IPV4); | ||
| 447 | - selector.matchIPDst(ip.ip()); | ||
| 448 | - treatment.transition(LOCAL_TABLE); | ||
| 449 | - FlowRule rule = DefaultFlowRule.builder() | ||
| 450 | - .forDevice(deviceId) | ||
| 451 | - .withSelector(selector.build()) | ||
| 452 | - .withTreatment(treatment.build()) | ||
| 453 | - .withPriority(HIGHEST_PRIORITY) | ||
| 454 | - .fromApp(applicationId) | ||
| 455 | - .makePermanent() | ||
| 456 | - .forTable(FIB_TABLE).build(); | ||
| 457 | - | ||
| 458 | - ops = install ? ops.add(rule) : ops.remove(rule); | ||
| 459 | - } else { | ||
| 460 | - log.warn("Driver does not currently process filtering condition" | ||
| 461 | - + " of type: {}", c.type()); | ||
| 462 | - fail(filt, ObjectiveError.UNSUPPORTED); | ||
| 463 | - } | ||
| 464 | - } | ||
| 465 | - // apply filtering flow rules | ||
| 466 | - flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { | ||
| 467 | - @Override | ||
| 468 | - public void onSuccess(FlowRuleOperations ops) { | ||
| 469 | - pass(filt); | ||
| 470 | - log.info("Applied filtering rules"); | ||
| 471 | - } | ||
| 472 | - | ||
| 473 | - @Override | ||
| 474 | - public void onError(FlowRuleOperations ops) { | ||
| 475 | - fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED); | ||
| 476 | - log.info("Failed to apply filtering rules"); | ||
| 477 | - } | ||
| 478 | - })); | ||
| 479 | - } | ||
| 480 | - | ||
| 481 | - protected void pass(Objective obj) { | ||
| 482 | - obj.context().ifPresent(context -> context.onSuccess(obj)); | ||
| 483 | - } | ||
| 484 | - | ||
| 485 | - protected void fail(Objective obj, ObjectiveError error) { | ||
| 486 | - obj.context().ifPresent(context -> context.onError(obj, error)); | ||
| 487 | - } | ||
| 488 | - | ||
| 489 | - protected void initializePipeline() { | ||
| 490 | - processMacTable(true); | ||
| 491 | - processVlanMplsTable(true); | ||
| 492 | - processVlanTable(true); | ||
| 493 | - processEtherTable(true); | ||
| 494 | - processCosTable(true); | ||
| 495 | - processFibTable(true); | ||
| 496 | - processLocalTable(true); | ||
| 497 | - } | ||
| 498 | - | ||
| 499 | - private void processMacTable(boolean install) { | ||
| 500 | - TrafficSelector.Builder selector; | ||
| 501 | - TrafficTreatment.Builder treatment; | ||
| 502 | - | ||
| 503 | - // Bcast rule | ||
| 504 | - selector = DefaultTrafficSelector.builder(); | ||
| 505 | - treatment = DefaultTrafficTreatment.builder(); | ||
| 506 | - | ||
| 507 | - selector.matchEthDst(MacAddress.BROADCAST); | ||
| 508 | - treatment.transition(VLAN_MPLS_TABLE); | ||
| 509 | - | ||
| 510 | - FlowRule rule = DefaultFlowRule.builder() | ||
| 511 | - .forDevice(deviceId) | ||
| 512 | - .withSelector(selector.build()) | ||
| 513 | - .withTreatment(treatment.build()) | ||
| 514 | - .withPriority(CONTROLLER_PRIORITY) | ||
| 515 | - .fromApp(appId) | ||
| 516 | - .makePermanent() | ||
| 517 | - .forTable(MAC_TABLE).build(); | ||
| 518 | - | ||
| 519 | - | ||
| 520 | - FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | ||
| 521 | - | ||
| 522 | - ops = install ? ops.add(rule) : ops.remove(rule); | ||
| 523 | - | ||
| 524 | - | ||
| 525 | - //Drop rule | ||
| 526 | - selector = DefaultTrafficSelector.builder(); | ||
| 527 | - treatment = DefaultTrafficTreatment.builder(); | ||
| 528 | - | ||
| 529 | - treatment.drop(); | ||
| 530 | - | ||
| 531 | - rule = DefaultFlowRule.builder() | ||
| 532 | - .forDevice(deviceId) | ||
| 533 | - .withSelector(selector.build()) | ||
| 534 | - .withTreatment(treatment.build()) | ||
| 535 | - .withPriority(DROP_PRIORITY) | ||
| 536 | - .fromApp(appId) | ||
| 537 | - .makePermanent() | ||
| 538 | - .forTable(MAC_TABLE).build(); | ||
| 539 | - | ||
| 540 | - | ||
| 541 | - ops = install ? ops.add(rule) : ops.remove(rule); | ||
| 542 | - | ||
| 543 | - flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { | ||
| 544 | - @Override | ||
| 545 | - public void onSuccess(FlowRuleOperations ops) { | ||
| 546 | - log.info("Provisioned mac table"); | ||
| 547 | - } | ||
| 548 | - | ||
| 549 | - @Override | ||
| 550 | - public void onError(FlowRuleOperations ops) { | ||
| 551 | - log.info("Failed to provision mac table"); | ||
| 552 | - } | ||
| 553 | - })); | ||
| 554 | - | ||
| 555 | - } | ||
| 556 | - | ||
| 557 | - protected void processVlanMplsTable(boolean install) { | ||
| 558 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 505 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
| 559 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment | ||
| 560 | - .builder(); | ||
| 561 | - FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | ||
| 562 | - FlowRule rule; | ||
| 563 | - | ||
| 564 | - selector.matchVlanId(VlanId.ANY); | ||
| 565 | - treatment.transition(VLAN_TABLE); | ||
| 566 | - | ||
| 567 | - rule = DefaultFlowRule.builder() | ||
| 568 | - .forDevice(deviceId) | ||
| 569 | - .withSelector(selector.build()) | ||
| 570 | - .withTreatment(treatment.build()) | ||
| 571 | - .withPriority(CONTROLLER_PRIORITY) | ||
| 572 | - .fromApp(appId) | ||
| 573 | - .makePermanent() | ||
| 574 | - .forTable(VLAN_MPLS_TABLE).build(); | ||
| 575 | - | ||
| 576 | - | ||
| 577 | - ops = install ? ops.add(rule) : ops.remove(rule); | ||
| 578 | - | ||
| 579 | - flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { | ||
| 580 | - @Override | ||
| 581 | - public void onSuccess(FlowRuleOperations ops) { | ||
| 582 | - log.info("Provisioned vlan/mpls table"); | ||
| 583 | - } | ||
| 584 | - | ||
| 585 | - @Override | ||
| 586 | - public void onError(FlowRuleOperations ops) { | ||
| 587 | - log.info( | ||
| 588 | - "Failed to provision vlan/mpls table"); | ||
| 589 | - } | ||
| 590 | - })); | ||
| 591 | - | ||
| 592 | - } | ||
| 593 | - | ||
| 594 | - private void processVlanTable(boolean install) { | ||
| 595 | - TrafficSelector.Builder selector; | ||
| 596 | - TrafficTreatment.Builder treatment; | ||
| 597 | - FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | ||
| 598 | - FlowRule rule; | ||
| 599 | - | ||
| 600 | - | ||
| 601 | - //Drop rule | ||
| 602 | - selector = DefaultTrafficSelector.builder(); | ||
| 603 | - treatment = DefaultTrafficTreatment.builder(); | ||
| 604 | 506 | ||
| 507 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
| 605 | treatment.drop(); | 508 | treatment.drop(); |
| 606 | 509 | ||
| 607 | - rule = DefaultFlowRule.builder() | 510 | + FlowRule rule = DefaultFlowRule.builder() |
| 608 | - .forDevice(deviceId) | ||
| 609 | - .withSelector(selector.build()) | ||
| 610 | - .withTreatment(treatment.build()) | ||
| 611 | - .withPriority(DROP_PRIORITY) | ||
| 612 | - .fromApp(appId) | ||
| 613 | - .makePermanent() | ||
| 614 | - .forTable(VLAN_TABLE).build(); | ||
| 615 | - | ||
| 616 | - ops = install ? ops.add(rule) : ops.remove(rule); | ||
| 617 | - | ||
| 618 | - flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { | ||
| 619 | - @Override | ||
| 620 | - public void onSuccess(FlowRuleOperations ops) { | ||
| 621 | - log.info("Provisioned vlan table"); | ||
| 622 | - } | ||
| 623 | - | ||
| 624 | - @Override | ||
| 625 | - public void onError(FlowRuleOperations ops) { | ||
| 626 | - log.info("Failed to provision vlan table"); | ||
| 627 | - } | ||
| 628 | - })); | ||
| 629 | - } | ||
| 630 | - | ||
| 631 | - private void processEtherTable(boolean install) { | ||
| 632 | - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
| 633 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment | ||
| 634 | - .builder(); | ||
| 635 | - FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | ||
| 636 | - FlowRule rule; | ||
| 637 | - | ||
| 638 | - selector.matchEthType(Ethernet.TYPE_ARP); | ||
| 639 | - treatment.punt(); | ||
| 640 | - | ||
| 641 | - rule = DefaultFlowRule.builder() | ||
| 642 | - .forDevice(deviceId) | ||
| 643 | - .withSelector(selector.build()) | ||
| 644 | - .withTreatment(treatment.build()) | ||
| 645 | - .withPriority(CONTROLLER_PRIORITY) | ||
| 646 | - .fromApp(appId) | ||
| 647 | - .makePermanent() | ||
| 648 | - .forTable(ETHER_TABLE).build(); | ||
| 649 | - | ||
| 650 | - ops = install ? ops.add(rule) : ops.remove(rule); | ||
| 651 | - | ||
| 652 | - selector = DefaultTrafficSelector.builder(); | ||
| 653 | - treatment = DefaultTrafficTreatment.builder(); | ||
| 654 | - | ||
| 655 | - selector.matchEthType(Ethernet.TYPE_IPV4); | ||
| 656 | - treatment.transition(COS_MAP_TABLE); | ||
| 657 | - | ||
| 658 | - rule = DefaultFlowRule.builder() | ||
| 659 | - .forDevice(deviceId) | ||
| 660 | - .withPriority(CONTROLLER_PRIORITY) | ||
| 661 | - .withSelector(selector.build()) | ||
| 662 | - .withTreatment(treatment.build()) | ||
| 663 | - .fromApp(appId) | ||
| 664 | - .makePermanent() | ||
| 665 | - .forTable(ETHER_TABLE).build(); | ||
| 666 | - | ||
| 667 | - ops = install ? ops.add(rule) : ops.remove(rule); | ||
| 668 | - | ||
| 669 | - //Drop rule | ||
| 670 | - selector = DefaultTrafficSelector.builder(); | ||
| 671 | - treatment = DefaultTrafficTreatment.builder(); | ||
| 672 | - | ||
| 673 | - treatment.drop(); | ||
| 674 | - | ||
| 675 | - rule = DefaultFlowRule.builder() | ||
| 676 | .forDevice(deviceId) | 511 | .forDevice(deviceId) |
| 677 | .withSelector(selector.build()) | 512 | .withSelector(selector.build()) |
| 678 | .withTreatment(treatment.build()) | 513 | .withTreatment(treatment.build()) |
| 679 | .withPriority(DROP_PRIORITY) | 514 | .withPriority(DROP_PRIORITY) |
| 680 | .fromApp(appId) | 515 | .fromApp(appId) |
| 681 | .makePermanent() | 516 | .makePermanent() |
| 682 | - .forTable(ETHER_TABLE).build(); | 517 | + .forTable(table).build(); |
| 683 | - | ||
| 684 | - | ||
| 685 | - ops = install ? ops.add(rule) : ops.remove(rule); | ||
| 686 | - | ||
| 687 | - flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { | ||
| 688 | - @Override | ||
| 689 | - public void onSuccess(FlowRuleOperations ops) { | ||
| 690 | - log.info("Provisioned ether table"); | ||
| 691 | - } | ||
| 692 | - | ||
| 693 | - @Override | ||
| 694 | - public void onError(FlowRuleOperations ops) { | ||
| 695 | - log.info("Failed to provision ether table"); | ||
| 696 | - } | ||
| 697 | - })); | ||
| 698 | 518 | ||
| 519 | + processFlowRule(install, rule, description); | ||
| 699 | } | 520 | } |
| 700 | 521 | ||
| 701 | - private void processCosTable(boolean install) { | 522 | + //Init helper: Table Miss = GoTo |
| 523 | + protected void processTableMissGoTo(boolean install, int table, int goTo, String description) { | ||
| 702 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 524 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
| 703 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment | ||
| 704 | - .builder(); | ||
| 705 | - FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | ||
| 706 | - FlowRule rule; | ||
| 707 | 525 | ||
| 708 | - treatment.transition(FIB_TABLE); | 526 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); |
| 527 | + treatment.transition(goTo); | ||
| 709 | 528 | ||
| 710 | - rule = DefaultFlowRule.builder() | 529 | + FlowRule rule = DefaultFlowRule.builder() |
| 711 | - .forDevice(deviceId) | ||
| 712 | - .withSelector(selector.build()) | ||
| 713 | - .withTreatment(treatment.build()) | ||
| 714 | - .withPriority(DROP_PRIORITY) | ||
| 715 | - .fromApp(appId) | ||
| 716 | - .makePermanent() | ||
| 717 | - .forTable(COS_MAP_TABLE).build(); | ||
| 718 | - | ||
| 719 | - ops = install ? ops.add(rule) : ops.remove(rule); | ||
| 720 | - | ||
| 721 | - flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { | ||
| 722 | - @Override | ||
| 723 | - public void onSuccess(FlowRuleOperations ops) { | ||
| 724 | - log.info("Provisioned cos table"); | ||
| 725 | - } | ||
| 726 | - | ||
| 727 | - @Override | ||
| 728 | - public void onError(FlowRuleOperations ops) { | ||
| 729 | - log.info("Failed to provision cos table"); | ||
| 730 | - } | ||
| 731 | - })); | ||
| 732 | - | ||
| 733 | - } | ||
| 734 | - | ||
| 735 | - private void processFibTable(boolean install) { | ||
| 736 | - TrafficSelector.Builder selector; | ||
| 737 | - TrafficTreatment.Builder treatment; | ||
| 738 | - FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | ||
| 739 | - FlowRule rule; | ||
| 740 | - | ||
| 741 | - //Drop rule | ||
| 742 | - selector = DefaultTrafficSelector.builder(); | ||
| 743 | - treatment = DefaultTrafficTreatment.builder(); | ||
| 744 | - | ||
| 745 | - treatment.drop(); | ||
| 746 | - | ||
| 747 | - rule = DefaultFlowRule.builder() | ||
| 748 | .forDevice(deviceId) | 530 | .forDevice(deviceId) |
| 749 | .withSelector(selector.build()) | 531 | .withSelector(selector.build()) |
| 750 | .withTreatment(treatment.build()) | 532 | .withTreatment(treatment.build()) |
| 751 | .withPriority(DROP_PRIORITY) | 533 | .withPriority(DROP_PRIORITY) |
| 752 | .fromApp(appId) | 534 | .fromApp(appId) |
| 753 | .makePermanent() | 535 | .makePermanent() |
| 754 | - .forTable(FIB_TABLE).build(); | 536 | + .forTable(table).build(); |
| 755 | - | ||
| 756 | - ops = install ? ops.add(rule) : ops.remove(rule); | ||
| 757 | 537 | ||
| 758 | - flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { | 538 | + processFlowRule(install, rule, description); |
| 759 | - @Override | ||
| 760 | - public void onSuccess(FlowRuleOperations ops) { | ||
| 761 | - log.info("Provisioned FIB table"); | ||
| 762 | - } | ||
| 763 | - | ||
| 764 | - @Override | ||
| 765 | - public void onError(FlowRuleOperations ops) { | ||
| 766 | - log.info("Failed to provision FIB table"); | ||
| 767 | - } | ||
| 768 | - })); | ||
| 769 | } | 539 | } |
| 770 | 540 | ||
| 771 | - private void processLocalTable(boolean install) { | 541 | + //Init helper: Apply flow rule |
| 772 | - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 542 | + protected void processFlowRule(boolean install, FlowRule rule, String description) { |
| 773 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment | ||
| 774 | - .builder(); | ||
| 775 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | 543 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); |
| 776 | - FlowRule rule; | ||
| 777 | - | ||
| 778 | - treatment.punt(); | ||
| 779 | - | ||
| 780 | - rule = DefaultFlowRule.builder() | ||
| 781 | - .forDevice(deviceId) | ||
| 782 | - .withSelector(selector.build()) | ||
| 783 | - .withTreatment(treatment.build()) | ||
| 784 | - .withPriority(CONTROLLER_PRIORITY) | ||
| 785 | - .fromApp(appId) | ||
| 786 | - .makePermanent() | ||
| 787 | - .forTable(LOCAL_TABLE).build(); | ||
| 788 | - | ||
| 789 | ops = install ? ops.add(rule) : ops.remove(rule); | 544 | ops = install ? ops.add(rule) : ops.remove(rule); |
| 790 | 545 | ||
| 791 | flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { | 546 | flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { |
| 792 | @Override | 547 | @Override |
| 793 | public void onSuccess(FlowRuleOperations ops) { | 548 | public void onSuccess(FlowRuleOperations ops) { |
| 794 | - log.info("Provisioned Local table"); | 549 | + log.info(description + " success: " + ops.toString() + ", " + rule.toString()); |
| 795 | } | 550 | } |
| 796 | 551 | ||
| 797 | @Override | 552 | @Override |
| 798 | public void onError(FlowRuleOperations ops) { | 553 | public void onError(FlowRuleOperations ops) { |
| 799 | - log.info("Failed to provision Local table"); | 554 | + log.info(description + " error: " + ops.toString() + ", " + rule.toString()); |
| 800 | } | 555 | } |
| 801 | })); | 556 | })); |
| 802 | } | 557 | } |
| 803 | - | ||
| 804 | - private class InnerGroupListener implements GroupListener { | ||
| 805 | - @Override | ||
| 806 | - public void event(GroupEvent event) { | ||
| 807 | - if (event.type() == GroupEvent.Type.GROUP_ADDED) { | ||
| 808 | - GroupKey key = event.subject().appCookie(); | ||
| 809 | - | ||
| 810 | - NextObjective obj = pendingGroups.getIfPresent(key); | ||
| 811 | - if (obj != null) { | ||
| 812 | - flowObjectiveStore.putNextGroup(obj.id(), new CorsaGroup(key)); | ||
| 813 | - pass(obj); | ||
| 814 | - pendingGroups.invalidate(key); | ||
| 815 | - } | ||
| 816 | - } | ||
| 817 | - } | ||
| 818 | - } | ||
| 819 | - | ||
| 820 | - | ||
| 821 | - private class GroupChecker implements Runnable { | ||
| 822 | - | ||
| 823 | - @Override | ||
| 824 | - public void run() { | ||
| 825 | - Set<GroupKey> keys = pendingGroups.asMap().keySet().stream() | ||
| 826 | - .filter(key -> groupService.getGroup(deviceId, key) != null) | ||
| 827 | - .collect(Collectors.toSet()); | ||
| 828 | - | ||
| 829 | - keys.stream().forEach(key -> { | ||
| 830 | - NextObjective obj = pendingGroups.getIfPresent(key); | ||
| 831 | - if (obj == null) { | ||
| 832 | - return; | ||
| 833 | - } | ||
| 834 | - pass(obj); | ||
| 835 | - pendingGroups.invalidate(key); | ||
| 836 | - log.info("Heard back from group service for group {}. " | ||
| 837 | - + "Applying pending forwarding objectives", obj.id()); | ||
| 838 | - flowObjectiveStore.putNextGroup(obj.id(), new CorsaGroup(key)); | ||
| 839 | - }); | ||
| 840 | - } | ||
| 841 | - } | ||
| 842 | - | ||
| 843 | - private class CorsaGroup implements NextGroup { | ||
| 844 | - | ||
| 845 | - private final GroupKey key; | ||
| 846 | - | ||
| 847 | - public CorsaGroup(GroupKey key) { | ||
| 848 | - this.key = key; | ||
| 849 | - } | ||
| 850 | - | ||
| 851 | - @SuppressWarnings("unused") | ||
| 852 | - public GroupKey key() { | ||
| 853 | - return key; | ||
| 854 | - } | ||
| 855 | - | ||
| 856 | - @Override | ||
| 857 | - public byte[] data() { | ||
| 858 | - return appKryo.serialize(key); | ||
| 859 | - } | ||
| 860 | - | ||
| 861 | - } | ||
| 862 | - | ||
| 863 | - @Override | ||
| 864 | - public List<String> getNextMappings(NextGroup nextGroup) { | ||
| 865 | - // TODO Implementation deferred to vendor | ||
| 866 | - return null; | ||
| 867 | - } | ||
| 868 | } | 558 | } | ... | ... |
| 1 | +/* | ||
| 2 | + * Copyright 2014-2016 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.drivers.corsa; | ||
| 18 | + | ||
| 19 | +import org.apache.felix.scr.annotations.Component; | ||
| 20 | +import org.onosproject.net.driver.AbstractDriverLoader; | ||
| 21 | + | ||
| 22 | +/** | ||
| 23 | + * Loader for Corsa device drivers. | ||
| 24 | + */ | ||
| 25 | +@Component(immediate = true) | ||
| 26 | +public class CorsaDriversLoader extends AbstractDriverLoader { | ||
| 27 | + public CorsaDriversLoader() { | ||
| 28 | + super("/corsa-drivers.xml"); | ||
| 29 | + } | ||
| 30 | +} |
| ... | @@ -13,9 +13,7 @@ | ... | @@ -13,9 +13,7 @@ |
| 13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. | 14 | * limitations under the License. |
| 15 | */ | 15 | */ |
| 16 | -package org.onosproject.driver.pipeline; | 16 | +package org.onosproject.drivers.corsa; |
| 17 | - | ||
| 18 | -import static org.slf4j.LoggerFactory.getLogger; | ||
| 19 | 17 | ||
| 20 | import org.onlab.packet.Ethernet; | 18 | import org.onlab.packet.Ethernet; |
| 21 | import org.onosproject.net.flow.DefaultFlowRule; | 19 | import org.onosproject.net.flow.DefaultFlowRule; |
| ... | @@ -26,18 +24,15 @@ import org.onosproject.net.flow.FlowRuleOperations; | ... | @@ -26,18 +24,15 @@ import org.onosproject.net.flow.FlowRuleOperations; |
| 26 | import org.onosproject.net.flow.FlowRuleOperationsContext; | 24 | import org.onosproject.net.flow.FlowRuleOperationsContext; |
| 27 | import org.onosproject.net.flow.TrafficSelector; | 25 | import org.onosproject.net.flow.TrafficSelector; |
| 28 | import org.onosproject.net.flow.TrafficTreatment; | 26 | import org.onosproject.net.flow.TrafficTreatment; |
| 29 | -import org.onosproject.net.flowobjective.ForwardingObjective; | ||
| 30 | -import org.onosproject.net.flowobjective.ObjectiveError; | ||
| 31 | import org.slf4j.Logger; | 27 | import org.slf4j.Logger; |
| 32 | 28 | ||
| 33 | -import java.util.Collection; | 29 | +import static org.slf4j.LoggerFactory.getLogger; |
| 34 | -import java.util.Collections; | ||
| 35 | 30 | ||
| 36 | /** | 31 | /** |
| 37 | * Driver for Corsa TTP. | 32 | * Driver for Corsa TTP. |
| 38 | * | 33 | * |
| 39 | */ | 34 | */ |
| 40 | -public class CorsaPipeline extends OVSCorsaPipeline { | 35 | +public class CorsaPipelineV1 extends OvsCorsaPipeline { |
| 41 | 36 | ||
| 42 | private final Logger log = getLogger(getClass()); | 37 | private final Logger log = getLogger(getClass()); |
| 43 | 38 | ||
| ... | @@ -76,13 +71,4 @@ public class CorsaPipeline extends OVSCorsaPipeline { | ... | @@ -76,13 +71,4 @@ public class CorsaPipeline extends OVSCorsaPipeline { |
| 76 | } | 71 | } |
| 77 | })); | 72 | })); |
| 78 | } | 73 | } |
| 79 | - | ||
| 80 | - @Override | ||
| 81 | - protected Collection<FlowRule> processSpecificSwitch(ForwardingObjective fwd) { | ||
| 82 | - /* Not supported by until CorsaPipelineV3 */ | ||
| 83 | - log.warn("Vlan switching not supported in corsa-v1 driver"); | ||
| 84 | - fail(fwd, ObjectiveError.UNSUPPORTED); | ||
| 85 | - return Collections.emptySet(); | ||
| 86 | - } | ||
| 87 | - | ||
| 88 | } | 74 | } | ... | ... |
| ... | @@ -13,31 +13,25 @@ | ... | @@ -13,31 +13,25 @@ |
| 13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. | 14 | * limitations under the License. |
| 15 | */ | 15 | */ |
| 16 | -package org.onosproject.driver.pipeline; | 16 | +package org.onosproject.drivers.corsa; |
| 17 | 17 | ||
| 18 | import org.onlab.packet.Ethernet; | 18 | import org.onlab.packet.Ethernet; |
| 19 | import org.onlab.packet.MacAddress; | 19 | import org.onlab.packet.MacAddress; |
| 20 | import org.onlab.packet.VlanId; | 20 | import org.onlab.packet.VlanId; |
| 21 | -import org.onosproject.core.ApplicationId; | ||
| 22 | import org.onosproject.net.flow.DefaultFlowRule; | 21 | import org.onosproject.net.flow.DefaultFlowRule; |
| 23 | import org.onosproject.net.flow.DefaultTrafficSelector; | 22 | import org.onosproject.net.flow.DefaultTrafficSelector; |
| 24 | import org.onosproject.net.flow.DefaultTrafficTreatment; | 23 | import org.onosproject.net.flow.DefaultTrafficTreatment; |
| 25 | import org.onosproject.net.flow.FlowRule; | 24 | import org.onosproject.net.flow.FlowRule; |
| 26 | -import org.onosproject.net.flow.FlowRuleOperations; | ||
| 27 | -import org.onosproject.net.flow.FlowRuleOperationsContext; | ||
| 28 | import org.onosproject.net.flow.TrafficSelector; | 25 | import org.onosproject.net.flow.TrafficSelector; |
| 29 | import org.onosproject.net.flow.TrafficTreatment; | 26 | import org.onosproject.net.flow.TrafficTreatment; |
| 30 | -import org.onosproject.net.flow.criteria.Criteria; | ||
| 31 | import org.onosproject.net.flow.criteria.Criterion; | 27 | import org.onosproject.net.flow.criteria.Criterion; |
| 32 | import org.onosproject.net.flow.criteria.EthCriterion; | 28 | import org.onosproject.net.flow.criteria.EthCriterion; |
| 33 | import org.onosproject.net.flow.criteria.IPCriterion; | 29 | import org.onosproject.net.flow.criteria.IPCriterion; |
| 34 | import org.onosproject.net.flow.criteria.PortCriterion; | 30 | import org.onosproject.net.flow.criteria.PortCriterion; |
| 35 | import org.onosproject.net.flow.criteria.VlanIdCriterion; | 31 | import org.onosproject.net.flow.criteria.VlanIdCriterion; |
| 36 | -import org.onosproject.net.flow.instructions.Instructions; | ||
| 37 | import org.onosproject.net.flow.instructions.L2ModificationInstruction; | 32 | import org.onosproject.net.flow.instructions.L2ModificationInstruction; |
| 38 | import org.onosproject.net.flowobjective.FilteringObjective; | 33 | import org.onosproject.net.flowobjective.FilteringObjective; |
| 39 | import org.onosproject.net.flowobjective.ForwardingObjective; | 34 | import org.onosproject.net.flowobjective.ForwardingObjective; |
| 40 | -import org.onosproject.net.flowobjective.ObjectiveError; | ||
| 41 | import org.onosproject.net.meter.Band; | 35 | import org.onosproject.net.meter.Band; |
| 42 | import org.onosproject.net.meter.DefaultBand; | 36 | import org.onosproject.net.meter.DefaultBand; |
| 43 | import org.onosproject.net.meter.DefaultMeterRequest; | 37 | import org.onosproject.net.meter.DefaultMeterRequest; |
| ... | @@ -49,9 +43,13 @@ import org.slf4j.Logger; | ... | @@ -49,9 +43,13 @@ import org.slf4j.Logger; |
| 49 | import java.util.Collection; | 43 | import java.util.Collection; |
| 50 | import java.util.Collections; | 44 | import java.util.Collections; |
| 51 | 45 | ||
| 46 | +import static org.onosproject.net.flow.FlowRule.Builder; | ||
| 52 | import static org.slf4j.LoggerFactory.getLogger; | 47 | import static org.slf4j.LoggerFactory.getLogger; |
| 53 | 48 | ||
| 54 | -public class CorsaPipelineV3 extends OVSCorsaPipeline { | 49 | +/** |
| 50 | + * Implementation of the Corsa pipeline handler for pipeline version 3. | ||
| 51 | + */ | ||
| 52 | +public class CorsaPipelineV3 extends AbstractCorsaPipeline { | ||
| 55 | 53 | ||
| 56 | private final Logger log = getLogger(getClass()); | 54 | private final Logger log = getLogger(getClass()); |
| 57 | 55 | ||
| ... | @@ -67,17 +65,27 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline { | ... | @@ -67,17 +65,27 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline { |
| 67 | 65 | ||
| 68 | protected static final byte MAX_VLAN_PCP = 7; | 66 | protected static final byte MAX_VLAN_PCP = 7; |
| 69 | 67 | ||
| 70 | - private MeterId defaultMeterId = null; | 68 | + protected MeterId defaultMeterId = null; |
| 71 | 69 | ||
| 72 | @Override | 70 | @Override |
| 73 | protected TrafficTreatment processNextTreatment(TrafficTreatment treatment) { | 71 | protected TrafficTreatment processNextTreatment(TrafficTreatment treatment) { |
| 74 | TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder(); | 72 | TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder(); |
| 75 | 73 | ||
| 76 | treatment.immediate().stream() | 74 | treatment.immediate().stream() |
| 77 | - .filter(i -> i instanceof L2ModificationInstruction.ModVlanIdInstruction || | 75 | + .filter(i -> { |
| 78 | - i instanceof L2ModificationInstruction.ModEtherInstruction || | 76 | + switch (i.type()) { |
| 79 | - i instanceof Instructions.OutputInstruction) | 77 | + case L2MODIFICATION: |
| 80 | - .forEach(i -> tb.add(i)); | 78 | + L2ModificationInstruction l2i = (L2ModificationInstruction) i; |
| 79 | + if (l2i instanceof L2ModificationInstruction.ModVlanIdInstruction || | ||
| 80 | + l2i instanceof L2ModificationInstruction.ModEtherInstruction) { | ||
| 81 | + return true; | ||
| 82 | + } | ||
| 83 | + case OUTPUT: | ||
| 84 | + return true; | ||
| 85 | + default: | ||
| 86 | + return false; | ||
| 87 | + } | ||
| 88 | + }).forEach(i -> tb.add(i)); | ||
| 81 | return tb.build(); | 89 | return tb.build(); |
| 82 | } | 90 | } |
| 83 | 91 | ||
| ... | @@ -87,7 +95,7 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline { | ... | @@ -87,7 +95,7 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline { |
| 87 | } | 95 | } |
| 88 | 96 | ||
| 89 | @Override | 97 | @Override |
| 90 | - protected FlowRule.Builder processSpecificRoutingRule(FlowRule.Builder rb) { | 98 | + protected Builder processSpecificRoutingRule(Builder rb) { |
| 91 | return rb.forTable(FIB_TABLE); | 99 | return rb.forTable(FIB_TABLE); |
| 92 | } | 100 | } |
| 93 | 101 | ||
| ... | @@ -101,7 +109,7 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline { | ... | @@ -101,7 +109,7 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline { |
| 101 | ((VlanIdCriterion) fwd.selector().getCriterion(Criterion.Type.VLAN_VID)).vlanId()) | 109 | ((VlanIdCriterion) fwd.selector().getCriterion(Criterion.Type.VLAN_VID)).vlanId()) |
| 102 | .build(); | 110 | .build(); |
| 103 | 111 | ||
| 104 | - FlowRule.Builder ruleBuilder = DefaultFlowRule.builder() | 112 | + Builder ruleBuilder = DefaultFlowRule.builder() |
| 105 | .fromApp(fwd.appId()) | 113 | .fromApp(fwd.appId()) |
| 106 | .withPriority(fwd.priority()) | 114 | .withPriority(fwd.priority()) |
| 107 | .forDevice(deviceId) | 115 | .forDevice(deviceId) |
| ... | @@ -119,101 +127,76 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline { | ... | @@ -119,101 +127,76 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline { |
| 119 | } | 127 | } |
| 120 | 128 | ||
| 121 | @Override | 129 | @Override |
| 122 | - protected void processFilter(FilteringObjective filt, boolean install, | 130 | + protected Collection<FlowRule> processArpTraffic(ForwardingObjective fwd, Builder rule) { |
| 123 | - ApplicationId applicationId) { | 131 | + //TODO |
| 124 | - // This driver only processes filtering criteria defined with switch | 132 | + return Collections.emptyList(); |
| 125 | - // ports as the key | 133 | + } |
| 126 | - PortCriterion p; | 134 | + |
| 127 | - if (!filt.key().equals(Criteria.dummy()) && | 135 | + @Override |
| 128 | - filt.key().type() == Criterion.Type.IN_PORT) { | 136 | + protected Collection<FlowRule> processLinkDiscovery(ForwardingObjective fwd, Builder rule) { |
| 129 | - p = (PortCriterion) filt.key(); | 137 | + //TODO |
| 130 | - } else { | 138 | + return Collections.emptyList(); |
| 131 | - log.warn("No key defined in filtering objective from app: {}. Not" | 139 | + } |
| 132 | - + "processing filtering objective", applicationId); | 140 | + |
| 133 | - fail(filt, ObjectiveError.UNKNOWN); | 141 | + @Override |
| 134 | - return; | 142 | + protected Collection<FlowRule> processIpTraffic(ForwardingObjective fwd, Builder rule) { |
| 135 | - } | 143 | + //TODO |
| 136 | - // convert filtering conditions for switch-intfs into flowrules | 144 | + return Collections.emptyList(); |
| 137 | - FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | 145 | + } |
| 138 | - for (Criterion c : filt.conditions()) { | 146 | + |
| 139 | - if (c.type() == Criterion.Type.ETH_DST) { | 147 | + @Override |
| 140 | - EthCriterion e = (EthCriterion) c; | 148 | + protected Builder processEthFiler(FilteringObjective filt, EthCriterion eth, PortCriterion port) { |
| 141 | - log.debug("adding rule for MAC: {}", e.mac()); | 149 | + log.debug("adding rule for MAC: {}", eth.mac()); |
| 142 | - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 150 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
| 143 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | 151 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); |
| 144 | - selector.matchEthDst(e.mac()); | 152 | + selector.matchEthDst(eth.mac()); |
| 145 | - selector.matchInPort(p.port()); | 153 | + selector.matchInPort(port.port()); |
| 146 | - treatment.transition(ETHER_TABLE); | 154 | + treatment.transition(ETHER_TABLE); |
| 147 | - FlowRule rule = DefaultFlowRule.builder() | 155 | + return DefaultFlowRule.builder() |
| 148 | - .forDevice(deviceId) | 156 | + .withSelector(selector.build()) |
| 149 | - .withSelector(selector.build()) | 157 | + .withTreatment(treatment.build()) |
| 150 | - .withTreatment(treatment.build()) | 158 | + .withPriority(CONTROLLER_PRIORITY) |
| 151 | - .withPriority(CONTROLLER_PRIORITY) | 159 | + .makePermanent() |
| 152 | - .fromApp(applicationId) | 160 | + .forTable(L3_IF_MAC_DA_TABLE); |
| 153 | - .makePermanent() | 161 | + } |
| 154 | - .forTable(L3_IF_MAC_DA_TABLE).build(); | 162 | + |
| 155 | - ops = install ? ops.add(rule) : ops.remove(rule); | 163 | + @Override |
| 156 | - } else if (c.type() == Criterion.Type.VLAN_VID) { | 164 | + protected Builder processVlanFiler(FilteringObjective filt, VlanIdCriterion vlan, PortCriterion port) { |
| 157 | - VlanIdCriterion v = (VlanIdCriterion) c; | 165 | + log.debug("adding rule for VLAN: {}", vlan.vlanId()); |
| 158 | - log.debug("adding rule for VLAN: {}", v.vlanId()); | 166 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
| 159 | - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 167 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); |
| 160 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | 168 | + selector.matchVlanId(vlan.vlanId()); |
| 161 | - selector.matchVlanId(v.vlanId()); | 169 | + selector.matchInPort(port.port()); |
| 162 | - selector.matchInPort(p.port()); | ||
| 163 | /* Static treatment for VLAN_CIRCUIT_TABLE */ | 170 | /* Static treatment for VLAN_CIRCUIT_TABLE */ |
| 164 | - treatment.setVlanPcp(MAX_VLAN_PCP); | 171 | + treatment.setVlanPcp(MAX_VLAN_PCP); |
| 165 | - treatment.setQueue(0); | 172 | + treatment.setQueue(0); |
| 166 | - treatment.meter(MeterId.meterId(defaultMeterId.id())); /* use default meter (Green) */ | 173 | + treatment.meter(MeterId.meterId(defaultMeterId.id())); /* use default meter (Green) */ |
| 167 | - treatment.transition(L3_IF_MAC_DA_TABLE); | 174 | + treatment.transition(L3_IF_MAC_DA_TABLE); |
| 168 | - FlowRule rule = DefaultFlowRule.builder() | 175 | + return DefaultFlowRule.builder() |
| 169 | - .forDevice(deviceId) | 176 | + .withSelector(selector.build()) |
| 170 | - .withSelector(selector.build()) | 177 | + .withTreatment(treatment.build()) |
| 171 | - .withTreatment(treatment.build()) | 178 | + .withPriority(CONTROLLER_PRIORITY) |
| 172 | - .withPriority(CONTROLLER_PRIORITY) | 179 | + .makePermanent() |
| 173 | - .fromApp(applicationId) | 180 | + .forTable(VLAN_CIRCUIT_TABLE); |
| 174 | - .makePermanent() | 181 | + } |
| 175 | - .forTable(VLAN_CIRCUIT_TABLE).build(); | 182 | + |
| 176 | - ops = install ? ops.add(rule) : ops.remove(rule); | 183 | + @Override |
| 177 | - } else if (c.type() == Criterion.Type.IPV4_DST) { | 184 | + protected Builder processIpFilter(FilteringObjective filt, IPCriterion ip, PortCriterion port) { |
| 178 | - IPCriterion ip = (IPCriterion) c; | 185 | + log.debug("adding rule for IP: {}", ip.ip()); |
| 179 | - log.debug("adding rule for IP: {}", ip.ip()); | 186 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
| 180 | - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 187 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); |
| 181 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | 188 | + selector.matchEthType(Ethernet.TYPE_IPV4); |
| 182 | - selector.matchEthType(Ethernet.TYPE_IPV4); | 189 | + selector.matchIPDst(ip.ip()); |
| 183 | - selector.matchIPDst(ip.ip()); | 190 | + treatment.transition(LOCAL_TABLE); |
| 184 | - treatment.transition(LOCAL_TABLE); | 191 | + return DefaultFlowRule.builder() |
| 185 | - FlowRule rule = DefaultFlowRule.builder() | 192 | + .withSelector(selector.build()) |
| 186 | - .forDevice(deviceId) | 193 | + .withTreatment(treatment.build()) |
| 187 | - .withSelector(selector.build()) | 194 | + .withPriority(HIGHEST_PRIORITY) |
| 188 | - .withTreatment(treatment.build()) | 195 | + .makePermanent() |
| 189 | - .withPriority(HIGHEST_PRIORITY) | 196 | + .forTable(FIB_TABLE); |
| 190 | - .fromApp(applicationId) | ||
| 191 | - .makePermanent() | ||
| 192 | - .forTable(FIB_TABLE).build(); | ||
| 193 | - | ||
| 194 | - ops = install ? ops.add(rule) : ops.remove(rule); | ||
| 195 | - } else { | ||
| 196 | - log.warn("Driver does not currently process filtering condition" | ||
| 197 | - + " of type: {}", c.type()); | ||
| 198 | - fail(filt, ObjectiveError.UNSUPPORTED); | ||
| 199 | - } | ||
| 200 | - } | ||
| 201 | - // apply filtering flow rules | ||
| 202 | - flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { | ||
| 203 | - @Override | ||
| 204 | - public void onSuccess(FlowRuleOperations ops) { | ||
| 205 | - pass(filt); | ||
| 206 | - log.info("Applied filtering rules"); | ||
| 207 | - } | ||
| 208 | - | ||
| 209 | - @Override | ||
| 210 | - public void onError(FlowRuleOperations ops) { | ||
| 211 | - fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED); | ||
| 212 | - log.info("Failed to apply filtering rules"); | ||
| 213 | - } | ||
| 214 | - })); | ||
| 215 | } | 197 | } |
| 216 | 198 | ||
| 199 | + @Override | ||
| 217 | public void initializePipeline() { | 200 | public void initializePipeline() { |
| 218 | processMeterTable(true); | 201 | processMeterTable(true); |
| 219 | processPortBasedProtoTable(true); /* Table 0 */ | 202 | processPortBasedProtoTable(true); /* Table 0 */ |
| ... | @@ -227,8 +210,8 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline { | ... | @@ -227,8 +210,8 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline { |
| 227 | processLocalTable(true); /* Table 9 */ | 210 | processLocalTable(true); /* Table 9 */ |
| 228 | } | 211 | } |
| 229 | 212 | ||
| 230 | - private void processMeterTable(boolean install) { | 213 | + protected void processMeterTable(boolean install) { |
| 231 | - /* Green meter : Pass all traffic */ | 214 | + //Green meter : Pass all traffic |
| 232 | Band dropBand = DefaultBand.builder() | 215 | Band dropBand = DefaultBand.builder() |
| 233 | .ofType(Band.Type.DROP) | 216 | .ofType(Band.Type.DROP) |
| 234 | .withRate(0xFFFFFFFF) /* Max Rate */ | 217 | .withRate(0xFFFFFFFF) /* Max Rate */ |
| ... | @@ -242,18 +225,22 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline { | ... | @@ -242,18 +225,22 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline { |
| 242 | defaultMeterId = meter.id(); | 225 | defaultMeterId = meter.id(); |
| 243 | } | 226 | } |
| 244 | 227 | ||
| 245 | - private void processPortBasedProtoTable(boolean install) { | 228 | + protected void processPortBasedProtoTable(boolean install) { |
| 246 | /* Default action */ | 229 | /* Default action */ |
| 247 | - processTableMissGoTo(install, PORT_BASED_PROTO_TABLE, VLAN_CHECK_TABLE); | 230 | + processTableMissGoTo(install, PORT_BASED_PROTO_TABLE, VLAN_CHECK_TABLE, "Provisioned port-based table"); |
| 248 | } | 231 | } |
| 249 | 232 | ||
| 250 | - private void processVlanCheckTable(boolean install) { | 233 | + protected void processVlanCheckTable(boolean install) { |
| 251 | - int table = VLAN_CHECK_TABLE; | ||
| 252 | 234 | ||
| 253 | /* Default action */ | 235 | /* Default action */ |
| 254 | - processTableMissDrop(install, table); | 236 | + processTableMissDrop(install, VLAN_CHECK_TABLE, "Provisioned vlantable drop"); |
| 237 | + | ||
| 238 | + processTaggedPackets(install); | ||
| 255 | 239 | ||
| 256 | - /* Tagged packets to VLAN_MAC_XLATE */ | 240 | + } |
| 241 | + | ||
| 242 | + /* Tagged packets to VLAN_MAC_XLATE */ | ||
| 243 | + protected void processTaggedPackets(boolean install) { | ||
| 257 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 244 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
| 258 | selector.matchVlanId(VlanId.ANY); | 245 | selector.matchVlanId(VlanId.ANY); |
| 259 | 246 | ||
| ... | @@ -267,29 +254,29 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline { | ... | @@ -267,29 +254,29 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline { |
| 267 | .withPriority(CONTROLLER_PRIORITY) | 254 | .withPriority(CONTROLLER_PRIORITY) |
| 268 | .fromApp(appId) | 255 | .fromApp(appId) |
| 269 | .makePermanent() | 256 | .makePermanent() |
| 270 | - .forTable(table).build(); | 257 | + .forTable(VLAN_CHECK_TABLE).build(); |
| 271 | - processFlowRule(install, rule); | 258 | + processFlowRule(install, rule, "Provisioned vlan table tagged packets"); |
| 272 | } | 259 | } |
| 273 | 260 | ||
| 274 | - private void processVlanMacXlateTable(boolean install) { | 261 | + protected void processVlanMacXlateTable(boolean install) { |
| 275 | /* Default action */ | 262 | /* Default action */ |
| 276 | - processTableMissGoTo(install, VLAN_MAC_XLATE_TABLE, VLAN_CIRCUIT_TABLE); | 263 | + processTableMissGoTo(install, VLAN_MAC_XLATE_TABLE, VLAN_CIRCUIT_TABLE, "Provisioned vlan mac table"); |
| 277 | } | 264 | } |
| 278 | 265 | ||
| 279 | - private void processVlanCircuitTable(boolean install) { | 266 | + protected void processVlanCircuitTable(boolean install) { |
| 280 | /* Default action */ | 267 | /* Default action */ |
| 281 | - processTableMissDrop(install, VLAN_CIRCUIT_TABLE); | 268 | + processTableMissDrop(install, VLAN_CIRCUIT_TABLE, "Provisioned vlan circuit"); |
| 282 | } | 269 | } |
| 283 | 270 | ||
| 284 | private void processPriorityMapTable(boolean install) { | 271 | private void processPriorityMapTable(boolean install) { |
| 285 | /* Not required currently */ | 272 | /* Not required currently */ |
| 286 | } | 273 | } |
| 287 | 274 | ||
| 288 | - private void processL3IFMacDATable(boolean install) { | 275 | + protected void processL3IFMacDATable(boolean install) { |
| 289 | int table = L3_IF_MAC_DA_TABLE; | 276 | int table = L3_IF_MAC_DA_TABLE; |
| 290 | 277 | ||
| 291 | /* Default action */ | 278 | /* Default action */ |
| 292 | - processTableMissDrop(install, table); | 279 | + processTableMissDrop(install, table, "Provisioned l3 table drop"); |
| 293 | 280 | ||
| 294 | /* Allow MAC broadcast frames on all ports */ | 281 | /* Allow MAC broadcast frames on all ports */ |
| 295 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 282 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
| ... | @@ -306,15 +293,15 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline { | ... | @@ -306,15 +293,15 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline { |
| 306 | .fromApp(appId) | 293 | .fromApp(appId) |
| 307 | .makePermanent() | 294 | .makePermanent() |
| 308 | .forTable(table).build(); | 295 | .forTable(table).build(); |
| 309 | - processFlowRule(install, rule); | 296 | + processFlowRule(install, rule, "Provisioned l3 table"); |
| 310 | } | 297 | } |
| 311 | 298 | ||
| 312 | 299 | ||
| 313 | - private void processEtherTable(boolean install) { | 300 | + protected void processEtherTable(boolean install) { |
| 314 | int table = ETHER_TABLE; | 301 | int table = ETHER_TABLE; |
| 315 | 302 | ||
| 316 | /* Default action */ | 303 | /* Default action */ |
| 317 | - processTableMissDrop(install, table); | 304 | + processTableMissDrop(install, table, "Provisioned ether type table drop"); |
| 318 | 305 | ||
| 319 | /* Arp to controller */ | 306 | /* Arp to controller */ |
| 320 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 307 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
| ... | @@ -331,7 +318,7 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline { | ... | @@ -331,7 +318,7 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline { |
| 331 | .fromApp(appId) | 318 | .fromApp(appId) |
| 332 | .makePermanent() | 319 | .makePermanent() |
| 333 | .forTable(table).build(); | 320 | .forTable(table).build(); |
| 334 | - processFlowRule(install, rule); | 321 | + processFlowRule(install, rule, "Provisioned ether type table arp"); |
| 335 | 322 | ||
| 336 | /* IP to FIB_TABLE */ | 323 | /* IP to FIB_TABLE */ |
| 337 | selector = DefaultTrafficSelector.builder(); | 324 | selector = DefaultTrafficSelector.builder(); |
| ... | @@ -348,18 +335,18 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline { | ... | @@ -348,18 +335,18 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline { |
| 348 | .fromApp(appId) | 335 | .fromApp(appId) |
| 349 | .makePermanent() | 336 | .makePermanent() |
| 350 | .forTable(table).build(); | 337 | .forTable(table).build(); |
| 351 | - processFlowRule(install, rule); | 338 | + processFlowRule(install, rule, "Provisioned ether type table ip"); |
| 352 | } | 339 | } |
| 353 | 340 | ||
| 354 | private void processFibTable(boolean install) { | 341 | private void processFibTable(boolean install) { |
| 355 | /* Default action */ | 342 | /* Default action */ |
| 356 | - processTableMissDrop(install, FIB_TABLE); | 343 | + processTableMissDrop(install, FIB_TABLE, "Provisioned fib drop"); |
| 357 | } | 344 | } |
| 358 | 345 | ||
| 359 | private void processLocalTable(boolean install) { | 346 | private void processLocalTable(boolean install) { |
| 360 | int table = LOCAL_TABLE; | 347 | int table = LOCAL_TABLE; |
| 361 | /* Default action */ | 348 | /* Default action */ |
| 362 | - processTableMissDrop(install, table); | 349 | + processTableMissDrop(install, table, "Provisioned local table drop"); |
| 363 | 350 | ||
| 364 | /* Send all protocols to controller */ | 351 | /* Send all protocols to controller */ |
| 365 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 352 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
| ... | @@ -375,62 +362,8 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline { | ... | @@ -375,62 +362,8 @@ public class CorsaPipelineV3 extends OVSCorsaPipeline { |
| 375 | .fromApp(appId) | 362 | .fromApp(appId) |
| 376 | .makePermanent() | 363 | .makePermanent() |
| 377 | .forTable(table).build(); | 364 | .forTable(table).build(); |
| 378 | - processFlowRule(install, rule); | 365 | + processFlowRule(install, rule, "Provisioned ether type table to controller"); |
| 379 | - } | ||
| 380 | - | ||
| 381 | - /* Init helper: Apply flow rule */ | ||
| 382 | - private void processFlowRule(boolean install, FlowRule rule) { | ||
| 383 | - FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | ||
| 384 | - ops = install ? ops.add(rule) : ops.remove(rule); | ||
| 385 | - | ||
| 386 | - flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { | ||
| 387 | - @Override | ||
| 388 | - public void onSuccess(FlowRuleOperations ops) { | ||
| 389 | - log.info("Flow provision success: " + ops.toString() + ", " + rule.toString()); | ||
| 390 | - } | ||
| 391 | - | ||
| 392 | - @Override | ||
| 393 | - public void onError(FlowRuleOperations ops) { | ||
| 394 | - log.info("Flow provision error: " + ops.toString() + ", " + rule.toString()); | ||
| 395 | - } | ||
| 396 | - })); | ||
| 397 | - } | ||
| 398 | - | ||
| 399 | - /* Init helper: Table Miss = Drop */ | ||
| 400 | - private void processTableMissDrop(boolean install, int table) { | ||
| 401 | - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
| 402 | - | ||
| 403 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
| 404 | - treatment.drop(); | ||
| 405 | - | ||
| 406 | - FlowRule rule = DefaultFlowRule.builder() | ||
| 407 | - .forDevice(deviceId) | ||
| 408 | - .withSelector(selector.build()) | ||
| 409 | - .withTreatment(treatment.build()) | ||
| 410 | - .withPriority(DROP_PRIORITY) | ||
| 411 | - .fromApp(appId) | ||
| 412 | - .makePermanent() | ||
| 413 | - .forTable(table).build(); | ||
| 414 | - | ||
| 415 | - processFlowRule(install, rule); | ||
| 416 | } | 366 | } |
| 417 | 367 | ||
| 418 | - /* Init helper: Table Miss = GoTo */ | ||
| 419 | - private void processTableMissGoTo(boolean install, int table, int goTo) { | ||
| 420 | - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
| 421 | - | ||
| 422 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
| 423 | - treatment.transition(goTo); | ||
| 424 | - | ||
| 425 | - FlowRule rule = DefaultFlowRule.builder() | ||
| 426 | - .forDevice(deviceId) | ||
| 427 | - .withSelector(selector.build()) | ||
| 428 | - .withTreatment(treatment.build()) | ||
| 429 | - .withPriority(DROP_PRIORITY) | ||
| 430 | - .fromApp(appId) | ||
| 431 | - .makePermanent() | ||
| 432 | - .forTable(table).build(); | ||
| 433 | 368 | ||
| 434 | - processFlowRule(install, rule); | ||
| 435 | - } | ||
| 436 | } | 369 | } | ... | ... |
| 1 | +/* | ||
| 2 | + * Copyright 2014-2016 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.drivers.corsa; | ||
| 18 | + | ||
| 19 | +import org.onlab.packet.Ethernet; | ||
| 20 | +import org.onlab.packet.IPv4; | ||
| 21 | +import org.onlab.packet.VlanId; | ||
| 22 | +import org.onosproject.net.flow.DefaultFlowRule; | ||
| 23 | +import org.onosproject.net.flow.DefaultTrafficSelector; | ||
| 24 | +import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
| 25 | +import org.onosproject.net.flow.FlowRule; | ||
| 26 | +import org.onosproject.net.flow.TrafficSelector; | ||
| 27 | +import org.onosproject.net.flow.TrafficTreatment; | ||
| 28 | +import org.onosproject.net.flow.criteria.Criterion; | ||
| 29 | +import org.onosproject.net.flow.criteria.IPCriterion; | ||
| 30 | +import org.onosproject.net.flow.criteria.IPProtocolCriterion; | ||
| 31 | +import org.onosproject.net.flowobjective.ForwardingObjective; | ||
| 32 | +import org.onosproject.net.flowobjective.ObjectiveError; | ||
| 33 | +import org.slf4j.Logger; | ||
| 34 | + | ||
| 35 | +import java.util.Collection; | ||
| 36 | +import java.util.Collections; | ||
| 37 | + | ||
| 38 | +import static org.onosproject.net.flow.FlowRule.Builder; | ||
| 39 | +import static org.slf4j.LoggerFactory.getLogger; | ||
| 40 | + | ||
| 41 | +public class CorsaPipelineV39 extends CorsaPipelineV3 { | ||
| 42 | + | ||
| 43 | + private final Logger log = getLogger(getClass()); | ||
| 44 | + | ||
| 45 | + private static final Short NATIVE_VLAN = 4095; | ||
| 46 | + | ||
| 47 | + @Override | ||
| 48 | + public void initializePipeline() { | ||
| 49 | + | ||
| 50 | + processMeterTable(true); //Meter Table | ||
| 51 | + processPortBasedProtoTable(true); | ||
| 52 | + processVlanCheckTable(true); //Table 1 | ||
| 53 | + processVlanMacXlateTable(true); //Table 2 | ||
| 54 | + processVlanCircuitTable(true); //Table 3 | ||
| 55 | + processL3IFMacDATable(true); //Table 5 | ||
| 56 | + processEtherTable(true); //Table 6 | ||
| 57 | + //TODO: to be implemented for intents | ||
| 58 | + //processFibTable(true); //Table 7 | ||
| 59 | + //processLocalTable(true); //Table 9 | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + @Override | ||
| 63 | + protected void processVlanCheckTable(boolean install) { | ||
| 64 | + //FIXME: error | ||
| 65 | + processTableMissGoTo(true, VLAN_CHECK_TABLE, VLAN_MAC_XLATE_TABLE, "Provisioned vlan tagged"); | ||
| 66 | + //Tag untagged packets | ||
| 67 | + processUntaggedPackets(install); | ||
| 68 | + | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + private void processUntaggedPackets(boolean install) { | ||
| 72 | + | ||
| 73 | + deviceService.getPorts(deviceId).forEach(port -> { | ||
| 74 | + if (!port.number().isLogical()) { | ||
| 75 | + | ||
| 76 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder() | ||
| 77 | + .pushVlan().setVlanId(VlanId.vlanId(NATIVE_VLAN)) | ||
| 78 | + .transition(VLAN_MAC_XLATE_TABLE); | ||
| 79 | + | ||
| 80 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder() | ||
| 81 | + .matchVlanId(VlanId.NONE) | ||
| 82 | + .matchInPort(port.number()); | ||
| 83 | + | ||
| 84 | + Builder rule = DefaultFlowRule.builder() | ||
| 85 | + .forDevice(deviceId) | ||
| 86 | + .withTreatment(treatment.build()) | ||
| 87 | + .withSelector(selector.build()) | ||
| 88 | + .withPriority(CONTROLLER_PRIORITY) | ||
| 89 | + .fromApp(appId) | ||
| 90 | + .makePermanent() | ||
| 91 | + .forTable(VLAN_CHECK_TABLE); | ||
| 92 | + | ||
| 93 | + processFlowRule(install, rule.build(), "Provisioned vlan untagged packet table"); | ||
| 94 | + } | ||
| 95 | + }); | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + @Override | ||
| 99 | + protected void processVlanCircuitTable(boolean install) { | ||
| 100 | + //Default action | ||
| 101 | + processTableMissDrop(install, VLAN_CIRCUIT_TABLE, "Provisioned vlan circuit table drop"); | ||
| 102 | + //FIXME: it should be done only per port based when intent is installed | ||
| 103 | + //Manage untagged packets | ||
| 104 | + processRouterPacket(install); | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + private void processRouterPacket(boolean install) { | ||
| 108 | + | ||
| 109 | + deviceService.getPorts(deviceId).forEach(port -> { | ||
| 110 | + if (!port.number().isLogical()) { | ||
| 111 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder() | ||
| 112 | + .matchVlanId(VlanId.vlanId(NATIVE_VLAN)) | ||
| 113 | + .matchInPort(port.number()); | ||
| 114 | + | ||
| 115 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder() | ||
| 116 | + .setVlanPcp((byte) 0) | ||
| 117 | + .setQueue(0) | ||
| 118 | + .meter(defaultMeterId) | ||
| 119 | + .transition(L3_IF_MAC_DA_TABLE); | ||
| 120 | + | ||
| 121 | + FlowRule rule = DefaultFlowRule.builder() | ||
| 122 | + .forDevice(deviceId) | ||
| 123 | + .withSelector(selector.build()) | ||
| 124 | + .withTreatment(treatment.build()) | ||
| 125 | + .withPriority(CONTROLLER_PRIORITY) | ||
| 126 | + .fromApp(appId) | ||
| 127 | + .makePermanent() | ||
| 128 | + .forTable(VLAN_CIRCUIT_TABLE).build(); | ||
| 129 | + processFlowRule(install, rule, "Provisioned vlan circuit table"); | ||
| 130 | + } | ||
| 131 | + }); | ||
| 132 | + } | ||
| 133 | + | ||
| 134 | + @Override | ||
| 135 | + protected void processL3IFMacDATable(boolean install) { | ||
| 136 | + int table = L3_IF_MAC_DA_TABLE; | ||
| 137 | + | ||
| 138 | + //Default action | ||
| 139 | + processTableMissDrop(install, table, "Provisioned l3 table drop"); | ||
| 140 | + | ||
| 141 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
| 142 | + | ||
| 143 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder() | ||
| 144 | + .transition(ETHER_TABLE); | ||
| 145 | + | ||
| 146 | + FlowRule rule = DefaultFlowRule.builder() | ||
| 147 | + .forDevice(deviceId) | ||
| 148 | + .withSelector(selector.build()) | ||
| 149 | + .withTreatment(treatment.build()) | ||
| 150 | + .withPriority(1) | ||
| 151 | + .fromApp(appId) | ||
| 152 | + .makePermanent() | ||
| 153 | + .forTable(table).build(); | ||
| 154 | + processFlowRule(install, rule, "Provisioned l3 table"); | ||
| 155 | + } | ||
| 156 | + | ||
| 157 | + protected void processEtherTable(boolean install) { | ||
| 158 | + | ||
| 159 | + //Default action | ||
| 160 | + processTableMissDrop(install, ETHER_TABLE, "Provisioned ether type table drop"); | ||
| 161 | + | ||
| 162 | + //IP to FIB_TABLE | ||
| 163 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder() | ||
| 164 | + .matchEthType(Ethernet.TYPE_IPV4); | ||
| 165 | + | ||
| 166 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder().transition(FIB_TABLE); | ||
| 167 | + | ||
| 168 | + FlowRule rule = DefaultFlowRule.builder() | ||
| 169 | + .forDevice(deviceId) | ||
| 170 | + .withSelector(selector.build()) | ||
| 171 | + .withTreatment(treatment.build()) | ||
| 172 | + .withPriority(CONTROLLER_PRIORITY) | ||
| 173 | + .fromApp(appId) | ||
| 174 | + .makePermanent() | ||
| 175 | + .forTable(ETHER_TABLE).build(); | ||
| 176 | + processFlowRule(install, rule, "Provisioned ether type table ip"); | ||
| 177 | + } | ||
| 178 | + | ||
| 179 | + @Override | ||
| 180 | + protected Collection<FlowRule> processArpTraffic(ForwardingObjective fwd, Builder rule) { | ||
| 181 | + rule.forTable(PORT_BASED_PROTO_TABLE); | ||
| 182 | + rule.withPriority(255); | ||
| 183 | + return Collections.singletonList(rule.build()); | ||
| 184 | + } | ||
| 185 | + | ||
| 186 | + @Override | ||
| 187 | + protected Collection<FlowRule> processLinkDiscovery(ForwardingObjective fwd, Builder rule) { | ||
| 188 | + rule.forTable(PORT_BASED_PROTO_TABLE); | ||
| 189 | + rule.withPriority(255); | ||
| 190 | + return Collections.singletonList(rule.build()); | ||
| 191 | + } | ||
| 192 | + | ||
| 193 | + @Override | ||
| 194 | + protected Collection<FlowRule> processIpTraffic(ForwardingObjective fwd, Builder rule) { | ||
| 195 | + IPCriterion ipSrc = (IPCriterion) fwd.selector() | ||
| 196 | + .getCriterion(Criterion.Type.IPV4_SRC); | ||
| 197 | + if (ipSrc != null) { | ||
| 198 | + log.warn("Driver does not currently handle matching Src IP"); | ||
| 199 | + fail(fwd, ObjectiveError.UNSUPPORTED); | ||
| 200 | + return Collections.emptySet(); | ||
| 201 | + } | ||
| 202 | + IPCriterion ipDst = (IPCriterion) fwd.selector() | ||
| 203 | + .getCriterion(Criterion.Type.IPV4_DST); | ||
| 204 | + if (ipDst != null) { | ||
| 205 | + log.error("Driver handles Dst IP matching as specific forwarding " | ||
| 206 | + + "objective, not versatile"); | ||
| 207 | + fail(fwd, ObjectiveError.UNSUPPORTED); | ||
| 208 | + return Collections.emptySet(); | ||
| 209 | + } | ||
| 210 | + IPProtocolCriterion ipProto = (IPProtocolCriterion) fwd.selector() | ||
| 211 | + .getCriterion(Criterion.Type.IP_PROTO); | ||
| 212 | + if (ipProto != null && ipProto.protocol() == IPv4.PROTOCOL_TCP) { | ||
| 213 | + log.warn("Driver automatically punts all packets reaching the " | ||
| 214 | + + "LOCAL table to the controller"); | ||
| 215 | + pass(fwd); | ||
| 216 | + return Collections.emptySet(); | ||
| 217 | + } | ||
| 218 | + return Collections.emptySet(); | ||
| 219 | + } | ||
| 220 | +} |
| ... | @@ -13,7 +13,7 @@ | ... | @@ -13,7 +13,7 @@ |
| 13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. | 14 | * limitations under the License. |
| 15 | */ | 15 | */ |
| 16 | -package org.onosproject.driver.handshaker; | 16 | +package org.onosproject.drivers.corsa; |
| 17 | 17 | ||
| 18 | import org.onosproject.net.meter.MeterId; | 18 | import org.onosproject.net.meter.MeterId; |
| 19 | import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch; | 19 | import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch; | ... | ... |
| 1 | +/* | ||
| 2 | + * Copyright 2014-2016 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.drivers.corsa; | ||
| 17 | + | ||
| 18 | +import org.onlab.packet.Ethernet; | ||
| 19 | +import org.onlab.packet.IPv4; | ||
| 20 | +import org.onlab.packet.MacAddress; | ||
| 21 | +import org.onlab.packet.VlanId; | ||
| 22 | +import org.onosproject.net.flow.DefaultFlowRule; | ||
| 23 | +import org.onosproject.net.flow.DefaultTrafficSelector; | ||
| 24 | +import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
| 25 | +import org.onosproject.net.flow.FlowRule; | ||
| 26 | +import org.onosproject.net.flow.FlowRuleOperations; | ||
| 27 | +import org.onosproject.net.flow.TrafficSelector; | ||
| 28 | +import org.onosproject.net.flow.TrafficTreatment; | ||
| 29 | +import org.onosproject.net.flow.criteria.Criterion; | ||
| 30 | +import org.onosproject.net.flow.criteria.EthCriterion; | ||
| 31 | +import org.onosproject.net.flow.criteria.IPCriterion; | ||
| 32 | +import org.onosproject.net.flow.criteria.IPProtocolCriterion; | ||
| 33 | +import org.onosproject.net.flow.criteria.PortCriterion; | ||
| 34 | +import org.onosproject.net.flow.criteria.VlanIdCriterion; | ||
| 35 | +import org.onosproject.net.flowobjective.FilteringObjective; | ||
| 36 | +import org.onosproject.net.flowobjective.ForwardingObjective; | ||
| 37 | +import org.onosproject.net.flowobjective.ObjectiveError; | ||
| 38 | +import org.slf4j.Logger; | ||
| 39 | + | ||
| 40 | +import java.util.Collection; | ||
| 41 | +import java.util.Collections; | ||
| 42 | + | ||
| 43 | +import static org.slf4j.LoggerFactory.getLogger; | ||
| 44 | + | ||
| 45 | +/** | ||
| 46 | + * OpenvSwitch emulation of the Corsa pipeline handler. | ||
| 47 | + */ | ||
| 48 | +public class OvsCorsaPipeline extends AbstractCorsaPipeline { | ||
| 49 | + | ||
| 50 | + private final Logger log = getLogger(getClass()); | ||
| 51 | + | ||
| 52 | + protected static final int MAC_TABLE = 0; | ||
| 53 | + protected static final int VLAN_MPLS_TABLE = 1; | ||
| 54 | + protected static final int VLAN_TABLE = 2; | ||
| 55 | + //protected static final int MPLS_TABLE = 3; | ||
| 56 | + protected static final int ETHER_TABLE = 4; | ||
| 57 | + protected static final int COS_MAP_TABLE = 5; | ||
| 58 | + protected static final int FIB_TABLE = 6; | ||
| 59 | + protected static final int LOCAL_TABLE = 9; | ||
| 60 | + | ||
| 61 | + @Override | ||
| 62 | + protected Collection<FlowRule> processArpTraffic(ForwardingObjective fwd, FlowRule.Builder rule) { | ||
| 63 | + log.warn("Driver automatically handles ARP packets by punting to controller " | ||
| 64 | + + " from ETHER table"); | ||
| 65 | + pass(fwd); | ||
| 66 | + return Collections.emptyList(); | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + @Override | ||
| 70 | + protected Collection<FlowRule> processLinkDiscovery(ForwardingObjective fwd, FlowRule.Builder rule) { | ||
| 71 | + log.warn("Driver currently does not currently handle LLDP packets"); | ||
| 72 | + fail(fwd, ObjectiveError.UNSUPPORTED); | ||
| 73 | + return Collections.emptyList(); | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + @Override | ||
| 77 | + protected Collection<FlowRule> processIpTraffic(ForwardingObjective fwd, FlowRule.Builder rule) { | ||
| 78 | + IPCriterion ipSrc = (IPCriterion) fwd.selector() | ||
| 79 | + .getCriterion(Criterion.Type.IPV4_SRC); | ||
| 80 | + if (ipSrc != null) { | ||
| 81 | + log.warn("Driver does not currently handle matching Src IP"); | ||
| 82 | + fail(fwd, ObjectiveError.UNSUPPORTED); | ||
| 83 | + return Collections.emptySet(); | ||
| 84 | + } | ||
| 85 | + IPCriterion ipDst = (IPCriterion) fwd.selector() | ||
| 86 | + .getCriterion(Criterion.Type.IPV4_DST); | ||
| 87 | + if (ipDst != null) { | ||
| 88 | + log.error("Driver handles Dst IP matching as specific forwarding " | ||
| 89 | + + "objective, not versatile"); | ||
| 90 | + fail(fwd, ObjectiveError.UNSUPPORTED); | ||
| 91 | + return Collections.emptySet(); | ||
| 92 | + } | ||
| 93 | + IPProtocolCriterion ipProto = (IPProtocolCriterion) fwd.selector() | ||
| 94 | + .getCriterion(Criterion.Type.IP_PROTO); | ||
| 95 | + if (ipProto != null && ipProto.protocol() == IPv4.PROTOCOL_TCP) { | ||
| 96 | + log.warn("Driver automatically punts all packets reaching the " | ||
| 97 | + + "LOCAL table to the controller"); | ||
| 98 | + pass(fwd); | ||
| 99 | + return Collections.emptySet(); | ||
| 100 | + } | ||
| 101 | + return Collections.emptySet(); | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + @Override | ||
| 105 | + protected FlowRule.Builder processSpecificRoutingRule(FlowRule.Builder rb) { | ||
| 106 | + return rb.forTable(FIB_TABLE); | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + @Override | ||
| 110 | + protected FlowRule.Builder processIpFilter(FilteringObjective filt, IPCriterion ip, PortCriterion port) { | ||
| 111 | + log.debug("adding rule for IP: {}", ip.ip()); | ||
| 112 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
| 113 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
| 114 | + selector.matchEthType(Ethernet.TYPE_IPV4); | ||
| 115 | + selector.matchIPDst(ip.ip()); | ||
| 116 | + treatment.transition(LOCAL_TABLE); | ||
| 117 | + return DefaultFlowRule.builder() | ||
| 118 | + .withSelector(selector.build()) | ||
| 119 | + .withTreatment(treatment.build()) | ||
| 120 | + .withPriority(HIGHEST_PRIORITY) | ||
| 121 | + .makePermanent() | ||
| 122 | + .forTable(FIB_TABLE); | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | + @Override | ||
| 126 | + protected FlowRule.Builder processVlanFiler(FilteringObjective filt, VlanIdCriterion vlan, PortCriterion port) { | ||
| 127 | + log.debug("adding rule for VLAN: {}", vlan.vlanId()); | ||
| 128 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
| 129 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
| 130 | + selector.matchVlanId(vlan.vlanId()); | ||
| 131 | + selector.matchInPort(port.port()); | ||
| 132 | + treatment.transition(ETHER_TABLE); | ||
| 133 | + treatment.deferred().popVlan(); | ||
| 134 | + return DefaultFlowRule.builder() | ||
| 135 | + .forDevice(deviceId) | ||
| 136 | + .withSelector(selector.build()) | ||
| 137 | + .withTreatment(treatment.build()) | ||
| 138 | + .withPriority(CONTROLLER_PRIORITY) | ||
| 139 | + .makePermanent() | ||
| 140 | + .forTable(VLAN_TABLE); | ||
| 141 | + } | ||
| 142 | + | ||
| 143 | + | ||
| 144 | + protected FlowRule.Builder processEthFiler(FilteringObjective filt, EthCriterion eth, PortCriterion port) { | ||
| 145 | + log.debug("adding rule for MAC: {}", eth.mac()); | ||
| 146 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
| 147 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
| 148 | + selector.matchEthDst(eth.mac()); | ||
| 149 | + treatment.transition(VLAN_MPLS_TABLE); | ||
| 150 | + return DefaultFlowRule.builder() | ||
| 151 | + .forDevice(deviceId) | ||
| 152 | + .withSelector(selector.build()) | ||
| 153 | + .withTreatment(treatment.build()) | ||
| 154 | + .withPriority(CONTROLLER_PRIORITY) | ||
| 155 | + .makePermanent() | ||
| 156 | + .forTable(MAC_TABLE); | ||
| 157 | + } | ||
| 158 | + | ||
| 159 | + @Override | ||
| 160 | + protected void initializePipeline() { | ||
| 161 | + processMacTable(true); | ||
| 162 | + processVlanMplsTable(true); | ||
| 163 | + processVlanTable(true); | ||
| 164 | + processEtherTable(true); | ||
| 165 | + processCosTable(true); | ||
| 166 | + processFibTable(true); | ||
| 167 | + processLocalTable(true); | ||
| 168 | + } | ||
| 169 | + | ||
| 170 | + private void processMacTable(boolean install) { | ||
| 171 | + TrafficSelector.Builder selector; | ||
| 172 | + TrafficTreatment.Builder treatment; | ||
| 173 | + | ||
| 174 | + // Bcast rule | ||
| 175 | + selector = DefaultTrafficSelector.builder(); | ||
| 176 | + treatment = DefaultTrafficTreatment.builder(); | ||
| 177 | + | ||
| 178 | + selector.matchEthDst(MacAddress.BROADCAST); | ||
| 179 | + treatment.transition(VLAN_MPLS_TABLE); | ||
| 180 | + | ||
| 181 | + FlowRule rule = DefaultFlowRule.builder() | ||
| 182 | + .forDevice(deviceId) | ||
| 183 | + .withSelector(selector.build()) | ||
| 184 | + .withTreatment(treatment.build()) | ||
| 185 | + .withPriority(CONTROLLER_PRIORITY) | ||
| 186 | + .fromApp(appId) | ||
| 187 | + .makePermanent() | ||
| 188 | + .forTable(MAC_TABLE).build(); | ||
| 189 | + processFlowRule(true, rule, "Provisioned mac table transition"); | ||
| 190 | + | ||
| 191 | + //Drop rule | ||
| 192 | + processTableMissDrop(true, MAC_TABLE, "Provisioned mac table drop action"); | ||
| 193 | + | ||
| 194 | + } | ||
| 195 | + | ||
| 196 | + protected void processVlanMplsTable(boolean install) { | ||
| 197 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
| 198 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment | ||
| 199 | + .builder(); | ||
| 200 | + FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | ||
| 201 | + FlowRule rule; | ||
| 202 | + | ||
| 203 | + selector.matchVlanId(VlanId.ANY); | ||
| 204 | + treatment.transition(VLAN_TABLE); | ||
| 205 | + | ||
| 206 | + rule = DefaultFlowRule.builder() | ||
| 207 | + .forDevice(deviceId) | ||
| 208 | + .withSelector(selector.build()) | ||
| 209 | + .withTreatment(treatment.build()) | ||
| 210 | + .withPriority(CONTROLLER_PRIORITY) | ||
| 211 | + .fromApp(appId) | ||
| 212 | + .makePermanent() | ||
| 213 | + .forTable(VLAN_MPLS_TABLE).build(); | ||
| 214 | + | ||
| 215 | + processFlowRule(true, rule, "Provisioned vlan/mpls table"); | ||
| 216 | + } | ||
| 217 | + | ||
| 218 | + private void processVlanTable(boolean install) { | ||
| 219 | + processTableMissDrop(true, VLAN_TABLE, "Provisioned vlan table"); | ||
| 220 | + } | ||
| 221 | + | ||
| 222 | + private void processEtherTable(boolean install) { | ||
| 223 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder() | ||
| 224 | + .matchEthType(Ethernet.TYPE_ARP); | ||
| 225 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment | ||
| 226 | + .builder() | ||
| 227 | + .punt(); | ||
| 228 | + | ||
| 229 | + FlowRule rule = DefaultFlowRule.builder() | ||
| 230 | + .forDevice(deviceId) | ||
| 231 | + .withSelector(selector.build()) | ||
| 232 | + .withTreatment(treatment.build()) | ||
| 233 | + .withPriority(CONTROLLER_PRIORITY) | ||
| 234 | + .fromApp(appId) | ||
| 235 | + .makePermanent() | ||
| 236 | + .forTable(ETHER_TABLE).build(); | ||
| 237 | + | ||
| 238 | + processFlowRule(true, rule, "Provisioned ether table"); | ||
| 239 | + selector = DefaultTrafficSelector.builder() | ||
| 240 | + .matchEthType(Ethernet.TYPE_IPV4); | ||
| 241 | + treatment = DefaultTrafficTreatment.builder() | ||
| 242 | + .transition(COS_MAP_TABLE); | ||
| 243 | + | ||
| 244 | + rule = DefaultFlowRule.builder() | ||
| 245 | + .forDevice(deviceId) | ||
| 246 | + .withPriority(CONTROLLER_PRIORITY) | ||
| 247 | + .withSelector(selector.build()) | ||
| 248 | + .withTreatment(treatment.build()) | ||
| 249 | + .fromApp(appId) | ||
| 250 | + .makePermanent() | ||
| 251 | + .forTable(ETHER_TABLE).build(); | ||
| 252 | + processFlowRule(true, rule, "Provisioned ether table"); | ||
| 253 | + | ||
| 254 | + //Drop rule | ||
| 255 | + processTableMissDrop(true, VLAN_TABLE, "Provisioned ether table"); | ||
| 256 | + | ||
| 257 | + } | ||
| 258 | + | ||
| 259 | + private void processCosTable(boolean install) { | ||
| 260 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment | ||
| 261 | + .builder() | ||
| 262 | + .transition(FIB_TABLE); | ||
| 263 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
| 264 | + | ||
| 265 | + FlowRule rule = DefaultFlowRule.builder() | ||
| 266 | + .forDevice(deviceId) | ||
| 267 | + .withSelector(selector.build()) | ||
| 268 | + .withTreatment(treatment.build()) | ||
| 269 | + .withPriority(DROP_PRIORITY) | ||
| 270 | + .fromApp(appId) | ||
| 271 | + .makePermanent() | ||
| 272 | + .forTable(COS_MAP_TABLE).build(); | ||
| 273 | + processFlowRule(true, rule, "Provisioned cos table"); | ||
| 274 | + | ||
| 275 | + } | ||
| 276 | + | ||
| 277 | + private void processFibTable(boolean install) { | ||
| 278 | + processTableMissDrop(true, FIB_TABLE, "Provisioned FIB table"); | ||
| 279 | + } | ||
| 280 | + | ||
| 281 | + private void processLocalTable(boolean install) { | ||
| 282 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
| 283 | + | ||
| 284 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment | ||
| 285 | + .builder() | ||
| 286 | + .punt(); | ||
| 287 | + | ||
| 288 | + FlowRule rule = DefaultFlowRule.builder() | ||
| 289 | + .forDevice(deviceId) | ||
| 290 | + .withSelector(selector.build()) | ||
| 291 | + .withTreatment(treatment.build()) | ||
| 292 | + .withPriority(CONTROLLER_PRIORITY) | ||
| 293 | + .fromApp(appId) | ||
| 294 | + .makePermanent() | ||
| 295 | + .forTable(LOCAL_TABLE).build(); | ||
| 296 | + | ||
| 297 | + processFlowRule(true, rule, "Provisioned Local table"); | ||
| 298 | + } | ||
| 299 | + | ||
| 300 | + | ||
| 301 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2014-2016 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +/** | ||
| 18 | + * Corsa drivers. | ||
| 19 | + */ | ||
| 20 | +package org.onosproject.drivers.corsa; | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<!-- | ||
| 3 | + ~ Copyright 2014-2016 Open Networking Laboratory | ||
| 4 | + ~ | ||
| 5 | + ~ Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | + ~ you may not use this file except in compliance with the License. | ||
| 7 | + ~ You may obtain a copy of the License at | ||
| 8 | + ~ | ||
| 9 | + ~ http://www.apache.org/licenses/LICENSE-2.0 | ||
| 10 | + ~ | ||
| 11 | + ~ Unless required by applicable law or agreed to in writing, software | ||
| 12 | + ~ distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | + ~ See the License for the specific language governing permissions and | ||
| 15 | + ~ limitations under the License. | ||
| 16 | + --> | ||
| 17 | +<drivers> | ||
| 18 | + <driver name="ovs-corsa" extends="ovs" | ||
| 19 | + manufacturer="Corsa" hwVersion="emulation" swVersion="0.0.0"> | ||
| 20 | + <behaviour api="org.onosproject.net.behaviour.Pipeliner" | ||
| 21 | + impl="org.onosproject.drivers.corsa.OvsCorsaPipeline"/> | ||
| 22 | + </driver> | ||
| 23 | + <driver name="corsa" | ||
| 24 | + manufacturer="Corsa" hwVersion="Corsa Element" swVersion="2.3.1"> | ||
| 25 | + <behaviour api="org.onosproject.net.behaviour.Pipeliner" | ||
| 26 | + impl="org.onosproject.drivers.corsa.CorsaPipelineV1"/> | ||
| 27 | + <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver" | ||
| 28 | + impl="org.onosproject.drivers.corsa.CorsaSwitchHandshaker"/> | ||
| 29 | + </driver> | ||
| 30 | + <driver name="corsa-v1" | ||
| 31 | + manufacturer="Corsa" hwVersion="Corsa Element" swVersion="2.3.1"> | ||
| 32 | + <behaviour api="org.onosproject.net.behaviour.Pipeliner" | ||
| 33 | + impl="org.onosproject.drivers.corsa.CorsaPipelineV1"/> | ||
| 34 | + <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver" | ||
| 35 | + impl="org.onosproject.drivers.corsa.CorsaSwitchHandshaker"/> | ||
| 36 | + </driver> | ||
| 37 | + <driver name="corsa-v3" | ||
| 38 | + manufacturer="Corsa" hwVersion="Corsa Element" swVersion="2.3.1"> | ||
| 39 | + <behaviour api="org.onosproject.net.behaviour.Pipeliner" | ||
| 40 | + impl="org.onosproject.drivers.corsa.CorsaPipelineV3"/> | ||
| 41 | + <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver" | ||
| 42 | + impl="org.onosproject.drivers.corsa.CorsaSwitchHandshaker"/> | ||
| 43 | + </driver> | ||
| 44 | + <driver name="corsa-v39" | ||
| 45 | + manufacturer="Corsa" hwVersion="CDP6420-A00" swVersion="corsa-ovs-datapath 1.4.88"> | ||
| 46 | + <behaviour api="org.onosproject.net.behaviour.Pipeliner" | ||
| 47 | + impl="org.onosproject.drivers.corsa.CorsaPipelineV39"/> | ||
| 48 | + <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver" | ||
| 49 | + impl="org.onosproject.drivers.corsa.CorsaSwitchHandshaker"/> | ||
| 50 | + </driver> | ||
| 51 | +</drivers> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| ... | @@ -39,11 +39,6 @@ | ... | @@ -39,11 +39,6 @@ |
| 39 | <behaviour api="org.onosproject.net.behaviour.MplsQuery" | 39 | <behaviour api="org.onosproject.net.behaviour.MplsQuery" |
| 40 | impl="org.onosproject.driver.query.FullMplsAvailable" /> | 40 | impl="org.onosproject.driver.query.FullMplsAvailable" /> |
| 41 | </driver> | 41 | </driver> |
| 42 | - <driver name="ovs-corsa" extends="ovs" | ||
| 43 | - manufacturer="Corsa" hwVersion="emulation" swVersion="0.0.0"> | ||
| 44 | - <behaviour api="org.onosproject.net.behaviour.Pipeliner" | ||
| 45 | - impl="org.onosproject.driver.pipeline.OVSCorsaPipeline"/> | ||
| 46 | - </driver> | ||
| 47 | <!-- Emulation of the spring-open pipeline using a CPqD OF 1.3 software switch. | 42 | <!-- Emulation of the spring-open pipeline using a CPqD OF 1.3 software switch. |
| 48 | ~ This driver is the default driver assigned to the CPqD switch. | 43 | ~ This driver is the default driver assigned to the CPqD switch. |
| 49 | --> | 44 | --> |
| ... | @@ -67,27 +62,6 @@ | ... | @@ -67,27 +62,6 @@ |
| 67 | <behaviour api="org.onosproject.net.behaviour.LambdaQuery" | 62 | <behaviour api="org.onosproject.net.behaviour.LambdaQuery" |
| 68 | impl="org.onosproject.driver.query.LincOELambdaQuery"/> | 63 | impl="org.onosproject.driver.query.LincOELambdaQuery"/> |
| 69 | </driver> | 64 | </driver> |
| 70 | - <driver name="corsa" | ||
| 71 | - manufacturer="Corsa" hwVersion="Corsa Element" swVersion="2.3.1"> | ||
| 72 | - <behaviour api="org.onosproject.net.behaviour.Pipeliner" | ||
| 73 | - impl="org.onosproject.driver.pipeline.CorsaPipeline"/> | ||
| 74 | - <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver" | ||
| 75 | - impl="org.onosproject.driver.handshaker.CorsaSwitchHandshaker"/> | ||
| 76 | - </driver> | ||
| 77 | - <driver name="corsa-v1" | ||
| 78 | - manufacturer="Corsa" hwVersion="Corsa Element" swVersion="2.3.1"> | ||
| 79 | - <behaviour api="org.onosproject.net.behaviour.Pipeliner" | ||
| 80 | - impl="org.onosproject.driver.pipeline.CorsaPipeline"/> | ||
| 81 | - <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver" | ||
| 82 | - impl="org.onosproject.driver.handshaker.CorsaSwitchHandshaker"/> | ||
| 83 | - </driver> | ||
| 84 | - <driver name="corsa-v3" | ||
| 85 | - manufacturer="Corsa" hwVersion="Corsa Element" swVersion="2.3.1"> | ||
| 86 | - <behaviour api="org.onosproject.net.behaviour.Pipeliner" | ||
| 87 | - impl="org.onosproject.driver.pipeline.CorsaPipelineV3"/> | ||
| 88 | - <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver" | ||
| 89 | - impl="org.onosproject.driver.handshaker.CorsaSwitchHandshaker"/> | ||
| 90 | - </driver> | ||
| 91 | <driver name="ofdpa" extends="default" | 65 | <driver name="ofdpa" extends="default" |
| 92 | manufacturer="Broadcom Corp." hwVersion="OF-DPA.*" swVersion="OF-DPA.*"> | 66 | manufacturer="Broadcom Corp." hwVersion="OF-DPA.*" swVersion="OF-DPA.*"> |
| 93 | <behaviour api="org.onosproject.net.behaviour.Pipeliner" | 67 | <behaviour api="org.onosproject.net.behaviour.Pipeliner" | ... | ... |
| ... | @@ -42,6 +42,7 @@ | ... | @@ -42,6 +42,7 @@ |
| 42 | <module>lumentum</module> | 42 | <module>lumentum</module> |
| 43 | <module>bti</module> | 43 | <module>bti</module> |
| 44 | <module>bmv2</module> | 44 | <module>bmv2</module> |
| 45 | + <module>corsa</module> | ||
| 45 | </modules> | 46 | </modules> |
| 46 | 47 | ||
| 47 | <!--<properties> | 48 | <!--<properties> | ... | ... |
-
Please register or login to post a comment