use of org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId in project netvirt by opendaylight.
the class OpenFlow13Provider method createIngressClassifierFilterEthNshFlow.
/*
* Ingress Classifier Filter Eth NSH flow:
* Only allows Non-NSH packets to proceed in the classifier
* Match on ethertype and null tunnel IP and resubmit to
* Ingress Dispatcher on match
*/
public Flow createIngressClassifierFilterEthNshFlow(NodeId nodeId) {
MatchBuilder match = new MatchBuilder();
OpenFlow13Utils.addMatchEthNsh(match);
OpenFlow13Utils.addMatchTunDstIp(match, NULL_IP);
List<Action> actionList = new ArrayList<>();
actionList.add(OpenFlow13Utils.createActionResubmitTable(NwConstants.LPORT_DISPATCHER_TABLE, actionList.size()));
InstructionsBuilder isb = OpenFlow13Utils.wrapActionsIntoApplyActionsInstruction(actionList);
String flowIdStr = INGRESS_CLASSIFIER_FILTER_ETHNSH_FLOW_NAME + nodeId.getValue();
return OpenFlow13Utils.createFlowBuilder(NwConstants.INGRESS_SFC_CLASSIFIER_FILTER_TABLE, INGRESS_CLASSIFIER_FILTER_ETH_NSH_PRIORITY, INGRESS_CLASSIFIER_FILTER_COOKIE, INGRESS_CLASSIFIER_FILTER_ETHNSH_FLOW_NAME, flowIdStr, match, isb).build();
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId 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;
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId in project netvirt by opendaylight.
the class OpenflowRenderer method renderPath.
@Override
// FindBugs reports "Useless object stored in variable flows" however it doesn't recognize the usage of forEach.
@SuppressFBWarnings("UC_USELESS_OBJECT")
public void renderPath(NodeId nodeId, Long nsp, short nsi, short nsl, String firstHopIp) {
List<Flow> flows = new ArrayList<>();
if (firstHopIp != null) {
Long port = geniusProvider.getEgressVxlanPortForNode(OpenFlow13Provider.getDpnIdFromNodeId(nodeId)).orElse(null);
if (port == null) {
LOG.error("OpenflowRenderer: cant get egressPort for nodeId [{}]", nodeId.getValue());
return;
}
Flow flow;
flow = openFlow13Provider.createEgressClassifierTransportEgressRemoteFlow(nodeId, nsp, port, firstHopIp);
flows.add(flow);
} else {
Flow flow;
flow = openFlow13Provider.createEgressClassifierTransportEgressLocalFlow(nodeId, nsp);
flows.add(flow);
}
short egressNsi = (short) (nsi - nsl);
flows.add(openFlow13Provider.createIngressClassifierFilterChainEgressFlow(nodeId, nsp, egressNsi));
ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> flows.forEach(flow -> this.openFlow13Provider.appendFlowForCreate(nodeId, flow, tx))), LOG, "Error rendering a path");
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId in project netvirt by opendaylight.
the class L2GatewayListener method update.
@Override
protected void update(InstanceIdentifier<L2gateway> identifier, L2gateway original, L2gateway update) {
LOG.trace("Updating L2gateway : key: {}, original value={}, update value={}", identifier, original, update);
List<L2gatewayConnection> connections = l2gwService.getAssociatedL2GwConnections(Sets.newHashSet(update.getUuid()));
if (connections == null) {
LOG.warn("There are no connections associated with l2 gateway uuid {} name {}", update.getUuid(), update.getName());
return;
}
if (original.getDevices() == null) {
connections.forEach((connection) -> l2gwService.addL2GatewayConnection(connection));
return;
}
jobCoordinator.enqueueJob("l2gw.update", () -> {
ReadWriteTransaction transaction = dataBroker.newReadWriteTransaction();
DeviceInterfaces updatedDeviceInterfaces = new DeviceInterfaces(update);
List<ListenableFuture<Void>> fts = new ArrayList<>();
original.getDevices().stream().filter((originalDevice) -> originalDevice.getInterfaces() != null).forEach((originalDevice) -> {
String deviceName = originalDevice.getDeviceName();
L2GatewayDevice l2GwDevice = l2GatewayCache.get(deviceName);
NodeId physicalSwitchNodeId = HwvtepSouthboundUtils.createManagedNodeId(new NodeId(l2GwDevice.getHwvtepNodeId()), deviceName);
originalDevice.getInterfaces().stream().filter((intf) -> !updatedDeviceInterfaces.containsInterface(deviceName, intf.getInterfaceName())).forEach((intf) -> {
connections.forEach((connection) -> {
Integer vlanId = connection.getSegmentId();
if (intf.getSegmentationIds() != null && !intf.getSegmentationIds().isEmpty()) {
for (Integer vlan : intf.getSegmentationIds()) {
HwvtepUtils.deleteVlanBinding(transaction, physicalSwitchNodeId, intf.getInterfaceName(), vlan);
}
} else {
LOG.debug("Deleting vlan binding {} {} {}", physicalSwitchNodeId, intf.getInterfaceName(), vlanId);
HwvtepUtils.deleteVlanBinding(transaction, physicalSwitchNodeId, intf.getInterfaceName(), vlanId);
}
});
});
});
fts.add(transaction.submit());
Futures.addCallback(fts.get(0), new FutureCallback<Void>() {
@Override
public void onSuccess(Void success) {
LOG.debug("Successfully deleted vlan bindings for l2gw update {}", update);
connections.forEach((l2GwConnection) -> l2gwService.addL2GatewayConnection(l2GwConnection, null, update));
}
@Override
public void onFailure(Throwable throwable) {
LOG.error("Failed to delete vlan bindings as part of l2gw udpate {}", update);
}
}, MoreExecutors.directExecutor());
return fts;
}, SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries());
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId in project netvirt by opendaylight.
the class L2GatewayUtils method createItmTunnels.
protected static void createItmTunnels(ItmRpcService itmRpcService, String hwvtepId, String psName, IpAddress tunnelIp) {
AddL2GwDeviceInputBuilder builder = new AddL2GwDeviceInputBuilder();
builder.setTopologyId(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID.getValue());
builder.setNodeId(HwvtepSouthboundUtils.createManagedNodeId(new NodeId(hwvtepId), psName).getValue());
builder.setIpAddress(tunnelIp);
try {
Future<RpcResult<Void>> result = itmRpcService.addL2GwDevice(builder.build());
RpcResult<Void> rpcResult = result.get();
if (rpcResult.isSuccessful()) {
LOG.info("Created ITM tunnels for {}", hwvtepId);
} else {
LOG.error("Failed to create ITM Tunnels: {}", rpcResult.getErrors());
}
} catch (InterruptedException | ExecutionException e) {
LOG.error("RPC to create ITM tunnels failed", e);
}
}
Aggregations