[CORD-46] Create a broadcast group for each subnet
DONE
- Expose subnet-to-ports information from DeviceProperties and DeviceConfiguration
- Create subnetNextObjectiveStore to store <DeviceId, IpPrefix> to nextId mapping
- Implement broadcast NextObjective in SpringOpenTTP
Use ALL group type to achieve broadcast
TODO (not in this submission)
- Push ARP table for a host when its location is learned
- Push default ARP table miss rule. Action = to the broadcast group
Change-Id: I2de28095e85289e75af3fc7a02c811b270b342ad
diff --git a/drivers/src/main/java/org/onosproject/driver/pipeline/SpringOpenTTP.java b/drivers/src/main/java/org/onosproject/driver/pipeline/SpringOpenTTP.java
index 7ef72fa..31297ff 100644
--- a/drivers/src/main/java/org/onosproject/driver/pipeline/SpringOpenTTP.java
+++ b/drivers/src/main/java/org/onosproject/driver/pipeline/SpringOpenTTP.java
@@ -247,6 +247,7 @@
private void addGroup(NextObjective nextObjective) {
log.debug("addGroup with type{} for nextObjective id {}",
nextObjective.type(), nextObjective.id());
+ List<GroupBucket> buckets;
switch (nextObjective.type()) {
case SIMPLE:
log.debug("processing SIMPLE next objective");
@@ -274,7 +275,7 @@
break;
case HASHED:
log.debug("processing HASHED next objective");
- List<GroupBucket> buckets = nextObjective
+ buckets = nextObjective
.next()
.stream()
.map((treatment) -> DefaultGroupBucket
@@ -298,8 +299,32 @@
}
break;
case BROADCAST:
+ log.debug("processing BROADCAST next objective");
+ buckets = nextObjective
+ .next()
+ .stream()
+ .map((treatment) -> DefaultGroupBucket
+ .createAllGroupBucket(treatment))
+ .collect(Collectors.toList());
+ if (!buckets.isEmpty()) {
+ final GroupKey key = new DefaultGroupKey(
+ appKryo.serialize(nextObjective
+ .id()));
+ GroupDescription groupDescription = new DefaultGroupDescription(
+ deviceId,
+ GroupDescription.Type.ALL,
+ new GroupBuckets(buckets),
+ key,
+ null,
+ nextObjective.appId());
+ log.debug("Creating BROADCAST group for next objective id {}",
+ nextObjective.id());
+ groupService.addGroup(groupDescription);
+ pendingGroups.put(key, nextObjective);
+ }
+ break;
case FAILOVER:
- log.debug("BROADCAST and FAILOVER next objectives not supported");
+ log.debug("FAILOVER next objectives not supported");
fail(nextObjective, ObjectiveError.UNSUPPORTED);
log.warn("Unsupported next objective type {}", nextObjective.type());
break;
@@ -327,6 +352,8 @@
bucket = DefaultGroupBucket.createIndirectGroupBucket(treatment);
} else if (group.type() == GroupDescription.Type.SELECT) {
bucket = DefaultGroupBucket.createSelectGroupBucket(treatment);
+ } else if (group.type() == GroupDescription.Type.ALL) {
+ bucket = DefaultGroupBucket.createAllGroupBucket(treatment);
} else {
log.warn("Unsupported Group type {}", group.type());
return;
@@ -357,6 +384,8 @@
bucket = DefaultGroupBucket.createIndirectGroupBucket(treatment);
} else if (group.type() == GroupDescription.Type.SELECT) {
bucket = DefaultGroupBucket.createSelectGroupBucket(treatment);
+ } else if (group.type() == GroupDescription.Type.ALL) {
+ bucket = DefaultGroupBucket.createAllGroupBucket(treatment);
} else {
log.warn("Unsupported Group type {}", group.type());
return;
@@ -539,7 +568,7 @@
protected List<FlowRule> processEthDstFilter(Criterion c,
FilteringObjective filt,
ApplicationId applicationId) {
- List<FlowRule> rules = new ArrayList<FlowRule>();
+ List<FlowRule> rules = new ArrayList<>();
EthCriterion e = (EthCriterion) c;
TrafficSelector.Builder selectorIp = DefaultTrafficSelector
.builder();
@@ -577,7 +606,7 @@
protected List<FlowRule> processVlanIdFilter(Criterion c,
FilteringObjective filt,
ApplicationId applicationId) {
- List<FlowRule> rules = new ArrayList<FlowRule>();
+ List<FlowRule> rules = new ArrayList<>();
VlanIdCriterion v = (VlanIdCriterion) c;
log.debug("adding rule for VLAN: {}", v.vlanId());
TrafficSelector.Builder selector = DefaultTrafficSelector