Search in sources :

Example 1 with DestinationSet

use of org.onosproject.segmentrouting.grouphandler.DestinationSet 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;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) DestinationSet(org.onosproject.segmentrouting.grouphandler.DestinationSet) DestinationSet(org.onosproject.segmentrouting.grouphandler.DestinationSet) HashMap(java.util.HashMap) DeviceId(org.onosproject.net.DeviceId) Builder(org.onosproject.net.flowobjective.ForwardingObjective.Builder) ForwardingObjective(org.onosproject.net.flowobjective.ForwardingObjective) DefaultForwardingObjective(org.onosproject.net.flowobjective.DefaultForwardingObjective) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) ConnectPoint(org.onosproject.net.ConnectPoint) DefaultGroupHandler(org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler)

Example 2 with DestinationSet

use of org.onosproject.segmentrouting.grouphandler.DestinationSet in project trellis-control by opennetworkinglab.

the class RoutingRulePopulator method populateIpRulesForRouter.

/**
 * Populates IP flow rules for a set of IP prefix in the target device.
 * The prefix are reachable via destination device(s).
 *
 * @param targetSw target device ID to set the rules
 * @param subnets the set of IP prefix
 * @param destSw1 destination switch where the prefixes are reachable
 * @param destSw2 paired destination switch if one exists for the subnets/prefixes.
 *                Should be null if there is no paired destination switch (by config)
 *                or if the given prefixes are reachable only via destSw1
 * @param nextHops map of destination switches and their next-hops.
 *                  Should only contain destination switches that are
 *                  actually meant to be routed to. If destSw2 is null, there
 *                  should not be an entry for destSw2 in this map.
 * @return true if all rules are set successfully, false otherwise
 */
private boolean populateIpRulesForRouter(DeviceId targetSw, Set<IpPrefix> subnets, DeviceId destSw1, DeviceId destSw2, Map<DeviceId, Set<DeviceId>> nextHops) {
    // pre-compute the needed information
    int segmentIdIPv41, segmentIdIPv42 = -1;
    int segmentIdIPv61, segmentIdIPv62 = -1;
    TrafficTreatment treatment = null;
    DestinationSet dsIPv4, dsIPv6;
    TrafficSelector metaIpv4Selector, metaIpv6Selector = null;
    int nextIdIPv4, nextIdIPv6, nextId;
    TrafficSelector selector;
    // start with MPLS SIDs
    try {
        segmentIdIPv41 = config.getIPv4SegmentId(destSw1);
        segmentIdIPv61 = config.getIPv6SegmentId(destSw1);
        if (destSw2 != null) {
            segmentIdIPv42 = config.getIPv4SegmentId(destSw2);
            segmentIdIPv62 = config.getIPv6SegmentId(destSw2);
        }
    } catch (DeviceConfigNotFoundException e) {
        log.warn(e.getMessage() + " Aborting populateIpRuleForRouter.");
        return false;
    }
    // build the IPv4 and IPv6 destination set
    if (destSw2 == null) {
        // single dst - create destination set based on next-hop
        // If the next hop is the same as the final destination, then MPLS
        // label is not set.
        Set<DeviceId> nhd1 = nextHops.get(destSw1);
        if (nhd1.size() == 1 && nhd1.iterator().next().equals(destSw1)) {
            dsIPv4 = DestinationSet.createTypePushNone(destSw1);
            dsIPv6 = DestinationSet.createTypePushNone(destSw1);
            treatment = DefaultTrafficTreatment.builder().immediate().decNwTtl().build();
        } else {
            dsIPv4 = DestinationSet.createTypePushBos(segmentIdIPv41, destSw1);
            dsIPv6 = DestinationSet.createTypePushBos(segmentIdIPv61, destSw1);
        }
    } else {
        // dst pair - IP rules for dst-pairs are always from other edge nodes
        // the destination set needs to have both destinations, even if there
        // are no next hops to one of them
        dsIPv4 = DestinationSet.createTypePushBos(segmentIdIPv41, destSw1, segmentIdIPv42, destSw2);
        dsIPv6 = DestinationSet.createTypePushBos(segmentIdIPv61, destSw1, segmentIdIPv62, destSw2);
    }
    // setup metadata to pass to nextObjective - indicate the vlan on egress
    // if needed by the switch pipeline. Since neighbor sets are always to
    // other neighboring routers, there is no subnet assigned on those ports.
    metaIpv4Selector = buildIpv4Selector().matchVlanId(srManager.getDefaultInternalVlan()).build();
    metaIpv6Selector = buildIpv6Selector().matchVlanId(srManager.getDefaultInternalVlan()).build();
    // get the group handler of the target switch
    DefaultGroupHandler grpHandler = srManager.getGroupHandler(targetSw);
    if (grpHandler == null) {
        log.warn("populateIPRuleForRouter: groupHandler for device {} " + "not found", targetSw);
        return false;
    }
    // get next id
    nextIdIPv4 = grpHandler.getNextObjectiveId(dsIPv4, nextHops, metaIpv4Selector, false);
    if (nextIdIPv4 <= 0) {
        log.warn("No next objective in {} for ds: {}", targetSw, dsIPv4);
        return false;
    }
    nextIdIPv6 = grpHandler.getNextObjectiveId(dsIPv6, nextHops, metaIpv6Selector, false);
    if (nextIdIPv6 <= 0) {
        log.warn("No next objective in {} for ds: {}", targetSw, dsIPv6);
        return false;
    }
    // build all the flow rules and send to the device
    for (IpPrefix subnet : subnets) {
        selector = buildIpSelectorFromIpPrefix(subnet).build();
        if (subnet.isIp4()) {
            nextId = nextIdIPv4;
        } else {
            nextId = nextIdIPv6;
        }
        ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective.builder().fromApp(srManager.appId).makePermanent().nextStep(nextId).withSelector(selector).withPriority(getPriorityFromPrefix(subnet)).withFlag(ForwardingObjective.Flag.SPECIFIC);
        if (treatment != null) {
            fwdBuilder.withTreatment(treatment);
        }
        log.debug("Installing {} forwarding objective for router IP/subnet {} " + "in switch {} with nextId: {}", subnet.isIp4() ? "IPv4" : "IPv6", subnet, targetSw, nextId);
        ObjectiveContext context = new DefaultObjectiveContext((objective) -> log.debug("IP rule for router {} populated in dev:{}", subnet, targetSw), (objective, error) -> log.warn("Failed to populate IP rule for router {}: {} in dev:{}", subnet, error, targetSw));
        srManager.flowObjectiveService.forward(targetSw, fwdBuilder.add(context));
    }
    rulePopulationCounter.addAndGet(subnets.size());
    return true;
}
Also used : DestinationSet(org.onosproject.segmentrouting.grouphandler.DestinationSet) DeviceId(org.onosproject.net.DeviceId) Builder(org.onosproject.net.flowobjective.ForwardingObjective.Builder) ForwardingObjective(org.onosproject.net.flowobjective.ForwardingObjective) DefaultForwardingObjective(org.onosproject.net.flowobjective.DefaultForwardingObjective) DefaultTrafficTreatment(org.onosproject.net.flow.DefaultTrafficTreatment) TrafficTreatment(org.onosproject.net.flow.TrafficTreatment) ConnectPoint(org.onosproject.net.ConnectPoint) DeviceConfigNotFoundException(org.onosproject.segmentrouting.config.DeviceConfigNotFoundException) IpPrefix(org.onlab.packet.IpPrefix) DefaultGroupHandler(org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler) DefaultObjectiveContext(org.onosproject.net.flowobjective.DefaultObjectiveContext) ObjectiveContext(org.onosproject.net.flowobjective.ObjectiveContext) DefaultObjectiveContext(org.onosproject.net.flowobjective.DefaultObjectiveContext) TrafficSelector(org.onosproject.net.flow.TrafficSelector) DefaultTrafficSelector(org.onosproject.net.flow.DefaultTrafficSelector)

