+ LOG.info("NextHop Manager Closed");
+ }
+
+ public void setInterfaceManager(IInterfaceManager ifManager) {
+ this.interfaceManager = ifManager;
+ }
+
+ public void setMdsalManager(IMdsalApiManager mdsalManager) {
+ this.mdsalManager = mdsalManager;
+ }
+
+ public void setIdManager(IdManager idManager) {
+ this.idManager = idManager;
+ }
+
+ private void createNexthopPointerPool() {
+ CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
+ .setPoolName("nextHopPointerPool")
+ .setIdStart(1L)
+ .setPoolSize(new BigInteger("65535"))
+ .build();
+ //TODO: Error handling
+ Future<RpcResult<Void>> result = idManager.createIdPool(createPool);
+// try {
+// LOG.info("Result2: {}",result.get());
+// } catch (InterruptedException | ExecutionException e) {
+// // TODO Auto-generated catch block
+// LOG.error("Error in result.get");
+// }
+
+ }
+
+
+ private long getVpnId(String vpnName) {
+ InstanceIdentifierBuilder<VpnInstance> idBuilder = InstanceIdentifier.builder(VpnInstances.class)
+ .child(VpnInstance.class, new VpnInstanceKey(vpnName));
+
+ InstanceIdentifier<VpnInstance> id = idBuilder.build();
+ InstanceIdentifier<VpnInstance1> idx = id.augmentation(VpnInstance1.class);
+ Optional<VpnInstance1> vpn = read(LogicalDatastoreType.CONFIGURATION, idx);
+
+ if (vpn.isPresent()) {
+ return vpn.get().getVpnId();
+ } else {
+ return 0;
+ }
+ }
+
+ private long getDpnId(String ifName) {
+ String[] fields = ifName.split(":");
+ long dpn = Integer.parseInt(fields[1]);
+ return dpn;
+ }
+
+ private int createNextHopPointer(String nexthopKey) {
+ GetUniqueIdInput getIdInput = new GetUniqueIdInputBuilder()
+ .setPoolName("nextHopPointerPool").setIdKey(nexthopKey)
+ .build();
+ //TODO: Proper error handling once IdManager code is complete
+ try {
+ Future<RpcResult<GetUniqueIdOutput>> result = idManager.getUniqueId(getIdInput);
+ RpcResult<GetUniqueIdOutput> rpcResult = result.get();
+ return rpcResult.getResult().getIdValue().intValue();
+ } catch (NullPointerException | InterruptedException | ExecutionException e) {
+ LOG.trace("",e);
+ }
+ return 0;
+ }
+
+ public void createLocalNextHop(String ifName, String vpnName, String ipAddress, String macAddress) {
+ String nhKey = new String("nexthop." + vpnName + ipAddress);
+ int groupId = createNextHopPointer(nhKey);
+
+ long vpnId = getVpnId(vpnName);
+ long dpnId = interfaceManager.getDpnForInterface(ifName);
+ VpnNexthop nexthop = getVpnNexthop(vpnId, ipAddress);
+ if (nexthop == null) {
+ List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
+ List<ActionInfo> listActionInfo = interfaceManager.getInterfaceEgressActions(ifName);
+ BucketInfo bucket = new BucketInfo(listActionInfo);
+ // MAC re-write
+ if (macAddress != null) {
+ listActionInfo.add(new ActionInfo(ActionType.set_field_eth_dest, new String[]{macAddress}));
+ } else {
+ //FIXME: Log message here.
+ }
+ listBucketInfo.add(bucket);
+ GroupEntity groupEntity = MDSALUtil.buildGroupEntity(
+ dpnId, groupId, ipAddress, GroupTypes.GroupIndirect, listBucketInfo);
+
+ // install Group
+ mdsalManager.installGroup(groupEntity);
+
+ //update MD-SAL DS
+ addVpnNexthopToDS(vpnId, ipAddress, groupId);
+ } else {
+ //check update
+ }
+ }
+
+ public void createRemoteNextHop(String ifName, String ofPortId, String ipAddress) {
+ String nhKey = new String("nexthop." + ifName + ipAddress);
+ int groupId = createNextHopPointer(nhKey);
+
+ long dpnId = getDpnId(ofPortId);
+ TunnelNexthop nexthop = getTunnelNexthop(dpnId, ipAddress);
+ if (nexthop == null) {
+
+ List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
+ List<ActionInfo> listActionInfo = interfaceManager.getInterfaceEgressActions(ifName);
+ BucketInfo bucket = new BucketInfo(listActionInfo);
+ // MAC re-write??
+ listBucketInfo.add(bucket);
+ GroupEntity groupEntity = MDSALUtil.buildGroupEntity(
+ dpnId, groupId, ipAddress, GroupTypes.GroupIndirect, listBucketInfo);
+ mdsalManager.installGroup(groupEntity);
+
+ //update MD-SAL DS
+ addTunnelNexthopToDS(dpnId, ipAddress, groupId);
+ } else {
+ //check update
+ }
+ }
+
+ private void addVpnNexthopToDS(long vpnId, String ipPrefix, long egressPointer) {
+
+ InstanceIdentifierBuilder<VpnNexthops> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
+ .child(VpnNexthops.class, new VpnNexthopsKey(vpnId));
+
+ // check if vpn node is there or to be created
+ InstanceIdentifier<VpnNexthops> id = idBuilder.build();
+ Optional<VpnNexthops> nexthops = read(LogicalDatastoreType.CONFIGURATION, id);
+ if (!nexthops.isPresent()) {
+ // create a new node
+ VpnNexthops node = new VpnNexthopsBuilder().setKey(new VpnNexthopsKey(vpnId)).setVpnId(vpnId).build();
+ asyncWrite(LogicalDatastoreType.OPERATIONAL, id, node, DEFAULT_CALLBACK);
+ }
+
+ // Add nexthop to vpn node
+ VpnNexthop nh = new VpnNexthopBuilder().
+ setKey(new VpnNexthopKey(ipPrefix)).
+ setIpAddress(ipPrefix).
+ setEgressPointer(egressPointer).build();
+
+ InstanceIdentifier<VpnNexthop> id1 = idBuilder
+ .child(VpnNexthop.class, new VpnNexthopKey(ipPrefix)).build();
+
+ asyncWrite(LogicalDatastoreType.OPERATIONAL, id1, nh, DEFAULT_CALLBACK);
+
+ }
+
+ private void addTunnelNexthopToDS(long dpnId, String ipPrefix, long egressPointer) {
+ InstanceIdentifierBuilder<TunnelNexthops> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
+ .child(TunnelNexthops.class, new TunnelNexthopsKey(dpnId));
+
+ // check if dpn node is there or to be created
+ InstanceIdentifier<TunnelNexthops> id = idBuilder.build();
+ Optional<TunnelNexthops> nexthops = read(LogicalDatastoreType.CONFIGURATION, id);
+ if (!nexthops.isPresent()) {
+ // create a new node
+ TunnelNexthops node = new TunnelNexthopsBuilder()
+ .setKey(new TunnelNexthopsKey(dpnId))
+ .setDpnId(dpnId)
+ .build();
+ asyncWrite(LogicalDatastoreType.OPERATIONAL, id, node, DEFAULT_CALLBACK);
+ }
+
+ // Add nexthop to dpn node
+ TunnelNexthop nh = new TunnelNexthopBuilder().
+ setKey(new TunnelNexthopKey(ipPrefix)).
+ setIpAddress(ipPrefix).
+ setEgressPointer(egressPointer).build();
+
+ InstanceIdentifier<TunnelNexthop> id1 = idBuilder
+ .child(TunnelNexthop.class, new TunnelNexthopKey(ipPrefix)).build();
+
+ asyncWrite(LogicalDatastoreType.OPERATIONAL, id1, nh, DEFAULT_CALLBACK);
+
+ }
+
+ private VpnNexthop getVpnNexthop(long vpnId, String ipAddress) {
+
+ // check if vpn node is there
+ InstanceIdentifierBuilder<VpnNexthops> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
+ .child(VpnNexthops.class, new VpnNexthopsKey(vpnId));
+ InstanceIdentifier<VpnNexthops> id = idBuilder.build();
+ Optional<VpnNexthops> vpnNexthops = read(LogicalDatastoreType.CONFIGURATION, id);
+ if (!vpnNexthops.isPresent()) {
+
+ // get nexthops list for vpn
+ List<VpnNexthop> nexthops = vpnNexthops.get().getVpnNexthop();
+ for (VpnNexthop nexthop : nexthops) {
+ if (nexthop.getIpAddress().equals(ipAddress)) {
+ // return nexthop
+ return nexthop;
+ }