use of org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron in project netvirt by opendaylight.
the class VpnManagerImpl method addArpResponderFlowsToExternalNetworkIps.
@Override
public void addArpResponderFlowsToExternalNetworkIps(String id, Collection<String> fixedIps, String macAddress, BigInteger dpnId, Uuid extNetworkId, WriteTransaction writeTx) {
if (dpnId == null || BigInteger.ZERO.equals(dpnId)) {
LOG.warn("Failed to install arp responder flows for router {}. DPN id is missing.", id);
return;
}
String extInterfaceName = elanService.getExternalElanInterface(extNetworkId.getValue(), dpnId);
if (extInterfaceName != null) {
doAddArpResponderFlowsToExternalNetworkIps(id, fixedIps, macAddress, dpnId, extNetworkId, writeTx, extInterfaceName);
return;
}
LOG.warn("Failed to install responder flows for {}. No external interface found for DPN id {}", id, dpnId);
if (!upgradeState.isUpgradeInProgress()) {
return;
}
// The following through the end of the function deals with an upgrade scenario where the neutron configuration
// is restored before the OVS switches reconnect. In such a case, the elan-dpn-interfaces entries will be
// missing from the operational data store. In order to mitigate this we use DataTreeEventCallbackRegistrar
// to wait for the exact operational md-sal object we need to contain the external interface we need.
LOG.info("Upgrade in process, waiting for an external interface to appear on dpn {} for elan {}", dpnId, extNetworkId.getValue());
InstanceIdentifier<DpnInterfaces> dpnInterfacesIid = elanService.getElanDpnInterfaceOperationalDataPath(extNetworkId.getValue(), dpnId);
eventCallbacks.onAddOrUpdate(LogicalDatastoreType.OPERATIONAL, dpnInterfacesIid, (unused, alsoUnused) -> {
LOG.info("Reattempting write of arp responder for external interfaces for external network {}", extNetworkId);
DpnInterfaces dpnInterfaces = elanService.getElanInterfaceInfoByElanDpn(extNetworkId.getValue(), dpnId);
if (dpnInterfaces == null) {
LOG.error("Could not retrieve DpnInterfaces for {}, {}", extNetworkId.getValue(), dpnId);
return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
}
String extIfc = null;
for (String dpnInterface : dpnInterfaces.getInterfaces()) {
if (interfaceManager.isExternalInterface(dpnInterface)) {
extIfc = dpnInterface;
break;
}
}
if (extIfc == null) {
if (upgradeState.isUpgradeInProgress()) {
LOG.info("External interface not found yet in elan {} on dpn {}, keep waiting", extNetworkId.getValue(), dpnInterfaces);
return DataTreeEventCallbackRegistrar.NextAction.CALL_AGAIN;
} else {
return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
}
}
final String extIfcFinal = extIfc;
ListenableFuture<Void> listenableFuture = txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
doAddArpResponderFlowsToExternalNetworkIps(id, fixedIps, macAddress, dpnId, extNetworkId, tx, extIfcFinal);
});
ListenableFutures.addErrorLogging(listenableFuture, LOG, "Error while configuring arp responder for ext. interface");
return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
});
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron in project netvirt by opendaylight.
the class NeutronPortChainListener method processPortChain.
private void processPortChain(PortChain newPortChain) {
// List of Port Pair Group attached to the Port Chain
List<PortPairGroup> portPairGroupList = new ArrayList<>();
// Port Pair Group and associated Port Pair
Map<Uuid, List<PortPair>> groupPortPairsList = new HashMap<>();
List<ServiceFunction> portChainServiceFunctionList = new ArrayList<>();
// Read chain related port pair group from neutron data store
for (Uuid ppgUuid : newPortChain.getPortPairGroups()) {
PortPairGroup ppg = neutronMdsalHelper.getNeutronPortPairGroup(ppgUuid);
if (ppg != null) {
List<PortPair> portPairList = new ArrayList<>();
portPairGroupList.add(ppg);
for (Uuid ppUuid : ppg.getPortPairs()) {
PortPair pp = neutronMdsalHelper.getNeutronPortPair(ppUuid);
if (pp == null) {
LOG.error("Port pair {} does not exist in the neutron data store", ppUuid);
return;
}
portPairList.add(pp);
}
groupPortPairsList.put(ppgUuid, portPairList);
}
}
// For each port pair group
for (PortPairGroup ppg : portPairGroupList) {
List<PortPair> portPairList = groupPortPairsList.get(ppg.getUuid());
// Generate all the SF and write it to SFC data store
for (PortPair portPair : portPairList) {
// Build the service function for the given port pair.
ServiceFunction serviceFunction = PortPairTranslator.buildServiceFunction(portPair, ppg);
portChainServiceFunctionList.add(serviceFunction);
// Write the Service Function to SFC data store.
LOG.info("Add Service Function {} for Port Pair {}", serviceFunction, portPair);
sfcMdsalHelper.addServiceFunction(serviceFunction);
}
// Build the SFF Builder from port pair group
ServiceFunctionForwarder serviceFunctionForwarder;
serviceFunctionForwarder = PortPairGroupTranslator.buildServiceFunctionForwarder(ppg, portPairList);
// Send SFF create request
LOG.info("Update Service Function Forwarder with {} for Port Pair Group {}", serviceFunctionForwarder, ppg);
sfcMdsalHelper.updateServiceFunctionForwarder(serviceFunctionForwarder);
}
// Build Service Function Chain Builder
ServiceFunctionChain sfc = PortChainTranslator.buildServiceFunctionChain(newPortChain, portChainServiceFunctionList);
// Write SFC to data store
if (sfc == null) {
LOG.warn("Service Function Chain building failed for Port Chain {}", newPortChain);
return;
}
LOG.info("Add service function chain {}", sfc);
sfcMdsalHelper.addServiceFunctionChain(sfc);
// Build Service Function Path Builder
ServiceFunctionPath sfp = PortChainTranslator.buildServiceFunctionPath(sfc);
// Write SFP to data store
LOG.info("Add service function path {}", sfp);
sfcMdsalHelper.addServiceFunctionPath(sfp);
// The RSP will automatically be created from the SFP added above.
// Add ACLs from flow classifiers
processFlowClassifiers(newPortChain, newPortChain.getFlowClassifiers(), sfp.getName().getValue());
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron in project netvirt by opendaylight.
the class OpenFlow13Provider method createIngressClassifierAclFlow.
/*
* Ingress Classifier ACL flow:
* Performs the ACL classification, and sends packets to Ingress Dispatcher
* Match on inport (corresponds to Neutron NW/tenant), Push NSH, init(nsp, nsi, C1, C2),
* and resubmit to Ingress Dispatcher to be sent down the rest of
* the pipeline
*/
public Flow createIngressClassifierAclFlow(NodeId nodeId, MatchBuilder match, Long port, long nsp, short nsi) {
OpenFlow13Utils.addMatchInPort(match, nodeId, port);
List<Action> actionList = new ArrayList<>();
actionList.add(OpenFlow13Utils.createActionNxPushNsh(actionList.size()));
actionList.add(OpenFlow13Utils.createActionNxLoadNshMdtype(NSH_MDTYPE_ONE, actionList.size()));
actionList.add(OpenFlow13Utils.createActionNxLoadNp(NSH_NP_ETH, actionList.size()));
actionList.add(OpenFlow13Utils.createActionNxLoadNsp((int) nsp, actionList.size()));
actionList.add(OpenFlow13Utils.createActionNxLoadNsi(nsi, actionList.size()));
actionList.add(OpenFlow13Utils.createActionNxLoadNshc1(ACL_FLAG_CONTEXT_VALUE, actionList.size()));
actionList.add(OpenFlow13Utils.createActionNxLoadNshc2(DEFAULT_NSH_CONTEXT_VALUE, actionList.size()));
actionList.add(OpenFlow13Utils.createActionResubmitTable(NwConstants.LPORT_DISPATCHER_TABLE, actionList.size()));
InstructionsBuilder isb = OpenFlow13Utils.wrapActionsIntoApplyActionsInstruction(actionList);
// The flowIdStr needs to be unique, so the best way to make it unique is to use the match
String flowIdStr = INGRESS_CLASSIFIER_ACL_FLOW_NAME + "_" + nodeId.getValue() + match.build().toString();
return OpenFlow13Utils.createFlowBuilder(NwConstants.INGRESS_SFC_CLASSIFIER_ACL_TABLE, INGRESS_CLASSIFIER_ACL_PRIORITY, INGRESS_CLASSIFIER_ACL_COOKIE, INGRESS_CLASSIFIER_ACL_FLOW_NAME, flowIdStr, match, isb).build();
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron in project netvirt by opendaylight.
the class ArpNotificationHandler method processArpLearning.
private void processArpLearning(String srcInterface, IpAddress srcIP, PhysAddress srcMac, BigInteger metadata, IpAddress dstIP) {
if (metadata != null && !Objects.equals(metadata, BigInteger.ZERO)) {
Optional<List<String>> vpnList = VpnUtil.getVpnHandlingIpv4AssociatedWithInterface(dataBroker, srcInterface);
if (vpnList.isPresent()) {
for (String vpnName : vpnList.get()) {
LOG.info("Received ARP for sender MAC {} and sender IP {} via interface {}", srcMac.getValue(), srcIP.getIpv4Address().getValue(), srcInterface);
String ipToQuery = srcIP.getIpv4Address().getValue();
LOG.info("ARP being processed for Source IP {}", ipToQuery);
VpnPortipToPort vpnPortipToPort = VpnUtil.getNeutronPortFromVpnPortFixedIp(dataBroker, vpnName, ipToQuery);
if (vpnPortipToPort != null) {
/* This is a well known neutron port and so should be ignored
* from being discovered
*/
continue;
}
LearntVpnVipToPort learntVpnVipToPort = VpnUtil.getLearntVpnVipToPort(dataBroker, vpnName, ipToQuery);
if (learntVpnVipToPort != null) {
String oldPortName = learntVpnVipToPort.getPortName();
String oldMac = learntVpnVipToPort.getMacAddress();
if (!oldMac.equalsIgnoreCase(srcMac.getValue())) {
// MAC has changed for requested IP
LOG.info("ARP Source IP/MAC data modified for IP {} with MAC {} and Port {}", ipToQuery, srcMac, srcInterface);
synchronized ((vpnName + ipToQuery).intern()) {
removeMipAdjacency(vpnName, oldPortName, srcIP);
VpnUtil.removeLearntVpnVipToPort(dataBroker, vpnName, ipToQuery);
putVpnIpToMigrateArpCache(vpnName, ipToQuery, srcMac);
}
}
} else if (!isIpInArpMigrateCache(vpnName, ipToQuery)) {
learnMacFromArpPackets(vpnName, srcInterface, srcIP, srcMac, dstIP);
}
}
} else {
LOG.info("ARP NO_RESOLVE: VPN not configured. Ignoring responding to ARP requests from this" + " Interface {}.", srcInterface);
return;
}
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron in project netvirt by opendaylight.
the class Ipv6ServiceInterfaceEventListener method add.
@Override
protected void add(InstanceIdentifier<Interface> key, Interface add) {
List<String> ofportIds = add.getLowerLayerIf();
if (!L2vlan.class.equals(add.getType())) {
return;
}
// In ipv6service, we are only interested in the notification for NeutronPort, so we skip other notifications
if (ofportIds == null || ofportIds.isEmpty() || !isNeutronPort(add.getName())) {
return;
}
org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface;
iface = ipv6ServiceUtils.getInterface(add.getName());
if (null != iface) {
LOG.debug("Port {} is a Neutron port", iface.getName());
NodeConnectorId nodeConnectorId = new NodeConnectorId(ofportIds.get(0));
BigInteger dpId = BigInteger.valueOf(MDSALUtil.getDpnIdFromPortName(nodeConnectorId));
if (!dpId.equals(Ipv6Constants.INVALID_DPID)) {
Uuid portId = new Uuid(iface.getName());
VirtualPort port = ifMgr.obtainV6Interface(portId);
if (port == null) {
LOG.info("Port {} does not include IPv6Address, skipping.", portId);
return;
}
Long ofPort = MDSALUtil.getOfPortNumberFromPortName(nodeConnectorId);
ifMgr.updateDpnInfo(portId, dpId, ofPort);
VirtualPort routerPort = ifMgr.getRouterV6InterfaceForNetwork(port.getNetworkID());
if (routerPort == null) {
LOG.info("Port {} is not associated to a Router, skipping.", portId);
return;
}
// Check and program icmpv6 punt flows on the dpnID if its the first VM on the host.
ifMgr.programIcmpv6PuntFlowsIfNecessary(portId, dpId, routerPort);
if (!port.getServiceBindingStatus()) {
jobCoordinator.enqueueJob("IPv6-" + String.valueOf(portId), () -> {
// Bind Service
Long elanTag = ifMgr.getNetworkElanTag(routerPort.getNetworkID());
ipv6ServiceUtils.bindIpv6Service(portId.getValue(), elanTag, NwConstants.IPV6_TABLE);
port.setServiceBindingStatus(true);
return Collections.emptyList();
}, SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries());
}
}
}
}
Aggregations