Example 3 with DestinationSet

use of org.onosproject.segmentrouting.grouphandler.DestinationSet in project trellis-control by opennetworkinglab.

the class TunnelHandler method createGroupsForTunnel.

private int createGroupsForTunnel(Tunnel tunnel) {
    Set<Integer> portNumbers;
    final int groupError = -1;
    DeviceId deviceId = config.getDeviceId(tunnel.labelIds().get(0));
    if (deviceId == null) {
        log.warn("No device found for SID {}", tunnel.labelIds().get(0));
        return groupError;
    } else if (groupHandlerMap.get(deviceId) == null) {
        log.warn("group handler not found for {}", deviceId);
        return groupError;
    }
    Set<DeviceId> deviceIds = new HashSet<>();
    int sid = tunnel.labelIds().get(1);
    if (config.isAdjacencySid(deviceId, sid)) {
        portNumbers = config.getPortsForAdjacencySid(deviceId, sid);
        for (Link link : linkService.getDeviceEgressLinks(deviceId)) {
            for (Integer port : portNumbers) {
                if (link.src().port().toLong() == port) {
                    deviceIds.add(link.dst().deviceId());
                }
            }
        }
    } else {
        deviceIds.add(config.getDeviceId(sid));
    }
    // For these NeighborSet isMpls is meaningless.
    // TODO : Revisit this, the code and also the type
    DestinationSet ns = DestinationSet.createTypePushBos(tunnel.labelIds().get(2), DeviceId.NONE);
    // should not remove the group.
    if (groupHandlerMap.get(deviceId).hasNextObjectiveId(ns)) {
        tunnel.allowToRemoveGroup(false);
    } else {
        tunnel.allowToRemoveGroup(true);
    }
    return groupHandlerMap.get(deviceId).getNextObjectiveId(ns, null, null, true);
}
Also used : DestinationSet(org.onosproject.segmentrouting.grouphandler.DestinationSet) DeviceId(org.onosproject.net.DeviceId) Link(org.onosproject.net.Link) HashSet(java.util.HashSet)

Aggregations

DeviceId (org.onosproject.net.DeviceId)3 DestinationSet (org.onosproject.segmentrouting.grouphandler.DestinationSet)3 HashSet (java.util.HashSet)2 ConnectPoint (org.onosproject.net.ConnectPoint)2 DefaultTrafficTreatment (org.onosproject.net.flow.DefaultTrafficTreatment)2 TrafficTreatment (org.onosproject.net.flow.TrafficTreatment)2 DefaultForwardingObjective (org.onosproject.net.flowobjective.DefaultForwardingObjective)2 ForwardingObjective (org.onosproject.net.flowobjective.ForwardingObjective)2 Builder (org.onosproject.net.flowobjective.ForwardingObjective.Builder)2 DefaultGroupHandler (org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler)2 HashMap (java.util.HashMap)1 Set (java.util.Set)1 IpPrefix (org.onlab.packet.IpPrefix)1 Link (org.onosproject.net.Link)1 DefaultTrafficSelector (org.onosproject.net.flow.DefaultTrafficSelector)1 TrafficSelector (org.onosproject.net.flow.TrafficSelector)1 DefaultObjectiveContext (org.onosproject.net.flowobjective.DefaultObjectiveContext)1 ObjectiveContext (org.onosproject.net.flowobjective.ObjectiveContext)1 DeviceConfigNotFoundException (org.onosproject.segmentrouting.config.DeviceConfigNotFoundException)1