use of org.onosproject.net.flowobjective.ForwardingObjective.Builder in project trellis-control by opennetworkinglab.
the class RoutingRulePopulator method getMplsForwardingObjective.
/**
* Returns a Forwarding Objective builder for the MPLS rule that references
* the desired Next Objective. Creates a DestinationSet that allows the
* groupHandler to create or find the required next objective.
*
* @param targetSw the target sw
* @param nextHops the set of next hops
* @param phpRequired true if penultimate-hop-popping is required
* @param isBos true if matched label is bottom-of-stack
* @param meta metadata for creating next objective
* @param routerIp the router ip representing the destination switch
* @param destSw the destination sw
* @return the mpls forwarding objective builder
*/
private ForwardingObjective.Builder getMplsForwardingObjective(DeviceId targetSw, Set<DeviceId> nextHops, boolean phpRequired, boolean isBos, TrafficSelector meta, IpAddress routerIp, int segmentId, DeviceId destSw) {
ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective.builder().withFlag(ForwardingObjective.Flag.SPECIFIC);
TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
DestinationSet ds = null;
DestinationSet.DestinationSetType dstType = null;
boolean simple = false;
if (phpRequired) {
// php case - pop should always be flow-action
log.debug("getMplsForwardingObjective: php required");
tbuilder.deferred().copyTtlIn();
if (isBos) {
if (routerIp.isIp4()) {
tbuilder.deferred().popMpls(EthType.EtherType.IPV4.ethType());
} else {
tbuilder.deferred().popMpls(EthType.EtherType.IPV6.ethType());
}
tbuilder.decNwTtl();
// standard case -> BoS == True; pop results in IP packet and forwarding
// is via an ECMP group
ds = DestinationSet.createTypePopBos(destSw);
} else {
tbuilder.deferred().popMpls(EthType.EtherType.MPLS_UNICAST.ethType()).decMplsTtl();
// double-label case -> BoS == False, pop results in MPLS packet
// depending on configuration we can ECMP this packet or choose one output
ds = DestinationSet.createTypePopNotBos(destSw);
if (!srManager.getMplsEcmp()) {
simple = true;
}
}
} else {
// swap with self case - SR CONTINUE
log.debug("getMplsForwardingObjective: swap with self");
tbuilder.deferred().decMplsTtl();
// swap results in MPLS packet with same BoS bit regardless of bit value
// depending on configuration we can ECMP this packet or choose one output
// differentiate here between swap with not bos or swap with bos
ds = isBos ? DestinationSet.createTypeSwapBos(segmentId, destSw) : DestinationSet.createTypeSwapNotBos(segmentId, destSw);
if (!srManager.getMplsEcmp()) {
simple = true;
}
}
fwdBuilder.withTreatment(tbuilder.build());
log.debug("Trying to get a nextObjId for mpls rule on device:{} to ds:{}", targetSw, ds);
DefaultGroupHandler gh = srManager.getGroupHandler(targetSw);
if (gh == null) {
log.warn("getNextObjectiveId query - groupHandler for device {} " + "not found", targetSw);
return null;
}
Map<DeviceId, Set<DeviceId>> dstNextHops = new HashMap<>();
dstNextHops.put(destSw, nextHops);
int nextId = gh.getNextObjectiveId(ds, dstNextHops, meta, simple);
if (nextId <= 0) {
log.warn("No next objective in {} for ds: {}", targetSw, ds);
return null;
} else {
log.debug("nextObjId found:{} for mpls rule on device:{} to ds:{}", nextId, targetSw, ds);
}
fwdBuilder.nextStep(nextId);
return fwdBuilder;
}
use of org.onosproject.net.flowobjective.ForwardingObjective.Builder in project trellis-control by opennetworkinglab.
the class RoutingRulePopulator method handleMpls.
/**
* Differentiates between popping and swapping labels when building an MPLS
* forwarding objective.
*
* @param targetSwId the target sw
* @param destSwId the destination sw
* @param nextHops the set of next hops
* @param segmentId the segmentId to match representing the destination
* switch
* @param routerIp the router ip representing the destination switch
* @return a collection of fwdobjective
*/
private Collection<ForwardingObjective> handleMpls(DeviceId targetSwId, DeviceId destSwId, Set<DeviceId> nextHops, int segmentId, IpAddress routerIp, boolean isMplsBos) {
TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
List<ForwardingObjective.Builder> fwdObjBuilders = Lists.newArrayList();
// For the transport of Pwaas we can use two or three MPLS label
sbuilder.matchEthType(Ethernet.MPLS_UNICAST);
sbuilder.matchMplsLabel(MplsLabel.mplsLabel(segmentId));
sbuilder.matchMplsBos(isMplsBos);
TrafficSelector selector = sbuilder.build();
// setup metadata to pass to nextObjective - indicate the vlan on egress
// if needed by the switch pipeline. Since mpls next-hops are always to
// other neighboring routers, there is no subnet assigned on those ports.
TrafficSelector.Builder metabuilder = DefaultTrafficSelector.builder(selector);
metabuilder.matchVlanId(srManager.getDefaultInternalVlan());
if (nextHops.size() == 1 && destSwId.equals(nextHops.toArray()[0])) {
// If the next hop is the destination router for the segment, do pop
log.debug("populateMplsRule: Installing MPLS forwarding objective for " + "label {} in switch {} with pop to next-hops {}", segmentId, targetSwId, nextHops);
ForwardingObjective.Builder fwdObjNoBosBuilder = getMplsForwardingObjective(targetSwId, nextHops, true, isMplsBos, metabuilder.build(), routerIp, segmentId, destSwId);
// Error case, we cannot handle, exit.
if (fwdObjNoBosBuilder == null) {
return Collections.emptyList();
}
fwdObjBuilders.add(fwdObjNoBosBuilder);
} else {
// next hop is not destination, irrespective of the number of next
// hops (1 or more) -- SR CONTINUE case (swap with self)
log.debug("Installing MPLS forwarding objective for " + "label {} in switch {} without pop to next-hops {}", segmentId, targetSwId, nextHops);
ForwardingObjective.Builder fwdObjNoBosBuilder = getMplsForwardingObjective(targetSwId, nextHops, false, isMplsBos, metabuilder.build(), routerIp, segmentId, destSwId);
// Error case, we cannot handle, exit.
if (fwdObjNoBosBuilder == null) {
return Collections.emptyList();
}
fwdObjBuilders.add(fwdObjNoBosBuilder);
}
List<ForwardingObjective> fwdObjs = Lists.newArrayList();
// We add the final property to the fwdObjs.
for (ForwardingObjective.Builder fwdObjBuilder : fwdObjBuilders) {
((Builder) ((Builder) fwdObjBuilder.fromApp(srManager.appId).makePermanent()).withSelector(selector).withPriority(SegmentRoutingService.DEFAULT_PRIORITY)).withFlag(ForwardingObjective.Flag.SPECIFIC);
ObjectiveContext context = new DefaultObjectiveContext((objective) -> log.debug("MPLS rule {} for SID {} populated in dev:{} ", objective.id(), segmentId, targetSwId), (objective, error) -> log.warn("Failed to populate MPLS rule {} for SID {}: {} in dev:{}", objective.id(), segmentId, error, targetSwId));
ForwardingObjective fob = fwdObjBuilder.add(context);
fwdObjs.add(fob);
}
return fwdObjs;
}
Aggregations