2 * Copyright (c) 2018 Red Hat, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.netvirt.natservice.internal;
10 import static org.opendaylight.netvirt.natservice.internal.AbstractSnatService.LOAD_END;
11 import static org.opendaylight.netvirt.natservice.internal.AbstractSnatService.LOAD_START;
12 import static org.opendaylight.netvirt.natservice.internal.NatUtil.getGroupIdKey;
14 import java.util.ArrayList;
15 import java.util.List;
16 import java.util.Objects;
17 import java.util.concurrent.ExecutionException;
18 import java.util.concurrent.Future;
19 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.genius.infra.Datastore.Configuration;
21 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
22 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
23 import org.opendaylight.genius.mdsalutil.ActionInfo;
24 import org.opendaylight.genius.mdsalutil.BucketInfo;
25 import org.opendaylight.genius.mdsalutil.GroupEntity;
26 import org.opendaylight.genius.mdsalutil.InstructionInfo;
27 import org.opendaylight.genius.mdsalutil.MDSALUtil;
28 import org.opendaylight.genius.mdsalutil.MatchInfo;
29 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
30 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
31 import org.opendaylight.genius.mdsalutil.NWUtil;
32 import org.opendaylight.genius.mdsalutil.NwConstants;
33 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
34 import org.opendaylight.genius.mdsalutil.actions.ActionNxLoadInPort;
35 import org.opendaylight.genius.mdsalutil.actions.ActionNxLoadMetadata;
36 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
37 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldTunnelId;
38 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
39 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
40 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
41 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
42 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
43 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
44 import org.opendaylight.netvirt.natservice.api.SnatServiceListener;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
54 import org.opendaylight.yangtools.yang.common.RpcResult;
55 import org.opendaylight.yangtools.yang.common.Uint32;
56 import org.opendaylight.yangtools.yang.common.Uint64;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
60 public class Ipv6ForwardingService implements SnatServiceListener {
61 private static final Logger LOG = LoggerFactory.getLogger(Ipv6ForwardingService.class);
63 protected final DataBroker dataBroker;
64 protected final IMdsalApiManager mdsalManager;
65 protected final IdManagerService idManager;
66 protected final NAPTSwitchSelector naptSwitchSelector;
67 protected final ItmRpcService itmManager;
68 protected final OdlInterfaceRpcService odlInterfaceRpcService;
69 protected final IInterfaceManager interfaceManager;
70 protected final Ipv6SubnetFlowProgrammer ipv6SubnetFlowProgrammer;
72 public Ipv6ForwardingService(final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
73 final ItmRpcService itmManager,
74 final OdlInterfaceRpcService odlInterfaceRpcService,
75 final IdManagerService idManager,
76 final NAPTSwitchSelector naptSwitchSelector,
77 final IInterfaceManager interfaceManager,
78 final Ipv6SubnetFlowProgrammer ipv6SubnetFlowProgrammer) {
79 this.dataBroker = dataBroker;
80 this.mdsalManager = mdsalManager;
81 this.itmManager = itmManager;
82 this.odlInterfaceRpcService = odlInterfaceRpcService;
83 this.idManager = idManager;
84 this.naptSwitchSelector = naptSwitchSelector;
85 this.interfaceManager = interfaceManager;
86 this.ipv6SubnetFlowProgrammer = ipv6SubnetFlowProgrammer;
90 public boolean addCentralizedRouterAllSwitch(TypedReadWriteTransaction<Configuration> confTx,
91 Routers routers, Uint64 primarySwitchId) {
92 String routerName = routers.getRouterName();
93 LOG.info("handleSnatAllSwitch : invoked for router {} with NAPTSwitch {} for {} flows",
94 routerName, primarySwitchId, "installing");
95 List<Uint64> switches = naptSwitchSelector.getDpnsForVpn(routerName);
97 * Primary switch handled separately since the pseudo port created may
98 * not be present in the switch list on delete.
100 addCentralizedRouter(confTx, routers, primarySwitchId, primarySwitchId);
101 for (Uint64 dpnId : switches) {
102 if (!Objects.equals(primarySwitchId, dpnId)) {
103 addCentralizedRouter(confTx, routers, primarySwitchId, dpnId);
110 public boolean addCentralizedRouter(TypedReadWriteTransaction<Configuration> confTx,
111 Routers routers, Uint64 primarySwitchId, Uint64 dpnId) {
112 Uint32 routerId = NatUtil.getVpnId(dataBroker, routers.getRouterName());
113 Uint64 routerMetadata = MetaDataUtil.getVpnIdMetadata(routerId.longValue());
115 if (!dpnId.equals(primarySwitchId)) {
116 LOG.info("handleSnat (non-NAPTSwitch) : {} flows on switch {} for router {}",
117 "Installing", dpnId, routers.getRouterName());
118 // Program default flow from FIB_TABLE(21) to PSNAT_TABLE(26) (egress direction)
119 addIpv6DefaultFibRoute(confTx, dpnId, routerId, routerMetadata);
121 // Currently we are only programming flows when ext-net has an IPv6Subnet
122 if (routerHasIpv6ExtSubnet(routers)) {
123 // Program flows on non-NAPTSwitch to send N/S packets to the NAPTSwitch
124 addIpv6PsNatMissEntryNonNaptSwitch(confTx, dpnId, routerId, routers.getRouterName(),
128 LOG.info("handleSnat (NAPTSwitch) : {} flows on switch {} for router {}",
129 "Installing", dpnId, routers.getRouterName());
130 // Program default flow from FIB_TABLE(21) to PSNAT_TABLE(26) (egress direction)
131 addIpv6DefaultFibRoute(confTx, dpnId, routerId, routerMetadata);
133 // Program flows from PSNAT_TABLE(26) to OUTBOUND_NAPT_TABLE(46) (egress direction)
134 addIpv6SnatMissEntryForNaptSwitch(confTx, dpnId, routerId, routerMetadata);
136 // Program flows in INTERNAL_TUNNEL_TABLE(36) for packets coming from non-NAPTSwitch (egress direction)
137 addIpv6TerminatingServiceTblEntry(confTx, dpnId, routerId, routerMetadata);
139 // Program flows from NAPT_PFIB_TABLE(47) to FIB_TABLE(21) (ingress direction)
140 addIpv6NaptPfibInboundFlow(confTx, dpnId, routerId, routerMetadata);
142 // Now installing flows that use SubnetInfo
143 ipv6SubnetFlowProgrammer.addSubnetSpecificFlows(confTx, dpnId, routerId, routers, routerMetadata);
149 public boolean removeCentralizedRouterAllSwitch(TypedReadWriteTransaction<Configuration> confTx,
150 Routers routers, Uint64 primarySwitchId) throws ExecutionException, InterruptedException {
151 String routerName = routers.getRouterName();
152 LOG.info("handleSnatAllSwitch : invoked for router {} with NAPTSwitch {} for {} flows",
153 routerName, primarySwitchId, "removing");
154 List<Uint64> switches = naptSwitchSelector.getDpnsForVpn(routerName);
156 * Primary switch handled separately since the pseudo port created may
157 * not be present in the switch list on delete.
159 removeCentralizedRouter(confTx, routers, primarySwitchId, primarySwitchId);
160 for (Uint64 dpnId : switches) {
161 if (!Objects.equals(primarySwitchId, dpnId)) {
162 removeCentralizedRouter(confTx, routers, primarySwitchId, dpnId);
169 public boolean removeCentralizedRouter(TypedReadWriteTransaction<Configuration> confTx,
170 Routers routers, Uint64 primarySwitchId, Uint64 dpnId)
171 throws ExecutionException, InterruptedException {
172 Uint32 routerId = NatUtil.getVpnId(dataBroker, routers.getRouterName());
173 Uint64 routerMetadata = MetaDataUtil.getVpnIdMetadata(routerId.longValue());
175 if (!dpnId.equals(primarySwitchId)) {
176 LOG.info("handleSnat (non-NAPTSwitch) : {} flows on switch {} for router {}",
177 "Removing", dpnId, routers.getRouterName());
178 // Program default flow from FIB_TABLE(21) to PSNAT_TABLE(26) (egress direction)
179 addIpv6DefaultFibRoute(confTx, dpnId, routerId, routerMetadata);
181 // Currently we are only programming flows when ext-net has an IPv6Subnet
182 if (routerHasIpv6ExtSubnet(routers)) {
183 // Program flows on non-NAPTSwitch to send N/S packets to the NAPTSwitch
184 addIpv6PsNatMissEntryNonNaptSwitch(confTx, dpnId, routerId, routers.getRouterName(),
188 LOG.info("handleSnat (NAPTSwitch) : {} flows on switch {} for router {}",
189 "Removing", dpnId, routers.getRouterName());
190 // Program default flow from FIB_TABLE(21) to PSNAT_TABLE(26) (egress direction)
191 removeIpv6DefaultFibRoute(confTx, dpnId, routerId);
193 // Program flows from PSNAT_TABLE(26) to OUTBOUND_NAPT_TABLE(46) (egress direction)
194 removeIpv6SnatMissEntryForNaptSwitch(confTx, dpnId, routerId);
196 // Program flows in INTERNAL_TUNNEL_TABLE(36) for packets coming from non-NAPTSwitch (egress direction)
197 removeIpv6TerminatingServiceTblEntry(confTx, dpnId, routerId);
199 // Program flows from NAPT_PFIB_TABLE(47) to FIB_TABLE(21) (ingress direction)
200 removeIpv6NaptPfibInboundFlow(confTx, dpnId, routerId);
202 // Now installing flows that use SubnetInfo
203 ipv6SubnetFlowProgrammer.removeSubnetSpecificFlows(confTx, dpnId, routerId, routers);
209 public boolean handleRouterUpdate(TypedReadWriteTransaction<Configuration> confTx,
210 Routers origRouter, Routers updatedRouter) throws ExecutionException, InterruptedException {
211 LOG.info("handleRouterUpdate : originalRouter {}, updatedRouter {}", origRouter, updatedRouter);
212 String routerName = origRouter.getRouterName();
213 Uint64 primarySwitchId = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
214 Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
215 Uint64 routerMetadata = MetaDataUtil.getVpnIdMetadata(routerId.longValue());
217 // If the external network is updated with an IPv6Subnet, program the necessary flows on non-NAPTSwitch
218 if (!routerHasIpv6ExtSubnet(origRouter) && routerHasIpv6ExtSubnet(updatedRouter)) {
219 List<Uint64> switches = naptSwitchSelector.getDpnsForVpn(routerName);
220 for (Uint64 dpnId : switches) {
221 if (!Objects.equals(primarySwitchId, dpnId)) {
222 LOG.info("handleRouterUpdate (non-NAPTSwitch) : Installing flows on switch {} for router {}",
224 addIpv6PsNatMissEntryNonNaptSwitch(confTx, dpnId, routerId, routerName,
230 ipv6SubnetFlowProgrammer.removeSubnetSpecificFlows(confTx, primarySwitchId, routerId, origRouter);
231 ipv6SubnetFlowProgrammer.addSubnetSpecificFlows(confTx, primarySwitchId, routerId, updatedRouter,
237 public boolean addSnatAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
238 Uint64 primarySwitchId) {
243 public boolean addSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
244 Uint64 primarySwitchId, Uint64 dpnId) {
249 public boolean removeSnatAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
250 Uint64 primarySwitchId) throws ExecutionException, InterruptedException {
255 public boolean removeSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
256 Uint64 primarySwitchId, Uint64 dpnId) throws ExecutionException, InterruptedException {
261 protected void addIpv6DefaultFibRoute(TypedReadWriteTransaction<Configuration> confTx, Uint64 dpnId,
262 Uint32 routerId, Uint64 routerMetadata) {
263 LOG.debug("installIpv6DefaultFibRoute : Installing default FIB route to PSNAT_TABLE on {}", dpnId);
264 List<MatchInfo> matches = new ArrayList<>();
265 matches.add(MatchEthernetType.IPV6);
266 matches.add(new MatchMetadata(routerMetadata, MetaDataUtil.METADATA_MASK_VRFID));
268 List<InstructionInfo> instructions = new ArrayList<>();
269 instructions.add(new InstructionGotoTable(NwConstants.PSNAT_TABLE));
271 String flowRef = NatUtil.getIpv6FlowRef(dpnId, NwConstants.L3_FIB_TABLE, routerId);
272 flowRef += ".Outbound";
273 NatUtil.addFlow(confTx, mdsalManager, dpnId, NwConstants.L3_FIB_TABLE, flowRef,
274 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef,
275 NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
278 protected void removeIpv6DefaultFibRoute(TypedReadWriteTransaction<Configuration> confTx, Uint64 dpnId,
279 Uint32 routerId) throws ExecutionException, InterruptedException {
280 LOG.debug("installIpv6DefaultFibRoute : Installing default FIB route to PSNAT_TABLE on {}", dpnId);
281 String flowRef = NatUtil.getIpv6FlowRef(dpnId, NwConstants.L3_FIB_TABLE, routerId);
282 flowRef += ".Outbound";
283 NatUtil.removeFlow(confTx, mdsalManager, dpnId, NwConstants.L3_FIB_TABLE, flowRef);
286 protected void addIpv6PsNatMissEntryNonNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
287 Uint64 dpnId, Uint32 routerId, String routerName, Uint64 primarySwitchId) {
288 LOG.debug("installIpv6PsNatMissEntryNonNaptSwitch : On Non-Napt Switch, installing SNAT miss entry in"
289 + " switch {} for router {}", dpnId, routerName);
290 List<ActionInfo> listActionInfoPrimary = new ArrayList<>();
291 List<BucketInfo> listBucketInfo = new ArrayList<>();
293 String ifNamePrimary = NatUtil.getTunnelInterfaceName(dpnId, primarySwitchId, itmManager);
294 if (ifNamePrimary != null) {
295 LOG.debug("installIpv6PsNatMissEntryNonNaptSwitch : On Non-Napt Switch, Primary Tunnel interface is {}",
297 listActionInfoPrimary = NatUtil.getEgressActionsForInterface(odlInterfaceRpcService, itmManager,
298 interfaceManager, ifNamePrimary, routerId, true);
300 LOG.warn("installIpv6PsNatMissEntryNonNaptSwitch: could not get tunnelInterface for {} on Switch {}",
301 primarySwitchId, dpnId);
304 BucketInfo bucketPrimary = new BucketInfo(listActionInfoPrimary);
305 listBucketInfo.add(0, bucketPrimary);
307 LOG.debug("installIpv6PsNatMissEntryNonNaptSwitch : installSnatMissEntry called for dpnId {} with"
308 + " primaryBucket {} ", dpnId, listBucketInfo.get(0));
310 long groupId = createGroupIdForIpv6Router(getGroupIdKey(routerName + "IPv6"));
311 GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName, GroupTypes.GroupAll,
313 LOG.debug("installing the PSNAT to NAPTSwitch GroupEntity:{} with GroupId: {}", groupEntity, groupId);
314 mdsalManager.addGroup(confTx, groupEntity);
315 List<MatchInfo> matches = new ArrayList<>();
316 matches.add(MatchEthernetType.IPV6);
317 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId.longValue()),
318 MetaDataUtil.METADATA_MASK_VRFID));
320 List<ActionInfo> actionsInfo = new ArrayList<>();
321 actionsInfo.add(new ActionSetFieldTunnelId(Uint64.valueOf(routerId)));
322 actionsInfo.add(new ActionGroup(groupId));
323 List<InstructionInfo> instructions = new ArrayList<>();
324 instructions.add(new InstructionApplyActions(actionsInfo));
326 String flowRef = NatUtil.getIpv6FlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
327 NatUtil.addFlow(confTx, mdsalManager, dpnId, NwConstants.PSNAT_TABLE, flowRef,
328 NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef,
329 NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
332 protected void addIpv6SnatMissEntryForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
333 Uint64 dpnId, Uint32 routerId, Uint64 routerMetadata) {
334 LOG.debug("installIpv6SnatMissEntryForNaptSwitch {} called for routerId {}", dpnId, routerId);
335 List<MatchInfo> matches = new ArrayList<>();
336 matches.add(MatchEthernetType.IPV6);
337 matches.add(new MatchMetadata(routerMetadata, MetaDataUtil.METADATA_MASK_VRFID));
339 List<InstructionInfo> instructions = new ArrayList<>();
340 instructions.add(new InstructionGotoTable(NwConstants.OUTBOUND_NAPT_TABLE));
342 String flowRef = NatUtil.getIpv6FlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
343 flowRef += ".Outbound";
344 NatUtil.addFlow(confTx, mdsalManager, dpnId, NwConstants.PSNAT_TABLE, flowRef,
345 NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef,
346 NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
349 protected void removeIpv6SnatMissEntryForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
350 Uint64 dpnId, Uint32 routerId)
351 throws ExecutionException, InterruptedException {
352 LOG.debug("installIpv6SnatMissEntryForNaptSwitch {} called for routerId {}", dpnId, routerId);
353 String flowRef = NatUtil.getIpv6FlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
354 flowRef += ".Outbound";
355 NatUtil.removeFlow(confTx, mdsalManager, dpnId, NwConstants.PSNAT_TABLE, flowRef);
358 protected void addIpv6TerminatingServiceTblEntry(TypedReadWriteTransaction<Configuration> confTx,
359 Uint64 dpnId, Uint32 routerId, Uint64 routerMetadata) {
360 LOG.debug("installIpv6TerminatingServiceTblEntry : creating entry for Terminating Service Table "
361 + "for switch {}, routerId {}", dpnId, routerId);
362 List<MatchInfo> matches = new ArrayList<>();
363 matches.add(MatchEthernetType.IPV6);
364 matches.add(new MatchTunnelId(Uint64.valueOf(routerId)));
366 List<ActionInfo> actionsInfos = new ArrayList<>();
367 ActionNxLoadMetadata actionLoadMeta = new ActionNxLoadMetadata(routerMetadata, LOAD_START, LOAD_END);
368 actionsInfos.add(actionLoadMeta);
369 actionsInfos.add(new ActionNxResubmit(NwConstants.OUTBOUND_NAPT_TABLE));
370 List<InstructionInfo> instructions = new ArrayList<>();
371 instructions.add(new InstructionApplyActions(actionsInfos));
373 String flowRef = NatUtil.getIpv6FlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId);
374 flowRef += ".Outbound";
375 NatUtil.addFlow(confTx, mdsalManager, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef,
376 NatConstants.DEFAULT_TS_FLOW_PRIORITY, flowRef,
377 NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
381 protected void removeIpv6TerminatingServiceTblEntry(TypedReadWriteTransaction<Configuration> confTx,
382 Uint64 dpnId, Uint32 routerId) throws ExecutionException, InterruptedException {
383 LOG.debug("installIpv6TerminatingServiceTblEntry : creating entry for Terminating Service Table "
384 + "for switch {}, routerId {}", dpnId, routerId);
385 String flowRef = NatUtil.getIpv6FlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId);
386 flowRef += ".Outbound";
387 NatUtil.removeFlow(confTx, mdsalManager, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef);
391 protected void addIpv6NaptPfibInboundFlow(TypedReadWriteTransaction<Configuration> confTx, Uint64 dpnId,
392 Uint32 routerId, Uint64 routerMetadata) {
393 LOG.debug("installIpv6NaptPfibInboundFlow : called for dpnId {} and routerId {} ", dpnId, routerId);
394 List<MatchInfoBase> matches = new ArrayList<>();
395 matches.add(MatchEthernetType.IPV6);
396 matches.add(new MatchMetadata(routerMetadata, MetaDataUtil.METADATA_MASK_VRFID));
398 ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
399 ArrayList<InstructionInfo> instructionInfo = new ArrayList<>();
400 listActionInfo.add(new ActionNxLoadInPort(Uint64.ZERO));
401 listActionInfo.add(new ActionNxResubmit(NwConstants.L3_FIB_TABLE));
402 instructionInfo.add(new InstructionApplyActions(listActionInfo));
404 String flowRef = NatUtil.getIpv6FlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, routerId);
405 flowRef += ".Inbound";
406 NatUtil.addFlow(confTx, mdsalManager, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef,
407 NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY,
408 flowRef, NwConstants.COOKIE_SNAT_TABLE,
409 matches, instructionInfo);
412 protected void removeIpv6NaptPfibInboundFlow(TypedReadWriteTransaction<Configuration> confTx, Uint64 dpnId,
414 throws ExecutionException, InterruptedException {
415 LOG.debug("installIpv6NaptPfibInboundFlow : called for dpnId {} and routerId {} ", dpnId, routerId);
416 String flowRef = NatUtil.getIpv6FlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, routerId);
417 flowRef += ".Inbound";
418 NatUtil.removeFlow(confTx, mdsalManager, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef);
421 protected long createGroupIdForIpv6Router(String groupIdKey) {
422 AllocateIdInput getIdInput = new AllocateIdInputBuilder()
423 .setPoolName(NatConstants.SNAT_IDPOOL_NAME).setIdKey(groupIdKey)
426 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
427 RpcResult<AllocateIdOutput> rpcResult = result.get();
428 return rpcResult.getResult().getIdValue().toJava();
429 } catch (NullPointerException | InterruptedException | ExecutionException e) {
430 LOG.error("createGroupIdForIPv6Router: Exception while creating group with key : {}", groupIdKey, e);
435 protected boolean routerHasIpv6ExtSubnet(Routers routers) {
436 for (ExternalIps externalIp : routers.getExternalIps()) {
437 if (!NWUtil.isIpv4Address(externalIp.getIpAddress())) {
438 LOG.debug("router {}, has an external IPv6 subnet {}",
439 routers.getRouterName(), externalIp.getIpAddress());
443 LOG.debug("router {}, does not have an external IPv6 subnet", routers.getRouterName());