Search in sources :

Example 1 with ClassifierRenderableEntry

use of org.opendaylight.netvirt.sfc.classifier.service.domain.api.ClassifierRenderableEntry in project netvirt by opendaylight.

the class ConfigurationClassifierImpl method getEntriesForSfpRedirect.

private Set<ClassifierRenderableEntry> getEntriesForSfpRedirect(String ruleName, String srcPort, String dstPort, String sfpName, Matches matches) {
    if (srcPort == null && dstPort == null) {
        LOG.warn("Ace {} ignored: no source or destination port to match against", ruleName);
        return Collections.emptySet();
    }
    if (Objects.equals(srcPort, dstPort)) {
        LOG.warn("Ace {} ignored: equal source and destination port not supported", ruleName);
        return Collections.emptySet();
    }
    List<RenderedServicePath> rsps = sfcProvider.readServicePathState(sfpName).orElse(Collections.emptyList()).stream().map(sfcProvider::getRenderedServicePath).filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList());
    // be missing. It will be handled on a later listener event.
    if (rsps.isEmpty()) {
        LOG.debug("Ace {} ignored: no RSPs for SFP {} yet available", ruleName, sfpName);
        return Collections.emptySet();
    }
    // An SFP will have two RSPs associated if symmetric, one otherwise.
    if (rsps.size() > 2) {
        LOG.warn("Ace {} ignored: more than two RSPs associated to SFP {} not supported", ruleName, sfpName);
        return Collections.emptySet();
    }
    RenderedServicePath forwardRsp = rsps.stream().filter(rsp -> !rsp.isReversePath()).findAny().orElse(null);
    RenderedServicePath reverseRsp = rsps.stream().filter(RenderedServicePath::isReversePath).filter(rsp -> forwardRsp != null && rsp.getSymmetricPathId().equals(forwardRsp.getPathId())).findAny().orElse(null);
    if (srcPort != null && forwardRsp == null) {
        LOG.debug("Ace {} ignored: no forward RSP yet available for SFP {} and source port {}", ruleName, sfpName, srcPort);
        return Collections.emptySet();
    }
    if (dstPort != null && reverseRsp == null) {
        LOG.debug("Ace {} ignored: no reverse RSP yet available for SFP {} and destination port {}", ruleName, sfpName, dstPort);
        return Collections.emptySet();
    }
    Set<ClassifierRenderableEntry> entries = new HashSet<>();
    if (srcPort != null) {
        entries.addAll(this.buildEntries(ruleName, Collections.singletonList(srcPort), matches, forwardRsp));
    }
    if (dstPort != null) {
        Matches invertedMatches = AclMatches.invertMatches(matches);
        entries.addAll(this.buildEntries(ruleName, Collections.singletonList(dstPort), invertedMatches, reverseRsp));
    }
    return entries;
}
Also used : Optional(java.util.Optional) Matches(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.Matches) AclMatches(org.opendaylight.netvirt.sfc.classifier.utils.AclMatches) ClassifierRenderableEntry(org.opendaylight.netvirt.sfc.classifier.service.domain.api.ClassifierRenderableEntry) RenderedServicePath(org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath) HashSet(java.util.HashSet)

Example 2 with ClassifierRenderableEntry

use of org.opendaylight.netvirt.sfc.classifier.service.domain.api.ClassifierRenderableEntry in project netvirt by opendaylight.

the class ConfigurationClassifierImpl method buildEntries.

