alshabib

WIP: Initial implementation of filterObjectives using driver subsystem.

Incomplete implementation

Change-Id: I3745d481027659d4ca44b72139e5461c02e8c3ef
...@@ -15,14 +15,11 @@ ...@@ -15,14 +15,11 @@
15 */ 15 */
16 package org.onosproject.bgprouter; 16 package org.onosproject.bgprouter;
17 17
18 -import java.util.Collection; 18 +import com.google.common.collect.ConcurrentHashMultiset;
19 -import java.util.Collections; 19 +import com.google.common.collect.HashMultimap;
20 -import java.util.HashMap; 20 +import com.google.common.collect.Maps;
21 -import java.util.HashSet; 21 +import com.google.common.collect.Multimap;
22 -import java.util.Map; 22 +import com.google.common.collect.Multiset;
23 -import java.util.Set;
24 -import java.util.stream.Collectors;
25 -
26 import org.apache.felix.scr.annotations.Activate; 23 import org.apache.felix.scr.annotations.Activate;
27 import org.apache.felix.scr.annotations.Component; 24 import org.apache.felix.scr.annotations.Component;
28 import org.apache.felix.scr.annotations.Deactivate; 25 import org.apache.felix.scr.annotations.Deactivate;
...@@ -45,12 +42,14 @@ import org.onosproject.net.flow.DefaultFlowRule; ...@@ -45,12 +42,14 @@ import org.onosproject.net.flow.DefaultFlowRule;
45 import org.onosproject.net.flow.DefaultTrafficSelector; 42 import org.onosproject.net.flow.DefaultTrafficSelector;
46 import org.onosproject.net.flow.DefaultTrafficTreatment; 43 import org.onosproject.net.flow.DefaultTrafficTreatment;
47 import org.onosproject.net.flow.FlowRule; 44 import org.onosproject.net.flow.FlowRule;
48 -import org.onosproject.net.flow.FlowRule.Type;
49 import org.onosproject.net.flow.FlowRuleOperations; 45 import org.onosproject.net.flow.FlowRuleOperations;
50 -import org.onosproject.net.flow.FlowRuleOperationsContext;
51 import org.onosproject.net.flow.FlowRuleService; 46 import org.onosproject.net.flow.FlowRuleService;
52 import org.onosproject.net.flow.TrafficSelector; 47 import org.onosproject.net.flow.TrafficSelector;
53 import org.onosproject.net.flow.TrafficTreatment; 48 import org.onosproject.net.flow.TrafficTreatment;
49 +import org.onosproject.net.flow.criteria.Criteria;
50 +import org.onosproject.net.flowobjective.DefaultFilteringObjective;
51 +import org.onosproject.net.flowobjective.FilteringObjective;
52 +import org.onosproject.net.flowobjective.FlowObjectiveService;
54 import org.onosproject.net.group.DefaultGroupBucket; 53 import org.onosproject.net.group.DefaultGroupBucket;
55 import org.onosproject.net.group.DefaultGroupDescription; 54 import org.onosproject.net.group.DefaultGroupDescription;
56 import org.onosproject.net.group.DefaultGroupKey; 55 import org.onosproject.net.group.DefaultGroupKey;
...@@ -73,11 +72,13 @@ import org.onosproject.routing.config.RoutingConfigurationService; ...@@ -73,11 +72,13 @@ import org.onosproject.routing.config.RoutingConfigurationService;
73 import org.slf4j.Logger; 72 import org.slf4j.Logger;
74 import org.slf4j.LoggerFactory; 73 import org.slf4j.LoggerFactory;
75 74
76 -import com.google.common.collect.ConcurrentHashMultiset; 75 +import java.util.Collection;
77 -import com.google.common.collect.HashMultimap; 76 +import java.util.Collections;
78 -import com.google.common.collect.Maps; 77 +import java.util.HashMap;
79 -import com.google.common.collect.Multimap; 78 +import java.util.HashSet;
80 -import com.google.common.collect.Multiset; 79 +import java.util.Map;
80 +import java.util.Set;
81 +import java.util.stream.Collectors;
81 82
82 /** 83 /**
83 * BgpRouter component. 84 * BgpRouter component.
...@@ -156,6 +157,10 @@ public class BgpRouter { ...@@ -156,6 +157,10 @@ public class BgpRouter {
156 .register(NextHopGroupKey.class) 157 .register(NextHopGroupKey.class)
157 .build(); 158 .build();
158 159
160 +
161 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
162 + protected FlowObjectiveService flowObjectiveService;
163 +
159 @Activate 164 @Activate
160 protected void activate() { 165 protected void activate() {
161 appId = coreService.registerApplication(BGP_ROUTER_APP); 166 appId = coreService.registerApplication(BGP_ROUTER_APP);
...@@ -377,336 +382,28 @@ public class BgpRouter { ...@@ -377,336 +382,28 @@ public class BgpRouter {
377 382
378 private class InternalTableHandler { 383 private class InternalTableHandler {
379 384
380 - private static final int CONTROLLER_PRIORITY = 255;
381 - private static final int DROP_PRIORITY = 0;
382 - private static final int HIGHEST_PRIORITY = 0xffff;
383 private Set<InterfaceIpAddress> intfIps = new HashSet<InterfaceIpAddress>(); 385 private Set<InterfaceIpAddress> intfIps = new HashSet<InterfaceIpAddress>();
384 private Set<MacAddress> intfMacs = new HashSet<MacAddress>(); 386 private Set<MacAddress> intfMacs = new HashSet<MacAddress>();
385 private Map<PortNumber, VlanId> portVlanPair = Maps.newHashMap(); 387 private Map<PortNumber, VlanId> portVlanPair = Maps.newHashMap();
386 388
387 public void provision(boolean install, Set<Interface> intfs) { 389 public void provision(boolean install, Set<Interface> intfs) {
388 getInterfaceConfig(intfs); 390 getInterfaceConfig(intfs);
389 - processTableZero(install);
390 - processTableOne(install);
391 - processTableTwo(install);
392 - processTableFour(install);
393 - processTableFive(install);
394 - processTableSix(install);
395 - processTableNine(install);
396 } 391 }
397 392
398 private void getInterfaceConfig(Set<Interface> intfs) { 393 private void getInterfaceConfig(Set<Interface> intfs) {
399 log.info("Processing {} router interfaces", intfs.size()); 394 log.info("Processing {} router interfaces", intfs.size());
400 for (Interface intf : intfs) { 395 for (Interface intf : intfs) {
396 + FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
397 + flowObjectiveService.filter(deviceId, Collections.singletonList(
398 + fob.addCondition(Criteria.matchEthDst(intf.mac()))
399 + .fromApp(appId).permit().add()));
401 intfIps.addAll(intf.ipAddresses()); 400 intfIps.addAll(intf.ipAddresses());
402 intfMacs.add(intf.mac()); 401 intfMacs.add(intf.mac());
403 portVlanPair.put(intf.connectPoint().port(), intf.vlan()); 402 portVlanPair.put(intf.connectPoint().port(), intf.vlan());
404 } 403 }
405 } 404 }
406 405
407 - private void processTableZero(boolean install) {
408 - TrafficSelector.Builder selector;
409 - TrafficTreatment.Builder treatment;
410 -
411 - // Bcast rule
412 - selector = DefaultTrafficSelector.builder();
413 - treatment = DefaultTrafficTreatment.builder();
414 -
415 - selector.matchEthDst(MacAddress.BROADCAST);
416 - treatment.transition(FlowRule.Type.VLAN_MPLS);
417 -
418 - FlowRule rule = new DefaultFlowRule(deviceId, selector.build(),
419 - treatment.build(),
420 - CONTROLLER_PRIORITY, appId, 0,
421 - true, FlowRule.Type.FIRST);
422 -
423 - FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
424 -
425 - ops = install ? ops.add(rule) : ops.remove(rule);
426 -
427 - // Interface MACs
428 - for (MacAddress mac : intfMacs) {
429 - log.debug("adding rule for MAC: {}", mac);
430 - selector = DefaultTrafficSelector.builder();
431 - treatment = DefaultTrafficTreatment.builder();
432 -
433 - selector.matchEthDst(mac);
434 - treatment.transition(FlowRule.Type.VLAN_MPLS);
435 -
436 - rule = new DefaultFlowRule(deviceId, selector.build(),
437 - treatment.build(),
438 - CONTROLLER_PRIORITY, appId, 0,
439 - true, FlowRule.Type.FIRST);
440 -
441 - ops = install ? ops.add(rule) : ops.remove(rule);
442 - }
443 -
444 - //Drop rule
445 - selector = DefaultTrafficSelector.builder();
446 - treatment = DefaultTrafficTreatment.builder();
447 -
448 - treatment.drop();
449 -
450 - rule = new DefaultFlowRule(deviceId, selector.build(),
451 - treatment.build(), DROP_PRIORITY, appId,
452 - 0, true, FlowRule.Type.FIRST);
453 -
454 - ops = install ? ops.add(rule) : ops.remove(rule);
455 -
456 - flowService.apply(ops.build(new FlowRuleOperationsContext() {
457 - @Override
458 - public void onSuccess(FlowRuleOperations ops) {
459 - log.info("Provisioned default table for bgp router");
460 - }
461 -
462 - @Override
463 - public void onError(FlowRuleOperations ops) {
464 - log.info("Failed to provision default table for bgp router");
465 - }
466 - }));
467 -
468 - }
469 -
470 - private void processTableOne(boolean install) {
471 - TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
472 - TrafficTreatment.Builder treatment = DefaultTrafficTreatment
473 - .builder();
474 - FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
475 - FlowRule rule;
476 -
477 - selector.matchVlanId(VlanId.ANY);
478 - treatment.transition(FlowRule.Type.VLAN);
479 -
480 - rule = new DefaultFlowRule(deviceId, selector.build(),
481 - treatment.build(), CONTROLLER_PRIORITY,
482 - appId, 0, true, FlowRule.Type.VLAN_MPLS);
483 -
484 - ops = install ? ops.add(rule) : ops.remove(rule);
485 -
486 - flowService.apply(ops.build(new FlowRuleOperationsContext() {
487 - @Override
488 - public void onSuccess(FlowRuleOperations ops) {
489 - log.info("Provisioned vlan/mpls table for bgp router");
490 - }
491 -
492 - @Override
493 - public void onError(FlowRuleOperations ops) {
494 - log.info(
495 - "Failed to provision vlan/mpls table for bgp router");
496 - }
497 - }));
498 -
499 - }
500 -
501 - private void processTableTwo(boolean install) {
502 - TrafficSelector.Builder selector;
503 - TrafficTreatment.Builder treatment;
504 - FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
505 - FlowRule rule;
506 -
507 - //Interface Vlans
508 - for (Map.Entry<PortNumber, VlanId> portVlan : portVlanPair.entrySet()) {
509 - log.debug("adding rule for VLAN: {}", portVlan);
510 - selector = DefaultTrafficSelector.builder();
511 - treatment = DefaultTrafficTreatment.builder();
512 -
513 - selector.matchVlanId(portVlan.getValue());
514 - selector.matchInPort(portVlan.getKey());
515 - treatment.transition(Type.ETHER);
516 - treatment.deferred().popVlan();
517 -
518 - rule = new DefaultFlowRule(deviceId, selector.build(),
519 - treatment.build(), CONTROLLER_PRIORITY, appId,
520 - 0, true, FlowRule.Type.VLAN);
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 = new DefaultFlowRule(deviceId, selector.build(),
532 - treatment.build(), DROP_PRIORITY, appId,
533 - 0, true, FlowRule.Type.VLAN);
534 -
535 - ops = install ? ops.add(rule) : ops.remove(rule);
536 -
537 - flowService.apply(ops.build(new FlowRuleOperationsContext() {
538 - @Override
539 - public void onSuccess(FlowRuleOperations ops) {
540 - log.info("Provisioned vlan table for bgp router");
541 - }
542 -
543 - @Override
544 - public void onError(FlowRuleOperations ops) {
545 - log.info("Failed to provision vlan table for bgp router");
546 - }
547 - }));
548 - }
549 -
550 - private void processTableFour(boolean install) {
551 - TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
552 - TrafficTreatment.Builder treatment = DefaultTrafficTreatment
553 - .builder();
554 - FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
555 - FlowRule rule;
556 -
557 - selector.matchEthType(Ethernet.TYPE_ARP);
558 - treatment.punt();
559 -
560 - rule = new DefaultFlowRule(deviceId, selector.build(),
561 - treatment.build(), CONTROLLER_PRIORITY,
562 - appId, 0, true, FlowRule.Type.ETHER);
563 -
564 - ops = install ? ops.add(rule) : ops.remove(rule);
565 -
566 - selector = DefaultTrafficSelector.builder();
567 - treatment = DefaultTrafficTreatment.builder();
568 -
569 - selector.matchEthType(Ethernet.TYPE_IPV4);
570 - treatment.transition(FlowRule.Type.COS);
571 -
572 - rule = new DefaultFlowRule(deviceId, selector.build(),
573 - treatment.build(), CONTROLLER_PRIORITY,
574 - appId, 0, true, FlowRule.Type.ETHER);
575 -
576 - ops = install ? ops.add(rule) : ops.remove(rule);
577 -
578 - //Drop rule
579 - selector = DefaultTrafficSelector.builder();
580 - treatment = DefaultTrafficTreatment.builder();
581 -
582 - treatment.drop();
583 -
584 - rule = new DefaultFlowRule(deviceId, selector.build(),
585 - treatment.build(), DROP_PRIORITY, appId,
586 - 0, true, FlowRule.Type.ETHER);
587 -
588 - ops = install ? ops.add(rule) : ops.remove(rule);
589 -
590 - flowService.apply(ops.build(new FlowRuleOperationsContext() {
591 - @Override
592 - public void onSuccess(FlowRuleOperations ops) {
593 - log.info("Provisioned ether table for bgp router");
594 - }
595 -
596 - @Override
597 - public void onError(FlowRuleOperations ops) {
598 - log.info("Failed to provision ether table for bgp router");
599 - }
600 - }));
601 -
602 - }
603 -
604 - private void processTableFive(boolean install) {
605 - TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
606 - TrafficTreatment.Builder treatment = DefaultTrafficTreatment
607 - .builder();
608 - FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
609 - FlowRule rule;
610 -
611 - treatment.transition(FlowRule.Type.IP);
612 -
613 - rule = new DefaultFlowRule(deviceId, selector.build(),
614 - treatment.build(), DROP_PRIORITY, appId,
615 - 0, true, FlowRule.Type.COS);
616 -
617 - ops = install ? ops.add(rule) : ops.remove(rule);
618 406
619 - flowService.apply(ops.build(new FlowRuleOperationsContext() {
620 - @Override
621 - public void onSuccess(FlowRuleOperations ops) {
622 - log.info("Provisioned cos table for bgp router");
623 - }
624 -
625 - @Override
626 - public void onError(FlowRuleOperations ops) {
627 - log.info("Failed to provision cos table for bgp router");
628 - }
629 - }));
630 -
631 - }
632 -
633 - private void processTableSix(boolean install) {
634 - TrafficSelector.Builder selector;
635 - TrafficTreatment.Builder treatment;
636 - FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
637 - FlowRule rule;
638 -
639 -
640 - //Interface IPs
641 - for (InterfaceIpAddress ipAddr : intfIps) {
642 - log.debug("adding rule for IPs: {}", ipAddr.ipAddress());
643 - selector = DefaultTrafficSelector.builder();
644 - treatment = DefaultTrafficTreatment.builder();
645 -
646 - selector.matchEthType(Ethernet.TYPE_IPV4);
647 - selector.matchIPDst(IpPrefix.valueOf(ipAddr.ipAddress(), 32));
648 - treatment.transition(Type.ACL);
649 -
650 - rule = new DefaultFlowRule(deviceId, selector.build(),
651 - treatment.build(), HIGHEST_PRIORITY, appId,
652 - 0, true, FlowRule.Type.IP);
653 -
654 - ops = install ? ops.add(rule) : ops.remove(rule);
655 - }
656 -
657 -
658 - //Drop rule
659 - selector = DefaultTrafficSelector.builder();
660 - treatment = DefaultTrafficTreatment.builder();
661 -
662 - treatment.drop();
663 -
664 - rule = new DefaultFlowRule(deviceId, selector.build(),
665 - treatment.build(), DROP_PRIORITY, appId,
666 - 0, true, FlowRule.Type.IP);
667 -
668 - ops = install ? ops.add(rule) : ops.remove(rule);
669 -
670 - flowService.apply(ops.build(new FlowRuleOperationsContext() {
671 - @Override
672 - public void onSuccess(FlowRuleOperations ops) {
673 - log.info("Provisioned FIB table for bgp router");
674 - }
675 -
676 - @Override
677 - public void onError(FlowRuleOperations ops) {
678 - log.info("Failed to provision FIB table for bgp router");
679 - }
680 - }));
681 - }
682 -
683 - private void processTableNine(boolean install) {
684 - TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
685 - TrafficTreatment.Builder treatment = DefaultTrafficTreatment
686 - .builder();
687 - FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
688 - FlowRule rule;
689 -
690 - treatment.punt();
691 -
692 - rule = new DefaultFlowRule(deviceId, selector.build(),
693 - treatment.build(), CONTROLLER_PRIORITY,
694 - appId, 0, true, FlowRule.Type.DEFAULT);
695 -
696 - ops = install ? ops.add(rule) : ops.remove(rule);
697 -
698 - flowService.apply(ops.build(new FlowRuleOperationsContext() {
699 - @Override
700 - public void onSuccess(FlowRuleOperations ops) {
701 - log.info("Provisioned Local table for bgp router");
702 - }
703 -
704 - @Override
705 - public void onError(FlowRuleOperations ops) {
706 - log.info("Failed to provision Local table for bgp router");
707 - }
708 - }));
709 - }
710 } 407 }
711 408
712 private class InternalGroupListener implements GroupListener { 409 private class InternalGroupListener implements GroupListener {
......
...@@ -26,4 +26,9 @@ public class AbstractBehaviour implements Behaviour { ...@@ -26,4 +26,9 @@ public class AbstractBehaviour implements Behaviour {
26 public void setData(DriverData data) { 26 public void setData(DriverData data) {
27 this.data = data; 27 this.data = data;
28 } 28 }
29 +
30 + @Override
31 + public DriverData data() {
32 + return data;
33 + }
29 } 34 }
......
...@@ -29,4 +29,11 @@ public interface Behaviour { ...@@ -29,4 +29,11 @@ public interface Behaviour {
29 */ 29 */
30 void setData(DriverData data); 30 void setData(DriverData data);
31 31
32 + /**
33 + * Obtains the driver data.
34 + *
35 + * @return driver data
36 + */
37 + DriverData data();
38 +
32 } 39 }
......
...@@ -32,7 +32,7 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -32,7 +32,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
32 public final class DefaultFilteringObjective implements FilteringObjective { 32 public final class DefaultFilteringObjective implements FilteringObjective {
33 33
34 34
35 - private final Criterion key; 35 + private final Type type;
36 private final boolean permanent; 36 private final boolean permanent;
37 private final int timeout; 37 private final int timeout;
38 private final ApplicationId appId; 38 private final ApplicationId appId;
...@@ -41,10 +41,10 @@ public final class DefaultFilteringObjective implements FilteringObjective { ...@@ -41,10 +41,10 @@ public final class DefaultFilteringObjective implements FilteringObjective {
41 private final int id; 41 private final int id;
42 private final Operation op; 42 private final Operation op;
43 43
44 - private DefaultFilteringObjective(Criterion key, boolean permanent, int timeout, 44 + private DefaultFilteringObjective(Type type, boolean permanent, int timeout,
45 ApplicationId appId, int priority, 45 ApplicationId appId, int priority,
46 List<Criterion> conditions, Operation op) { 46 List<Criterion> conditions, Operation op) {
47 - this.key = key; 47 + this.type = type;
48 this.permanent = permanent; 48 this.permanent = permanent;
49 this.timeout = timeout; 49 this.timeout = timeout;
50 this.appId = appId; 50 this.appId = appId;
...@@ -52,14 +52,13 @@ public final class DefaultFilteringObjective implements FilteringObjective { ...@@ -52,14 +52,13 @@ public final class DefaultFilteringObjective implements FilteringObjective {
52 this.conditions = conditions; 52 this.conditions = conditions;
53 this.op = op; 53 this.op = op;
54 54
55 - this.id = Objects.hash(key, conditions, permanent, 55 + this.id = Objects.hash(type, conditions, permanent,
56 timeout, appId, priority); 56 timeout, appId, priority);
57 } 57 }
58 58
59 -
60 @Override 59 @Override
61 - public Criterion key() { 60 + public Type type() {
62 - return key; 61 + return this.type;
63 } 62 }
64 63
65 @Override 64 @Override
...@@ -111,7 +110,7 @@ public final class DefaultFilteringObjective implements FilteringObjective { ...@@ -111,7 +110,7 @@ public final class DefaultFilteringObjective implements FilteringObjective {
111 private final ImmutableList.Builder<Criterion> listBuilder 110 private final ImmutableList.Builder<Criterion> listBuilder
112 = ImmutableList.builder(); 111 = ImmutableList.builder();
113 112
114 - private Criterion key; 113 + private Type type;
115 private boolean permanent = DEFAULT_PERMANENT; 114 private boolean permanent = DEFAULT_PERMANENT;
116 private int timeout = DEFAULT_TIMEOUT; 115 private int timeout = DEFAULT_TIMEOUT;
117 private ApplicationId appId; 116 private ApplicationId appId;
...@@ -124,8 +123,14 @@ public final class DefaultFilteringObjective implements FilteringObjective { ...@@ -124,8 +123,14 @@ public final class DefaultFilteringObjective implements FilteringObjective {
124 } 123 }
125 124
126 @Override 125 @Override
127 - public Builder withKey(Criterion criterion) { 126 + public Builder permit() {
128 - key = criterion; 127 + this.type = Type.PERMIT;
128 + return this;
129 + }
130 +
131 + @Override
132 + public Builder deny() {
133 + this.type = Type.DENY;
129 return this; 134 return this;
130 } 135 }
131 136
...@@ -157,11 +162,11 @@ public final class DefaultFilteringObjective implements FilteringObjective { ...@@ -157,11 +162,11 @@ public final class DefaultFilteringObjective implements FilteringObjective {
157 @Override 162 @Override
158 public FilteringObjective add() { 163 public FilteringObjective add() {
159 List<Criterion> conditions = listBuilder.build(); 164 List<Criterion> conditions = listBuilder.build();
160 - checkNotNull(key, "Must have a key."); 165 + checkNotNull(type, "Must have a type.");
161 checkArgument(!conditions.isEmpty(), "Must have at least one condition."); 166 checkArgument(!conditions.isEmpty(), "Must have at least one condition.");
162 checkNotNull(appId, "Must supply an application id"); 167 checkNotNull(appId, "Must supply an application id");
163 168
164 - return new DefaultFilteringObjective(key, permanent, timeout, 169 + return new DefaultFilteringObjective(type, permanent, timeout,
165 appId, priority, conditions, 170 appId, priority, conditions,
166 Operation.ADD); 171 Operation.ADD);
167 172
...@@ -170,11 +175,11 @@ public final class DefaultFilteringObjective implements FilteringObjective { ...@@ -170,11 +175,11 @@ public final class DefaultFilteringObjective implements FilteringObjective {
170 @Override 175 @Override
171 public FilteringObjective remove() { 176 public FilteringObjective remove() {
172 List<Criterion> conditions = listBuilder.build(); 177 List<Criterion> conditions = listBuilder.build();
173 - checkNotNull(key, "Must have a key."); 178 + checkNotNull(type, "Must have a type.");
174 checkArgument(!conditions.isEmpty(), "Must have at least one condition."); 179 checkArgument(!conditions.isEmpty(), "Must have at least one condition.");
175 checkNotNull(appId, "Must supply an application id"); 180 checkNotNull(appId, "Must supply an application id");
176 181
177 - return new DefaultFilteringObjective(key, permanent, timeout, 182 + return new DefaultFilteringObjective(type, permanent, timeout,
178 appId, priority, conditions, 183 appId, priority, conditions,
179 Operation.REMOVE); 184 Operation.REMOVE);
180 185
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
15 */ 15 */
16 package org.onosproject.net.flowobjective; 16 package org.onosproject.net.flowobjective;
17 17
18 +import org.onosproject.core.ApplicationId;
18 import org.onosproject.net.flow.criteria.Criterion; 19 import org.onosproject.net.flow.criteria.Criterion;
19 20
20 import java.util.Collection; 21 import java.util.Collection;
...@@ -27,12 +28,23 @@ import java.util.Collection; ...@@ -27,12 +28,23 @@ import java.util.Collection;
27 */ 28 */
28 public interface FilteringObjective extends Objective { 29 public interface FilteringObjective extends Objective {
29 30
31 + enum Type {
32 + /**
33 + * Enables the filtering condition.
34 + */
35 + PERMIT,
36 +
37 + /**
38 + * Disables the filtering condition.
39 + */
40 + DENY
41 + }
42 +
30 /** 43 /**
31 - * Represents filtering key used in this filter. 44 + * Obtain this filtering type.
32 - * 45 + * @return the type
33 - * @return a criterion
34 */ 46 */
35 - Criterion key(); 47 + public Type type();
36 48
37 /** 49 /**
38 * The set of conditions the filter must provision at the device. 50 * The set of conditions the filter must provision at the device.
...@@ -55,12 +67,23 @@ public interface FilteringObjective extends Objective { ...@@ -55,12 +67,23 @@ public interface FilteringObjective extends Objective {
55 public Builder addCondition(Criterion criterion); 67 public Builder addCondition(Criterion criterion);
56 68
57 /** 69 /**
58 - * Add a filtering key. 70 + * Permit this filtering condition set.
59 - * 71 + * @return a filtering builder
60 - * @param criterion new criterion 72 + */
61 - * @return a filtering builder. 73 + public Builder permit();
74 +
75 + /**
76 + * Deny this filtering condition set.
77 + * @return a filtering builder
78 + */
79 + public Builder deny();
80 +
81 + /**
82 + * Assigns an application id.
83 + * @param appId an application id
84 + * @return a filtering builder
62 */ 85 */
63 - public Builder withKey(Criterion criterion); 86 + public Builder fromApp(ApplicationId appId);
64 87
65 /** 88 /**
66 * Builds the filtering objective that will be added. 89 * Builds the filtering objective that will be added.
......
...@@ -15,7 +15,9 @@ ...@@ -15,7 +15,9 @@
15 */ 15 */
16 package org.onosproject.net.flowobjective.impl; 16 package org.onosproject.net.flowobjective.impl;
17 17
18 +import com.google.common.collect.Lists;
18 import com.google.common.collect.Maps; 19 import com.google.common.collect.Maps;
20 +import com.google.common.util.concurrent.Futures;
19 import org.apache.felix.scr.annotations.Activate; 21 import org.apache.felix.scr.annotations.Activate;
20 import org.apache.felix.scr.annotations.Component; 22 import org.apache.felix.scr.annotations.Component;
21 import org.apache.felix.scr.annotations.Deactivate; 23 import org.apache.felix.scr.annotations.Deactivate;
...@@ -43,11 +45,13 @@ import org.onosproject.net.flowobjective.FilteringObjective; ...@@ -43,11 +45,13 @@ import org.onosproject.net.flowobjective.FilteringObjective;
43 import org.onosproject.net.flowobjective.FlowObjectiveService; 45 import org.onosproject.net.flowobjective.FlowObjectiveService;
44 import org.onosproject.net.flowobjective.ForwardingObjective; 46 import org.onosproject.net.flowobjective.ForwardingObjective;
45 import org.onosproject.net.flowobjective.NextObjective; 47 import org.onosproject.net.flowobjective.NextObjective;
48 +import org.onosproject.net.flowobjective.Objective;
46 import org.onosproject.net.group.GroupService; 49 import org.onosproject.net.group.GroupService;
47 import org.slf4j.Logger; 50 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory; 51 import org.slf4j.LoggerFactory;
49 52
50 import java.util.Collection; 53 import java.util.Collection;
54 +import java.util.Collections;
51 import java.util.Map; 55 import java.util.Map;
52 import java.util.concurrent.Future; 56 import java.util.concurrent.Future;
53 57
...@@ -87,12 +91,16 @@ public class FlowObjectiveManager implements FlowObjectiveService { ...@@ -87,12 +91,16 @@ public class FlowObjectiveManager implements FlowObjectiveService {
87 91
88 92
89 private final Map<DeviceId, DriverHandler> driverHandlers = Maps.newConcurrentMap(); 93 private final Map<DeviceId, DriverHandler> driverHandlers = Maps.newConcurrentMap();
94 + private final Map<DeviceId, Pipeliner> pipeliners = Maps.newConcurrentMap();
90 95
91 private final PipelinerContext context = new InnerPipelineContext(); 96 private final PipelinerContext context = new InnerPipelineContext();
92 private final MastershipListener mastershipListener = new InnerMastershipListener(); 97 private final MastershipListener mastershipListener = new InnerMastershipListener();
93 private final DeviceListener deviceListener = new InnerDeviceListener(); 98 private final DeviceListener deviceListener = new InnerDeviceListener();
94 99
95 protected ServiceDirectory serviceDirectory = new DefaultServiceDirectory(); 100 protected ServiceDirectory serviceDirectory = new DefaultServiceDirectory();
101 +
102 + private final Map<DeviceId, Collection<Objective>> pendingObjectives =
103 + Maps.newConcurrentMap();
96 private NodeId localNode; 104 private NodeId localNode;
97 105
98 @Activate 106 @Activate
...@@ -114,26 +122,51 @@ public class FlowObjectiveManager implements FlowObjectiveService { ...@@ -114,26 +122,51 @@ public class FlowObjectiveManager implements FlowObjectiveService {
114 @Override 122 @Override
115 public Future<Boolean> filter(DeviceId deviceId, 123 public Future<Boolean> filter(DeviceId deviceId,
116 Collection<FilteringObjective> filteringObjectives) { 124 Collection<FilteringObjective> filteringObjectives) {
117 - return getDevicePipeliner(deviceId).filter(filteringObjectives); 125 + if (deviceService.isAvailable(deviceId)) {
126 + return getDevicePipeliner(deviceId).filter(filteringObjectives);
127 + } else {
128 + filteringObjectives.forEach(obj -> updatePendingMap(deviceId, obj));
129 + }
130 + return Futures.immediateFuture(true);
118 } 131 }
119 132
133 +
134 +
120 @Override 135 @Override
121 public Future<Boolean> forward(DeviceId deviceId, 136 public Future<Boolean> forward(DeviceId deviceId,
122 Collection<ForwardingObjective> forwardingObjectives) { 137 Collection<ForwardingObjective> forwardingObjectives) {
123 - return getDevicePipeliner(deviceId).forward(forwardingObjectives); 138 + if (deviceService.isAvailable(deviceId)) {
139 + return getDevicePipeliner(deviceId).forward(forwardingObjectives);
140 + } else {
141 + forwardingObjectives.forEach(obj -> updatePendingMap(deviceId, obj));
142 + }
143 + return Futures.immediateFuture(true);
124 } 144 }
125 145
126 @Override 146 @Override
127 public Future<Boolean> next(DeviceId deviceId, 147 public Future<Boolean> next(DeviceId deviceId,
128 Collection<NextObjective> nextObjectives) { 148 Collection<NextObjective> nextObjectives) {
129 - return getDevicePipeliner(deviceId).next(nextObjectives); 149 + if (deviceService.isAvailable(deviceId)) {
150 + return getDevicePipeliner(deviceId).next(nextObjectives);
151 + } else {
152 + nextObjectives.forEach(obj -> updatePendingMap(deviceId, obj));
153 + }
154 + return Futures.immediateFuture(true);
130 } 155 }
131 156
132 - // Retrieves the device handler pipeline behaviour from the cache. 157 + private void updatePendingMap(DeviceId deviceId, Objective pending) {
158 + if (pendingObjectives.putIfAbsent(deviceId, Lists.newArrayList(pending)) != null) {
159 + Collection<Objective> objectives = pendingObjectives.get(deviceId);
160 + objectives.add(pending);
161 + }
162 +
163 + }
164 +
165 + // Retrieves the device pipeline behaviour from the cache.
133 private Pipeliner getDevicePipeliner(DeviceId deviceId) { 166 private Pipeliner getDevicePipeliner(DeviceId deviceId) {
134 - DriverHandler handler = driverHandlers.get(deviceId); 167 + Pipeliner pipeliner = pipeliners.get(deviceId);
135 - checkState(handler != null, NOT_INITIALIZED); 168 + checkState(pipeliner != null, NOT_INITIALIZED);
136 - return handler != null ? handler.behaviour(Pipeliner.class) : null; 169 + return pipeliner;
137 } 170 }
138 171
139 172
...@@ -164,6 +197,7 @@ public class FlowObjectiveManager implements FlowObjectiveService { ...@@ -164,6 +197,7 @@ public class FlowObjectiveManager implements FlowObjectiveService {
164 case DEVICE_AVAILABILITY_CHANGED: 197 case DEVICE_AVAILABILITY_CHANGED:
165 if (deviceService.isAvailable(event.subject().id())) { 198 if (deviceService.isAvailable(event.subject().id())) {
166 setupPipelineHandler(event.subject().id()); 199 setupPipelineHandler(event.subject().id());
200 + processPendingObjectives(event.subject().id());
167 } 201 }
168 break; 202 break;
169 case DEVICE_UPDATED: 203 case DEVICE_UPDATED:
...@@ -182,6 +216,21 @@ public class FlowObjectiveManager implements FlowObjectiveService { ...@@ -182,6 +216,21 @@ public class FlowObjectiveManager implements FlowObjectiveService {
182 break; 216 break;
183 } 217 }
184 } 218 }
219 +
220 + private void processPendingObjectives(DeviceId deviceId) {
221 + pendingObjectives.get(deviceId).forEach(obj -> {
222 + if (obj instanceof NextObjective) {
223 + getDevicePipeliner(deviceId)
224 + .next(Collections.singletonList((NextObjective) obj));
225 + } else if (obj instanceof ForwardingObjective) {
226 + getDevicePipeliner(deviceId)
227 + .forward(Collections.singletonList((ForwardingObjective) obj));
228 + } else {
229 + getDevicePipeliner(deviceId)
230 + .filter(Collections.singletonList((FilteringObjective) obj));
231 + }
232 + });
233 + }
185 } 234 }
186 235
187 private void setupPipelineHandler(DeviceId deviceId) { 236 private void setupPipelineHandler(DeviceId deviceId) {
...@@ -205,7 +254,9 @@ public class FlowObjectiveManager implements FlowObjectiveService { ...@@ -205,7 +254,9 @@ public class FlowObjectiveManager implements FlowObjectiveService {
205 } 254 }
206 255
207 // Always (re)initialize the pipeline behaviour 256 // Always (re)initialize the pipeline behaviour
208 - handler.behaviour(Pipeliner.class).init(deviceId, context); 257 + Pipeliner pipeliner = handler.behaviour(Pipeliner.class);
258 + pipeliner.init(deviceId, context);
259 + pipeliners.putIfAbsent(deviceId, pipeliner);
209 log.info("Driver {} bound to device {}", handler.driver().name(), deviceId); 260 log.info("Driver {} bound to device {}", handler.driver().name(), deviceId);
210 } 261 }
211 } 262 }
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
15 */ 15 */
16 package org.onosproject.driver.pipeline; 16 package org.onosproject.driver.pipeline;
17 17
18 +import com.google.common.collect.Sets;
19 +import com.google.common.util.concurrent.SettableFuture;
18 import org.onlab.osgi.ServiceDirectory; 20 import org.onlab.osgi.ServiceDirectory;
19 import org.onlab.packet.Ethernet; 21 import org.onlab.packet.Ethernet;
20 import org.onlab.packet.MacAddress; 22 import org.onlab.packet.MacAddress;
...@@ -34,9 +36,12 @@ import org.onosproject.net.flow.FlowRuleOperationsContext; ...@@ -34,9 +36,12 @@ import org.onosproject.net.flow.FlowRuleOperationsContext;
34 import org.onosproject.net.flow.FlowRuleService; 36 import org.onosproject.net.flow.FlowRuleService;
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.criteria.Criteria;
40 +import org.onosproject.net.flow.criteria.Criterion;
37 import org.onosproject.net.flowobjective.FilteringObjective; 41 import org.onosproject.net.flowobjective.FilteringObjective;
38 import org.onosproject.net.flowobjective.ForwardingObjective; 42 import org.onosproject.net.flowobjective.ForwardingObjective;
39 import org.onosproject.net.flowobjective.NextObjective; 43 import org.onosproject.net.flowobjective.NextObjective;
44 +import org.onosproject.net.flowobjective.Objective;
40 import org.slf4j.Logger; 45 import org.slf4j.Logger;
41 46
42 import java.util.Collection; 47 import java.util.Collection;
...@@ -79,7 +84,54 @@ public class OVSCorsaPipeline extends AbstractBehaviour implements Pipeliner { ...@@ -79,7 +84,54 @@ public class OVSCorsaPipeline extends AbstractBehaviour implements Pipeliner {
79 84
80 @Override 85 @Override
81 public Future<Boolean> filter(Collection<FilteringObjective> filteringObjectives) { 86 public Future<Boolean> filter(Collection<FilteringObjective> filteringObjectives) {
82 - return null; 87 + Collection<Future<Boolean>> results =
88 + Sets.newHashSet();
89 + filteringObjectives.stream()
90 + .filter(obj -> obj.type() == FilteringObjective.Type.PERMIT)
91 + .forEach(obj -> obj.conditions()
92 + .forEach(condition ->
93 + results.add(processCondition(condition,
94 + obj.op() == Objective.Operation.ADD,
95 + obj.appId()))
96 + ));
97 +
98 + //TODO: return something more helpful/sensible in the future (no pun intended)
99 + return results.iterator().next();
100 +
101 + }
102 +
103 + private Future<Boolean> processCondition(Criterion c, boolean install,
104 + ApplicationId applicationId) {
105 + SettableFuture<Boolean> result = SettableFuture.create();
106 + if (c.type() == Criterion.Type.ETH_DST) {
107 + Criteria.EthCriterion e = (Criteria.EthCriterion) c;
108 + log.debug("adding rule for MAC: {}", e.mac());
109 +
110 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
111 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
112 + selector.matchEthDst(e.mac());
113 + treatment.transition(FlowRule.Type.VLAN_MPLS);
114 + FlowRule rule = new DefaultFlowRule(deviceId, selector.build(),
115 + treatment.build(),
116 + CONTROLLER_PRIORITY, applicationId, 0,
117 + true, FlowRule.Type.FIRST);
118 + FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
119 + ops = install ? ops.add(rule) : ops.remove(rule);
120 + flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
121 + @Override
122 + public void onSuccess(FlowRuleOperations ops) {
123 + result.set(true);
124 + log.info("Provisioned default table for bgp router");
125 + }
126 +
127 + @Override
128 + public void onError(FlowRuleOperations ops) {
129 + result.set(false);
130 + log.info("Failed to provision default table for bgp router");
131 + }
132 + }));
133 + }
134 + return result;
83 } 135 }
84 136
85 @Override 137 @Override
......