Brian O'Connor

ONOS-4383 Updating traffic selector for {MP2SP,SP2MP}IntentCompilers

Apply egress action to ingress selector for non-ingress devices

Change-Id: I98b4c591d09cc4b5d0e0ff89eaeac44ba07e6326
...@@ -18,7 +18,6 @@ package org.onosproject.cli.net; ...@@ -18,7 +18,6 @@ package org.onosproject.cli.net;
18 import org.apache.karaf.shell.commands.Argument; 18 import org.apache.karaf.shell.commands.Argument;
19 import org.apache.karaf.shell.commands.Command; 19 import org.apache.karaf.shell.commands.Command;
20 import org.onosproject.net.ConnectPoint; 20 import org.onosproject.net.ConnectPoint;
21 -import org.onosproject.net.flow.DefaultTrafficTreatment;
22 import org.onosproject.net.flow.TrafficSelector; 21 import org.onosproject.net.flow.TrafficSelector;
23 import org.onosproject.net.flow.TrafficTreatment; 22 import org.onosproject.net.flow.TrafficTreatment;
24 import org.onosproject.net.intent.Constraint; 23 import org.onosproject.net.intent.Constraint;
...@@ -59,7 +58,7 @@ public class AddSinglePointToMultiPointIntentCommand extends ConnectivityIntentC ...@@ -59,7 +58,7 @@ public class AddSinglePointToMultiPointIntentCommand extends ConnectivityIntentC
59 } 58 }
60 59
61 TrafficSelector selector = buildTrafficSelector(); 60 TrafficSelector selector = buildTrafficSelector();
62 - TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment(); 61 + TrafficTreatment treatment = buildTrafficTreatment();
63 List<Constraint> constraints = buildConstraints(); 62 List<Constraint> constraints = buildConstraints();
64 63
65 SinglePointToMultiPointIntent intent = 64 SinglePointToMultiPointIntent intent =
......
...@@ -22,6 +22,8 @@ import org.apache.felix.scr.annotations.Component; ...@@ -22,6 +22,8 @@ import org.apache.felix.scr.annotations.Component;
22 import org.apache.felix.scr.annotations.Deactivate; 22 import org.apache.felix.scr.annotations.Deactivate;
23 import org.apache.felix.scr.annotations.Reference; 23 import org.apache.felix.scr.annotations.Reference;
24 import org.apache.felix.scr.annotations.ReferenceCardinality; 24 import org.apache.felix.scr.annotations.ReferenceCardinality;
25 +import org.onlab.packet.Ip4Address;
26 +import org.onlab.packet.IpPrefix;
25 import org.onosproject.core.ApplicationId; 27 import org.onosproject.core.ApplicationId;
26 import org.onosproject.core.CoreService; 28 import org.onosproject.core.CoreService;
27 import org.onosproject.net.ConnectPoint; 29 import org.onosproject.net.ConnectPoint;
...@@ -34,10 +36,25 @@ import org.onosproject.net.flow.DefaultTrafficTreatment; ...@@ -34,10 +36,25 @@ import org.onosproject.net.flow.DefaultTrafficTreatment;
34 import org.onosproject.net.flow.FlowRule; 36 import org.onosproject.net.flow.FlowRule;
35 import org.onosproject.net.flow.TrafficSelector; 37 import org.onosproject.net.flow.TrafficSelector;
36 import org.onosproject.net.flow.TrafficTreatment; 38 import org.onosproject.net.flow.TrafficTreatment;
39 +import org.onosproject.net.flow.instructions.L2ModificationInstruction;
40 +import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
41 +import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsBosInstruction;
42 +import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction;
43 +import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnelIdInstruction;
44 +import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
45 +import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
46 +import org.onosproject.net.flow.instructions.L3ModificationInstruction;
47 +import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpEthInstruction;
48 +import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpIPInstruction;
49 +import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpOpInstruction;
50 +import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
51 +import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
52 +import org.onosproject.net.flow.instructions.L4ModificationInstruction.ModTransportPortInstruction;
37 import org.onosproject.net.intent.FlowRuleIntent; 53 import org.onosproject.net.intent.FlowRuleIntent;
38 import org.onosproject.net.intent.Intent; 54 import org.onosproject.net.intent.Intent;
39 import org.onosproject.net.intent.IntentCompiler; 55 import org.onosproject.net.intent.IntentCompiler;
40 import org.onosproject.net.intent.LinkCollectionIntent; 56 import org.onosproject.net.intent.LinkCollectionIntent;
57 +import org.onosproject.net.intent.impl.IntentCompilationException;
41 58
42 import java.util.ArrayList; 59 import java.util.ArrayList;
43 import java.util.Collections; 60 import java.util.Collections;
...@@ -109,15 +126,20 @@ public class LinkCollectionIntentCompiler implements IntentCompiler<LinkCollecti ...@@ -109,15 +126,20 @@ public class LinkCollectionIntentCompiler implements IntentCompiler<LinkCollecti
109 .forEach(ingressTreatmentBuilder::setOutput); 126 .forEach(ingressTreatmentBuilder::setOutput);
110 TrafficTreatment ingressTreatment = ingressTreatmentBuilder.build(); 127 TrafficTreatment ingressTreatment = ingressTreatmentBuilder.build();
111 128
129 + TrafficSelector defaultTrafficSelector = applyTreatmentToSelector(intent.selector(), ingressTreatment);
130 +
112 List<FlowRule> rules = new ArrayList<>(inPorts.size()); 131 List<FlowRule> rules = new ArrayList<>(inPorts.size());
113 for (PortNumber inPort: inPorts) { 132 for (PortNumber inPort: inPorts) {
114 - TrafficSelector selector = DefaultTrafficSelector.builder(intent.selector()).matchInPort(inPort).build(); 133 + TrafficSelector.Builder selectorBuilder;
115 TrafficTreatment treatment; 134 TrafficTreatment treatment;
116 if (ingressPorts.contains(inPort)) { 135 if (ingressPorts.contains(inPort)) {
136 + selectorBuilder = DefaultTrafficSelector.builder(intent.selector());
117 treatment = ingressTreatment; 137 treatment = ingressTreatment;
118 } else { 138 } else {
139 + selectorBuilder = DefaultTrafficSelector.builder(defaultTrafficSelector);
119 treatment = defaultTreatment; 140 treatment = defaultTreatment;
120 } 141 }
142 + TrafficSelector selector = selectorBuilder.matchInPort(inPort).build();
121 143
122 FlowRule rule = DefaultFlowRule.builder() 144 FlowRule rule = DefaultFlowRule.builder()
123 .forDevice(deviceId) 145 .forDevice(deviceId)
...@@ -132,4 +154,169 @@ public class LinkCollectionIntentCompiler implements IntentCompiler<LinkCollecti ...@@ -132,4 +154,169 @@ public class LinkCollectionIntentCompiler implements IntentCompiler<LinkCollecti
132 154
133 return rules; 155 return rules;
134 } 156 }
157 +
158 + private TrafficSelector applyTreatmentToSelector(TrafficSelector selector, TrafficTreatment treatment) {
159 + TrafficSelector.Builder defaultSelectorBuilder = DefaultTrafficSelector.builder(selector);
160 + treatment.allInstructions().forEach(instruction -> {
161 + switch (instruction.type()) {
162 + case L0MODIFICATION:
163 + case L1MODIFICATION:
164 + throw new IntentCompilationException("L0 and L1 mods not supported");
165 + case L2MODIFICATION:
166 + L2ModificationInstruction l2mod = (L2ModificationInstruction) instruction;
167 + switch (l2mod.subtype()) {
168 + case ETH_SRC:
169 + case ETH_DST:
170 + ModEtherInstruction ethInstr = (ModEtherInstruction) l2mod;
171 + switch (ethInstr.subtype()) {
172 + case ETH_SRC:
173 + defaultSelectorBuilder.matchEthSrc(ethInstr.mac());
174 + break;
175 + case ETH_DST:
176 + defaultSelectorBuilder.matchEthDst(ethInstr.mac());
177 + break;
178 + default:
179 + throw new IntentCompilationException("Bad eth subtype");
180 + }
181 + break;
182 + case VLAN_ID:
183 + ModVlanIdInstruction vlanIdInstr = (ModVlanIdInstruction) l2mod;
184 + defaultSelectorBuilder.matchVlanId(vlanIdInstr.vlanId());
185 + break;
186 + case VLAN_PUSH:
187 + //FIXME
188 + break;
189 + case VLAN_POP:
190 + //TODO how do we handle dropped label? remove the selector?
191 + throw new IntentCompilationException("Can't handle pop label");
192 + case VLAN_PCP:
193 + ModVlanPcpInstruction vlanPcpInstruction = (ModVlanPcpInstruction) l2mod;
194 + defaultSelectorBuilder.matchVlanPcp(vlanPcpInstruction.vlanPcp());
195 + break;
196 + case MPLS_LABEL:
197 + case MPLS_PUSH:
198 + //FIXME
199 + ModMplsLabelInstruction mplsInstr = (ModMplsLabelInstruction) l2mod;
200 + defaultSelectorBuilder.matchMplsLabel(mplsInstr.label());
201 + break;
202 + case MPLS_POP:
203 + //TODO how do we handle dropped label? remove the selector?
204 + throw new IntentCompilationException("Can't handle pop label");
205 + case DEC_MPLS_TTL:
206 + // no-op
207 + break;
208 + case MPLS_BOS:
209 + ModMplsBosInstruction mplsBosInstr = (ModMplsBosInstruction) l2mod;
210 + defaultSelectorBuilder.matchMplsBos(mplsBosInstr.mplsBos());
211 + break;
212 + case TUNNEL_ID:
213 + ModTunnelIdInstruction tunInstr = (ModTunnelIdInstruction) l2mod;
214 + defaultSelectorBuilder.matchTunnelId(tunInstr.tunnelId());
215 + break;
216 + default:
217 + throw new IntentCompilationException("Unknown L2 Modification instruction");
218 + }
219 + break;
220 + case L3MODIFICATION:
221 + L3ModificationInstruction l3mod = (L3ModificationInstruction) instruction;
222 + // TODO check ethernet proto
223 + switch (l3mod.subtype()) {
224 + case IPV4_SRC:
225 + case IPV4_DST:
226 + case IPV6_SRC:
227 + case IPV6_DST:
228 + ModIPInstruction ipInstr = (ModIPInstruction) l3mod;
229 + // TODO check if ip falls in original prefix
230 + IpPrefix prefix = ipInstr.ip().toIpPrefix();
231 + switch (ipInstr.subtype()) {
232 + case IPV4_SRC:
233 + defaultSelectorBuilder.matchIPSrc(prefix);
234 + break;
235 + case IPV4_DST:
236 + defaultSelectorBuilder.matchIPSrc(prefix);
237 + break;
238 + case IPV6_SRC:
239 + defaultSelectorBuilder.matchIPv6Src(prefix);
240 + break;
241 + case IPV6_DST:
242 + defaultSelectorBuilder.matchIPv6Dst(prefix);
243 + break;
244 + default:
245 + throw new IntentCompilationException("Bad type for IP instruction");
246 + }
247 + break;
248 + case IPV6_FLABEL:
249 + ModIPv6FlowLabelInstruction ipFlowInstr = (ModIPv6FlowLabelInstruction) l3mod;
250 + defaultSelectorBuilder.matchIPv6FlowLabel(ipFlowInstr.flowLabel());
251 + break;
252 + case DEC_TTL:
253 + // no-op
254 + break;
255 + case TTL_OUT:
256 + // no-op
257 + break;
258 + case TTL_IN:
259 + // no-op
260 + break;
261 + case ARP_SPA:
262 + ModArpIPInstruction arpIpInstr = (ModArpIPInstruction) l3mod;
263 + if (arpIpInstr.ip().isIp4()) {
264 + defaultSelectorBuilder.matchArpSpa((Ip4Address) arpIpInstr.ip());
265 + } else {
266 + throw new IntentCompilationException("IPv6 not supported for ARP");
267 + }
268 + break;
269 + case ARP_SHA:
270 + ModArpEthInstruction arpEthInstr = (ModArpEthInstruction) l3mod;
271 + defaultSelectorBuilder.matchArpSha(arpEthInstr.mac());
272 + break;
273 + case ARP_OP:
274 + ModArpOpInstruction arpOpInstr = (ModArpOpInstruction) l3mod;
275 + //FIXME is the long to int cast safe?
276 + defaultSelectorBuilder.matchArpOp((int) arpOpInstr.op());
277 + break;
278 + default:
279 + throw new IntentCompilationException("Unknown L3 Modification instruction");
280 + }
281 + break;
282 + case L4MODIFICATION:
283 + if (instruction instanceof ModTransportPortInstruction) {
284 + // TODO check IP proto
285 + ModTransportPortInstruction l4mod = (ModTransportPortInstruction) instruction;
286 + switch (l4mod.subtype()) {
287 + case TCP_SRC:
288 + defaultSelectorBuilder.matchTcpSrc(l4mod.port());
289 + break;
290 + case TCP_DST:
291 + defaultSelectorBuilder.matchTcpDst(l4mod.port());
292 + break;
293 + case UDP_SRC:
294 + defaultSelectorBuilder.matchUdpSrc(l4mod.port());
295 + break;
296 + case UDP_DST:
297 + defaultSelectorBuilder.matchUdpDst(l4mod.port());
298 + break;
299 + default:
300 + throw new IntentCompilationException("Unknown L4 Modification instruction");
301 + }
302 + } else {
303 + throw new IntentCompilationException("Unknown L4 Modification instruction");
304 + }
305 + break;
306 + case NOACTION:
307 + case OUTPUT:
308 + case GROUP:
309 + case QUEUE:
310 + case TABLE:
311 + case METER:
312 + case METADATA:
313 + case EXTENSION: // TODO is extension no-op or unsupported?
314 + // Nothing to do
315 + break;
316 + default:
317 + throw new IntentCompilationException("Unknown instruction type");
318 + }
319 + });
320 + return defaultSelectorBuilder.build();
321 + }
135 } 322 }
......