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;
}
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;
}
Aggregations