use of org.onosproject.net.flow.instructions.Instruction in project onos by opennetworkinglab.
the class Ofdpa2GroupHandler method prepareL2InterfaceGroup.
private List<GroupInfo> prepareL2InterfaceGroup(NextObjective nextObj, VlanId assignedVlan) {
ImmutableList.Builder<GroupInfo> groupInfoBuilder = ImmutableList.builder();
// break up broadcast next objective to multiple groups
Collection<TrafficTreatment> buckets = nextObj.nextTreatments().stream().filter(nt -> nt.type() == NextTreatment.Type.TREATMENT).map(nt -> ((DefaultNextTreatment) nt).treatment()).collect(Collectors.toSet());
// Each treatment is converted to an L2 interface group
for (TrafficTreatment treatment : buckets) {
TrafficTreatment.Builder newTreatment = DefaultTrafficTreatment.builder();
PortNumber portNum = null;
VlanId egressVlan = null;
// ensure that the only allowed treatments are pop-vlan and output
for (Instruction ins : treatment.allInstructions()) {
if (ins.type() == Instruction.Type.L2MODIFICATION) {
L2ModificationInstruction l2ins = (L2ModificationInstruction) ins;
switch(l2ins.subtype()) {
case VLAN_POP:
newTreatment.add(l2ins);
break;
case VLAN_ID:
egressVlan = ((L2ModificationInstruction.ModVlanIdInstruction) l2ins).vlanId();
break;
default:
log.debug("action {} not permitted for broadcast nextObj", l2ins.subtype());
break;
}
} else if (ins.type() == Instruction.Type.OUTPUT) {
portNum = ((Instructions.OutputInstruction) ins).port();
newTreatment.add(ins);
} else {
log.debug("TrafficTreatment of type {} not permitted in " + " broadcast nextObjective", ins.type());
}
}
if (portNum == null) {
log.debug("Can't find output port for the bucket {}.", treatment);
continue;
}
// assemble info for l2 interface group
VlanId l2InterfaceGroupVlan = (egressVlan != null && !assignedVlan.equals(egressVlan)) ? egressVlan : assignedVlan;
int l2gk = l2InterfaceGroupKey(deviceId, l2InterfaceGroupVlan, portNum.toLong());
final GroupKey l2InterfaceGroupKey = new DefaultGroupKey(appKryo.serialize(l2gk));
int l2InterfaceGroupId = L2_INTERFACE_TYPE | ((l2InterfaceGroupVlan.toShort() & THREE_NIBBLE_MASK) << PORT_LEN) | ((int) portNum.toLong() & FOUR_NIBBLE_MASK);
GroupBucket l2InterfaceGroupBucket = DefaultGroupBucket.createIndirectGroupBucket(newTreatment.build());
GroupDescription l2InterfaceGroupDescription = new DefaultGroupDescription(deviceId, GroupDescription.Type.INDIRECT, new GroupBuckets(Collections.singletonList(l2InterfaceGroupBucket)), l2InterfaceGroupKey, l2InterfaceGroupId, nextObj.appId());
log.debug("Trying L2-Interface: device:{} gid:{} gkey:{} nextid:{}", deviceId, Integer.toHexString(l2InterfaceGroupId), l2InterfaceGroupKey, nextObj.id());
groupInfoBuilder.add(new GroupInfo(l2InterfaceGroupDescription, l2InterfaceGroupDescription));
}
return groupInfoBuilder.build();
}
use of org.onosproject.net.flow.instructions.Instruction in project onos by opennetworkinglab.
the class Ofdpa2GroupHandler method processSimpleNextObjective.
/**
* As per the OFDPA 2.0 TTP, packets are sent out of ports by using
* a chain of groups. The simple Next Objective passed in by the application
* is broken up into a group chain. The following chains can be created
* depending on the parameters in the Next Objective.
* 1. L2 Interface group (no chaining)
* 2. L3 Unicast group -> L2 Interface group
* 3. MPLS Interface group -> L2 Interface group
* 4. MPLS Swap group -> MPLS Interface group -> L2 Interface group
* 5. PW initiation group chain
*
* @param nextObj the nextObjective of type SIMPLE
*/
private void processSimpleNextObjective(NextObjective nextObj) {
TrafficTreatment treatment = nextObj.next().iterator().next();
// determine if plain L2 or L3->L2 or MPLS Swap -> MPLS Interface -> L2
boolean plainL2 = true;
boolean mplsSwap = false;
MplsLabel mplsLabel = null;
for (Instruction ins : treatment.allInstructions()) {
if (ins.type() == Instruction.Type.L2MODIFICATION) {
L2ModificationInstruction l2ins = (L2ModificationInstruction) ins;
if (l2ins.subtype() == L2ModificationInstruction.L2SubType.ETH_DST || l2ins.subtype() == L2ModificationInstruction.L2SubType.ETH_SRC) {
plainL2 = false;
}
// a MPLS Swap group before the MPLS Interface Group
if (l2ins.subtype() == L2ModificationInstruction.L2SubType.MPLS_LABEL) {
mplsSwap = true;
mplsLabel = ((L2ModificationInstruction.ModMplsLabelInstruction) l2ins).label();
}
}
}
if (plainL2) {
createL2InterfaceGroup(nextObj);
return;
}
// In order to understand if it is a pseudowire related
// next objective we look for the tunnel id in the meta.
boolean isPw = false;
if (nextObj.meta() != null) {
TunnelIdCriterion tunnelIdCriterion = (TunnelIdCriterion) nextObj.meta().getCriterion(TUNNEL_ID);
if (tunnelIdCriterion != null) {
isPw = true;
}
}
if (mplsSwap && !isPw) {
log.debug("Creating a MPLS Swap -> MPLS Interface -> L2 Interface group chain.");
// break up simple next objective to GroupChain objects
GroupInfo groupInfo = createL2L3Chain(treatment, nextObj.id(), nextObj.appId(), true, nextObj.meta());
if (groupInfo == null) {
log.error("Could not process nextObj={} in dev:{}", nextObj.id(), deviceId);
fail(nextObj, ObjectiveError.BADPARAMS);
return;
}
Deque<GroupKey> gkeyChain = new ArrayDeque<>();
// l2 interface
gkeyChain.addFirst(groupInfo.innerMostGroupDesc().appCookie());
// mpls interface
gkeyChain.addFirst(groupInfo.nextGroupDesc().appCookie());
// creating the mpls swap group and adding it to the chain
int nextGid = groupInfo.nextGroupDesc().givenGroupId();
int index = getNextAvailableIndex();
GroupDescription swapGroupDescription = createMplsSwap(nextGid, OfdpaMplsGroupSubType.MPLS_SWAP_LABEL, index, mplsLabel, nextObj.appId());
// ensure swap group is added after L2L3 chain
GroupKey swapGroupKey = swapGroupDescription.appCookie();
GroupChainElem swapChainElem = new GroupChainElem(swapGroupDescription, 1, false, deviceId);
updatePendingGroups(groupInfo.nextGroupDesc().appCookie(), swapChainElem);
gkeyChain.addFirst(swapGroupKey);
// ensure nextObjective waits on the outermost groupKey
List<Deque<GroupKey>> allGroupKeys = Lists.newArrayList();
allGroupKeys.add(gkeyChain);
OfdpaNextGroup ofdpaGrp = new OfdpaNextGroup(allGroupKeys, nextObj);
updatePendingNextObjective(swapGroupKey, ofdpaGrp);
// now we are ready to send the l2 groupDescription (inner), as all the stores
// that will get async replies have been updated. By waiting to update
// the stores, we prevent nasty race conditions.
groupService.addGroup(groupInfo.innerMostGroupDesc());
} else if (!isPw) {
boolean isMpls = false;
if (nextObj.meta() != null) {
isMpls = isNotMplsBos(nextObj.meta());
}
log.debug("Creating a {} -> L2 Interface group chain.", (isMpls) ? "MPLS Interface" : "L3 Unicast");
// break up simple next objective to GroupChain objects
GroupInfo groupInfo = createL2L3Chain(treatment, nextObj.id(), nextObj.appId(), isMpls, nextObj.meta());
if (groupInfo == null) {
log.error("Could not process nextObj={} in dev:{}", nextObj.id(), deviceId);
fail(nextObj, ObjectiveError.BADPARAMS);
return;
}
// create object for local and distributed storage
Deque<GroupKey> gkeyChain = new ArrayDeque<>();
gkeyChain.addFirst(groupInfo.innerMostGroupDesc().appCookie());
gkeyChain.addFirst(groupInfo.nextGroupDesc().appCookie());
List<Deque<GroupKey>> allGroupKeys = Lists.newArrayList();
allGroupKeys.add(gkeyChain);
OfdpaNextGroup ofdpaGrp = new OfdpaNextGroup(allGroupKeys, nextObj);
// store l3groupkey with the ofdpaNextGroup for the nextObjective that depends on it
updatePendingNextObjective(groupInfo.nextGroupDesc().appCookie(), ofdpaGrp);
// now we are ready to send the l2 groupDescription (inner), as all the stores
// that will get async replies have been updated. By waiting to update
// the stores, we prevent nasty race conditions.
groupService.addGroup(groupInfo.innerMostGroupDesc());
} else {
// We handle the pseudo wire with a different a procedure.
// This procedure is meant to handle both initiation and
// termination of the pseudo wire.
processPwNextObjective(nextObj);
}
}
use of org.onosproject.net.flow.instructions.Instruction in project onos by opennetworkinglab.
the class Ofdpa2Pipeline method versatileTreatmentBuilder.
/**
* Helper function to create traffic treatment builder for versatile forwarding objectives.
*
* @param fwd original forwarding objective
* @return treatment builder for the flow rule, or null if there is an error.
*/
protected TrafficTreatment.Builder versatileTreatmentBuilder(ForwardingObjective fwd) {
// XXX driver does not currently do type checking as per Tables 65-67 in
// OFDPA 2.0 spec. The only allowed treatment is a punt to the controller.
TrafficTreatment.Builder ttBuilder = DefaultTrafficTreatment.builder();
if (fwd.treatment() != null) {
for (Instruction ins : fwd.treatment().allInstructions()) {
if (ins instanceof OutputInstruction) {
OutputInstruction o = (OutputInstruction) ins;
if (PortNumber.CONTROLLER.equals(o.port())) {
ttBuilder.add(o);
} else {
log.warn("Only allowed treatments in versatile forwarding " + "objectives are punts to the controller");
}
} else if (ins instanceof NoActionInstruction) {
// No action is allowed and nothing needs to be done
} else {
log.warn("Cannot process instruction in versatile fwd {}", ins);
}
}
if (fwd.treatment().clearedDeferred()) {
ttBuilder.wipeDeferred();
}
}
if (fwd.nextId() != null) {
// Override case
NextGroup next = getGroupForNextObjective(fwd.nextId());
if (next == null) {
fail(fwd, ObjectiveError.BADPARAMS);
return null;
}
List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
// we only need the top level group's key to point the flow to it
Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst());
if (group == null) {
log.warn("Group with key:{} for next-id:{} not found in dev:{}", gkeys.get(0).peekFirst(), fwd.nextId(), deviceId);
fail(fwd, ObjectiveError.GROUPMISSING);
return null;
}
ttBuilder.deferred().group(group.id());
}
return ttBuilder;
}
use of org.onosproject.net.flow.instructions.Instruction in project onos by opennetworkinglab.
the class Ofdpa2Pipeline method processEthTypeSpecificInternal.
/**
* Internal implementation of processEthTypeSpecific.
* <p>
* Wildcarded IPv4_DST is not supported in OFDPA i12. Therefore, we break
* the rule into 0.0.0.0/1 and 128.0.0.0/1.
* The allowDefaultRoute must be set to false for OFDPA i12.
* </p>
*
* @param fwd the forwarding objective
* @param allowDefaultRoute allow wildcarded IPv4_DST or not
* @param mplsNextTable next MPLS table
* @return A collection of flow rules, or an empty set
*/
protected Collection<FlowRule> processEthTypeSpecificInternal(ForwardingObjective fwd, boolean allowDefaultRoute, int mplsNextTable) {
TrafficSelector selector = fwd.selector();
EthTypeCriterion ethType = (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
boolean emptyGroup = false;
int forTableId;
TrafficSelector.Builder filteredSelector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder tb = DefaultTrafficTreatment.builder();
TrafficSelector.Builder complementarySelector = DefaultTrafficSelector.builder();
if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) {
if (buildIpv4Selector(filteredSelector, complementarySelector, fwd, allowDefaultRoute) < 0) {
return Collections.emptyList();
}
// We need to set properly the next table
IpPrefix ipv4Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV4_DST)).ip();
if (ipv4Dst.isMulticast()) {
forTableId = MULTICAST_ROUTING_TABLE;
} else {
forTableId = UNICAST_ROUTING_TABLE;
}
// TODO decrementing IP ttl is done automatically for routing, this
// action is ignored or rejected in ofdpa as it is not fully implemented
// if (fwd.treatment() != null) {
// for (Instruction instr : fwd.treatment().allInstructions()) {
// if (instr instanceof L3ModificationInstruction &&
// ((L3ModificationInstruction) instr).subtype() == L3SubType.DEC_TTL) {
// tb.deferred().add(instr);
// }
// }
// }
} else if (ethType.ethType().toShort() == Ethernet.TYPE_IPV6) {
if (buildIpv6Selector(filteredSelector, fwd) < 0) {
return Collections.emptyList();
}
// We need to set the proper next table
IpPrefix ipv6Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV6_DST)).ip();
if (ipv6Dst.isMulticast()) {
forTableId = MULTICAST_ROUTING_TABLE;
} else {
forTableId = UNICAST_ROUTING_TABLE;
}
// TODO decrementing IP ttl is done automatically for routing, this
// action is ignored or rejected in ofdpa as it is not fully implemented
// if (fwd.treatment() != null) {
// for (Instruction instr : fwd.treatment().allInstructions()) {
// if (instr instanceof L3ModificationInstruction &&
// ((L3ModificationInstruction) instr).subtype() == L3SubType.DEC_TTL) {
// tb.deferred().add(instr);
// }
// }
// }
} else {
filteredSelector.matchEthType(Ethernet.MPLS_UNICAST).matchMplsLabel(((MplsCriterion) selector.getCriterion(Criterion.Type.MPLS_LABEL)).label());
MplsBosCriterion bos = (MplsBosCriterion) selector.getCriterion(MPLS_BOS);
if (bos != null && requireMplsBosMatch()) {
filteredSelector.matchMplsBos(bos.mplsBos());
}
forTableId = MPLS_TABLE_1;
log.debug("processing MPLS specific forwarding objective {} -> next:{}" + " in dev {}", fwd.id(), fwd.nextId(), deviceId);
if (fwd.treatment() != null) {
for (Instruction instr : fwd.treatment().allInstructions()) {
if (instr instanceof L2ModificationInstruction && ((L2ModificationInstruction) instr).subtype() == L2SubType.MPLS_POP) {
// setting the MPLS_TYPE so pop can happen down the pipeline
if (requireMplsPop()) {
if (mplsNextTable == MPLS_TYPE_TABLE && isNotMplsBos(selector)) {
tb.immediate().popMpls();
}
} else {
// Skip mpls pop action for mpls_unicast label
if (instr instanceof ModMplsHeaderInstruction && !((ModMplsHeaderInstruction) instr).ethernetType().equals(EtherType.MPLS_UNICAST.ethType())) {
tb.immediate().add(instr);
}
}
}
if (requireMplsTtlModification()) {
if (instr instanceof L3ModificationInstruction && ((L3ModificationInstruction) instr).subtype() == L3SubType.DEC_TTL) {
// FIXME Should modify the app to send the correct DEC_MPLS_TTL instruction
tb.immediate().decMplsTtl();
}
if (instr instanceof L3ModificationInstruction && ((L3ModificationInstruction) instr).subtype() == L3SubType.TTL_IN) {
tb.immediate().add(instr);
}
}
}
}
}
if (fwd.nextId() != null) {
NextGroup next = getGroupForNextObjective(fwd.nextId());
if (next != null) {
List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data());
// we only need the top level group's key to point the flow to it
Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst());
if (group == null) {
log.warn("Group with key:{} for next-id:{} not found in dev:{}", gkeys.get(0).peekFirst(), fwd.nextId(), deviceId);
fail(fwd, ObjectiveError.GROUPMISSING);
return Collections.emptySet();
}
if (isNotMplsBos(selector) && group.type().equals(SELECT)) {
log.warn("SR CONTINUE case cannot be handled as MPLS ECMP " + "is not implemented in OF-DPA yet. Aborting flow {} -> next:{} " + "in this device {}", fwd.id(), fwd.nextId(), deviceId);
fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
return Collections.emptySet();
}
tb.deferred().group(group.id());
// retrying flows may be necessary due to bug CORD-554
if (gkeys.size() == 1 && gkeys.get(0).size() == 1) {
if (shouldRetry()) {
log.warn("Found empty group 0x{} in dev:{} .. will retry fwd:{}", Integer.toHexString(group.id().id()), deviceId, fwd.id());
emptyGroup = true;
}
}
} else {
log.warn("Cannot find group for nextId:{} in dev:{}. Aborting fwd:{}", fwd.nextId(), deviceId, fwd.id());
fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
return Collections.emptySet();
}
}
if (forTableId == MPLS_TABLE_1) {
if (mplsNextTable == MPLS_L3_TYPE_TABLE) {
Ofdpa3SetMplsType setMplsType = new Ofdpa3SetMplsType(Ofdpa3MplsType.L3_PHP);
// set mpls type as apply_action
tb.immediate().extension(setMplsType, deviceId);
}
tb.transition(mplsNextTable);
} else {
tb.transition(ACL_TABLE);
}
if (fwd.treatment() != null && fwd.treatment().clearedDeferred()) {
if (supportsUnicastBlackHole()) {
tb.wipeDeferred();
} else {
log.warn("Clear Deferred is not supported Unicast Routing Table on device {}", deviceId);
return Collections.emptySet();
}
}
FlowRule.Builder ruleBuilder = DefaultFlowRule.builder().fromApp(fwd.appId()).withPriority(fwd.priority()).forDevice(deviceId).withSelector(filteredSelector.build()).withTreatment(tb.build()).forTable(forTableId);
if (fwd.permanent()) {
ruleBuilder.makePermanent();
} else {
ruleBuilder.makeTemporary(fwd.timeout());
}
Collection<FlowRule> flowRuleCollection = new ArrayList<>();
flowRuleCollection.add(ruleBuilder.build());
if (!allowDefaultRoute) {
flowRuleCollection.add(defaultRoute(fwd, complementarySelector, forTableId, tb));
log.debug("Default rule 0.0.0.0/0 is being installed two rules");
}
if (emptyGroup) {
retryExecutorService.schedule(new RetryFlows(fwd, flowRuleCollection), RETRY_MS, TimeUnit.MILLISECONDS);
}
return flowRuleCollection;
}
use of org.onosproject.net.flow.instructions.Instruction in project onos by opennetworkinglab.
the class Ofdpa3GroupHandler method processPwNextObjective.
@Override
protected void processPwNextObjective(NextObjective nextObjective) {
log.info("Started deploying nextObjective id={} for pseudowire", nextObjective.id());
TrafficTreatment treatment = nextObjective.next().iterator().next();
Deque<GroupKey> gkeyChain = new ArrayDeque<>();
GroupChainElem groupChainElem;
GroupKey groupKey;
GroupDescription groupDescription;
// Now we separate the mpls actions from the l2/l3 actions
TrafficTreatment.Builder l2L3Treatment = DefaultTrafficTreatment.builder();
TrafficTreatment.Builder mplsTreatment = DefaultTrafficTreatment.builder();
createL2L3AndMplsTreatments(treatment, l2L3Treatment, mplsTreatment);
// We create the chain from mpls intf group to
// l2 intf group.
GroupInfo groupInfo = createL2L3ChainInternal(l2L3Treatment.build(), nextObjective.id(), nextObjective.appId(), true, nextObjective.meta(), false);
if (groupInfo == null) {
log.error("Could not process nextObj={} in dev:{}", nextObjective.id(), deviceId);
OfdpaPipelineUtility.fail(nextObjective, ObjectiveError.GROUPINSTALLATIONFAILED);
return;
}
// We update the chain with the last two groups;
gkeyChain.addFirst(groupInfo.innerMostGroupDesc().appCookie());
gkeyChain.addFirst(groupInfo.nextGroupDesc().appCookie());
// We retrieve also all mpls instructions.
List<List<Instruction>> mplsInstructionSets = Lists.newArrayList();
List<Instruction> mplsInstructionSet = Lists.newArrayList();
L3ModificationInstruction l3Ins;
for (Instruction ins : treatment.allInstructions()) {
// Each mpls instruction set is delimited by a
// copy ttl outward action.
mplsInstructionSet.add(ins);
if (ins.type() == Instruction.Type.L3MODIFICATION) {
l3Ins = (L3ModificationInstruction) ins;
if (l3Ins.subtype() == TTL_OUT) {
mplsInstructionSets.add(mplsInstructionSet);
mplsInstructionSet = Lists.newArrayList();
}
}
}
if (mplsInstructionSets.size() > MAX_DEPTH_UNPROTECTED_PW) {
log.error("Next Objective for pseudo wire should have at " + "most {} mpls instruction sets. Next Objective Id:{}", MAX_DEPTH_UNPROTECTED_PW, nextObjective.id());
OfdpaPipelineUtility.fail(nextObjective, ObjectiveError.BADPARAMS);
return;
}
log.debug("Size of mpls instructions is {}.", mplsInstructionSets.size());
log.debug("mpls instructions sets are {}.", mplsInstructionSets);
int nextGid = groupInfo.nextGroupDesc().givenGroupId();
int index;
// this is for inter-co pws
if (mplsInstructionSets.size() == MAX_DEPTH_UNPROTECTED_PW) {
log.debug("Creating inter-co pw mpls chains with nextid {}", nextObjective.id());
// We deal with the label 2 group.
index = getNextAvailableIndex();
groupDescription = createMplsTunnelLabelGroup(nextGid, OfdpaMplsGroupSubType.MPLS_TUNNEL_LABEL_2, index, mplsInstructionSets.get(2), nextObjective.appId());
groupKey = new DefaultGroupKey(Ofdpa2Pipeline.appKryo.serialize(index));
// We update the chain.
groupChainElem = new GroupChainElem(groupDescription, 1, false, deviceId);
updatePendingGroups(groupInfo.nextGroupDesc().appCookie(), groupChainElem);
gkeyChain.addFirst(groupKey);
// We have to create tunnel label group and
// l2 vpn group before to send the inner most
// group. We update the nextGid.
nextGid = groupDescription.givenGroupId();
groupInfo = new GroupInfo(groupInfo.innerMostGroupDesc(), groupDescription);
log.debug("Trying Label 2 Group: device:{} gid:{} gkey:{} nextId:{}", deviceId, Integer.toHexString(nextGid), groupKey, nextObjective.id());
}
// inside a single co
if (mplsInstructionSets.size() == 2) {
log.debug("Creating leaf-leaf pw mpls chains with nextid {}", nextObjective.id());
// We deal with the label 1 group.
index = getNextAvailableIndex();
groupDescription = createMplsTunnelLabelGroup(nextGid, OfdpaMplsGroupSubType.MPLS_TUNNEL_LABEL_1, index, mplsInstructionSets.get(1), nextObjective.appId());
groupKey = new DefaultGroupKey(Ofdpa2Pipeline.appKryo.serialize(index));
groupChainElem = new GroupChainElem(groupDescription, 1, false, deviceId);
updatePendingGroups(groupInfo.nextGroupDesc().appCookie(), groupChainElem);
gkeyChain.addFirst(groupKey);
// We have to create the l2 vpn group before
// to send the inner most group.
nextGid = groupDescription.givenGroupId();
groupInfo = new GroupInfo(groupInfo.innerMostGroupDesc(), groupDescription);
log.debug("Trying Label 1 Group: device:{} gid:{} gkey:{} nextId:{}", deviceId, Integer.toHexString(nextGid), groupKey, nextObjective.id());
// Finally we create the l2 vpn group.
index = getNextAvailableIndex();
groupDescription = createMplsL2VpnGroup(nextGid, index, mplsInstructionSets.get(0), nextObjective.appId());
groupKey = new DefaultGroupKey(Ofdpa2Pipeline.appKryo.serialize(index));
groupChainElem = new GroupChainElem(groupDescription, 1, false, deviceId);
updatePendingGroups(groupInfo.nextGroupDesc().appCookie(), groupChainElem);
gkeyChain.addFirst(groupKey);
OfdpaNextGroup ofdpaGrp = new OfdpaNextGroup(Collections.singletonList(gkeyChain), nextObjective);
updatePendingNextObjective(groupKey, ofdpaGrp);
log.debug("Trying L2 Vpn Group: device:{} gid:{} gkey:{} nextId:{}", deviceId, Integer.toHexString(nextGid), groupKey, nextObjective.id());
// Finally we send the innermost group.
log.debug("Sending innermost group {} in group chain on device {} ", Integer.toHexString(groupInfo.innerMostGroupDesc().givenGroupId()), deviceId);
groupService.addGroup(groupInfo.innerMostGroupDesc());
}
// only one label is used
if (mplsInstructionSets.size() == 1) {
log.debug("Creating leaf-spine pw mpls chains with nextid {}", nextObjective.id());
// Finally we create the l2 vpn group.
index = getNextAvailableIndex();
groupDescription = createMplsL2VpnGroup(nextGid, index, mplsInstructionSets.get(0), nextObjective.appId());
groupKey = new DefaultGroupKey(Ofdpa2Pipeline.appKryo.serialize(index));
groupChainElem = new GroupChainElem(groupDescription, 1, false, deviceId);
updatePendingGroups(groupInfo.nextGroupDesc().appCookie(), groupChainElem);
gkeyChain.addFirst(groupKey);
OfdpaNextGroup ofdpaGrp = new OfdpaNextGroup(Collections.singletonList(gkeyChain), nextObjective);
updatePendingNextObjective(groupKey, ofdpaGrp);
log.debug("Trying L2 Vpn Group: device:{} gid:{} gkey:{} nextId:{}", deviceId, Integer.toHexString(nextGid), groupKey, nextObjective.id());
// Finally we send the innermost group.
log.debug("Sending innermost group {} in group chain on device {} ", Integer.toHexString(groupInfo.innerMostGroupDesc().givenGroupId()), deviceId);
groupService.addGroup(groupInfo.innerMostGroupDesc());
}
}
Aggregations