lishuai
Committed by Gerrit Code Review

[ONOS-3514] Add L3 flows for Classifier table, ARP table, L3forward

table, DNAT table and SNAT table.

Change-Id: Idb7f7343e33ce01c2d7aa9935a6deef858a2546c
...@@ -21,6 +21,7 @@ import java.util.Collection; ...@@ -21,6 +21,7 @@ import java.util.Collection;
21 import java.util.Collections; 21 import java.util.Collections;
22 22
23 import org.onlab.osgi.ServiceDirectory; 23 import org.onlab.osgi.ServiceDirectory;
24 +import org.onlab.packet.EthType.EtherType;
24 import org.onosproject.core.ApplicationId; 25 import org.onosproject.core.ApplicationId;
25 import org.onosproject.core.CoreService; 26 import org.onosproject.core.CoreService;
26 import org.onosproject.net.DeviceId; 27 import org.onosproject.net.DeviceId;
...@@ -36,6 +37,7 @@ import org.onosproject.net.flow.FlowRuleOperationsContext; ...@@ -36,6 +37,7 @@ import org.onosproject.net.flow.FlowRuleOperationsContext;
36 import org.onosproject.net.flow.FlowRuleService; 37 import org.onosproject.net.flow.FlowRuleService;
37 import org.onosproject.net.flow.TrafficSelector; 38 import org.onosproject.net.flow.TrafficSelector;
38 import org.onosproject.net.flow.TrafficTreatment; 39 import org.onosproject.net.flow.TrafficTreatment;
40 +import org.onosproject.net.flow.criteria.Criteria;
39 import org.onosproject.net.flow.criteria.Criterion.Type; 41 import org.onosproject.net.flow.criteria.Criterion.Type;
40 import org.onosproject.net.flow.instructions.Instructions; 42 import org.onosproject.net.flow.instructions.Instructions;
41 import org.onosproject.net.flowobjective.FilteringObjective; 43 import org.onosproject.net.flowobjective.FilteringObjective;
...@@ -63,6 +65,10 @@ public class OpenVSwitchPipeline extends DefaultSingleTablePipeline ...@@ -63,6 +65,10 @@ public class OpenVSwitchPipeline extends DefaultSingleTablePipeline
63 protected DeviceService deviceService; 65 protected DeviceService deviceService;
64 private static final int TIME_OUT = 0; 66 private static final int TIME_OUT = 0;
65 private static final int CLASSIFIER_TABLE = 0; 67 private static final int CLASSIFIER_TABLE = 0;
68 + private static final int ARP_TABLE = 10;
69 + private static final int DNAT_TABLE = 20;
70 + private static final int L3FWD_TABLE = 30;
71 + private static final int SNAT_TABLE = 40;
66 private static final int MAC_TABLE = 50; 72 private static final int MAC_TABLE = 50;
67 private static final int TABLE_MISS_PRIORITY = 0; 73 private static final int TABLE_MISS_PRIORITY = 0;
68 74
...@@ -131,6 +137,10 @@ public class OpenVSwitchPipeline extends DefaultSingleTablePipeline ...@@ -131,6 +137,10 @@ public class OpenVSwitchPipeline extends DefaultSingleTablePipeline
131 137
132 private void initializePipeline() { 138 private void initializePipeline() {
133 processClassifierTable(true); 139 processClassifierTable(true);
140 + processArpTable(true);
141 + processDnatTable(true);
142 + processL3fwdTable(true);
143 + processSnatTable(true);
134 processMacTable(true); 144 processMacTable(true);
135 } 145 }
136 146
...@@ -150,6 +160,70 @@ public class OpenVSwitchPipeline extends DefaultSingleTablePipeline ...@@ -150,6 +160,70 @@ public class OpenVSwitchPipeline extends DefaultSingleTablePipeline
150 applyRules(install, rule); 160 applyRules(install, rule);
151 } 161 }
152 162
163 + private void processArpTable(boolean install) {
164 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
165 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
166 +
167 + treatment.transition(MAC_TABLE);
168 +
169 + FlowRule rule;
170 + rule = DefaultFlowRule.builder().forDevice(deviceId)
171 + .withSelector(selector.build())
172 + .withTreatment(treatment.build())
173 + .withPriority(TABLE_MISS_PRIORITY).fromApp(appId)
174 + .makePermanent().forTable(ARP_TABLE).build();
175 +
176 + applyRules(install, rule);
177 + }
178 +
179 + private void processDnatTable(boolean install) {
180 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
181 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
182 +
183 + treatment.transition(MAC_TABLE);
184 +
185 + FlowRule rule;
186 + rule = DefaultFlowRule.builder().forDevice(deviceId)
187 + .withSelector(selector.build())
188 + .withTreatment(treatment.build())
189 + .withPriority(TABLE_MISS_PRIORITY).fromApp(appId)
190 + .makePermanent().forTable(DNAT_TABLE).build();
191 +
192 + applyRules(install, rule);
193 + }
194 +
195 + private void processL3fwdTable(boolean install) {
196 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
197 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
198 +
199 + treatment.transition(SNAT_TABLE);
200 +
201 + FlowRule rule;
202 + rule = DefaultFlowRule.builder().forDevice(deviceId)
203 + .withSelector(selector.build())
204 + .withTreatment(treatment.build())
205 + .withPriority(TABLE_MISS_PRIORITY).fromApp(appId)
206 + .makePermanent().forTable(L3FWD_TABLE).build();
207 +
208 + applyRules(install, rule);
209 + }
210 +
211 + private void processSnatTable(boolean install) {
212 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
213 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
214 +
215 + treatment.transition(MAC_TABLE);
216 +
217 + FlowRule rule;
218 + rule = DefaultFlowRule.builder().forDevice(deviceId)
219 + .withSelector(selector.build())
220 + .withTreatment(treatment.build())
221 + .withPriority(TABLE_MISS_PRIORITY).fromApp(appId)
222 + .makePermanent().forTable(SNAT_TABLE).build();
223 +
224 + applyRules(install, rule);
225 + }
226 +
153 private void processMacTable(boolean install) { 227 private void processMacTable(boolean install) {
154 TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); 228 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
155 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); 229 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
...@@ -213,16 +287,80 @@ public class OpenVSwitchPipeline extends DefaultSingleTablePipeline ...@@ -213,16 +287,80 @@ public class OpenVSwitchPipeline extends DefaultSingleTablePipeline
213 if (fwd.permanent()) { 287 if (fwd.permanent()) {
214 ruleBuilder.makePermanent(); 288 ruleBuilder.makePermanent();
215 } 289 }
216 - if (selector.getCriterion(Type.ETH_DST) != null 290 + Integer transition = null;
291 + Integer forTable = null;
292 + // MAC table flow rules
293 + if ((selector.getCriterion(Type.TUNNEL_ID) != null && selector
294 + .getCriterion(Type.ETH_DST) != null)
217 || tb.allInstructions().contains(Instructions.createDrop())) { 295 || tb.allInstructions().contains(Instructions.createDrop())) {
218 - ruleBuilder.withTreatment(tb); 296 + forTable = MAC_TABLE;
219 - ruleBuilder.forTable(MAC_TABLE); 297 + return reassemblyFlowRule(ruleBuilder, tb, transition, forTable);
220 - } else { 298 + }
221 - TrafficTreatment.Builder newTraffic = DefaultTrafficTreatment.builder(); 299 + // CLASSIFIER table flow rules
300 + if (selector.getCriterion(Type.IN_PORT) != null) {
301 + forTable = CLASSIFIER_TABLE;
302 + if (selector.getCriterion(Type.ETH_SRC) != null
303 + && selector.getCriterion(Type.ETH_DST) != null) {
304 + transition = L3FWD_TABLE;
305 + } else if (selector.getCriterion(Type.ETH_SRC) != null
306 + || selector.getCriterion(Type.TUNNEL_ID) != null) {
307 + transition = MAC_TABLE;
308 + } else if (selector.getCriterion(Type.IPV4_DST) != null) {
309 + transition = DNAT_TABLE;
310 + }
311 + return reassemblyFlowRule(ruleBuilder, tb, transition, forTable);
312 + }
313 + // ARP table flow rules
314 + if (selector.getCriterion(Type.ETH_TYPE) != null
315 + && selector.getCriterion(Type.ETH_TYPE).equals(Criteria
316 + .matchEthType(EtherType.ARP.ethType().toShort()))) {
317 + // CLASSIFIER table arp flow rules
318 + if (selector.getCriterion(Type.TUNNEL_ID) == null) {
319 + transition = ARP_TABLE;
320 + forTable = CLASSIFIER_TABLE;
321 + return reassemblyFlowRule(ruleBuilder, tb, transition, forTable);
322 + }
323 + forTable = ARP_TABLE;
324 + return reassemblyFlowRule(ruleBuilder, tb, transition, forTable);
325 + }
326 + // L3FWD table flow rules
327 + if (selector.getCriterion(Type.TUNNEL_ID) != null
328 + && selector.getCriterion(Type.IPV4_DST) != null) {
329 + transition = MAC_TABLE;
330 + forTable = L3FWD_TABLE;
331 + return reassemblyFlowRule(ruleBuilder, tb, transition, forTable);
332 + }
333 + // DNAT table flow rules
334 + if (selector.getCriterion(Type.IPV4_DST) != null) {
335 + transition = L3FWD_TABLE;
336 + forTable = DNAT_TABLE;
337 + return reassemblyFlowRule(ruleBuilder, tb, transition, forTable);
338 + }
339 + // SNAT table flow rules
340 + if (selector.getCriterion(Type.TUNNEL_ID) != null
341 + && selector.getCriterion(Type.IPV4_SRC) != null) {
342 + transition = MAC_TABLE;
343 + forTable = SNAT_TABLE;
344 + return reassemblyFlowRule(ruleBuilder, tb, transition, forTable);
345 + }
346 + return Collections.singletonList(ruleBuilder.build());
347 + }
348 +
349 + private Collection<FlowRule> reassemblyFlowRule(FlowRule.Builder ruleBuilder,
350 + TrafficTreatment tb,
351 + Integer transition,
352 + Integer forTable) {
353 + if (transition != null) {
354 + TrafficTreatment.Builder newTraffic = DefaultTrafficTreatment
355 + .builder();
222 tb.allInstructions().forEach(t -> newTraffic.add(t)); 356 tb.allInstructions().forEach(t -> newTraffic.add(t));
223 - newTraffic.transition(MAC_TABLE); 357 + newTraffic.transition(transition);
224 ruleBuilder.withTreatment(newTraffic.build()); 358 ruleBuilder.withTreatment(newTraffic.build());
225 - ruleBuilder.forTable(CLASSIFIER_TABLE); 359 + } else {
360 + ruleBuilder.withTreatment(tb);
361 + }
362 + if (forTable != null) {
363 + ruleBuilder.forTable(forTable);
226 } 364 }
227 return Collections.singletonList(ruleBuilder.build()); 365 return Collections.singletonList(ruleBuilder.build());
228 } 366 }
......