private static final String NEXTHOP_ID_POOL_NAME = "nextHopPointerPool";
private static final long FIXED_DELAY_IN_MILLISECONDS = 4000;
private L3VPNTransportTypes configuredTransportTypeL3VPN = L3VPNTransportTypes.Invalid;
+ private Long waitTimeForSyncInstall;
private static final FutureCallback<Void> DEFAULT_CALLBACK =
- new FutureCallback<Void>() {
- public void onSuccess(Void result) {
- LOG.debug("Success in Datastore write operation");
- }
- public void onFailure(Throwable error) {
- LOG.error("Error in Datastore write operation", error);
- }
- };
+ new FutureCallback<Void>() {
+ @Override
+ public void onSuccess(Void result) {
+ LOG.debug("Success in Datastore write operation");
+ }
+ @Override
+ public void onFailure(Throwable error) {
+ LOG.error("Error in Datastore write operation", error);
+ };
+ };
/**
- * Provides nexthop functions
- * Creates group ID pool
- *
- * @param db - dataBroker reference
- */
+ * Provides nexthop functions
+ * Creates group ID pool
+ *
+ * @param db - dataBroker reference
+ */
public NexthopManager(final DataBroker db) {
broker = db;
+ waitTimeForSyncInstall = Long.getLong("wait.time.sync.install");
+ if (waitTimeForSyncInstall == null)
+ waitTimeForSyncInstall = 1000L;
}
@Override
protected void createNexthopPointerPool() {
CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
- .setPoolName(NEXTHOP_ID_POOL_NAME)
- .setLow(150000L)
- .setHigh(175000L)
- .build();
+ .setPoolName(NEXTHOP_ID_POOL_NAME)
+ .setLow(150000L)
+ .setHigh(175000L)
+ .build();
//TODO: Error handling
Future<RpcResult<Void>> result = idManager.createIdPool(createPool);
LOG.trace("NextHopPointerPool result : {}", result);
protected long createNextHopPointer(String nexthopKey) {
AllocateIdInput getIdInput = new AllocateIdInputBuilder()
- .setPoolName(NEXTHOP_ID_POOL_NAME).setIdKey(nexthopKey)
- .build();
+ .setPoolName(NEXTHOP_ID_POOL_NAME).setIdKey(nexthopKey)
+ .build();
//TODO: Proper error handling once IdManager code is complete
try {
Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
protected void removeNextHopPointer(String nexthopKey) {
ReleaseIdInput idInput = new ReleaseIdInputBuilder().
- setPoolName(NEXTHOP_ID_POOL_NAME)
- .setIdKey(nexthopKey).build();
+ setPoolName(NEXTHOP_ID_POOL_NAME)
+ .setIdKey(nexthopKey).build();
try {
Future<RpcResult<Void>> result = idManager.releaseId(idInput);
RpcResult<Void> rpcResult = result.get();
}
protected List<ActionInfo> getEgressActionsForInterface(String ifName) {
- List<ActionInfo> listActionInfo = new ArrayList<>();
+ List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
try {
Future<RpcResult<GetEgressActionsForInterfaceOutput>> result =
- interfaceManager.getEgressActionsForInterface(
- new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName).build());
+ interfaceManager.getEgressActionsForInterface(
+ new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName).build());
RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
if(!rpcResult.isSuccessful()) {
LOG.warn("RPC Call to Get egress actions for interface {} returned with Errors {}", ifName, rpcResult.getErrors());
} else {
List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actions =
- rpcResult.getResult().getAction();
+ rpcResult.getResult().getAction();
for (Action action : actions) {
org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionClass = action.getAction();
if (actionClass instanceof OutputActionCase) {
listActionInfo.add(new ActionInfo(ActionType.output,
- new String[] {((OutputActionCase)actionClass).getOutputAction()
- .getOutputNodeConnector().getValue()}));
+ new String[] {((OutputActionCase)actionClass).getOutputAction()
+ .getOutputNodeConnector().getValue()}));
} else if (actionClass instanceof PushVlanActionCase) {
listActionInfo.add(new ActionInfo(ActionType.push_vlan, new String[] {}));
} else if (actionClass instanceof SetFieldCase) {
if (((SetFieldCase)actionClass).getSetField().getVlanMatch() != null) {
int vlanVid = ((SetFieldCase)actionClass).getSetField().getVlanMatch().getVlanId().getVlanId().getValue();
listActionInfo.add(new ActionInfo(ActionType.set_field_vlan_vid,
- new String[] { Long.toString(vlanVid) }));
+ new String[] { Long.toString(vlanVid) }));
}
}
}
protected String getTunnelInterfaceName(BigInteger srcDpId, BigInteger dstDpId) {
Class<? extends TunnelTypeBase> tunType = getReqTunType(getReqTransType().toUpperCase());
+ Future<RpcResult<GetTunnelInterfaceNameOutput>> result;
try {
- Future<RpcResult<GetTunnelInterfaceNameOutput>> result = itmManager.getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder()
- .setSourceDpid(srcDpId)
- .setDestinationDpid(dstDpId)
- .setTunnelType(tunType).build());
+ result = itmManager.getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder()
+ .setSourceDpid(srcDpId)
+ .setDestinationDpid(dstDpId)
+ .setTunnelType(tunType)
+ .build());
RpcResult<GetTunnelInterfaceNameOutput> rpcResult = result.get();
if(!rpcResult.isSuccessful()) {
LOG.warn("RPC Call to getTunnelInterfaceId returned with Errors {}", rpcResult.getErrors());
} catch (InterruptedException | ExecutionException e) {
LOG.warn("Exception when getting tunnel interface Id for tunnel between {} and {}", srcDpId, dstDpId, e);
}
-
return null;
}
- protected String getTunnelInterfaceName(BigInteger srcDpId, IpAddress dstIp) {
+
+
+ protected String getTunnelInterfaceName(BigInteger srcDpId, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress dstIp) {
Class<? extends TunnelTypeBase> tunType = getReqTunType(getReqTransType().toUpperCase());
+ Future<RpcResult<GetInternalOrExternalInterfaceNameOutput>> result;
try {
- Future<RpcResult<GetInternalOrExternalInterfaceNameOutput>> result = itmManager.getInternalOrExternalInterfaceName(new GetInternalOrExternalInterfaceNameInputBuilder()
- .setSourceDpid(srcDpId)
- .setDestinationIp(dstIp)
- .setTunnelType(tunType).build());
+ result = itmManager.getInternalOrExternalInterfaceName(new GetInternalOrExternalInterfaceNameInputBuilder()
+ .setSourceDpid(srcDpId)
+ .setDestinationIp(dstIp)
+ .setTunnelType(tunType)
+ .build());
RpcResult<GetInternalOrExternalInterfaceNameOutput> rpcResult = result.get();
if(!rpcResult.isSuccessful()) {
LOG.warn("RPC Call to getTunnelInterfaceName returned with Errors {}", rpcResult.getErrors());
} catch (InterruptedException | ExecutionException e) {
LOG.warn("Exception when getting tunnel interface Id for tunnel between {} and {}", srcDpId, dstIp, e);
}
-
return null;
}
String nextHopLockStr = new String(vpnId + ipAddress);
synchronized (nextHopLockStr.intern()) {
VpnNexthop nexthop = getVpnNexthop(vpnId, ipAddress);
- LOG.trace("nexthop: {}", nexthop);
+ LOG.trace("nexthop: {} retrieved for vpnId {}, prefix {}, ifName {} on dpn {}", nexthop,
+ vpnId, ipAddress, ifName, dpnId);
if (nexthop == null) {
Optional<Adjacency> adjacencyData =
read(LogicalDatastoreType.OPERATIONAL, getAdjacencyIdentifier(ifName, ipAddress));
String macAddress = adjacencyData.isPresent() ? adjacencyData.get().getMacAddress() : null;
- List<BucketInfo> listBucketInfo = new ArrayList<>();
+ List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
List<ActionInfo> listActionInfo = getEgressActionsForInterface(ifName);
BucketInfo bucket = new BucketInfo(listActionInfo);
// MAC re-write
}
listBucketInfo.add(bucket);
GroupEntity groupEntity = MDSALUtil.buildGroupEntity(
- dpnId, groupId, ipAddress, GroupTypes.GroupIndirect, listBucketInfo);
-
- //update MD-SAL DS
- addVpnNexthopToDS(dpnId, vpnId, ipAddress, groupId);
+ dpnId, groupId, ipAddress, GroupTypes.GroupAll, listBucketInfo);
+ LOG.trace("Install LNH Group: id {}, mac address {}, interface {} for prefix {}", groupId, macAddress, ifName, ipAddress);
// install Group
mdsalManager.syncInstallGroup(groupEntity, FIXED_DELAY_IN_MILLISECONDS);
+ try{
+ LOG.info("Sleeping for {} to wait for the groups to get programmed.", waitTimeForSyncInstall);
+ Thread.sleep(waitTimeForSyncInstall);
+ }catch(InterruptedException error){
+ LOG.warn("Error while waiting for group {} to install.", groupId);
+ LOG.debug("{}", error);
+ }
+ //update MD-SAL DS
+ addVpnNexthopToDS(dpnId, vpnId, ipAddress, groupId);
} else {
//nexthop exists already; a new flow is going to point to it, increment the flowrefCount by 1
protected void addVpnNexthopToDS(BigInteger dpnId, long vpnId, String ipPrefix, long egressPointer) {
InstanceIdentifierBuilder<VpnNexthops> idBuilder = InstanceIdentifier.builder(
- L3nexthop.class)
+ L3nexthop.class)
.child(VpnNexthops.class, new VpnNexthopsKey(vpnId));
// Add nexthop to vpn node
// check if vpn node is there
InstanceIdentifierBuilder<VpnNexthops> idBuilder =
- InstanceIdentifier.builder(L3nexthop.class).child(VpnNexthops.class,
- new VpnNexthopsKey(vpnId));
+ InstanceIdentifier.builder(L3nexthop.class).child(VpnNexthops.class,
+ new VpnNexthopsKey(vpnId));
InstanceIdentifier<VpnNexthops> id = idBuilder.build();
Optional<VpnNexthops> vpnNexthops = read(LogicalDatastoreType.OPERATIONAL, id);
if (vpnNexthops.isPresent()) {
}
- public String getRemoteNextHopPointer(BigInteger localDpnId, BigInteger remoteDpnId,
- long vpnId, String prefixIp, String nextHopIp) {
+ public String getRemoteNextHopPointer(BigInteger remoteDpnId, long vpnId, String prefixIp, String nextHopIp) {
String tunnelIfName = null;
- LOG.trace("getRemoteNextHopPointer: input [localDpnId {} remoteDpnId {}, vpnId {}, prefixIp {}, nextHopIp {} ]",
- localDpnId, remoteDpnId, vpnId, prefixIp, nextHopIp);
+ LOG.trace("getRemoteNextHopPointer: input [remoteDpnId {}, vpnId {}, prefixIp {}, nextHopIp {} ]",
+ remoteDpnId, vpnId, prefixIp, nextHopIp);
- LOG.trace("getRemoteNextHopPointer: Calling ITM with localDpnId {} ", localDpnId);
if (nextHopIp != null && !nextHopIp.isEmpty()) {
try{
// here use the config for tunnel type param
- tunnelIfName = getTunnelInterfaceName(remoteDpnId, IpAddressBuilder.getDefaultInstance(nextHopIp));
- }catch(Exception ex){
- LOG.error("Error while retrieving nexthop pointer for nexthop {} : ", nextHopIp, ex.getMessage());
+ tunnelIfName = getTunnelInterfaceName(remoteDpnId, org.opendaylight.yang.gen.v1.urn.ietf.params.xml
+ .ns.yang.ietf.inet.types.rev130715.IpAddressBuilder.getDefaultInstance(nextHopIp));
+ } catch(Exception ex){
+ LOG.error("Error while retrieving nexthop pointer for nexthop {} : ", nextHopIp, ex.getMessage());
}
}
return tunnelIfName;
delete(LogicalDatastoreType.OPERATIONAL, id);
}
-
+
public void removeLocalNextHop(BigInteger dpnId, Long vpnId, String ipAddress) {
String nextHopLockStr = new String(vpnId + ipAddress);
int newFlowrefCnt = nh.getFlowrefCount() - 1;
if (newFlowrefCnt == 0) { //remove the group only if there are no more flows using this group
GroupEntity groupEntity = MDSALUtil.buildGroupEntity(
- dpnId, nh.getEgressPointer(), ipAddress, GroupTypes.GroupIndirect, null);
+ dpnId, nh.getEgressPointer(), ipAddress, GroupTypes.GroupAll, null);
// remove Group ...
mdsalManager.removeGroup(groupEntity);
//update MD-SAL DS
removeVpnNexthopFromDS(vpnId, ipAddress);
//release groupId
removeNextHopPointer(getNextHopKey(vpnId, ipAddress));
- LOG.debug("Local Next hop for {} on dpn {} successfully deleted", ipAddress, dpnId);
+ LOG.debug("Local Next hop {} for {} {} on dpn {} successfully deleted", nh.getEgressPointer(), vpnId, ipAddress, dpnId);
} else {
//just update the flowrefCount of the vpnNexthop
VpnNexthop currNh = new VpnNexthopBuilder().setKey(new VpnNexthopKey(ipAddress)).setFlowrefCount(newFlowrefCnt).build();
private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
- InstanceIdentifier<T> path) {
+ InstanceIdentifier<T> path) {
ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
}
private <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
- InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
+ InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
WriteTransaction tx = broker.newWriteOnlyTransaction();
tx.merge(datastoreType, path, data, true);
Futures.addCallback(tx.submit(), callback);
}
private <T extends DataObject> void syncWrite(LogicalDatastoreType datastoreType,
- InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
+ InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
WriteTransaction tx = broker.newWriteOnlyTransaction();
tx.merge(datastoreType, path, data, true);
tx.submit();
private InstanceIdentifier<Adjacency> getAdjacencyIdentifier(String vpnInterfaceName, String ipAddress) {
return InstanceIdentifier.builder(VpnInterfaces.class)
- .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).augmentation(
- Adjacencies.class).child(Adjacency.class, new AdjacencyKey(ipAddress)).build();
+ .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).augmentation(
+ Adjacencies.class).child(Adjacency.class, new AdjacencyKey(ipAddress)).build();
}
InstanceIdentifier<Adjacencies> getAdjListPath(String vpnInterfaceName) {
Adjacencies.class).build();
}
-
public void setConfTransType(String service,String transportType) {
if (!service.toUpperCase().equals("L3VPN")) {
return confTransType;
}
- Class<? extends TunnelTypeBase> getReqTunType(String transportType) {
+ public Class<? extends TunnelTypeBase> getReqTunType(String transportType) {
if (transportType.equals("VXLAN")) {
return TunnelTypeVxlan.class;
} else if (transportType.equals("GRE")) {
return TunnelTypeMplsOverGre.class;
}
}
+
+ public String getTransportTypeStr ( String tunType) {
+ if (tunType.equals(TunnelTypeVxlan.class.toString())) {
+ return ITMConstants.TUNNEL_TYPE_VXLAN;
+ } else if (tunType.equals(TunnelTypeGre.class.toString())) {
+ return ITMConstants.TUNNEL_TYPE_GRE;
+ } else if (tunType.equals(TunnelTypeMplsOverGre.class.toString())){
+ return ITMConstants.TUNNEL_TYPE_MPLS_OVER_GRE;
+ } else {
+ return ITMConstants.TUNNEL_TYPE_INVALID;
+ }
+ }
}