*/
package org.opendaylight.netvirt.natservice.internal;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.math.BigInteger;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
+import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
import org.opendaylight.genius.infra.Datastore.Configuration;
import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Destination;
import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.netvirt.fibmanager.api.IFibManager;
import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
import org.opendaylight.netvirt.natservice.api.SnatServiceListener;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AdjacenciesBuilder;
protected final IVpnFootprintService vpnFootprintService;
protected final IFibManager fibManager;
protected final NatDataUtil natDataUtil;
+ protected final DataTreeEventCallbackRegistrar eventCallbacks;
protected AbstractSnatService(final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
final ItmRpcService itmManager, final OdlInterfaceRpcService odlInterfaceRpcService,
final IdManagerService idManager, final NAPTSwitchSelector naptSwitchSelector,
final IInterfaceManager interfaceManager,
final IVpnFootprintService vpnFootprintService,
- final IFibManager fibManager, final NatDataUtil natDataUtil) {
+ final IFibManager fibManager, final NatDataUtil natDataUtil,
+ final DataTreeEventCallbackRegistrar eventCallbacks) {
this.dataBroker = dataBroker;
this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.mdsalManager = mdsalManager;
this.vpnFootprintService = vpnFootprintService;
this.fibManager = fibManager;
this.natDataUtil = natDataUtil;
+ this.eventCallbacks = eventCallbacks;
}
protected DataBroker getDataBroker() {
}
protected void addSnatMissEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
- Long routerId, String routerName, BigInteger primarySwitchId) {
+ Long routerId, String routerName, BigInteger primarySwitchId) {
LOG.debug("installSnatMissEntry : Installing SNAT miss entry in switch {}", dpnId);
List<ActionInfo> listActionInfoPrimary = new ArrayList<>();
String ifNamePrimary = getTunnelInterfaceName(dpnId, primarySwitchId);
LOG.debug("installing the PSNAT to NAPTSwitch GroupEntity:{} with GroupId: {}", groupEntity, groupId);
mdsalManager.addGroup(confTx, groupEntity);
+ //Add the flow to send the packet to the group only after group is available in Config datastore
+ InstanceIdentifier<Group> groupIid = NatUtil.getGroupInstanceId(dpnId, groupId);
+ try {
+ if (confTx.read(groupIid).get().isPresent()) {
+ LOG.info("group {} is present in the config hence adding the flow", groupId);
+ addSnatMissFlowForGroup(confTx, dpnId, routerId, groupId);
+ return;
+ }
+ eventCallbacks.onAddOrUpdate(LogicalDatastoreType.CONFIGURATION,
+ NatUtil.getGroupInstanceId(dpnId, groupId), (unused, newGroupId) -> {
+ LOG.info("group {} is created in the config", groupId);
+ ListenableFutures.addErrorLogging(
+ txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+ innerConfTx -> addSnatMissFlowForGroup(innerConfTx, dpnId, routerId, groupId)),
+ LOG, "Error adding flow for the group {}",groupId);
+ return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
+ }, Duration.ofSeconds(5), iid -> LOG.error("groupId {} not found in config datastore",
+ groupId));
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Error programming SNAT miss entryfor dpn {}", dpnId);
+ }
+ }
+
+ private void addSnatMissFlowForGroup(TypedReadWriteTransaction<Configuration> confTx,
+ BigInteger dpnId, Long routerId, long groupId) {
// Install miss entry pointing to group
- LOG.debug("installSnatMissEntry : buildSnatFlowEntity is called for dpId {}, routerName {} and groupId {}",
- dpnId, routerName, groupId);
+ LOG.debug("installSnatMissEntry : buildSnatFlowEntity is called for dpId {}, routerId {} and groupId {}",
+ dpnId, routerId, groupId);
List<MatchInfo> matches = new ArrayList<>();
matches.add(new MatchEthernetType(0x0800L));
matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
import java.util.List;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
import org.opendaylight.genius.infra.Datastore.Configuration;
import org.opendaylight.genius.infra.TypedReadWriteTransaction;
import org.opendaylight.genius.infra.TypedWriteTransaction;
IdManagerService idManager, NAPTSwitchSelector naptSwitchSelector,
OdlInterfaceRpcService odlInterfaceRpcService,
IInterfaceManager interfaceManager, IVpnFootprintService vpnFootprintService,
- IFibManager fibManager, NatDataUtil natDataUtil) {
+ IFibManager fibManager, NatDataUtil natDataUtil,
+ DataTreeEventCallbackRegistrar eventCallbacks) {
super(dataBroker, mdsalManager, itmManager, odlInterfaceRpcService, idManager, naptSwitchSelector,
- interfaceManager, vpnFootprintService, fibManager, natDataUtil);
+ interfaceManager, vpnFootprintService, fibManager, natDataUtil, eventCallbacks);
}
@Override
import java.math.BigInteger;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
import org.opendaylight.genius.infra.Datastore.Configuration;
import org.opendaylight.genius.infra.TypedReadWriteTransaction;
import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
IdManagerService idManager, NAPTSwitchSelector naptSwitchSelector,
IInterfaceManager interfaceManager,
IVpnFootprintService vpnFootprintService,
- IFibManager fibManager, NatDataUtil natDataUtil) {
+ IFibManager fibManager, NatDataUtil natDataUtil,
+ DataTreeEventCallbackRegistrar eventCallbacks) {
super(dataBroker, mdsalManager, itmManager, idManager, naptSwitchSelector,
odlInterfaceRpcService, interfaceManager, vpnFootprintService, fibManager ,
- natDataUtil);
+ natDataUtil, eventCallbacks);
}
@Override
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanDpnInterfaces;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
.child(DpnInterfaces.class, new DpnInterfacesKey(dpId)).build();
}
+ public static InstanceIdentifier<Group> getGroupInstanceId(BigInteger dpnId, long groupId) {
+ return InstanceIdentifier.builder(Nodes.class).child(Node.class, new NodeKey(new NodeId("openflow:" + dpnId)))
+ .augmentation(FlowCapableNode.class).child(Group.class, new GroupKey(new GroupId(groupId))).build();
+ }
+
public static void createGroupIdPool(IdManagerService idManager) {
CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
.setPoolName(NatConstants.SNAT_IDPOOL_NAME)
import javax.inject.Inject;
import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
import org.opendaylight.infrautils.inject.AbstractLifecycle;
private final IVpnFootprintService vpnFootprintService;
private final IFibManager fibManager;
private final NatDataUtil natDataUtil;
+ private final DataTreeEventCallbackRegistrar eventCallbacks;
@Inject
public SnatServiceImplFactory(final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
final IInterfaceManager interfaceManager,
final IVpnFootprintService vpnFootprintService,
final IFibManager fibManager,
- final NatDataUtil natDataUtil) {
+ final NatDataUtil natDataUtil,
+ final DataTreeEventCallbackRegistrar eventCallbacks) {
this.dataBroker = dataBroker;
this.mdsalManager = mdsalManager;
this.itmManager = itmManager;
this.vpnFootprintService = vpnFootprintService;
this.fibManager = fibManager;
this.natDataUtil = natDataUtil;
+ this.eventCallbacks = eventCallbacks;
}
@Override
if (natMode == NatMode.Conntrack) {
return new FlatVlanConntrackBasedSnatService(dataBroker, mdsalManager, itmManager, odlInterfaceRpcService,
- idManager, naptSwitchSelector, interfaceManager, vpnFootprintService, fibManager, natDataUtil);
+ idManager, naptSwitchSelector, interfaceManager, vpnFootprintService, fibManager, natDataUtil,
+ eventCallbacks);
}
return null;
}
NatConstants.ODL_VNI_POOL_NAME);
return new VxlanGreConntrackBasedSnatService(dataBroker, mdsalManager, itmManager, odlInterfaceRpcService,
idManager, naptSwitchSelector, externalRouterListener, elanManager, interfaceManager,
- vpnFootprintService, fibManager, natDataUtil);
+ vpnFootprintService, fibManager, natDataUtil, eventCallbacks);
}
return null;
}
import java.util.List;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
import org.opendaylight.genius.infra.Datastore.Configuration;
import org.opendaylight.genius.infra.TypedReadWriteTransaction;
import org.opendaylight.genius.infra.TypedWriteTransaction;
ExternalRoutersListener externalRouterListener, IElanService elanManager,
IInterfaceManager interfaceManager,
IVpnFootprintService vpnFootprintService,
- IFibManager fibManager, NatDataUtil natDataUtil) {
+ IFibManager fibManager, NatDataUtil natDataUtil,
+ DataTreeEventCallbackRegistrar eventCallbacks) {
super(dataBroker, mdsalManager, itmManager, idManager, naptSwitchSelector, odlInterfaceRpcService,
- interfaceManager, vpnFootprintService, fibManager, natDataUtil);
+ interfaceManager, vpnFootprintService, fibManager, natDataUtil, eventCallbacks);
this.externalRouterListener = externalRouterListener;
this.elanManager = elanManager;
}