private Set<ClassifierRenderableEntry> buildEntries(String ruleName, @NonNull List<String> interfaces, @NonNull Matches matches, @NonNull RenderedServicePath rsp) {
    String rspName = rsp.getName().getValue();
    Long nsp = rsp.getPathId();
    Short nsi = rsp.getStartingIndex();
    Short nsl = rsp.getRenderedServicePathHop() == null ? null : (short) rsp.getRenderedServicePathHop().size();
    if (nsp == null || nsi == null || nsl == null) {
        LOG.warn("Ace {} RSP {} ignored: no valid NSI or NSP or length", ruleName, rspName);
        return Collections.emptySet();
    }
    DpnIdType firstHopDpn = sfcProvider.getFirstHopIngressInterfaceFromRsp(rsp).flatMap(geniusProvider::getDpnIdFromInterfaceName).orElse(null);
    if (firstHopDpn == null) {
        LOG.warn("Ace {} RSP {} ignored: no valid first hop DPN", ruleName, rspName);
        return Collections.emptySet();
    }
    String lastHopInterface = sfcProvider.getLastHopEgressInterfaceFromRsp(rsp).orElse(null);
    if (lastHopInterface == null) {
        LOG.warn("Ace {} RSP {} ignored: has no valid last hop interface", ruleName, rspName);
        return Collections.emptySet();
    }
    DpnIdType lastHopDpn = geniusProvider.getDpnIdFromInterfaceName(lastHopInterface).orElse(null);
    if (lastHopDpn == null) {
        LOG.warn("Ace {} RSP {} ignored: has no valid last hop DPN", ruleName, rspName);
        return Collections.emptySet();
    }
    Map<NodeId, List<InterfaceKey>> nodeToInterfaces = new HashMap<>();
    for (String iface : interfaces) {
        geniusProvider.getNodeIdFromLogicalInterface(iface).ifPresent(nodeId -> nodeToInterfaces.computeIfAbsent(nodeId, key -> new ArrayList<>()).add(new InterfaceKey(iface)));
    }
    LOG.trace("Ace {} RSP {}: got classifier nodes and interfaces: {}", ruleName, rspName, nodeToInterfaces);
    String firstHopIp = geniusProvider.getIpFromDpnId(firstHopDpn).orElse(null);
    Set<ClassifierRenderableEntry> entries = new HashSet<>();
    nodeToInterfaces.forEach((nodeId, ifaces) -> {
        // Get node info
        DpnIdType nodeDpn = new DpnIdType(OpenFlow13Provider.getDpnIdFromNodeId(nodeId));
        String nodeIp = geniusProvider.getIpFromDpnId(nodeDpn).orElse(LOCAL_HOST_IP);
        if (firstHopIp == null && !nodeDpn.equals(firstHopDpn)) {
            LOG.warn("Ace {} RSP {} classifier {} ignored: no IP to reach first hop DPN {}", ruleName, rspName, nodeId, firstHopDpn);
            return;
        }
        // Add entries that are not based on ingress or egress interface
        entries.add(ClassifierEntry.buildNodeEntry(nodeId));
        entries.add(ClassifierEntry.buildPathEntry(nodeId, nsp, nsi, nsl, nodeDpn.equals(firstHopDpn) ? null : firstHopIp));
        // Add entries based on ingress interface
        ifaces.forEach(interfaceKey -> {
            entries.add(ClassifierEntry.buildIngressEntry(interfaceKey));
            entries.add(ClassifierEntry.buildMatchEntry(nodeId, geniusProvider.getNodeConnectorIdFromInterfaceName(interfaceKey.getName()).get(), matches, nsp, nsi));
        });
        // hand-off can happen through the dispatcher table
        if (nodeDpn.equals(lastHopDpn)) {
            entries.add(ClassifierEntry.buildIngressEntry(new InterfaceKey(lastHopInterface)));
        }
        // Egress services must bind to egress ports. Since we dont know before-hand what
        // the egress ports will be, we will bind on all switch ports. If the packet
        // doesnt have NSH, it will be returned to the the egress dispatcher table.
        List<Interfaces> interfaceUuidStrList = geniusProvider.getInterfacesFromNode(nodeId);
        interfaceUuidStrList.forEach(interfaceUuidStr -> {
            InterfaceKey interfaceKey = new InterfaceKey(interfaceUuidStr.getInterfaceName());
            Optional<String> remoteIp = geniusProvider.getRemoteIpAddress(interfaceUuidStr.getInterfaceName());
            entries.add(ClassifierEntry.buildEgressEntry(interfaceKey, remoteIp.orElse(nodeIp)));
        });
    });
    return entries;
}
Also used : HashMap(java.util.HashMap) DpnIdType(org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.sfc.sff.logical.rev160620.DpnIdType) Interfaces(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.get.dpn._interface.list.output.Interfaces) NodeId(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId) ClassifierRenderableEntry(org.opendaylight.netvirt.sfc.classifier.service.domain.api.ClassifierRenderableEntry) ArrayList(java.util.ArrayList) List(java.util.List) InterfaceKey(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey) HashSet(java.util.HashSet)

Aggregations

HashSet (java.util.HashSet)2 ClassifierRenderableEntry (org.opendaylight.netvirt.sfc.classifier.service.domain.api.ClassifierRenderableEntry)2 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Optional (java.util.Optional)1 AclMatches (org.opendaylight.netvirt.sfc.classifier.utils.AclMatches)1 RenderedServicePath (org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath)1 DpnIdType (org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.sfc.sff.logical.rev160620.DpnIdType)1 Matches (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.Matches)1 InterfaceKey (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey)1 Interfaces (org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.get.dpn._interface.list.output.Interfaces)1 NodeId (org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId)1