Search in sources :

Example 26 with Ip4Prefix

use of org.onlab.packet.Ip4Prefix in project onos by opennetworkinglab.

the class BgpUpdate method parsePathAttributes.

/**
 * Parse BGP Path Attributes from the BGP UPDATE message.
 *
 * @param bgpSession the BGP Session to use
 * @param ctx the Channel Handler Context
 * @param message the message to parse
 * @param decodedBgpRoutes the container to store the decoded BGP Route
 * Entries. It might already contain some route entries such as withdrawn
 * IPv4 prefixes
 * @throws BgpMessage.BgpParseException
 */
// CHECKSTYLE IGNORE MethodLength FOR NEXT 300 LINES
private static void parsePathAttributes(BgpSession bgpSession, ChannelHandlerContext ctx, ChannelBuffer message, DecodedBgpRoutes decodedBgpRoutes) throws BgpMessage.BgpParseException {
    // 
    // Parsed values
    // 
    // Mandatory
    Short origin = -1;
    // Mandatory
    BgpRouteEntry.AsPath asPath = null;
    // Legacy NLRI (RFC 4271). Mandatory NEXT_HOP if legacy NLRI is used
    MpNlri legacyNlri = new MpNlri(BgpConstants.Open.Capabilities.MultiprotocolExtensions.AFI_IPV4, BgpConstants.Open.Capabilities.MultiprotocolExtensions.SAFI_UNICAST);
    // Optional
    long multiExitDisc = BgpConstants.Update.MultiExitDisc.LOWEST_MULTI_EXIT_DISC;
    // Mandatory
    Long localPref = null;
    // Optional: unused
    Long aggregatorAsNumber = null;
    // Optional: unused
    Ip4Address aggregatorIpAddress = null;
    // Optional
    Collection<MpNlri> mpNlriReachList = new ArrayList<>();
    // Optional
    Collection<MpNlri> mpNlriUnreachList = new ArrayList<>();
    // 
    // Get and verify the Path Attributes Length
    // 
    int pathAttributeLength = message.readUnsignedShort();
    if (pathAttributeLength > message.readableBytes()) {
        // ERROR: Malformed Attribute List
        actionsBgpUpdateMalformedAttributeList(bgpSession, ctx);
        String errorMsg = "Malformed Attribute List";
        throw new BgpMessage.BgpParseException(errorMsg);
    }
    if (pathAttributeLength == 0) {
        return;
    }
    // 
    // Parse the Path Attributes
    // 
    int pathAttributeEnd = message.readerIndex() + pathAttributeLength;
    while (message.readerIndex() < pathAttributeEnd) {
        int attrFlags = message.readUnsignedByte();
        if (message.readerIndex() >= pathAttributeEnd) {
            // ERROR: Malformed Attribute List
            actionsBgpUpdateMalformedAttributeList(bgpSession, ctx);
            String errorMsg = "Malformed Attribute List";
            throw new BgpMessage.BgpParseException(errorMsg);
        }
        int attrTypeCode = message.readUnsignedByte();
        // The Attribute Flags
        boolean optionalBit = ((0x80 & attrFlags) != 0);
        boolean transitiveBit = ((0x40 & attrFlags) != 0);
        boolean partialBit = ((0x20 & attrFlags) != 0);
        boolean extendedLengthBit = ((0x10 & attrFlags) != 0);
        // The Attribute Length
        int attrLen = 0;
        int attrLenOctets = 1;
        if (extendedLengthBit) {
            attrLenOctets = 2;
        }
        if (message.readerIndex() + attrLenOctets > pathAttributeEnd) {
            // ERROR: Malformed Attribute List
            actionsBgpUpdateMalformedAttributeList(bgpSession, ctx);
            String errorMsg = "Malformed Attribute List";
            throw new BgpMessage.BgpParseException(errorMsg);
        }
        if (extendedLengthBit) {
            attrLen = message.readUnsignedShort();
        } else {
            attrLen = message.readUnsignedByte();
        }
        if (message.readerIndex() + attrLen > pathAttributeEnd) {
            // ERROR: Malformed Attribute List
            actionsBgpUpdateMalformedAttributeList(bgpSession, ctx);
            String errorMsg = "Malformed Attribute List";
            throw new BgpMessage.BgpParseException(errorMsg);
        }
        // Verify the Attribute Flags
        verifyBgpUpdateAttributeFlags(bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
        // 
        switch(attrTypeCode) {
            case BgpConstants.Update.Origin.TYPE:
                // Attribute Type Code ORIGIN
                origin = parseAttributeTypeOrigin(bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
                break;
            case BgpConstants.Update.AsPath.TYPE:
                // Attribute Type Code AS_PATH
                asPath = parseAttributeTypeAsPath(bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
                break;
            case BgpConstants.Update.NextHop.TYPE:
                // Attribute Type Code NEXT_HOP
                legacyNlri.nextHop4 = parseAttributeTypeNextHop(bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
                break;
            case BgpConstants.Update.MultiExitDisc.TYPE:
                // Attribute Type Code MULTI_EXIT_DISC
                multiExitDisc = parseAttributeTypeMultiExitDisc(bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
                break;
            case BgpConstants.Update.LocalPref.TYPE:
                // Attribute Type Code LOCAL_PREF
                localPref = parseAttributeTypeLocalPref(bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
                break;
            case BgpConstants.Update.AtomicAggregate.TYPE:
                // Attribute Type Code ATOMIC_AGGREGATE
                parseAttributeTypeAtomicAggregate(bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
                // Nothing to do: this attribute is primarily informational
                break;
            case BgpConstants.Update.Aggregator.TYPE:
                // Attribute Type Code AGGREGATOR
                Pair<Long, Ip4Address> aggregator = parseAttributeTypeAggregator(bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
                aggregatorAsNumber = aggregator.getLeft();
                aggregatorIpAddress = aggregator.getRight();
                break;
            case BgpConstants.Update.MpReachNlri.TYPE:
                // Attribute Type Code MP_REACH_NLRI
                MpNlri mpNlriReach = parseAttributeTypeMpReachNlri(bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
                if (mpNlriReach != null) {
                    mpNlriReachList.add(mpNlriReach);
                }
                break;
            case BgpConstants.Update.MpUnreachNlri.TYPE:
                // Attribute Type Code MP_UNREACH_NLRI
                MpNlri mpNlriUnreach = parseAttributeTypeMpUnreachNlri(bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
                if (mpNlriUnreach != null) {
                    mpNlriUnreachList.add(mpNlriUnreach);
                }
                break;
            default:
                // NOTE: Parse any new Attribute Types if needed
                if (!optionalBit) {
                    // ERROR: Unrecognized Well-known Attribute
                    actionsBgpUpdateUnrecognizedWellKnownAttribute(bgpSession, ctx, attrTypeCode, attrLen, attrFlags, message);
                    String errorMsg = "Unrecognized Well-known Attribute: " + attrTypeCode;
                    throw new BgpMessage.BgpParseException(errorMsg);
                }
                // Skip the data from the unrecognized attribute
                log.debug("BGP RX UPDATE message from {}: " + "Unrecognized Attribute Type {}", bgpSession.remoteInfo().address(), attrTypeCode);
                message.skipBytes(attrLen);
                break;
        }
    }
    // 
    // Parse the NLRI (Network Layer Reachability Information)
    // 
    int nlriLength = message.readableBytes();
    try {
        Collection<Ip4Prefix> addedPrefixes4 = parsePackedIp4Prefixes(nlriLength, message);
        // Store it inside the legacy NLRI wrapper
        legacyNlri.nlri4 = addedPrefixes4;
    } catch (BgpMessage.BgpParseException e) {
        // ERROR: Invalid Network Field
        log.debug("Exception parsing NLRI from BGP peer {}: ", bgpSession.remoteInfo().bgpId(), e);
        actionsBgpUpdateInvalidNetworkField(bgpSession, ctx);
        // Rethrow the exception
        throw e;
    }
    // Verify the Well-known Attributes
    verifyBgpUpdateWellKnownAttributes(bgpSession, ctx, origin, asPath, localPref, legacyNlri, mpNlriReachList);
    // 
    for (MpNlri mpNlri : mpNlriUnreachList) {
        BgpRouteEntry bgpRouteEntry;
        // The deleted IPv4 routes
        for (Ip4Prefix prefix : mpNlri.nlri4) {
            bgpRouteEntry = bgpSession.findBgpRoute(prefix);
            if (bgpRouteEntry != null) {
                decodedBgpRoutes.deletedUnicastRoutes4.put(prefix, bgpRouteEntry);
            }
        }
        // The deleted IPv6 routes
        for (Ip6Prefix prefix : mpNlri.nlri6) {
            bgpRouteEntry = bgpSession.findBgpRoute(prefix);
            if (bgpRouteEntry != null) {
                decodedBgpRoutes.deletedUnicastRoutes6.put(prefix, bgpRouteEntry);
            }
        }
    }
    // 
    // Generate the added routes
    // 
    mpNlriReachList.add(legacyNlri);
    for (MpNlri mpNlri : mpNlriReachList) {
        BgpRouteEntry bgpRouteEntry;
        // The added IPv4 routes
        for (Ip4Prefix prefix : mpNlri.nlri4) {
            bgpRouteEntry = new BgpRouteEntry(bgpSession, prefix, mpNlri.nextHop4, origin.byteValue(), asPath, localPref);
            bgpRouteEntry.setMultiExitDisc(multiExitDisc);
            if (bgpRouteEntry.hasAsPathLoop(bgpSession.localInfo().asNumber())) {
                log.debug("BGP RX UPDATE message IGNORED from {}: {} " + "nextHop {}: contains AS Path loop", bgpSession.remoteInfo().address(), prefix, mpNlri.nextHop4);
                continue;
            } else {
                log.debug("BGP RX UPDATE message ADDED from {}: {} nextHop {}", bgpSession.remoteInfo().address(), prefix, mpNlri.nextHop4);
            }
            // Remove from the collection of deleted routes
            decodedBgpRoutes.deletedUnicastRoutes4.remove(prefix);
            decodedBgpRoutes.addedUnicastRoutes4.put(prefix, bgpRouteEntry);
        }
        // The added IPv6 routes
        for (Ip6Prefix prefix : mpNlri.nlri6) {
            bgpRouteEntry = new BgpRouteEntry(bgpSession, prefix, mpNlri.nextHop6, origin.byteValue(), asPath, localPref);
            bgpRouteEntry.setMultiExitDisc(multiExitDisc);
            if (bgpRouteEntry.hasAsPathLoop(bgpSession.localInfo().asNumber())) {
                log.debug("BGP RX UPDATE message IGNORED from {}: {} " + "nextHop {}: contains AS Path loop", bgpSession.remoteInfo().address(), prefix, mpNlri.nextHop6);
                continue;
            } else {
                log.debug("BGP RX UPDATE message ADDED from {}: {} nextHop {}", bgpSession.remoteInfo().address(), prefix, mpNlri.nextHop6);
            }
            // Remove from the collection of deleted routes
            decodedBgpRoutes.deletedUnicastRoutes6.remove(prefix);
            decodedBgpRoutes.addedUnicastRoutes6.put(prefix, bgpRouteEntry);
        }
    }
}
Also used : Ip4Address(org.onlab.packet.Ip4Address) ArrayList(java.util.ArrayList) Ip6Prefix(org.onlab.packet.Ip6Prefix) Ip4Prefix(org.onlab.packet.Ip4Prefix)

Example 27 with Ip4Prefix

use of org.onlab.packet.Ip4Prefix in project onos by opennetworkinglab.

the class BgpUpdate method processBgpUpdate.

/**
 * Processes BGP UPDATE message.
 *
 * @param bgpSession the BGP Session to use
 * @param ctx the Channel Handler Context
 * @param message the message to process
 */
static void processBgpUpdate(BgpSession bgpSession, ChannelHandlerContext ctx, ChannelBuffer message) {
    DecodedBgpRoutes decodedBgpRoutes = new DecodedBgpRoutes();
    int minLength = BgpConstants.BGP_UPDATE_MIN_LENGTH - BgpConstants.BGP_HEADER_LENGTH;
    if (message.readableBytes() < minLength) {
        log.debug("BGP RX UPDATE Error from {}: " + "Message length {} too short. Must be at least {}", bgpSession.remoteInfo().address(), message.readableBytes(), minLength);
        // 
        // ERROR: Bad Message Length
        // 
        // Send NOTIFICATION and close the connection
        ChannelBuffer txMessage = BgpNotification.prepareBgpNotificationBadMessageLength(message.readableBytes() + BgpConstants.BGP_HEADER_LENGTH);
        ctx.getChannel().write(txMessage);
        bgpSession.closeSession(ctx);
        return;
    }
    log.debug("BGP RX UPDATE message from {}", bgpSession.remoteInfo().address());
    // 
    // Parse the UPDATE message
    // 
    // 
    // Parse the Withdrawn Routes
    // 
    int withdrawnRoutesLength = message.readUnsignedShort();
    if (withdrawnRoutesLength > message.readableBytes()) {
        // ERROR: Malformed Attribute List
        actionsBgpUpdateMalformedAttributeList(bgpSession, ctx);
        return;
    }
    Collection<Ip4Prefix> withdrawnPrefixes = null;
    try {
        withdrawnPrefixes = parsePackedIp4Prefixes(withdrawnRoutesLength, message);
    } catch (BgpMessage.BgpParseException e) {
        // ERROR: Invalid Network Field
        log.debug("Exception parsing Withdrawn Prefixes from BGP peer {}: ", bgpSession.remoteInfo().bgpId(), e);
        actionsBgpUpdateInvalidNetworkField(bgpSession, ctx);
        return;
    }
    for (Ip4Prefix prefix : withdrawnPrefixes) {
        log.debug("BGP RX UPDATE message WITHDRAWN from {}: {}", bgpSession.remoteInfo().address(), prefix);
        BgpRouteEntry bgpRouteEntry = bgpSession.findBgpRoute(prefix);
        if (bgpRouteEntry != null) {
            decodedBgpRoutes.deletedUnicastRoutes4.put(prefix, bgpRouteEntry);
        }
    }
    // 
    try {
        parsePathAttributes(bgpSession, ctx, message, decodedBgpRoutes);
    } catch (BgpMessage.BgpParseException e) {
        log.debug("Exception parsing Path Attributes from BGP peer {}: ", bgpSession.remoteInfo().bgpId(), e);
        // NOTE: The session was already closed, so nothing else to do
        return;
    }
    // 
    for (Ip4Prefix ip4Prefix : decodedBgpRoutes.deletedUnicastRoutes4.keySet()) {
        bgpSession.removeBgpRoute(ip4Prefix);
    }
    // 
    for (BgpRouteEntry bgpRouteEntry : decodedBgpRoutes.addedUnicastRoutes4.values()) {
        bgpSession.addBgpRoute(bgpRouteEntry);
    }
    // 
    for (Ip6Prefix ip6Prefix : decodedBgpRoutes.deletedUnicastRoutes6.keySet()) {
        bgpSession.removeBgpRoute(ip6Prefix);
    }
    // 
    for (BgpRouteEntry bgpRouteEntry : decodedBgpRoutes.addedUnicastRoutes6.values()) {
        bgpSession.addBgpRoute(bgpRouteEntry);
    }
    // 
    // Push the updates to the BGP Merged RIB
    // 
    BgpRouteSelector bgpRouteSelector = bgpSession.getBgpSessionManager().getBgpRouteSelector();
    bgpRouteSelector.routeUpdates(decodedBgpRoutes.addedUnicastRoutes4.values(), decodedBgpRoutes.deletedUnicastRoutes4.values());
    bgpRouteSelector.routeUpdates(decodedBgpRoutes.addedUnicastRoutes6.values(), decodedBgpRoutes.deletedUnicastRoutes6.values());
    // Start the Session Timeout timer
    bgpSession.restartSessionTimeoutTimer(ctx);
}
Also used : Ip6Prefix(org.onlab.packet.Ip6Prefix) Ip4Prefix(org.onlab.packet.Ip4Prefix) ChannelBuffer(org.jboss.netty.buffer.ChannelBuffer)

Example 28 with Ip4Prefix

use of org.onlab.packet.Ip4Prefix in project fabric-tna by stratum.

the class FabricUpfProgrammable method removeInterface.

private void removeInterface(UpfInterface upfInterface) throws UpfProgrammableException {
    Ip4Prefix ifacePrefix = upfInterface.getPrefix();
    if (upfInterface.isCore()) {
        applyUplinkRecirculation(ifacePrefix, true);
    }
    // access/dbuf interfaces and then fall through in the next step where we try to remove the core flow
    if (!upfInterface.isCore()) {
        PiCriterion match1 = PiCriterion.builder().matchLpm(HDR_IPV4_DST_ADDR, ifacePrefix.address().toInt(), ifacePrefix.prefixLength()).matchExact(HDR_GTPU_IS_VALID, 1).build();
        // removeEntry does return false only for severe issues, before we had
        // a safe fall through. This part should not be affected since core and access
        // flows are different in the match keys and should not result in wrong removal
        removeEntry(match1, FABRIC_INGRESS_UPF_INTERFACES, true);
    }
    // This additional step might be also needed in case of unknown interfaces
    PiCriterion match2 = PiCriterion.builder().matchLpm(HDR_IPV4_DST_ADDR, ifacePrefix.address().toInt(), ifacePrefix.prefixLength()).matchExact(HDR_GTPU_IS_VALID, 0).build();
    removeEntry(match2, FABRIC_INGRESS_UPF_INTERFACES, false);
}
Also used : PiCriterion(org.onosproject.net.flow.criteria.PiCriterion) Ip4Prefix(org.onlab.packet.Ip4Prefix)

Example 29 with Ip4Prefix

use of org.onlab.packet.Ip4Prefix in project up4 by omec-project.

the class Up4DeviceManager method configInterfaces.

@Override
public Collection<UpfInterface> configInterfaces() {
    Collection<UpfInterface> interfaces = new ArrayList<>();
    if (config.n3Address().isPresent()) {
        if (config.sliceId().isPresent()) {
            interfaces.add(UpfInterface.createN3From(config.n3Address().get(), config.sliceId().get()));
        } else {
            log.error("Missing slice ID in the netcfg to configure N3 interface for {}", config.n3Address().get());
        }
    }
    for (Ip4Prefix uePool : config.uePools()) {
        if (config.sliceId().isPresent()) {
            interfaces.add(UpfInterface.createUePoolFrom(uePool, config.sliceId().get()));
        } else {
            log.error("Missing slice ID in the netcfg to configure N6 interface for UE subnet {}", uePool);
        }
    }
    Ip4Address dbufDrainAddr = config.dbufDrainAddr();
    if (dbufDrainAddr != null) {
        // TODO: change slice ID when adding multi-slice support,
        // see: https://jira.opennetworking.org/browse/SDFAB-986
        interfaces.add(UpfInterface.createDbufReceiverFrom(dbufDrainAddr, DEFAULT_SLICE_ID));
    }
    return interfaces;
}
Also used : ArrayList(java.util.ArrayList) Ip4Address(org.onlab.packet.Ip4Address) UpfInterface(org.onosproject.net.behaviour.upf.UpfInterface) Ip4Prefix(org.onlab.packet.Ip4Prefix)

Example 30 with Ip4Prefix

use of org.onlab.packet.Ip4Prefix in project up4 by omec-project.

the class Up4TranslatorImpl method upfEntityToUp4TableEntry.

@Override
public PiTableEntry upfEntityToUp4TableEntry(UpfEntity entity) throws Up4TranslationException {
    PiTableEntry.Builder tableEntryBuilder = PiTableEntry.builder();
    PiAction.Builder actionBuilder = PiAction.builder();
    PiMatchKey.Builder matchBuilder = PiMatchKey.builder();
    switch(entity.type()) {
        case INTERFACE:
            tableEntryBuilder.forTable(PRE_QOS_PIPE_INTERFACES);
            UpfInterface upfIntf = (UpfInterface) entity;
            byte direction;
            byte srcIface;
            actionBuilder.withId(PRE_QOS_PIPE_SET_SOURCE_IFACE);
            if (upfIntf.isAccess()) {
                srcIface = IFACE_ACCESS;
                direction = DIRECTION_UPLINK;
            } else if (upfIntf.isCore()) {
                srcIface = IFACE_CORE;
                direction = DIRECTION_DOWNLINK;
            } else {
                throw new Up4TranslationException("UPF Interface is not Access nor CORE: " + upfIntf);
            }
            actionBuilder.withParameter(new PiActionParam(SRC_IFACE, srcIface)).withParameter(new PiActionParam(DIRECTION, direction)).withParameter(new PiActionParam(SLICE_ID, (byte) upfIntf.sliceId()));
            matchBuilder.addFieldMatch(new PiLpmFieldMatch(HDR_IPV4_DST_PREFIX, ImmutableByteSequence.copyFrom(upfIntf.prefix().address().toOctets()), upfIntf.prefix().prefixLength()));
            break;
        case SESSION_UPLINK:
            tableEntryBuilder.forTable(PRE_QOS_PIPE_SESSIONS_UPLINK);
            UpfSessionUplink sessionUplink = (UpfSessionUplink) entity;
            matchBuilder.addFieldMatch(new PiExactFieldMatch(HDR_N3_ADDRESS, ImmutableByteSequence.copyFrom(sessionUplink.tunDstAddr().toOctets()))).addFieldMatch(new PiExactFieldMatch(HDR_TEID, ImmutableByteSequence.copyFrom(sessionUplink.teid())));
            if (sessionUplink.needsDropping()) {
                actionBuilder.withId(PRE_QOS_PIPE_SET_SESSION_UPLINK_DROP);
            } else {
                actionBuilder.withId(PRE_QOS_PIPE_SET_SESSION_UPLINK);
                actionBuilder.withParameter(new PiActionParam(SESSION_METER_IDX, sessionUplink.sessionMeterIdx()));
            }
            break;
        case SESSION_DOWNLINK:
            tableEntryBuilder.forTable(PRE_QOS_PIPE_SESSIONS_DOWNLINK);
            UpfSessionDownlink sessionDownlink = (UpfSessionDownlink) entity;
            matchBuilder.addFieldMatch(new PiExactFieldMatch(HDR_UE_ADDRESS, ImmutableByteSequence.copyFrom(sessionDownlink.ueAddress().toOctets())));
            if (sessionDownlink.needsDropping() && sessionDownlink.needsBuffering()) {
                log.error("We don't support DROP + BUFF on the UP4 northbound! Defaulting to only BUFF");
                actionBuilder.withId(PRE_QOS_PIPE_SET_SESSION_DOWNLINK_BUFF);
                actionBuilder.withParameter(new PiActionParam(SESSION_METER_IDX, sessionDownlink.sessionMeterIdx()));
            } else if (sessionDownlink.needsDropping()) {
                actionBuilder.withId(PRE_QOS_PIPE_SET_SESSION_DOWNLINK_DROP);
            } else {
                actionBuilder.withParameter(new PiActionParam(SESSION_METER_IDX, sessionDownlink.sessionMeterIdx()));
                if (sessionDownlink.needsBuffering()) {
                    actionBuilder.withId(PRE_QOS_PIPE_SET_SESSION_DOWNLINK_BUFF);
                } else {
                    actionBuilder.withParameter(new PiActionParam(TUNNEL_PEER_ID, ImmutableByteSequence.copyFrom(sessionDownlink.tunPeerId())));
                    actionBuilder.withId(PRE_QOS_PIPE_SET_SESSION_DOWNLINK);
                }
            }
            break;
        case TERMINATION_UPLINK:
            tableEntryBuilder.forTable(PRE_QOS_PIPE_TERMINATIONS_UPLINK);
            UpfTerminationUplink upfTerminationUl = (UpfTerminationUplink) entity;
            matchBuilder.addFieldMatch(new PiExactFieldMatch(HDR_UE_ADDRESS, ImmutableByteSequence.copyFrom(upfTerminationUl.ueSessionId().toOctets()))).addFieldMatch(new PiExactFieldMatch(HDR_APP_ID, ImmutableByteSequence.copyFrom(upfTerminationUl.applicationId())));
            actionBuilder.withParameter(new PiActionParam(CTR_IDX, upfTerminationUl.counterId()));
            if (upfTerminationUl.needsDropping()) {
                actionBuilder.withId(PRE_QOS_PIPE_UPLINK_TERM_DROP);
            } else {
                if (upfTerminationUl.trafficClass() != null) {
                    actionBuilder.withId(PRE_QOS_PIPE_UPLINK_TERM_FWD);
                    actionBuilder.withParameter(new PiActionParam(TC, upfTerminationUl.trafficClass()));
                } else {
                    actionBuilder.withId(PRE_QOS_PIPE_UPLINK_TERM_FWD_NO_TC);
                }
                actionBuilder.withParameter(new PiActionParam(APP_METER_IDX, upfTerminationUl.appMeterIdx()));
            }
            break;
        case TERMINATION_DOWNLINK:
            tableEntryBuilder.forTable(PRE_QOS_PIPE_TERMINATIONS_DOWNLINK);
            UpfTerminationDownlink upfTerminationDl = (UpfTerminationDownlink) entity;
            matchBuilder.addFieldMatch(new PiExactFieldMatch(HDR_UE_ADDRESS, ImmutableByteSequence.copyFrom(upfTerminationDl.ueSessionId().toOctets()))).addFieldMatch(new PiExactFieldMatch(HDR_APP_ID, ImmutableByteSequence.copyFrom(upfTerminationDl.applicationId())));
            actionBuilder.withParameter(new PiActionParam(CTR_IDX, upfTerminationDl.counterId()));
            if (upfTerminationDl.needsDropping()) {
                actionBuilder.withId(PRE_QOS_PIPE_DOWNLINK_TERM_DROP);
            } else {
                actionBuilder.withParameter(new PiActionParam(TEID, upfTerminationDl.teid())).withParameter(new PiActionParam(QFI, upfTerminationDl.qfi()));
                if (upfTerminationDl.trafficClass() != null) {
                    actionBuilder.withId(PRE_QOS_PIPE_DOWNLINK_TERM_FWD);
                    actionBuilder.withParameter(new PiActionParam(TC, upfTerminationDl.trafficClass()));
                } else {
                    actionBuilder.withId(PRE_QOS_PIPE_DOWNLINK_TERM_FWD_NO_TC);
                }
                actionBuilder.withParameter(new PiActionParam(APP_METER_IDX, upfTerminationDl.appMeterIdx()));
            }
            break;
        case TUNNEL_PEER:
            tableEntryBuilder.forTable(PRE_QOS_PIPE_TUNNEL_PEERS);
            UpfGtpTunnelPeer gtpTunnelPeer = (UpfGtpTunnelPeer) entity;
            matchBuilder.addFieldMatch(new PiExactFieldMatch(HDR_TUNNEL_PEER_ID, ImmutableByteSequence.copyFrom(gtpTunnelPeer.tunPeerId())));
            actionBuilder.withId(PRE_QOS_PIPE_LOAD_TUNNEL_PARAM).withParameter(new PiActionParam(SRC_ADDR, gtpTunnelPeer.src().toOctets())).withParameter(new PiActionParam(DST_ADDR, gtpTunnelPeer.dst().toOctets())).withParameter(new PiActionParam(SPORT, gtpTunnelPeer.srcPort()));
            break;
        case APPLICATION:
            tableEntryBuilder.forTable(PRE_QOS_PIPE_APPLICATIONS);
            UpfApplication application = (UpfApplication) entity;
            tableEntryBuilder.withPriority(application.priority());
            actionBuilder.withId(PRE_QOS_PIPE_SET_APP_ID).withParameter(new PiActionParam(APP_ID, application.appId()));
            matchBuilder.addFieldMatch(new PiExactFieldMatch(HDR_SLICE_ID, ImmutableByteSequence.copyFrom((byte) application.sliceId())));
            if (application.ip4Prefix().isPresent()) {
                Ip4Prefix ipPrefix = application.ip4Prefix().get();
                matchBuilder.addFieldMatch(new PiLpmFieldMatch(HDR_APP_IP_ADDR, ImmutableByteSequence.copyFrom(ipPrefix.address().toOctets()), ipPrefix.prefixLength()));
            }
            if (application.l4PortRange().isPresent()) {
                Range<Short> portRange = application.l4PortRange().get();
                matchBuilder.addFieldMatch(new PiRangeFieldMatch(HDR_APP_L4_PORT, ImmutableByteSequence.copyFrom(portRange.lowerEndpoint()), ImmutableByteSequence.copyFrom(portRange.upperEndpoint())));
            }
            if (application.ipProto().isPresent()) {
                byte ipProto = application.ipProto().get();
                matchBuilder.addFieldMatch(new PiTernaryFieldMatch(HDR_APP_IP_PROTO, ImmutableByteSequence.copyFrom(ipProto), ImmutableByteSequence.ofOnes(1)));
            }
            break;
        case SESSION_METER:
        case APPLICATION_METER:
        case COUNTER:
        default:
            throw new Up4TranslationException("Attempting to translate an unsupported UPF entity to a table entry! " + entity);
    }
    return tableEntryBuilder.withMatchKey(matchBuilder.build()).withAction(actionBuilder.build()).build();
}
Also used : UpfSessionUplink(org.onosproject.net.behaviour.upf.UpfSessionUplink) PiMatchKey(org.onosproject.net.pi.runtime.PiMatchKey) UpfTerminationDownlink(org.onosproject.net.behaviour.upf.UpfTerminationDownlink) PiRangeFieldMatch(org.onosproject.net.pi.runtime.PiRangeFieldMatch) UpfSessionDownlink(org.onosproject.net.behaviour.upf.UpfSessionDownlink) UpfApplication(org.onosproject.net.behaviour.upf.UpfApplication) PiTernaryFieldMatch(org.onosproject.net.pi.runtime.PiTernaryFieldMatch) UpfGtpTunnelPeer(org.onosproject.net.behaviour.upf.UpfGtpTunnelPeer) UpfTerminationUplink(org.onosproject.net.behaviour.upf.UpfTerminationUplink) PiAction(org.onosproject.net.pi.runtime.PiAction) PiLpmFieldMatch(org.onosproject.net.pi.runtime.PiLpmFieldMatch) PiTableEntry(org.onosproject.net.pi.runtime.PiTableEntry) UpfInterface(org.onosproject.net.behaviour.upf.UpfInterface) PiExactFieldMatch(org.onosproject.net.pi.runtime.PiExactFieldMatch) Ip4Prefix(org.onlab.packet.Ip4Prefix) PiActionParam(org.onosproject.net.pi.runtime.PiActionParam)

Aggregations

Ip4Prefix (org.onlab.packet.Ip4Prefix)32 Ip4Address (org.onlab.packet.Ip4Address)20 Test (org.junit.Test)15 ArrayList (java.util.ArrayList)11 Ip6Prefix (org.onlab.packet.Ip6Prefix)10 Ip6Address (org.onlab.packet.Ip6Address)6 ChannelBuffer (org.jboss.netty.buffer.ChannelBuffer)4 LinkedList (java.util.LinkedList)2 Up4AdminService (org.omecproject.up4.impl.Up4AdminService)2 OduSignalId (org.onosproject.net.OduSignalId)2 UpfInterface (org.onosproject.net.behaviour.upf.UpfInterface)2 DefaultTrafficSelector (org.onosproject.net.flow.DefaultTrafficSelector)2 TrafficSelector (org.onosproject.net.flow.TrafficSelector)2 OFOxm (org.projectfloodlight.openflow.protocol.oxm.OFOxm)2 CircuitSignalID (org.projectfloodlight.openflow.types.CircuitSignalID)2 IPv4Address (org.projectfloodlight.openflow.types.IPv4Address)2 IPv6Address (org.projectfloodlight.openflow.types.IPv6Address)2 OFVlanVidMatch (org.projectfloodlight.openflow.types.OFVlanVidMatch)2 JsonNode (com.fasterxml.jackson.databind.JsonNode)1 ArrayNode (com.fasterxml.jackson.databind.node.ArrayNode)1