blob: 69b3510b900964156256eda5c7342b0255014333 [file] [log] [blame]
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +02001/*
2 * Copyright 2016-present 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
17package org.onosproject.sdxl2;
18
Carolina Fernandezad893432016-07-18 11:11:34 +020019import org.apache.felix.scr.annotations.Activate;
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +020020import org.apache.felix.scr.annotations.Component;
Carolina Fernandezad893432016-07-18 11:11:34 +020021import org.apache.felix.scr.annotations.Deactivate;
Carolina Fernandez38c97572016-08-14 17:33:53 +020022import org.apache.felix.scr.annotations.Modified;
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +020023import org.apache.felix.scr.annotations.Reference;
24import org.apache.felix.scr.annotations.ReferenceCardinality;
25import org.apache.felix.scr.annotations.Service;
Carolina Fernandez38c97572016-08-14 17:33:53 +020026import org.apache.felix.scr.annotations.Property;
pierventrebbb2e362016-06-26 19:42:48 +020027import org.onlab.packet.Ethernet;
28import org.onlab.packet.ICMP6;
29import org.onlab.packet.IPv6;
Carolina Fernandez38c97572016-08-14 17:33:53 +020030import org.onosproject.cfg.ComponentConfigService;
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +020031import org.onosproject.core.ApplicationId;
32import org.onosproject.core.CoreService;
pierventre1483e642016-06-08 18:52:29 +020033import org.onosproject.net.ConnectPoint;
pierventrebbb2e362016-06-26 19:42:48 +020034import org.onosproject.net.DeviceId;
pierventre1483e642016-06-08 18:52:29 +020035import org.onosproject.net.edge.EdgePortService;
pierventrebbb2e362016-06-26 19:42:48 +020036import org.onosproject.net.flow.DefaultTrafficSelector;
37import org.onosproject.net.flow.TrafficSelector;
Carolina Fernandez38c97572016-08-14 17:33:53 +020038import org.onosproject.net.intent.Intent;
pierventre1483e642016-06-08 18:52:29 +020039import org.onosproject.net.intent.IntentService;
Carolina Fernandez38c97572016-08-14 17:33:53 +020040import org.onosproject.net.intent.IntentState;
pierventre1483e642016-06-08 18:52:29 +020041import org.onosproject.net.intent.Key;
pierventrebbb2e362016-06-26 19:42:48 +020042import org.onosproject.net.packet.InboundPacket;
43import org.onosproject.net.packet.PacketContext;
44import org.onosproject.net.packet.PacketProcessor;
45import org.onosproject.net.packet.PacketService;
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +020046import org.osgi.service.component.ComponentContext;
47import org.slf4j.Logger;
48import org.slf4j.LoggerFactory;
pierventre3849e562016-05-11 11:47:32 +020049
50import java.util.Collections;
Carolina Fernandez38c97572016-08-14 17:33:53 +020051import java.util.Dictionary;
52import java.util.Iterator;
pierventre3849e562016-05-11 11:47:32 +020053import java.util.Optional;
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +020054import java.util.Set;
Carolina Fernandezad893432016-07-18 11:11:34 +020055import java.util.stream.Collectors;
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +020056
57import static com.google.common.base.Preconditions.checkNotNull;
58import static com.google.common.base.Preconditions.checkState;
Carolina Fernandez38c97572016-08-14 17:33:53 +020059import static com.google.common.base.Strings.isNullOrEmpty;
pierventrebbb2e362016-06-26 19:42:48 +020060import static org.onlab.packet.Ethernet.TYPE_ARP;
61import static org.onlab.packet.Ethernet.TYPE_IPV6;
62import static org.onlab.packet.ICMP6.NEIGHBOR_ADVERTISEMENT;
63import static org.onlab.packet.ICMP6.NEIGHBOR_SOLICITATION;
64import static org.onlab.packet.IPv6.PROTOCOL_ICMP6;
65import static org.onosproject.net.packet.PacketPriority.CONTROL;
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +020066
Carolina Fernandezad893432016-07-18 11:11:34 +020067
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +020068/**
Carolina Fernandezad893432016-07-18 11:11:34 +020069 * Implements SdxL2Service.
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +020070 */
71@Component(immediate = true)
72@Service
73public class SdxL2Manager implements SdxL2Service {
74
75 private static final String SDXL2_APP = "org.onosproject.sdxl2";
Carolina Fernandez38c97572016-08-14 17:33:53 +020076 private static final String ERROR_ADD_VC_CPS = "Unable to find %s and %s in sdxl2=%s";
Carolina Fernandezad893432016-07-18 11:11:34 +020077 private static final String ERROR_ADD_VC_VLANS =
78 "Cannot create VC when CPs have different number of VLANs";
79 private static final String ERROR_ADD_VC_VLANS_CLI =
80 "\u001B[0;31mError executing command: " + ERROR_ADD_VC_VLANS + "\u001B[0;49m";
81 private static final String VC_0 = "MAC";
Carolina Fernandez38c97572016-08-14 17:33:53 +020082 @Property(name = "VirtualCircuitType", value = VC_0, label = "Tunnel mechanism for Virtual Circuits")
83 private String vcType = VC_0;
84 private String previousvcType = vcType;
85
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +020086 private static Logger log = LoggerFactory.getLogger(SdxL2Manager.class);
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +020087 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
88 protected SdxL2Store sdxL2Store;
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +020089 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
90 protected CoreService coreService;
pierventre1483e642016-06-08 18:52:29 +020091 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
92 protected IntentService intentService;
pierventre1483e642016-06-08 18:52:29 +020093 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
94 protected EdgePortService edgePortService;
pierventrebbb2e362016-06-26 19:42:48 +020095 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Carolina Fernandez38c97572016-08-14 17:33:53 +020096 protected ComponentConfigService cfgService;
97 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
pierventrebbb2e362016-06-26 19:42:48 +020098 protected PacketService packetService;
Carolina Fernandez38c97572016-08-14 17:33:53 +020099
pierventrebbb2e362016-06-26 19:42:48 +0200100 protected SdxL2Processor processor = new SdxL2Processor();
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +0200101 protected ApplicationId appId;
pierventre1483e642016-06-08 18:52:29 +0200102 protected SdxL2MonitoringService monitoringManager;
Carolina Fernandezad893432016-07-18 11:11:34 +0200103 protected SdxL2ArpNdpHandler arpndpHandler;
104 protected SdxL2VCService vcManager;
pierventrebbb2e362016-06-26 19:42:48 +0200105
106
Carolina Fernandezad893432016-07-18 11:11:34 +0200107 /**
108 * Activates the implementation of the SDX-L2 service.
109 * @param context ComponentContext object
110 */
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +0200111 @Activate
112 protected void activate(ComponentContext context) {
113 appId = coreService.registerApplication(SDXL2_APP);
pierventre1483e642016-06-08 18:52:29 +0200114 monitoringManager = new SdxL2MonitoringManager(appId, intentService, edgePortService);
Carolina Fernandez38c97572016-08-14 17:33:53 +0200115 SdxL2ArpNdpHandler.setVcType(VC_0);
116 vcManager = buildVCManager();
117 cfgService.registerProperties(getClass());
118 readComponentConfiguration(context);
119 changeVCTunnel();
pierventrebbb2e362016-06-26 19:42:48 +0200120 handleArpNdp();
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +0200121 log.info("Started");
122 }
123
Carolina Fernandezad893432016-07-18 11:11:34 +0200124 /**
125 * Deactivates the implementation of the SDX-L2 service.
126 */
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +0200127 @Deactivate
128 protected void deactivate() {
Carolina Fernandez38c97572016-08-14 17:33:53 +0200129 this.cleanup();
pierventrebbb2e362016-06-26 19:42:48 +0200130 unhandleArpNdp();
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +0200131 log.info("Stopped");
132 }
133
Carolina Fernandez38c97572016-08-14 17:33:53 +0200134 @Modified
135 public void modified(ComponentContext context) {
136 readComponentConfiguration(context);
137 changeVCTunnel();
138 }
139
140 /**
141 * Determines if the currently used VC is active or not.
142 *
143 * @return Boolean value indicating whether VC is active (true) or not (false).
144 */
145 private boolean isCircuitActive() {
146 Iterator<Intent> intents = intentService.getIntents().iterator();
147 Intent intent;
148 while (intents.hasNext()) {
149 intent = intents.next();
150 if (intent.appId().equals(this.appId) &&
151 intentService.getIntentState(intent.key()) == IntentState.INSTALLED) {
152 return true;
153 }
154 }
155 return false;
156 }
157
158
159 /**
160 * Checks if property name is defined and set to True.
161 *
162 * @param properties properties to be looked up
163 * @param propertyName the name of the property to look up
164 * @return value when the propertyName is defined or return null
165 */
166 private static String isTunnelEnabled(Dictionary<?, ?> properties,
167 String propertyName) {
168 String value = null;
169 try {
170 String s = (String) properties.get(propertyName);
171 value = isNullOrEmpty(s) ? null : s.trim();
172 if (value != null &&
173 !value.equals("MAC") &&
174 !value.equals("VLAN") &&
175 !value.equals("MPLS")) {
176 value = null;
177 }
178 } catch (ClassCastException e) {
179 // No propertyName defined.
180 }
181 return value;
182 }
183
184 /**
185 * Extracts properties from the component configuration context.
186 *
187 * @param context the component context
188 */
189 private void readComponentConfiguration(ComponentContext context) {
190 Dictionary<?, ?> properties = context.getProperties();
191 String tunnel;
192 tunnel = isTunnelEnabled(properties, "VirtualCircuitType");
193 if (tunnel == null) {
194 log.info("Tunnel mechanism for VC is not configured, " +
195 "using current value {}", vcType);
196 } else {
197 vcType = tunnel;
198 log.info("Configured. Tunnel mechanism is {}", vcType);
199 }
200 }
201
202 /**
203 * Changes the tunnel mechanism for the VCs.
204 */
205 private void changeVCTunnel() {
206 if (previousvcType.equals(vcType)) {
207 log.info("Tunnel mechanism has not been changed");
208 return;
209 }
210 if (isCircuitActive()) {
211 log.info("Change of tunnels not allowed - there are active circuits");
212 vcType = previousvcType;
213 return;
214 }
215 previousvcType = vcType;
216 SdxL2ArpNdpHandler.setVcType(vcType);
217 vcManager = buildVCManager();
218 }
219
220 /**
221 * Builds a VC depending on the internal variable "vcType", previously set-up.
222 * Default circuit is through VLANs
223 *
224 * @return VirtualCircuit object of the selected type
225 */
226 private SdxL2VCService buildVCManager() {
227 SdxL2VCService manager;
228 switch (vcType) {
229 case "MAC":
230 manager = new SdxL2MacVCManager(appId, sdxL2Store, intentService);
231 break;
232 case "MPLS":
233 manager = new SdxL2MplsVCManager(appId, sdxL2Store, intentService);
234 break;
235 default:
236 case "VLAN":
237 manager = new SdxL2VlanVCManager(appId, sdxL2Store, intentService);
238 break;
239 }
240 return manager;
241 }
242
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +0200243 @Override
244 public void createSdxL2(String sdxl2) {
pierventre3849e562016-05-11 11:47:32 +0200245
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +0200246 checkNotNull(sdxl2, "sdxl2 name cannot be null");
247 checkState(!sdxl2.contains(","), "sdxl2 names cannot contain commas");
248 checkState(!sdxl2.contains("|"), "sdxl2 names cannot contain pipe");
249 checkState(!sdxl2.contains("-"), "sdxl2 names cannot contain dash");
250 checkState(!sdxl2.contains(":"), "sdxl2 names cannot contain colon");
251
252 try {
253 this.sdxL2Store.putSdxL2(sdxl2);
254 } catch (SdxL2Exception e) {
pierventre3849e562016-05-11 11:47:32 +0200255 log.info(e.getMessage());
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +0200256 }
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +0200257 }
258
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +0200259 @Override
260 public void deleteSdxL2(String sdxl2) {
pierventre3849e562016-05-11 11:47:32 +0200261
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +0200262 checkNotNull(sdxl2, "sdxl2 name cannot be null");
263
264 try {
265 this.sdxL2Store.removeSdxL2(sdxl2);
266 } catch (SdxL2Exception e) {
pierventre3849e562016-05-11 11:47:32 +0200267 log.info(e.getMessage());
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +0200268 }
269
270 }
271
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +0200272 @Override
273 public Set<String> getSdxL2s() {
274 return this.sdxL2Store.getSdxL2s();
275 }
276
pierventre3849e562016-05-11 11:47:32 +0200277 @Override
278 public void addSdxL2ConnectionPoint(String sdxl2, SdxL2ConnectionPoint sdxl2cp) {
279
280 checkNotNull(sdxl2, "sdxl2 name cannot be null");
281 checkNotNull(sdxl2cp, "SdxL2ConnectionPoint cannot be null");
282
283 try {
284 this.sdxL2Store.addSdxL2ConnectionPoint(sdxl2, sdxl2cp);
285 } catch (SdxL2Exception e) {
286 log.info(e.getMessage());
287 }
288
289 }
290
pierventre3849e562016-05-11 11:47:32 +0200291 @Override
292 public Set<String> getSdxL2ConnectionPoints(Optional<String> sdxl2) {
293
294 try {
295 return this.sdxL2Store.getSdxL2ConnectionPoints(sdxl2);
296 } catch (SdxL2Exception e) {
297 log.info(e.getMessage());
298 }
299
300 return Collections.emptySet();
pierventre3849e562016-05-11 11:47:32 +0200301 }
302
pierventre3849e562016-05-11 11:47:32 +0200303 @Override
304 public void removeSdxL2ConnectionPoint(String sdxl2cp) {
305
306 checkNotNull(sdxl2cp, "SdxL2ConnectionPoint name cannot be null");
307
308 try {
309 this.sdxL2Store.removeSdxL2ConnectionPoint(sdxl2cp);
310 } catch (SdxL2Exception e) {
311 log.info(e.getMessage());
312 }
313
314 }
315
Carolina Fernandezad893432016-07-18 11:11:34 +0200316 @Override
317 public void addVC(String sdxl2, String sdxl2cplhs, String sdxl2cprhs) {
318 SdxL2ConnectionPoint lhs = this.getSdxL2ConnectionPoint(sdxl2cplhs);
319 SdxL2ConnectionPoint rhs = this.getSdxL2ConnectionPoint(sdxl2cprhs);
320
321 Set<String> cps = this.getSdxL2ConnectionPoints(Optional.of(sdxl2))
322 .parallelStream()
323 .filter(cptemp -> (cptemp.equals(sdxl2cplhs) || cptemp.equals(sdxl2cprhs)))
324 .collect(Collectors.toSet());
325
326 checkState(cps.size() == 2, ERROR_ADD_VC_CPS, sdxl2cplhs, sdxl2cprhs, sdxl2);
327
328 if ((lhs.vlanIds().size() != rhs.vlanIds().size()) &&
329 (lhs.vlanIds().size() > 1 || rhs.vlanIds().size() > 1)) {
330 // User can correct this issue in the CLI. Show in console and log
331 System.err.println(ERROR_ADD_VC_VLANS_CLI);
332 log.info(ERROR_ADD_VC_VLANS);
333 return;
334 }
335 this.vcManager.addVC(sdxl2, lhs, rhs);
336 }
337
338 @Override
339 public void removeVC(String vc) {
340 checkNotNull(vc, "VC name cannot be null");
341 String[] splitKeyCPs = vc.split(":");
342 checkState(splitKeyCPs.length == 2, "Bad name format $sdx:$something");
343 String[] cps = splitKeyCPs[1].split("-");
344 checkState(cps.length == 2, "Bad name format $sdx:$lhs-$rhs");
345
346 String lhsName = cps[0];
347 String rhsName = cps[1];
348 SdxL2ConnectionPoint lhs = this.getSdxL2ConnectionPoint(lhsName);
349 SdxL2ConnectionPoint rhs = this.getSdxL2ConnectionPoint(rhsName);
350 if (lhs == null || rhs == null) {
351 return;
352 }
353
354 Set<String> cpsByVC = this.getSdxL2ConnectionPoints(Optional.of(splitKeyCPs[0]))
355 .parallelStream()
356 .filter(tempCP -> (tempCP.equals(lhs.name()) || tempCP.equals(rhs.name())))
357 .collect(Collectors.toSet());
358
359 if (cpsByVC.size() != 2) {
360 return;
361 }
362 this.vcManager.removeVC(lhs, rhs);
363 }
364
pierventre1483e642016-06-08 18:52:29 +0200365 @Override
366 public SdxL2ConnectionPoint getSdxL2ConnectionPoint(String sdxl2cp) {
367 checkNotNull(sdxl2cp, "SdxL2ConnectionPoint name cannot be null");
368 try {
369 return this.sdxL2Store.getSdxL2ConnectionPoint(sdxl2cp);
370 } catch (SdxL2Exception e) {
371 log.info(e.getMessage());
372 }
pierventre1483e642016-06-08 18:52:29 +0200373 return null;
374 }
375
Carolina Fernandezad893432016-07-18 11:11:34 +0200376 @Override
377 public Set<String> getVirtualCircuits(Optional<String> sdxl2) {
378 return this.vcManager.getVCs(sdxl2);
379 }
380
381 @Override
382 public VirtualCircuit getVirtualCircuit(String sdxl2vc) {
383 checkNotNull(sdxl2vc, "VC name cannot be null");
384 String[] splitKeyCPs = sdxl2vc.split(":");
385 checkState(splitKeyCPs.length == 2, "Bad name format $sdx:$something");
386 String[] cps = splitKeyCPs[1].split("-");
387 checkState(cps.length == 2, "Bad name format $sdx:$lhs-$rhs");
388
389 SdxL2ConnectionPoint lhs = this.getSdxL2ConnectionPoint(cps[0]);
390 SdxL2ConnectionPoint rhs = this.getSdxL2ConnectionPoint(cps[1]);
391 VirtualCircuit vc = null;
392 if (lhs == null || rhs == null) {
393 return vc;
394 }
395
396 String result = this.vcManager.getVC(lhs, rhs);
397 if (result != null) {
398 vc = new VirtualCircuit(lhs, rhs);
399 }
400 return vc;
401 }
402
pierventre1483e642016-06-08 18:52:29 +0200403 @Override
404 public SdxL2State getIntentState(Key intentKey) {
405 checkNotNull(intentKey, "Intent key cannot be null");
406 return this.monitoringManager.getIntentState(intentKey);
407 }
408
pierventre1483e642016-06-08 18:52:29 +0200409 @Override
410 public SdxL2State getEdgePortState(ConnectPoint edgeport) {
411 checkNotNull(edgeport, "Edge port cannot be null");
412 return this.monitoringManager.getEdgePortState(edgeport);
413 }
414
415 /**
416 * Cleans the state of the Application.
417 */
418 @Override
419 public void cleanSdxL2() {
Carolina Fernandez38c97572016-08-14 17:33:53 +0200420 Set<String> sdxl2s = this.getSdxL2s();
421 sdxl2s.forEach(sdxl2 -> this.deleteSdxL2(sdxl2));
422 }
423
424 /**
425 * Stops monitoring and unregister configuration service.
426 */
427 public void cleanup() {
pierventre1483e642016-06-08 18:52:29 +0200428 this.monitoringManager.cleanup();
Carolina Fernandez38c97572016-08-14 17:33:53 +0200429 this.cfgService.unregisterProperties(getClass(), false);
pierventre1483e642016-06-08 18:52:29 +0200430 }
431
pierventrebbb2e362016-06-26 19:42:48 +0200432 /**
Carolina Fernandezad893432016-07-18 11:11:34 +0200433 * Requests ARP and NDP packets to the PacketService
pierventrebbb2e362016-06-26 19:42:48 +0200434 * and registers the SDX-L2 PacketProcessor.
435 */
436 private void handleArpNdp() {
Carolina Fernandez38c97572016-08-14 17:33:53 +0200437 SdxL2ArpNdpHandler.setVcType(VC_0);
pierventrebbb2e362016-06-26 19:42:48 +0200438 arpndpHandler = new SdxL2ArpNdpHandler(intentService, packetService, appId);
439 packetService.addProcessor(processor, PacketProcessor.director(1));
440
441 // ARP packet
442 TrafficSelector.Builder selectorBuilder =
443 DefaultTrafficSelector.builder();
444 selectorBuilder.matchEthType(TYPE_ARP);
445 packetService.requestPackets(selectorBuilder.build(),
Carolina Fernandezad893432016-07-18 11:11:34 +0200446 CONTROL, appId, Optional.<DeviceId>empty());
pierventrebbb2e362016-06-26 19:42:48 +0200447
448 // IPv6 Neighbor Solicitation packet.
449 selectorBuilder = DefaultTrafficSelector.builder();
450 selectorBuilder.matchEthType(TYPE_IPV6);
451 selectorBuilder.matchIPProtocol(PROTOCOL_ICMP6);
452 selectorBuilder.matchIcmpv6Type(NEIGHBOR_SOLICITATION);
453 packetService.requestPackets(selectorBuilder.build(),
Carolina Fernandezad893432016-07-18 11:11:34 +0200454 CONTROL, appId, Optional.<DeviceId>empty());
pierventrebbb2e362016-06-26 19:42:48 +0200455
456 // IPv6 Neighbor Advertisement packet.
457 selectorBuilder = DefaultTrafficSelector.builder();
458 selectorBuilder.matchEthType(TYPE_IPV6);
459 selectorBuilder.matchIPProtocol(PROTOCOL_ICMP6);
460 selectorBuilder.matchIcmpv6Type(NEIGHBOR_ADVERTISEMENT);
461 packetService.requestPackets(selectorBuilder.build(),
Carolina Fernandezad893432016-07-18 11:11:34 +0200462 CONTROL, appId, Optional.<DeviceId>empty());
pierventrebbb2e362016-06-26 19:42:48 +0200463 }
464
465 /**
466 * Withdraws the requests for ARP/NDP packets and
467 * unregisters the SDX-L2 PacketProcessor.
468 */
469 private void unhandleArpNdp() {
470 arpndpHandler = null;
471 packetService.removeProcessor(processor);
472 processor = null;
473
474 TrafficSelector.Builder selectorBuilder =
475 DefaultTrafficSelector.builder();
476 selectorBuilder.matchEthType(TYPE_ARP);
477 packetService.cancelPackets(selectorBuilder.build(),
Carolina Fernandezad893432016-07-18 11:11:34 +0200478 CONTROL, appId, Optional.<DeviceId>empty());
pierventrebbb2e362016-06-26 19:42:48 +0200479
480 selectorBuilder = DefaultTrafficSelector.builder();
481 selectorBuilder.matchEthType(TYPE_IPV6);
482 selectorBuilder.matchIPProtocol(PROTOCOL_ICMP6);
483 selectorBuilder.matchIcmpv6Type(NEIGHBOR_SOLICITATION);
484 packetService.cancelPackets(selectorBuilder.build(),
Carolina Fernandezad893432016-07-18 11:11:34 +0200485 CONTROL, appId, Optional.<DeviceId>empty());
pierventrebbb2e362016-06-26 19:42:48 +0200486
487 selectorBuilder = DefaultTrafficSelector.builder();
488 selectorBuilder.matchEthType(TYPE_IPV6);
489 selectorBuilder.matchIPProtocol(PROTOCOL_ICMP6);
490 selectorBuilder.matchIcmpv6Type(NEIGHBOR_ADVERTISEMENT);
491 packetService.cancelPackets(selectorBuilder.build(),
Carolina Fernandezad893432016-07-18 11:11:34 +0200492 CONTROL, appId, Optional.<DeviceId>empty());
pierventrebbb2e362016-06-26 19:42:48 +0200493 }
494
495 /**
496 * Packet processor responsible for forwarding packets along their paths.
497 */
498 private class SdxL2Processor implements PacketProcessor {
499
500 /**
501 * Processes the inbound packet as specified in the given context.
502 *
503 * @param context packet processing context
504 */
505 @Override
506 public void process(PacketContext context) {
507
508 /** Stop processing if the packet has been handled, since we
509 * can't do any more to it
510 */
511 if (context.isHandled()) {
512 return;
513 }
514
515 InboundPacket pkt = context.inPacket();
516 Ethernet ethPkt = pkt.parsed();
517 if (ethPkt == null) {
518 return;
519 }
520
521 boolean handled = false;
522 if (ethPkt.getEtherType() == TYPE_ARP) {
523 //handle the arp packet.
524 handled = arpndpHandler.handlePacket(context);
525 } else if (ethPkt.getEtherType() == TYPE_IPV6) {
526 IPv6 ipv6Pkt = (IPv6) ethPkt.getPayload();
527 if (ipv6Pkt.getNextHeader() == IPv6.PROTOCOL_ICMP6) {
528 ICMP6 icmp6Pkt = (ICMP6) ipv6Pkt.getPayload();
529 if (icmp6Pkt.getIcmpType() == NEIGHBOR_SOLICITATION ||
530 icmp6Pkt.getIcmpType() == NEIGHBOR_ADVERTISEMENT) {
531 // handle ICMPv6 solicitations and advertisements
532 handled = arpndpHandler.handlePacket(context);
533 }
534 }
535 }
536
537 if (handled) {
538 context.block();
539 }
540
541 }
542 }
Pier Luigi Ventre0a023f42016-04-30 11:03:15 +0200543}