mirror of
https://github.com/opennetworkinglab/onos.git
synced 2026-05-04 19:56:49 +02:00
[CORD-2721] Implement group bucket modification
Change-Id: I0f637ec4ff2b0c12db53d70fed195ea28e542535
This commit is contained in:
parent
931d3e7a4a
commit
f810a7a2e7
@ -1568,38 +1568,71 @@ public class SegmentRoutingManager implements SegmentRoutingService {
|
||||
Sets.difference(new HashSet<>(prevIntf.ipAddressesList()),
|
||||
new HashSet<>(intf.ipAddressesList())));
|
||||
|
||||
if (prevIntf.vlanNative() != VlanId.NONE && !intf.vlanNative().equals(prevIntf.vlanNative())) {
|
||||
// RemoveVlanNative
|
||||
updateVlanConfigInternal(deviceId, portNum, prevIntf.vlanNative(), true, false);
|
||||
if (!prevIntf.vlanNative().equals(VlanId.NONE)
|
||||
&& !prevIntf.vlanNative().equals(intf.vlanUntagged())
|
||||
&& !prevIntf.vlanNative().equals(intf.vlanNative())) {
|
||||
if (intf.vlanTagged().contains(prevIntf.vlanNative())) {
|
||||
// Update filtering objective and L2IG group bucket
|
||||
updatePortVlanTreatment(deviceId, portNum, prevIntf.vlanNative(), false);
|
||||
} else {
|
||||
// RemoveVlanNative
|
||||
updateVlanConfigInternal(deviceId, portNum, prevIntf.vlanNative(), true, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!prevIntf.vlanUntagged().equals(VlanId.NONE)
|
||||
&& !prevIntf.vlanUntagged().equals(intf.vlanUntagged())
|
||||
&& !prevIntf.vlanUntagged().equals(intf.vlanNative())) {
|
||||
if (intf.vlanTagged().contains(prevIntf.vlanUntagged())) {
|
||||
// Update filtering objective and L2IG group bucket
|
||||
updatePortVlanTreatment(deviceId, portNum, prevIntf.vlanUntagged(), false);
|
||||
} else {
|
||||
// RemoveVlanUntagged
|
||||
updateVlanConfigInternal(deviceId, portNum, prevIntf.vlanUntagged(), true, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!prevIntf.vlanTagged().isEmpty() && !intf.vlanTagged().equals(prevIntf.vlanTagged())) {
|
||||
// RemoveVlanTagged
|
||||
prevIntf.vlanTagged().stream().filter(i -> !intf.vlanTagged().contains(i)).forEach(
|
||||
vlanId -> updateVlanConfigInternal(deviceId, portNum, vlanId, false, false)
|
||||
);
|
||||
Sets.difference(prevIntf.vlanTagged(), intf.vlanTagged()).stream()
|
||||
.filter(i -> !intf.vlanUntagged().equals(i))
|
||||
.filter(i -> !intf.vlanNative().equals(i))
|
||||
.forEach(vlanId -> updateVlanConfigInternal(
|
||||
deviceId, portNum, vlanId, false, false));
|
||||
}
|
||||
|
||||
if (prevIntf.vlanUntagged() != VlanId.NONE && !intf.vlanUntagged().equals(prevIntf.vlanUntagged())) {
|
||||
// RemoveVlanUntagged
|
||||
updateVlanConfigInternal(deviceId, portNum, prevIntf.vlanUntagged(), true, false);
|
||||
}
|
||||
|
||||
if (intf.vlanNative() != VlanId.NONE && !prevIntf.vlanNative().equals(intf.vlanNative())) {
|
||||
// AddVlanNative
|
||||
updateVlanConfigInternal(deviceId, portNum, intf.vlanNative(), true, true);
|
||||
if (!intf.vlanNative().equals(VlanId.NONE)
|
||||
&& !prevIntf.vlanNative().equals(intf.vlanNative())
|
||||
&& !prevIntf.vlanUntagged().equals(intf.vlanNative())) {
|
||||
if (prevIntf.vlanTagged().contains(intf.vlanNative())) {
|
||||
// Update filtering objective and L2IG group bucket
|
||||
updatePortVlanTreatment(deviceId, portNum, intf.vlanNative(), true);
|
||||
} else {
|
||||
// AddVlanNative
|
||||
updateVlanConfigInternal(deviceId, portNum, intf.vlanNative(), true, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (!intf.vlanTagged().isEmpty() && !intf.vlanTagged().equals(prevIntf.vlanTagged())) {
|
||||
// AddVlanTagged
|
||||
intf.vlanTagged().stream().filter(i -> !prevIntf.vlanTagged().contains(i)).forEach(
|
||||
vlanId -> updateVlanConfigInternal(deviceId, portNum, vlanId, false, true)
|
||||
Sets.difference(intf.vlanTagged(), prevIntf.vlanTagged()).stream()
|
||||
.filter(i -> !prevIntf.vlanUntagged().equals(i))
|
||||
.filter(i -> !prevIntf.vlanNative().equals(i))
|
||||
.forEach(vlanId -> updateVlanConfigInternal(
|
||||
deviceId, portNum, vlanId, false, true)
|
||||
);
|
||||
}
|
||||
|
||||
if (intf.vlanUntagged() != VlanId.NONE && !prevIntf.vlanUntagged().equals(intf.vlanUntagged())) {
|
||||
// AddVlanUntagged
|
||||
updateVlanConfigInternal(deviceId, portNum, intf.vlanUntagged(), true, true);
|
||||
if (!intf.vlanUntagged().equals(VlanId.NONE)
|
||||
&& !prevIntf.vlanUntagged().equals(intf.vlanUntagged())
|
||||
&& !prevIntf.vlanNative().equals(intf.vlanUntagged())) {
|
||||
if (prevIntf.vlanTagged().contains(intf.vlanUntagged())) {
|
||||
// Update filtering objective and L2IG group bucket
|
||||
updatePortVlanTreatment(deviceId, portNum, intf.vlanUntagged(), true);
|
||||
} else {
|
||||
// AddVlanUntagged
|
||||
updateVlanConfigInternal(deviceId, portNum, intf.vlanUntagged(), true, true);
|
||||
}
|
||||
}
|
||||
addSubnetConfig(prevIntf.connectPoint(),
|
||||
Sets.difference(new HashSet<>(intf.ipAddressesList()),
|
||||
@ -1609,6 +1642,26 @@ public class SegmentRoutingManager implements SegmentRoutingService {
|
||||
}
|
||||
}
|
||||
|
||||
private void updatePortVlanTreatment(DeviceId deviceId, PortNumber portNum,
|
||||
VlanId vlanId, boolean pushVlan) {
|
||||
DefaultGroupHandler grpHandler = getGroupHandler(deviceId);
|
||||
if (grpHandler == null) {
|
||||
log.warn("Failed to retrieve group handler for device {}", deviceId);
|
||||
return;
|
||||
}
|
||||
|
||||
// Update filtering objective for a single port
|
||||
routingRulePopulator.updateSinglePortFilters(deviceId, portNum, !pushVlan, vlanId, false);
|
||||
routingRulePopulator.updateSinglePortFilters(deviceId, portNum, pushVlan, vlanId, true);
|
||||
|
||||
if (getVlanNextObjectiveId(deviceId, vlanId) != -1) {
|
||||
// Update L2IG bucket of the port
|
||||
grpHandler.updateL2InterfaceGroupBucket(portNum, vlanId, pushVlan);
|
||||
} else {
|
||||
log.warn("Failed to retrieve next objective for vlan {} in device {}:{}", vlanId, deviceId, portNum);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateVlanConfigInternal(DeviceId deviceId, PortNumber portNum,
|
||||
VlanId vlanId, boolean pushVlan, boolean install) {
|
||||
DefaultGroupHandler grpHandler = getGroupHandler(deviceId);
|
||||
@ -1628,7 +1681,7 @@ public class SegmentRoutingManager implements SegmentRoutingService {
|
||||
if (nextId != -1 && !install) {
|
||||
// Update next objective for a single port as an output port
|
||||
// Remove a single port from L2FG
|
||||
grpHandler.updateGroupFromVlanConfiguration(portNum, Collections.singleton(vlanId), nextId, install);
|
||||
grpHandler.updateGroupFromVlanConfiguration(vlanId, portNum, nextId, install);
|
||||
// Remove L2 Bridging rule and L3 Unicast rule to the host
|
||||
hostHandler.processIntfVlanUpdatedEvent(deviceId, portNum, vlanId, pushVlan, install);
|
||||
// Remove broadcast forwarding rule and corresponding L2FG for VLAN
|
||||
@ -1645,7 +1698,7 @@ public class SegmentRoutingManager implements SegmentRoutingService {
|
||||
} else if (install) {
|
||||
if (nextId != -1) {
|
||||
// Add a single port to L2FG
|
||||
grpHandler.updateGroupFromVlanConfiguration(portNum, Collections.singleton(vlanId), nextId, install);
|
||||
grpHandler.updateGroupFromVlanConfiguration(vlanId, portNum, nextId, install);
|
||||
} else {
|
||||
// Create L2FG for VLAN
|
||||
grpHandler.createBcastGroupFromVlan(vlanId, Collections.singleton(portNum));
|
||||
|
||||
@ -1277,12 +1277,56 @@ public class DefaultGroupHandler {
|
||||
bc.run();
|
||||
}
|
||||
|
||||
public void updateGroupFromVlanConfiguration(PortNumber portNumber, Collection<VlanId> vlanIds,
|
||||
int nextId, boolean install) {
|
||||
vlanIds.forEach(vlanId -> updateGroupFromVlanInternal(vlanId, portNumber, nextId, install));
|
||||
/**
|
||||
* Modifies L2IG bucket when the interface configuration is updated, especially
|
||||
* when the interface has same VLAN ID but the VLAN type is changed (e.g., from
|
||||
* vlan-tagged [10] to vlan-untagged 10), which requires changes on
|
||||
* TrafficTreatment in turn.
|
||||
*
|
||||
* @param portNumber the port on this device that needs to be updated
|
||||
* @param vlanId the vlan id corresponding to this port
|
||||
* @param pushVlan indicates if packets should be sent out untagged or not out
|
||||
* from the port. If true, updated TrafficTreatment involves
|
||||
* pop vlan tag action. If false, updated TrafficTreatment
|
||||
* does not involve pop vlan tag action.
|
||||
*/
|
||||
public void updateL2InterfaceGroupBucket(PortNumber portNumber, VlanId vlanId, boolean pushVlan) {
|
||||
TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
|
||||
if (pushVlan) {
|
||||
tBuilder.popVlan();
|
||||
}
|
||||
tBuilder.setOutput(portNumber);
|
||||
|
||||
TrafficSelector metadata =
|
||||
DefaultTrafficSelector.builder().matchVlanId(vlanId).build();
|
||||
|
||||
int nextId = getVlanNextObjectiveId(vlanId);
|
||||
|
||||
NextObjective.Builder nextObjBuilder = DefaultNextObjective
|
||||
.builder().withId(nextId)
|
||||
.withType(NextObjective.Type.SIMPLE).fromApp(appId)
|
||||
.addTreatment(tBuilder.build())
|
||||
.withMeta(metadata);
|
||||
|
||||
ObjectiveContext context = new DefaultObjectiveContext(
|
||||
(objective) -> log.debug("port {} successfully updated NextObj {} on {}",
|
||||
portNumber, nextId, deviceId),
|
||||
(objective, error) ->
|
||||
log.warn("port {} failed to updated NextObj {} on {}: {}",
|
||||
portNumber, nextId, deviceId, error));
|
||||
|
||||
flowObjectiveService.next(deviceId, nextObjBuilder.modify(context));
|
||||
}
|
||||
|
||||
private void updateGroupFromVlanInternal(VlanId vlanId, PortNumber portNum, int nextId, boolean install) {
|
||||
/**
|
||||
* Adds a single port to the L2FG or removes it from the L2FG.
|
||||
*
|
||||
* @param vlanId the vlan id corresponding to this port
|
||||
* @param portNum the port on this device to be updated
|
||||
* @param nextId the next objective ID for the given vlan id
|
||||
* @param install if true, adds the port to L2FG. If false, removes it from L2FG.
|
||||
*/
|
||||
public void updateGroupFromVlanConfiguration(VlanId vlanId, PortNumber portNum, int nextId, boolean install) {
|
||||
TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
|
||||
if (toPopVlan(portNum, vlanId)) {
|
||||
tBuilder.popVlan();
|
||||
|
||||
@ -315,6 +315,24 @@ public final class DefaultNextObjective implements NextObjective {
|
||||
return new DefaultNextObjective(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NextObjective modify() {
|
||||
return modify(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NextObjective modify(ObjectiveContext context) {
|
||||
treatments = listBuilder.build();
|
||||
op = Operation.MODIFY;
|
||||
this.context = context;
|
||||
checkNotNull(appId, "Must supply an application id");
|
||||
checkNotNull(id, "id cannot be null");
|
||||
checkNotNull(type, "The type cannot be null");
|
||||
checkArgument(!treatments.isEmpty(), "Must have at least one treatment");
|
||||
|
||||
return new DefaultNextObjective(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NextObjective verify() {
|
||||
return verify(null);
|
||||
|
||||
@ -227,6 +227,23 @@ public interface NextObjective extends Objective {
|
||||
*/
|
||||
NextObjective removeFromExisting(ObjectiveContext context);
|
||||
|
||||
/**
|
||||
* Build the next objective that will be modified with {@link Operation}
|
||||
* MODIFY.
|
||||
*
|
||||
* @return a next objective
|
||||
*/
|
||||
|
||||
NextObjective modify();
|
||||
/**
|
||||
* Build the next objective that will be modified, with {@link Operation}
|
||||
* MODIFY. The context will be used to notify the calling application.
|
||||
*
|
||||
* @param context an objective context
|
||||
* @return a next objective
|
||||
*/
|
||||
NextObjective modify(ObjectiveContext context);
|
||||
|
||||
/**
|
||||
* Builds the next objective that needs to be verified.
|
||||
*
|
||||
|
||||
@ -62,6 +62,11 @@ public interface Objective {
|
||||
*/
|
||||
REMOVE_FROM_EXISTING,
|
||||
|
||||
/**
|
||||
* Modify an existing Next Objective. Can be used to modify group buckets.
|
||||
*/
|
||||
MODIFY,
|
||||
|
||||
/**
|
||||
* Verifies that an existing Next Objective's collection of treatments
|
||||
* are correctly represented by the underlying implementation of the objective.
|
||||
|
||||
@ -804,24 +804,6 @@ public class Ofdpa2GroupHandler {
|
||||
});
|
||||
}
|
||||
|
||||
private List<GroupBucket> createL3MulticastBucket(List<GroupInfo> groupInfos) {
|
||||
List<GroupBucket> l3McastBuckets = new ArrayList<>();
|
||||
// For each inner group
|
||||
groupInfos.forEach(groupInfo -> {
|
||||
// Points to L3 interface group if there is one.
|
||||
// Otherwise points to L2 interface group directly.
|
||||
GroupDescription nextGroupDesc = (groupInfo.nextGroupDesc() != null) ?
|
||||
groupInfo.nextGroupDesc() : groupInfo.innerMostGroupDesc();
|
||||
TrafficTreatment.Builder ttb = DefaultTrafficTreatment.builder();
|
||||
ttb.group(new GroupId(nextGroupDesc.givenGroupId()));
|
||||
GroupBucket abucket = DefaultGroupBucket.createAllGroupBucket(ttb.build());
|
||||
l3McastBuckets.add(abucket);
|
||||
});
|
||||
// Done return the new list of buckets
|
||||
return l3McastBuckets;
|
||||
}
|
||||
|
||||
|
||||
private void createL3MulticastGroup(NextObjective nextObj, VlanId vlanId,
|
||||
List<GroupInfo> groupInfos) {
|
||||
// Let's create a new list mcast buckets
|
||||
@ -1197,7 +1179,8 @@ public class Ofdpa2GroupHandler {
|
||||
newBuckets = generateNextGroupBuckets(unsentGroups, SELECT);
|
||||
|
||||
// retrieve the original L3 ECMP group
|
||||
Group l3ecmpGroup = retrieveTopLevelGroup(allActiveKeys, nextObjective.id());
|
||||
Group l3ecmpGroup = retrieveTopLevelGroup(allActiveKeys, deviceId,
|
||||
groupService, nextObjective.id());
|
||||
if (l3ecmpGroup == null) {
|
||||
fail(nextObjective, ObjectiveError.GROUPMISSING);
|
||||
return;
|
||||
@ -1270,7 +1253,8 @@ public class Ofdpa2GroupHandler {
|
||||
List<Deque<GroupKey>> allActiveKeys,
|
||||
List<GroupInfo> groupInfos,
|
||||
VlanId assignedVlan) {
|
||||
Group l2FloodGroup = retrieveTopLevelGroup(allActiveKeys, nextObj.id());
|
||||
Group l2FloodGroup = retrieveTopLevelGroup(allActiveKeys, deviceId,
|
||||
groupService, nextObj.id());
|
||||
|
||||
if (l2FloodGroup == null) {
|
||||
log.warn("Can't find L2 flood group while adding bucket to it. NextObj = {}",
|
||||
@ -1350,7 +1334,8 @@ public class Ofdpa2GroupHandler {
|
||||
List<GroupBucket> newBuckets = createL3MulticastBucket(groupInfos);
|
||||
|
||||
// get the group being edited
|
||||
Group l3mcastGroup = retrieveTopLevelGroup(allActiveKeys, nextObj.id());
|
||||
Group l3mcastGroup = retrieveTopLevelGroup(allActiveKeys, deviceId,
|
||||
groupService, nextObj.id());
|
||||
if (l3mcastGroup == null) {
|
||||
fail(nextObj, ObjectiveError.GROUPMISSING);
|
||||
return;
|
||||
@ -1578,6 +1563,56 @@ public class Ofdpa2GroupHandler {
|
||||
flowObjectiveStore.removeNextGroup(nextObjective.id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify buckets in the L2 interface group.
|
||||
*
|
||||
* @param nextObjective a next objective that contains information for the
|
||||
* buckets to be modified in the group
|
||||
* @param next the representation of the existing group-chains for this next
|
||||
* objective, from which the innermost group buckets to remove are determined
|
||||
*/
|
||||
protected void modifyBucketFromGroup(NextObjective nextObjective, NextGroup next) {
|
||||
if (nextObjective.type() != NextObjective.Type.SIMPLE) {
|
||||
log.warn("ModifyBucketFromGroup cannot be applied to nextType:{} in dev:{} for next:{}",
|
||||
nextObjective.type(), deviceId, nextObjective.id());
|
||||
fail(nextObjective, ObjectiveError.UNSUPPORTED);
|
||||
return;
|
||||
}
|
||||
|
||||
VlanId assignedVlan = readVlanFromSelector(nextObjective.meta());
|
||||
if (assignedVlan == null) {
|
||||
log.warn("VLAN ID required by simple next obj is missing. Abort.");
|
||||
fail(nextObjective, ObjectiveError.BADPARAMS);
|
||||
return;
|
||||
}
|
||||
|
||||
List<GroupInfo> groupInfos = prepareL2InterfaceGroup(nextObjective, assignedVlan);
|
||||
|
||||
// There is only one L2 interface group in this case
|
||||
GroupDescription l2InterfaceGroupDesc = groupInfos.get(0).innerMostGroupDesc();
|
||||
|
||||
// Replace group bucket for L2 interface group
|
||||
groupService.setBucketsForGroup(deviceId,
|
||||
l2InterfaceGroupDesc.appCookie(),
|
||||
l2InterfaceGroupDesc.buckets(),
|
||||
l2InterfaceGroupDesc.appCookie(),
|
||||
l2InterfaceGroupDesc.appId());
|
||||
|
||||
// update store - synchronize access as there may be multiple threads
|
||||
// trying to remove buckets from the same group, each with its own
|
||||
// potentially stale copy of allActiveKeys
|
||||
synchronized (flowObjectiveStore) {
|
||||
List<Deque<GroupKey>> modifiedGroupKeys = Lists.newArrayList();
|
||||
ArrayDeque<GroupKey> top = new ArrayDeque<>();
|
||||
top.add(l2InterfaceGroupDesc.appCookie());
|
||||
modifiedGroupKeys.add(top);
|
||||
|
||||
flowObjectiveStore.putNextGroup(nextObjective.id(),
|
||||
new OfdpaNextGroup(modifiedGroupKeys,
|
||||
nextObjective));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks existing buckets in {@link NextGroup} to verify if they match
|
||||
* the buckets in the given {@link NextObjective}. Adds or removes buckets
|
||||
@ -1840,24 +1875,6 @@ public class Ofdpa2GroupHandler {
|
||||
return (int) nextIndex.incrementAndGet();
|
||||
}
|
||||
|
||||
protected Group retrieveTopLevelGroup(List<Deque<GroupKey>> allActiveKeys,
|
||||
int nextid) {
|
||||
GroupKey topLevelGroupKey;
|
||||
if (!allActiveKeys.isEmpty()) {
|
||||
topLevelGroupKey = allActiveKeys.get(0).peekFirst();
|
||||
} else {
|
||||
log.warn("Could not determine top level group while processing"
|
||||
+ "next:{} in dev:{}", nextid, deviceId);
|
||||
return null;
|
||||
}
|
||||
Group topGroup = groupService.getGroup(deviceId, topLevelGroupKey);
|
||||
if (topGroup == null) {
|
||||
log.warn("Could not find top level group while processing "
|
||||
+ "next:{} in dev:{}", nextid, deviceId);
|
||||
}
|
||||
return topGroup;
|
||||
}
|
||||
|
||||
protected void processPendingAddGroupsOrNextObjs(GroupKey key, boolean added) {
|
||||
//first check for group chain
|
||||
Set<OfdpaGroupHandlerUtility.GroupChainElem> gceSet = pendingGroups.asMap().remove(key);
|
||||
|
||||
@ -381,6 +381,16 @@ public class Ofdpa2Pipeline extends AbstractHandlerBehaviour implements Pipeline
|
||||
nextObjective.id(), deviceId);
|
||||
groupHandler.removeBucketFromGroup(nextObjective, nextGroup);
|
||||
break;
|
||||
case MODIFY:
|
||||
if (nextGroup == null) {
|
||||
log.warn("Cannot modify next {} that does not exist in device {}",
|
||||
nextObjective.id(), deviceId);
|
||||
return;
|
||||
}
|
||||
log.debug("Processing NextObjective id {} in dev {} - modify bucket",
|
||||
nextObjective.id(), deviceId);
|
||||
groupHandler.modifyBucketFromGroup(nextObjective, nextGroup);
|
||||
break;
|
||||
case VERIFY:
|
||||
if (nextGroup == null) {
|
||||
log.warn("Cannot verify next {} that does not exist in device {}",
|
||||
|
||||
@ -394,6 +394,43 @@ public final class OfdpaGroupHandlerUtility {
|
||||
return ImmutableList.copyOf(newBuckets);
|
||||
}
|
||||
|
||||
static List<GroupBucket> createL3MulticastBucket(List<GroupInfo> groupInfos) {
|
||||
List<GroupBucket> l3McastBuckets = new ArrayList<>();
|
||||
// For each inner group
|
||||
groupInfos.forEach(groupInfo -> {
|
||||
// Points to L3 interface group if there is one.
|
||||
// Otherwise points to L2 interface group directly.
|
||||
GroupDescription nextGroupDesc = (groupInfo.nextGroupDesc() != null) ?
|
||||
groupInfo.nextGroupDesc() : groupInfo.innerMostGroupDesc();
|
||||
TrafficTreatment.Builder ttb = DefaultTrafficTreatment.builder();
|
||||
ttb.group(new GroupId(nextGroupDesc.givenGroupId()));
|
||||
GroupBucket abucket = DefaultGroupBucket.createAllGroupBucket(ttb.build());
|
||||
l3McastBuckets.add(abucket);
|
||||
});
|
||||
// Done return the new list of buckets
|
||||
return l3McastBuckets;
|
||||
}
|
||||
|
||||
static Group retrieveTopLevelGroup(List<Deque<GroupKey>> allActiveKeys,
|
||||
DeviceId deviceId,
|
||||
GroupService groupService,
|
||||
int nextid) {
|
||||
GroupKey topLevelGroupKey;
|
||||
if (!allActiveKeys.isEmpty()) {
|
||||
topLevelGroupKey = allActiveKeys.get(0).peekFirst();
|
||||
} else {
|
||||
log.warn("Could not determine top level group while processing"
|
||||
+ "next:{} in dev:{}", nextid, deviceId);
|
||||
return null;
|
||||
}
|
||||
Group topGroup = groupService.getGroup(deviceId, topLevelGroupKey);
|
||||
if (topGroup == null) {
|
||||
log.warn("Could not find top level group while processing "
|
||||
+ "next:{} in dev:{}", nextid, deviceId);
|
||||
}
|
||||
return topGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts VlanId from given group ID.
|
||||
*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user