Charles Chan
Committed by Gerrit Code Review

[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
......@@ -23,7 +23,6 @@ import org.onlab.packet.IpPrefix;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.MastershipRole;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -97,7 +96,7 @@ public class DefaultRoutingHandler {
log.debug("populateAllRoutingRules: populationStatus is STARTED");
for (Device sw : srManager.deviceService.getDevices()) {
if (srManager.mastershipService.getLocalRole(sw.id()) != MastershipRole.MASTER) {
if (!srManager.mastershipService.isLocalMaster(sw.id())) {
log.debug("populateAllRoutingRules: skipping device {}...we are not master",
sw.id());
continue;
......@@ -146,8 +145,7 @@ public class DefaultRoutingHandler {
// Take the snapshots of the links
updatedEcmpSpgMap = new HashMap<>();
for (Device sw : srManager.deviceService.getDevices()) {
if (srManager.mastershipService.
getLocalRole(sw.id()) != MastershipRole.MASTER) {
if (!srManager.mastershipService.isLocalMaster(sw.id())) {
continue;
}
ECMPShortestPathGraph ecmpSpgUpdated =
......@@ -273,8 +271,7 @@ public class DefaultRoutingHandler {
for (Device sw : srManager.deviceService.getDevices()) {
log.debug("Computing the impacted routes for device {} due to link fail",
sw.id());
if (srManager.mastershipService.
getLocalRole(sw.id()) != MastershipRole.MASTER) {
if (!srManager.mastershipService.isLocalMaster(sw.id())) {
continue;
}
ECMPShortestPathGraph ecmpSpg = currentEcmpSpgMap.get(sw.id());
......@@ -320,8 +317,7 @@ public class DefaultRoutingHandler {
for (Device sw : srManager.deviceService.getDevices()) {
log.debug("Computing the impacted routes for device {}",
sw.id());
if (srManager.mastershipService.
getLocalRole(sw.id()) != MastershipRole.MASTER) {
if (!srManager.mastershipService.isLocalMaster(sw.id())) {
log.debug("No mastership for {} and skip route optimization",
sw.id());
continue;
......
......@@ -44,8 +44,6 @@ import java.util.concurrent.ConcurrentHashMap;
* Segment Routing configuration component that reads the
* segment routing related configuration from Network Configuration Manager
* component and organizes in more accessible formats.
*
* TODO: Merge multiple Segment Routing configuration wrapper classes into one.
*/
public class DeviceConfiguration implements DeviceProperties {
......@@ -251,6 +249,26 @@ public class DeviceConfiguration implements DeviceProperties {
return allSegmentIds;
}
@Override
public Map<Ip4Prefix, List<PortNumber>> getSubnetPortsMap(DeviceId deviceId) {
Map<Ip4Prefix, List<PortNumber>> subnetPortMap = new HashMap<>();
// Construct subnet-port mapping from port-subnet mapping
Map<PortNumber, Ip4Prefix> portSubnetMap =
this.deviceConfigMap.get(deviceId).subnets;
portSubnetMap.forEach((port, subnet) -> {
if (subnetPortMap.containsKey(subnet)) {
subnetPortMap.get(subnet).add(port);
} else {
ArrayList<PortNumber> ports = new ArrayList<>();
ports.add(port);
subnetPortMap.put(subnet, ports);
}
});
return subnetPortMap;
}
/**
* Returns the device identifier or data plane identifier (dpid)
* of a segment router given its segment id.
......
......@@ -22,13 +22,17 @@ import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.Ethernet;
import org.onlab.packet.VlanId;
import org.onlab.packet.IPv4;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip4Prefix;
import org.onlab.packet.VlanId;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.util.KryoNamespace;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.event.Event;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.config.ConfigFactory;
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigRegistry;
......@@ -57,6 +61,7 @@ import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.onosproject.net.topology.TopologyService;
import org.onosproject.segmentrouting.grouphandler.SubnetNextObjectiveStoreKey;
import org.onosproject.store.service.EventuallyConsistentMap;
import org.onosproject.store.service.EventuallyConsistentMapBuilder;
import org.onosproject.store.service.StorageService;
......@@ -136,6 +141,7 @@ public class SegmentRoutingManager implements SegmentRoutingService {
// Per device next objective ID store with (device id + neighbor set) as key
private EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey,
Integer> nsNextObjStore = null;
private EventuallyConsistentMap<SubnetNextObjectiveStoreKey, Integer> subnetNextObjStore = null;
private EventuallyConsistentMap<String, Tunnel> tunnelStore = null;
private EventuallyConsistentMap<String, Policy> policyStore = null;
// Per device, per-subnet assigned-vlans store, with (device id + subnet
......@@ -180,6 +186,8 @@ public class SegmentRoutingManager implements SegmentRoutingService {
kryoBuilder = new KryoNamespace.Builder()
.register(NeighborSetNextObjectiveStoreKey.class,
SubnetNextObjectiveStoreKey.class,
SubnetAssignedVidStoreKey.class,
NeighborSet.class,
DeviceId.class,
URI.class,
......@@ -191,8 +199,11 @@ public class SegmentRoutingManager implements SegmentRoutingService {
Policy.class,
TunnelPolicy.class,
Policy.Type.class,
SubnetAssignedVidStoreKey.class,
VlanId.class
VlanId.class,
Ip4Address.class,
Ip4Prefix.class,
IpAddress.Version.class,
ConnectPoint.class
);
log.debug("Creating EC map nsnextobjectivestore");
......@@ -206,6 +217,16 @@ public class SegmentRoutingManager implements SegmentRoutingService {
.build();
log.trace("Current size {}", nsNextObjStore.size());
log.debug("Creating EC map subnetnextobjectivestore");
EventuallyConsistentMapBuilder<SubnetNextObjectiveStoreKey, Integer>
subnetNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder();
subnetNextObjStore = subnetNextObjMapBuilder
.withName("subnetnextobjectivestore")
.withSerializer(kryoBuilder)
.withTimestampProvider((k, v) -> new WallClockTimestamp())
.build();
EventuallyConsistentMapBuilder<String, Tunnel> tunnelMapBuilder =
storageService.eventuallyConsistentMapBuilder();
......@@ -399,6 +420,25 @@ public class SegmentRoutingManager implements SegmentRoutingService {
}
}
/**
* Returns the next objective ID for the Subnet given. If the nextObjectiveID does not exist,
* a new one is created and returned.
*
* @param deviceId Device ID
* @param prefix Subnet
* @return next objective ID
*/
public int getSubnetNextObjectiveId(DeviceId deviceId, IpPrefix prefix) {
if (groupHandlerMap.get(deviceId) != null) {
log.trace("getSubnetNextObjectiveId query in device {}", deviceId);
return groupHandlerMap
.get(deviceId).getSubnetNextObjectiveId(prefix);
} else {
log.warn("getSubnetNextObjectiveId query in device {} not found", deviceId);
return -1;
}
}
private class InternalPacketProcessor implements PacketProcessor {
@Override
public void process(PacketContext context) {
......@@ -559,15 +599,20 @@ public class SegmentRoutingManager implements SegmentRoutingService {
//Because in a multi-instance setup, instances can initiate
//groups for any devices. Also the default TTP rules are needed
//to be pushed before inserting any IP table entries for any device
DefaultGroupHandler dgh = DefaultGroupHandler.
DefaultGroupHandler groupHandler = DefaultGroupHandler.
createGroupHandler(device.id(),
appId,
deviceConfiguration,
linkService,
flowObjectiveService,
nsNextObjStore);
groupHandlerMap.put(device.id(), dgh);
nsNextObjStore,
subnetNextObjStore);
groupHandlerMap.put(device.id(), groupHandler);
defaultRoutingHandler.populatePortAddressingRules(device.id());
if (mastershipService.isLocalMaster(device.id())) {
groupHandler.createGroupsFromSubnetConfig();
}
}
private void processPortRemoved(Device device, Port port) {
......@@ -610,9 +655,14 @@ public class SegmentRoutingManager implements SegmentRoutingService {
.createGroupHandler(device.id(), appId,
deviceConfiguration, linkService,
flowObjectiveService,
nsNextObjStore);
nsNextObjStore,
subnetNextObjStore);
groupHandlerMap.put(device.id(), groupHandler);
defaultRoutingHandler.populatePortAddressingRules(device.id());
if (mastershipService.isLocalMaster(device.id())) {
groupHandler.createGroupsFromSubnetConfig();
}
}
defaultRoutingHandler.startPopulationProcess();
......
......@@ -53,8 +53,11 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler {
FlowObjectiveService flowObjService,
EventuallyConsistentMap<
NeighborSetNextObjectiveStoreKey,
Integer> nsNextObjStore) {
super(deviceId, appId, config, linkService, flowObjService, nsNextObjStore);
Integer> nsNextObjStore,
EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
Integer> subnetNextObjStore) {
super(deviceId, appId, config, linkService, flowObjService,
nsNextObjStore, subnetNextObjStore);
}
@Override
......
......@@ -25,10 +25,11 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.stream.Collectors;
import org.onlab.packet.Ip4Prefix;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.MplsLabel;
import org.onlab.util.KryoNamespace;
......@@ -74,7 +75,8 @@ public class DefaultGroupHandler {
// new HashMap<NeighborSet, Integer>();
protected EventuallyConsistentMap<
NeighborSetNextObjectiveStoreKey, Integer> nsNextObjStore = null;
protected Random rand = new Random();
protected EventuallyConsistentMap<
SubnetNextObjectiveStoreKey, Integer> subnetNextObjStore = null;
protected KryoNamespace.Builder kryo = new KryoNamespace.Builder()
.register(URI.class).register(HashSet.class)
......@@ -90,7 +92,9 @@ public class DefaultGroupHandler {
FlowObjectiveService flowObjService,
EventuallyConsistentMap<
NeighborSetNextObjectiveStoreKey,
Integer> nsNextObjStore) {
Integer> nsNextObjStore,
EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
Integer> subnetNextObjStore) {
this.deviceId = checkNotNull(deviceId);
this.appId = checkNotNull(appId);
this.deviceConfig = checkNotNull(config);
......@@ -101,6 +105,7 @@ public class DefaultGroupHandler {
nodeMacAddr = checkNotNull(config.getDeviceMac(deviceId));
this.flowObjectiveService = flowObjService;
this.nsNextObjStore = nsNextObjStore;
this.subnetNextObjStore = subnetNextObjStore;
populateNeighborMaps();
}
......@@ -115,7 +120,8 @@ public class DefaultGroupHandler {
* @param config interface to retrieve the device properties
* @param linkService link service object
* @param flowObjService flow objective service object
* @param nsNextObjStore next objective store map
* @param nsNextObjStore NeighborSet next objective store map
* @param subnetNextObjStore subnet next objective store map
* @return default group handler type
*/
public static DefaultGroupHandler createGroupHandler(DeviceId deviceId,
......@@ -123,18 +129,23 @@ public class DefaultGroupHandler {
DeviceProperties config,
LinkService linkService,
FlowObjectiveService flowObjService,
EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey,
Integer> nsNextObjStore) {
EventuallyConsistentMap<
NeighborSetNextObjectiveStoreKey,
Integer> nsNextObjStore,
EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
Integer> subnetNextObjStore) {
if (config.isEdgeDevice(deviceId)) {
return new DefaultEdgeGroupHandler(deviceId, appId, config,
linkService,
flowObjService,
nsNextObjStore);
nsNextObjStore,
subnetNextObjStore);
} else {
return new DefaultTransitGroupHandler(deviceId, appId, config,
linkService,
flowObjService,
nsNextObjStore);
nsNextObjStore,
subnetNextObjStore);
}
}
......@@ -323,6 +334,44 @@ public class DefaultGroupHandler {
}
/**
* Returns the next objective associated with the neighborset.
* If there is no next objective for this neighborset, this API
* would create a next objective and return.
*
* @param prefix subnet information
* @return int if found or -1
*/
public int getSubnetNextObjectiveId(IpPrefix prefix) {
Integer nextId = subnetNextObjStore.
get(new SubnetNextObjectiveStoreKey(deviceId, prefix));
if (nextId == null) {
log.trace("getSubnetNextObjectiveId in device{}: Next objective id "
+ "not found for {} and creating", deviceId, prefix);
log.trace("getSubnetNextObjectiveId: subnetNextObjStore contents for device {}: {}",
deviceId,
subnetNextObjStore.entrySet()
.stream()
.filter((subnetStoreEntry) ->
(subnetStoreEntry.getKey().deviceId().equals(deviceId)))
.collect(Collectors.toList()));
createGroupsFromSubnetConfig();
nextId = subnetNextObjStore.
get(new SubnetNextObjectiveStoreKey(deviceId, prefix));
if (nextId == null) {
log.warn("subnetNextObjStore: unable to create next objective");
return -1;
} else {
log.debug("subnetNextObjStore in device{}: Next objective id {} "
+ "created for {}", deviceId, nextId, prefix);
}
} else {
log.trace("subnetNextObjStore in device{}: Next objective id {} "
+ "found for {}", deviceId, nextId, prefix);
}
return nextId;
}
/**
* Checks if the next objective ID (group) for the neighbor set exists or not.
*
* @param ns neighbor set to check
......@@ -486,6 +535,35 @@ public class DefaultGroupHandler {
}
}
public void createGroupsFromSubnetConfig() {
Map<Ip4Prefix, List<PortNumber>> subnetPortMap =
this.deviceConfig.getSubnetPortsMap(this.deviceId);
// Construct a broadcast group for each subnet
subnetPortMap.forEach((subnet, ports) -> {
int nextId = flowObjectiveService.allocateNextId();
NextObjective.Builder nextObjBuilder = DefaultNextObjective
.builder().withId(nextId)
.withType(NextObjective.Type.BROADCAST).fromApp(appId);
ports.forEach(port -> {
TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
tBuilder.setOutput(port);
nextObjBuilder.addTreatment(tBuilder.build());
});
NextObjective nextObj = nextObjBuilder.add();
flowObjectiveService.next(deviceId, nextObj);
log.debug("createGroupFromSubnetConfig: Submited "
+ "next objective {} in device {}",
nextId, deviceId);
SubnetNextObjectiveStoreKey key =
new SubnetNextObjectiveStoreKey(deviceId, subnet);
subnetNextObjStore.put(key, nextId);
});
}
public GroupKey getGroupKey(Object obj) {
return new DefaultGroupKey(kryo.build().serialize(obj));
}
......
......@@ -46,8 +46,11 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler {
FlowObjectiveService flowObjService,
EventuallyConsistentMap<
NeighborSetNextObjectiveStoreKey,
Integer> nsNextObjStore) {
super(deviceId, appId, config, linkService, flowObjService, nsNextObjStore);
Integer> nsNextObjStore,
EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
Integer> subnetNextObjStore) {
super(deviceId, appId, config, linkService, flowObjService,
nsNextObjStore, subnetNextObjStore);
}
@Override
......
......@@ -16,9 +16,12 @@
package org.onosproject.segmentrouting.grouphandler;
import java.util.List;
import java.util.Map;
import org.onlab.packet.Ip4Prefix;
import org.onlab.packet.MacAddress;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
/**
* Mechanism through which group handler module retrieves
......@@ -33,6 +36,7 @@ public interface DeviceProperties {
* @return segment id of a device
*/
int getSegmentId(DeviceId deviceId);
/**
* Returns the Mac address of a device to be used in group creation.
*
......@@ -40,6 +44,7 @@ public interface DeviceProperties {
* @return mac address of a device
*/
MacAddress getDeviceMac(DeviceId deviceId);
/**
* Indicates whether a device is edge device or transit/core device.
*
......@@ -47,6 +52,7 @@ public interface DeviceProperties {
* @return boolean
*/
boolean isEdgeDevice(DeviceId deviceId);
/**
* Returns all segment IDs to be considered in building auto
*
......@@ -54,4 +60,16 @@ public interface DeviceProperties {
* @return list of segment IDs
*/
List<Integer> getAllDeviceSegmentIds();
/**
* Returns subnet-to-ports mapping of given device.
*
* For each entry of the map
* Key: a subnet
* Value: a list of ports, which are bound to the subnet
*
* @param deviceId device identifier
* @return a map that contains all subnet-to-ports mapping of given device
*/
Map<Ip4Prefix, List<PortNumber>> getSubnetPortsMap(DeviceId deviceId);
}
......
......@@ -54,7 +54,8 @@ public class PolicyGroupHandler extends DefaultGroupHandler {
* @param config interface to retrieve the device properties
* @param linkService link service object
* @param flowObjService flow objective service object
* @param nsNextObjStore next objective store map
* @param nsNextObjStore NeighborSet next objective store map
* @param subnetNextObjStore subnet next objective store map
*/
public PolicyGroupHandler(DeviceId deviceId,
ApplicationId appId,
......@@ -62,8 +63,11 @@ public class PolicyGroupHandler extends DefaultGroupHandler {
LinkService linkService,
FlowObjectiveService flowObjService,
EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey,
Integer> nsNextObjStore) {
super(deviceId, appId, config, linkService, flowObjService, nsNextObjStore);
Integer> nsNextObjStore,
EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
Integer> subnetNextObjStore) {
super(deviceId, appId, config, linkService, flowObjService,
nsNextObjStore, subnetNextObjStore);
}
public PolicyGroupIdentifier createPolicyGroupChain(String id,
......
/*
* Copyright 2014-2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.segmentrouting.grouphandler;
import org.onlab.packet.IpPrefix;
import org.onosproject.net.DeviceId;
import java.util.Objects;
/**
* Class definition of Key for Subnet to NextObjective store.
*/
public class SubnetNextObjectiveStoreKey {
private final DeviceId deviceId;
private final IpPrefix prefix;
public SubnetNextObjectiveStoreKey(DeviceId deviceId,
IpPrefix prefix) {
this.deviceId = deviceId;
this.prefix = prefix;
}
/**
* Gets device id in this SubnetNextObjectiveStoreKey.
*
* @return device id
*/
public DeviceId deviceId() {
return this.deviceId;
}
/**
* Gets subnet information in this SubnetNextObjectiveStoreKey.
*
* @return subnet information
*/
public IpPrefix prefix() {
return this.prefix;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof SubnetNextObjectiveStoreKey)) {
return false;
}
SubnetNextObjectiveStoreKey that =
(SubnetNextObjectiveStoreKey) o;
return (Objects.equals(this.deviceId, that.deviceId) &&
Objects.equals(this.prefix, that.prefix));
}
@Override
public int hashCode() {
return Objects.hash(deviceId, prefix);
}
@Override
public String toString() {
return "Device: " + deviceId + " Subnet: " + prefix;
}
}
......@@ -139,6 +139,20 @@ public final class DefaultGroupBucket implements GroupBucket, StoredGroupBucketE
watchGroup);
}
/**
* Creates all group bucket.
*
* @param treatment traffic treatment associated with group bucket
* @return all group bucket object
*/
public static GroupBucket createAllGroupBucket(TrafficTreatment treatment) {
return new DefaultGroupBucket(GroupDescription.Type.ALL,
treatment,
(short) -1,
null,
null);
}
@Override
public GroupDescription.Type type() {
return this.type;
......
......@@ -247,6 +247,7 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
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 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
break;
case HASHED:
log.debug("processing HASHED next objective");
List<GroupBucket> buckets = nextObjective
buckets = nextObjective
.next()
.stream()
.map((treatment) -> DefaultGroupBucket
......@@ -298,8 +299,32 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
}
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 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
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 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
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 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
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 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
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
......
......@@ -115,6 +115,10 @@ public class GroupBucketEntryBuilder {
DefaultGroupBucket.createFailoverGroupBucket(treatment,
port, groupId);
break;
case ALL:
groupBucket =
DefaultGroupBucket.createAllGroupBucket(treatment);
break;
default:
log.error("Unsupported Group type : {}", type);
}
......