2 * Copyright © 2016, 2017 Ericsson India Global Services Pvt Ltd. 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
9 package org.opendaylight.netvirt.vpnmanager;
11 import com.google.common.base.Optional;
12 import com.google.common.collect.Iterators;
13 import com.google.common.net.InetAddresses;
14 import com.google.common.util.concurrent.FutureCallback;
15 import com.google.common.util.concurrent.ListenableFuture;
16 import java.math.BigInteger;
17 import java.net.Inet4Address;
18 import java.net.Inet6Address;
19 import java.net.InetAddress;
20 import java.net.UnknownHostException;
21 import java.text.SimpleDateFormat;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.Date;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Locale;
31 import java.util.Map.Entry;
33 import java.util.concurrent.ExecutionException;
34 import java.util.concurrent.Future;
35 import java.util.function.Predicate;
36 import java.util.stream.Collectors;
37 import javax.annotation.Nonnull;
38 import javax.annotation.Nullable;
39 import javax.inject.Singleton;
41 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
42 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
43 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
44 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
45 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
46 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
47 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
48 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
49 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
50 import org.opendaylight.genius.mdsalutil.FlowEntity;
51 import org.opendaylight.genius.mdsalutil.FlowEntityBuilder;
52 import org.opendaylight.genius.mdsalutil.InstructionInfo;
53 import org.opendaylight.genius.mdsalutil.MDSALUtil;
54 import org.opendaylight.genius.mdsalutil.MatchInfo;
55 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
56 import org.opendaylight.genius.mdsalutil.NWUtil;
57 import org.opendaylight.genius.mdsalutil.NwConstants;
58 import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
59 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
60 import org.opendaylight.genius.mdsalutil.instructions.InstructionWriteMetadata;
61 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
62 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetDestination;
63 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
64 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
65 import org.opendaylight.genius.utils.ServiceIndex;
66 import org.opendaylight.genius.utils.SystemPropertyReader;
67 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
68 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
69 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
70 import org.opendaylight.netvirt.elanmanager.api.ElanHelper;
71 import org.opendaylight.netvirt.fibmanager.api.FibHelper;
72 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
73 import org.opendaylight.netvirt.neutronvpn.api.enums.IpVersionChoice;
74 import org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager;
75 import org.opendaylight.netvirt.vpnmanager.api.InterfaceUtils;
76 import org.opendaylight.netvirt.vpnmanager.api.VpnExtraRouteHelper;
77 import org.opendaylight.netvirt.vpnmanager.api.VpnHelper;
78 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
79 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
80 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
81 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
82 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
83 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
84 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder;
85 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
86 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.vpn._interface.VpnInstanceNames;
87 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
88 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
89 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
90 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
91 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
92 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
93 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdOutput;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.IfIndexesInterfaceMap;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._if.indexes._interface.map.IfIndexInterface;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._if.indexes._interface.map.IfIndexInterfaceKey;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetInterfaceFromIfIndexInput;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetInterfaceFromIfIndexInputBuilder;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetInterfaceFromIfIndexOutput;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.ipv6.nd.util.rev170210.Ipv6NdUtilService;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.ipv6.nd.util.rev170210.SendNeighborSolicitationToOfGroupInput;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.ipv6.nd.util.rev170210.SendNeighborSolicitationToOfGroupInputBuilder;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.ipv6.nd.util.rev170210.SendNeighborSolicitationToOfGroupOutput;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.LockManagerService;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.TimeUnits;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.TryLockInput;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.TryLockInputBuilder;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.TryLockOutput;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.UnlockInput;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.UnlockInputBuilder;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.UnlockOutput;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanDpnInterfaces;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanTagNameMap;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeVlan;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesListKey;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesBuilder;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesKey;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceKey;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.tag.name.map.ElanTagName;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.tag.name.map.ElanTagNameKey;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.VrfEntryBase;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.extraroute.rds.map.extraroute.rds.dest.prefixes.AllocatedRdsBuilder;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.extraroute.rds.map.extraroute.rds.dest.prefixes.AllocatedRdsKey;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTablesKey;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntryKey;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.L3nexthop;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.VpnNexthops;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.VpnNexthopsKey;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AdjacenciesBuilder;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AdjacenciesOp;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AdjacenciesOpBuilder;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortEventAction;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortEventData;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PrefixToInterface;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.SubnetOpData;
157 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.SubnetsAssociatedToRouteTargets;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
160 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInterfaceOpData;
161 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnToExtraroutes;
162 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
163 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency.AdjacencyType;
164 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey;
165 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
166 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPortBuilder;
167 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPortKey;
168 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.event.data.LearntVpnVipToPortEvent;
169 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.event.data.LearntVpnVipToPortEventBuilder;
170 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.event.data.LearntVpnVipToPortEventKey;
171 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.VpnIds;
172 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.VpnIdsKey;
173 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
174 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesBuilder;
175 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesKey;
176 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.SubnetOpDataEntry;
177 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnet.op.data.SubnetOpDataEntryKey;
178 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnets.associated.to.route.targets.RouteTarget;
179 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnets.associated.to.route.targets.RouteTargetKey;
180 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnets.associated.to.route.targets.route.target.AssociatedSubnet;
181 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnets.associated.to.route.targets.route.target.AssociatedSubnetKey;
182 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnets.associated.to.route.targets.route.target.associated.subnet.AssociatedVpn;
183 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnets.associated.to.route.targets.route.target.associated.subnet.AssociatedVpnBuilder;
184 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.subnets.associated.to.route.targets.route.target.associated.subnet.AssociatedVpnKey;
185 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntry;
186 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntryBuilder;
187 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntryKey;
188 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
189 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
190 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnTargets;
191 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
192 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpntargets.VpnTarget;
193 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstanceBuilder;
194 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroutes.Vpn;
195 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroutes.VpnKey;
196 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroutes.vpn.extra.routes.Routes;
197 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroutes.vpn.extra.routes.RoutesBuilder;
198 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
199 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
200 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
201 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
202 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
203 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
204 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
205 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
206 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
207 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
208 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
209 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
210 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkAttributes.NetworkType;
211 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
212 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
213 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
214 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
215 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
216 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
217 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
218 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
219 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
220 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.IpVersionBase;
221 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.IpVersionV4;
222 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.ext.rev150712.NetworkL3Extension;
223 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
224 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.NetworkKey;
225 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
226 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
227 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
228 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
229 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
230 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
231 import org.opendaylight.yangtools.yang.binding.DataObject;
232 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
233 import org.opendaylight.yangtools.yang.common.RpcResult;
234 import org.slf4j.Logger;
235 import org.slf4j.LoggerFactory;
238 public final class VpnUtil {
240 private static final Logger LOG = LoggerFactory.getLogger(VpnUtil.class);
242 static final int SINGLE_TRANSACTION_BROKER_NO_RETRY = 1;
244 private final DataBroker dataBroker;
245 private final IdManagerService idManager;
246 private final IBgpManager bgpManager;
247 private final LockManagerService lockManager;
248 private final INeutronVpnManager neutronVpnService;
249 private final IMdsalApiManager mdsalManager;
250 private final IInterfaceManager interfaceManager;
251 private final JobCoordinator jobCoordinator;
252 private final ManagedNewTransactionRunner txRunner;
253 private final OdlInterfaceRpcService ifmRpcService;
256 * Class to generate timestamps with microsecond precision.
257 * For example: MicroTimestamp.INSTANCE.get() = "2012-10-21 19:13:45.267128"
259 public enum MicroTimestamp {
262 private long startDate ;
263 private long startNanoseconds ;
264 private SimpleDateFormat dateFormat ;
267 this.startDate = System.currentTimeMillis() ;
268 this.startNanoseconds = System.nanoTime() ;
269 this.dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS") ;
272 public String get() {
273 long microSeconds = (System.nanoTime() - this.startNanoseconds) / 1000 ;
274 long date = this.startDate + microSeconds / 1000 ;
275 return this.dateFormat.format(date) + String.format("%03d", microSeconds % 1000) ;
279 public VpnUtil(DataBroker dataBroker, IdManagerService idManager, IBgpManager bgpManager,
280 LockManagerService lockManager, INeutronVpnManager neutronVpnService,
281 IMdsalApiManager mdsalManager, JobCoordinator jobCoordinator,
282 IInterfaceManager interfaceManager, OdlInterfaceRpcService ifmRpcService) {
283 this.dataBroker = dataBroker;
284 this.idManager = idManager;
285 this.bgpManager = bgpManager;
286 this.lockManager = lockManager;
287 this.neutronVpnService = neutronVpnService;
288 this.mdsalManager = mdsalManager;
289 this.interfaceManager = interfaceManager;
290 this.jobCoordinator = jobCoordinator;
291 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
292 this.ifmRpcService = ifmRpcService;
295 public static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
296 return InstanceIdentifier.builder(VpnInterfaces.class)
297 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
300 static InstanceIdentifier<VpnInterfaceOpDataEntry> getVpnInterfaceOpDataEntryIdentifier(String vpnInterfaceName,
302 return InstanceIdentifier.builder(VpnInterfaceOpData.class).child(VpnInterfaceOpDataEntry.class,
303 new VpnInterfaceOpDataEntryKey(vpnInterfaceName, vpnName)).build();
306 static InstanceIdentifier<VpnInstance> getVpnInstanceIdentifier(String vpnName) {
307 return InstanceIdentifier.builder(VpnInstances.class)
308 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
311 VpnInterface getVpnInterface(String vpnInterfaceName) {
312 InstanceIdentifier<VpnInterface> id = getVpnInterfaceIdentifier(vpnInterfaceName);
313 Optional<VpnInterface> vpnInterface = read(LogicalDatastoreType.CONFIGURATION, id);
314 return vpnInterface.isPresent() ? vpnInterface.get() : null;
317 static VpnInterfaceOpDataEntry getVpnInterfaceOpDataEntry(String intfName, String vpnName, AdjacenciesOp aug,
318 BigInteger dpnId, Boolean isSheduledForRemove, long lportTag,
320 return new VpnInterfaceOpDataEntryBuilder().withKey(new VpnInterfaceOpDataEntryKey(intfName, vpnName))
321 .setDpnId(dpnId).setScheduledForRemove(isSheduledForRemove).addAugmentation(AdjacenciesOp.class, aug)
322 .setLportTag(lportTag).setGatewayMacAddress(gwMac).build();
325 Optional<VpnInterfaceOpDataEntry> getVpnInterfaceOpDataEntry(String vpnInterfaceName, String vpnName) {
326 InstanceIdentifier<VpnInterfaceOpDataEntry> id = getVpnInterfaceOpDataEntryIdentifier(vpnInterfaceName,
328 Optional<VpnInterfaceOpDataEntry> vpnInterfaceOpDataEntry = read(LogicalDatastoreType.OPERATIONAL,
330 return vpnInterfaceOpDataEntry;
333 static InstanceIdentifier<Prefixes> getPrefixToInterfaceIdentifier(long vpnId, String ipPrefix) {
334 return InstanceIdentifier.builder(PrefixToInterface.class).child(VpnIds.class, new VpnIdsKey(vpnId))
335 .child(Prefixes.class, new PrefixesKey(ipPrefix)).build();
338 static InstanceIdentifier<VpnIds> getPrefixToInterfaceIdentifier(long vpnId) {
339 return InstanceIdentifier.builder(PrefixToInterface.class).child(VpnIds.class, new VpnIdsKey(vpnId)).build();
342 static Prefixes getPrefixToInterface(BigInteger dpId, String vpnInterfaceName, String ipPrefix, Uuid subnetId,
343 Prefixes.PrefixCue prefixCue) {
344 return new PrefixesBuilder().setDpnId(dpId).setVpnInterfaceName(vpnInterfaceName).setIpAddress(ipPrefix)
345 .setSubnetId(subnetId).setPrefixCue(prefixCue).build();
348 Optional<Prefixes> getPrefixToInterface(long vpnId, String ipPrefix) {
349 return read(LogicalDatastoreType.OPERATIONAL, getPrefixToInterfaceIdentifier(vpnId, getIpPrefix(ipPrefix)));
353 * Get VRF table given a Route Distinguisher.
355 * @param rd Route-Distinguisher
356 * @return VrfTables that holds the list of VrfEntries of the specified rd
358 VrfTables getVrfTable(String rd) {
359 InstanceIdentifier<VrfTables> id = InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class,
360 new VrfTablesKey(rd)).build();
361 Optional<VrfTables> vrfTable = read(LogicalDatastoreType.CONFIGURATION, id);
362 return vrfTable.isPresent() ? vrfTable.get() : null;
366 * Retrieves the VrfEntries that belong to a given VPN filtered out by
367 * Origin, searching by its Route-Distinguisher.
369 * @param rd Route-distinguisher of the VPN
370 * @param originsToConsider Only entries whose origin is included in this list will be considered
371 * @return the list of VrfEntries
373 public List<VrfEntry> getVrfEntriesByOrigin(String rd, List<RouteOrigin> originsToConsider) {
374 List<VrfEntry> result = new ArrayList<>();
375 List<VrfEntry> allVpnVrfEntries = getAllVrfEntries(rd);
376 for (VrfEntry vrfEntry : allVpnVrfEntries) {
377 if (originsToConsider.contains(RouteOrigin.value(vrfEntry.getOrigin()))) {
378 result.add(vrfEntry);
385 * Retrieves all the VrfEntries that belong to a given VPN searching by its
386 * Route-Distinguisher.
388 * @param rd Route-distinguisher of the VPN
389 * @return the list of VrfEntries
391 public List<VrfEntry> getAllVrfEntries(String rd) {
392 VrfTables vrfTables = getVrfTable(rd);
393 return vrfTables != null ? vrfTables.getVrfEntry() : new ArrayList<>();
396 //FIXME: Implement caches for DS reads
397 public VpnInstance getVpnInstance(String vpnInstanceName) {
398 InstanceIdentifier<VpnInstance> id = InstanceIdentifier.builder(VpnInstances.class).child(VpnInstance.class,
399 new VpnInstanceKey(vpnInstanceName)).build();
400 Optional<VpnInstance> vpnInstance = read(LogicalDatastoreType.CONFIGURATION, id);
401 return vpnInstance.isPresent() ? vpnInstance.get() : null;
404 List<VpnInstanceOpDataEntry> getAllVpnInstanceOpData() {
405 InstanceIdentifier<VpnInstanceOpData> id = InstanceIdentifier.builder(VpnInstanceOpData.class).build();
406 Optional<VpnInstanceOpData> vpnInstanceOpDataOptional = read(LogicalDatastoreType.OPERATIONAL, id);
407 return vpnInstanceOpDataOptional.isPresent() ? vpnInstanceOpDataOptional.get().getVpnInstanceOpDataEntry()
408 : Collections.emptyList();
411 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data
412 .vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces> getDpnVpnInterfaces(VpnInstance vpnInstance,
414 String primaryRd = getPrimaryRd(vpnInstance);
415 InstanceIdentifier<VpnToDpnList> dpnToVpnId = VpnHelper.getVpnToDpnListIdentifier(primaryRd, dpnId);
416 Optional<VpnToDpnList> dpnInVpn = read(LogicalDatastoreType.OPERATIONAL, dpnToVpnId);
417 return dpnInVpn.isPresent() ? dpnInVpn.get().getVpnInterfaces() : Collections.emptyList();
420 static List<String> getListOfRdsFromVpnInstance(VpnInstance vpnInstance) {
421 VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
422 LOG.trace("vpnConfig {}", vpnConfig);
423 return vpnConfig.getRouteDistinguisher() != null ? vpnConfig.getRouteDistinguisher() : Collections.emptyList();
426 VrfEntry getVrfEntry(String rd, String ipPrefix) {
427 VrfTables vrfTable = getVrfTable(rd);
428 // TODO: why check VrfTables if we later go for the specific VrfEntry?
429 if (vrfTable != null) {
430 InstanceIdentifier<VrfEntry> vrfEntryId =
431 InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).child(
432 VrfEntry.class, new VrfEntryKey(ipPrefix)).build();
433 Optional<VrfEntry> vrfEntry = read(LogicalDatastoreType.CONFIGURATION, vrfEntryId);
434 if (vrfEntry.isPresent()) {
435 return vrfEntry.get();
441 public List<Adjacency> getAdjacenciesForVpnInterfaceFromConfig(String intfName) {
442 final InstanceIdentifier<VpnInterface> identifier = getVpnInterfaceIdentifier(intfName);
443 InstanceIdentifier<Adjacencies> path = identifier.augmentation(Adjacencies.class);
444 Optional<Adjacencies> adjacencies = read(LogicalDatastoreType.CONFIGURATION, path);
445 if (adjacencies.isPresent()) {
446 List<Adjacency> nextHops = adjacencies.get().getAdjacency();
452 static Routes getVpnToExtraroute(String ipPrefix, List<String> nextHopList) {
453 return new RoutesBuilder().setPrefix(ipPrefix).setNexthopIpList(nextHopList).build();
456 String getVpnInterfaceName(BigInteger metadata) throws InterruptedException, ExecutionException {
457 GetInterfaceFromIfIndexInputBuilder ifIndexInputBuilder = new GetInterfaceFromIfIndexInputBuilder();
458 BigInteger lportTag = MetaDataUtil.getLportFromMetadata(metadata);
459 ifIndexInputBuilder.setIfIndex(lportTag.intValue());
460 GetInterfaceFromIfIndexInput input = ifIndexInputBuilder.build();
461 Future<RpcResult<GetInterfaceFromIfIndexOutput>> interfaceFromIfIndex =
462 ifmRpcService.getInterfaceFromIfIndex(input);
463 GetInterfaceFromIfIndexOutput interfaceFromIfIndexOutput;
464 RpcResult<GetInterfaceFromIfIndexOutput> rpcResult = interfaceFromIfIndex.get();
465 if (rpcResult == null) {
468 interfaceFromIfIndexOutput = rpcResult.getResult();
469 return interfaceFromIfIndexOutput.getInterfaceName();
472 static AllocatedRdsBuilder getRdsBuilder(String nexthop, String rd) {
473 return new AllocatedRdsBuilder().withKey(new AllocatedRdsKey(nexthop)).setNexthop(nexthop).setRd(rd);
476 public static Adjacencies getVpnInterfaceAugmentation(List<Adjacency> nextHopList) {
477 return new AdjacenciesBuilder().setAdjacency(nextHopList).build();
480 static AdjacenciesOp getVpnInterfaceOpDataEntryAugmentation(List<Adjacency> nextHopList) {
481 return new AdjacenciesOpBuilder().setAdjacency(nextHopList).build();
484 static InstanceIdentifier<Interface> getInterfaceIdentifier(String interfaceName) {
485 return InstanceIdentifier.builder(Interfaces.class).child(Interface.class,
486 new InterfaceKey(interfaceName)).build();
489 public static BigInteger getCookieL3(int vpnId) {
490 return VpnConstants.COOKIE_L3_BASE.add(new BigInteger("0610000", 16)).add(BigInteger.valueOf(vpnId));
493 public int getUniqueId(String poolName, String idKey) {
494 AllocateIdInput getIdInput = new AllocateIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
496 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
497 RpcResult<AllocateIdOutput> rpcResult = result.get();
498 if (rpcResult.isSuccessful()) {
499 return rpcResult.getResult().getIdValue().intValue();
501 LOG.error("getUniqueId: RPC Call to Get Unique Id from pool {} with key {} returned with Errors {}",
502 poolName, idKey, rpcResult.getErrors());
504 } catch (InterruptedException | ExecutionException e) {
505 LOG.error("getUniqueId: Exception when getting Unique Id from pool {} for key {}", poolName, idKey, e);
510 void releaseId(String poolName, String idKey) {
511 ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
513 RpcResult<ReleaseIdOutput> rpcResult = idManager.releaseId(idInput).get();
514 if (!rpcResult.isSuccessful()) {
515 LOG.error("releaseId: RPC Call to release Id for key {} from pool {} returned with Errors {}",
516 idKey, poolName, rpcResult.getErrors());
518 } catch (InterruptedException | ExecutionException e) {
519 LOG.error("releaseId: Exception when releasing Id for key {} from pool {}", idKey, poolName, e);
523 public static String getNextHopLabelKey(String rd, String prefix) {
524 return rd + VpnConstants.SEPARATOR + prefix;
528 * Retrieves the dataplane identifier of a specific VPN, searching by its
531 * @param vpnName Name of the VPN
532 * @return the dataplane identifier of the VPN, the VrfTag.
534 public long getVpnId(String vpnName) {
535 if (vpnName == null) {
536 return VpnConstants.INVALID_ID;
539 return read(LogicalDatastoreType.CONFIGURATION, VpnOperDsUtils.getVpnInstanceToVpnIdIdentifier(vpnName))
540 .toJavaUtil().map(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
541 .vpn.instance.to.vpn.id.VpnInstance::getVpnId).orElse(VpnConstants.INVALID_ID);
545 * Retrieves the VPN Route Distinguisher searching by its Vpn instance name.
547 * @param vpnName Name of the VPN
548 * @return the route-distinguisher of the VPN
550 public String getVpnRd(String vpnName) {
551 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
552 .VpnInstance> vpnInstance = read(LogicalDatastoreType.CONFIGURATION,
553 VpnOperDsUtils.getVpnInstanceToVpnIdIdentifier(vpnName));
555 if (vpnInstance.isPresent()) {
556 rd = vpnInstance.get().getVrfId();
561 List<String> getVpnRdsFromVpnInstanceConfig(String vpnName) {
562 InstanceIdentifier<VpnInstance> id = InstanceIdentifier.builder(VpnInstances.class)
563 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
564 Optional<VpnInstance> vpnInstance = read(LogicalDatastoreType.CONFIGURATION, id);
565 return vpnInstance.isPresent() ? getListOfRdsFromVpnInstance(vpnInstance.get()) : new ArrayList<>();
569 * Remove from MDSAL all those VrfEntries in a VPN that have an specific RouteOrigin.
571 * @param rd Route Distinguisher
572 * @param origin Origin of the Routes to be removed (see {@link RouteOrigin})
574 public void removeVrfEntriesByOrigin(String rd, RouteOrigin origin) {
575 InstanceIdentifier<VrfTables> vpnVrfTableIid =
576 InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).build();
577 Optional<VrfTables> vrfTablesOpc = read(LogicalDatastoreType.CONFIGURATION, vpnVrfTableIid);
578 if (vrfTablesOpc.isPresent()) {
579 VrfTables vrfTables = vrfTablesOpc.get();
580 ListenableFutures.addErrorLogging(
581 new ManagedNewTransactionRunnerImpl(dataBroker).callWithNewWriteOnlyTransactionAndSubmit(tx -> {
582 for (VrfEntry vrfEntry : vrfTables.getVrfEntry()) {
583 if (origin == RouteOrigin.value(vrfEntry.getOrigin())) {
584 tx.delete(LogicalDatastoreType.CONFIGURATION,
585 vpnVrfTableIid.child(VrfEntry.class, vrfEntry.key()));
588 }), LOG, "Error removing VRF entries by origin");
592 public List<VrfEntry> findVrfEntriesByNexthop(String rd, String nexthop) {
593 InstanceIdentifier<VrfTables> vpnVrfTableIid =
594 InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).build();
595 Optional<VrfTables> vrfTablesOpc = read(LogicalDatastoreType.CONFIGURATION, vpnVrfTableIid);
596 List<VrfEntry> matches = new ArrayList<>();
597 if (vrfTablesOpc.isPresent()) {
598 VrfTables vrfTables = vrfTablesOpc.get();
599 for (VrfEntry vrfEntry : vrfTables.getVrfEntry()) {
600 vrfEntry.getRoutePaths().stream()
601 .filter(routePath -> routePath.getNexthopAddress() != null && routePath.getNexthopAddress()
602 .equals(nexthop)).findFirst().ifPresent(routePath -> matches.add(vrfEntry));
608 public void removeVrfEntries(String rd, List<VrfEntry> vrfEntries) {
609 InstanceIdentifier<VrfTables> vpnVrfTableIid =
610 InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).build();
611 ListenableFutures.addErrorLogging(
612 new ManagedNewTransactionRunnerImpl(dataBroker).callWithNewWriteOnlyTransactionAndSubmit(tx -> {
613 for (VrfEntry vrfEntry : vrfEntries) {
614 tx.delete(LogicalDatastoreType.CONFIGURATION,
615 vpnVrfTableIid.child(VrfEntry.class, vrfEntry.key()));
617 }), LOG, "Error removing VRF entries");
620 // TODO Clean up the exception handling
621 @SuppressWarnings("checkstyle:IllegalCatch")
622 public void withdrawRoutes(String rd, List<VrfEntry> vrfEntries) {
623 vrfEntries.forEach(vrfEntry -> {
625 bgpManager.withdrawPrefix(rd, vrfEntry.getDestPrefix());
626 } catch (Exception e) {
627 LOG.error("withdrawRoutes: Could not withdraw route to {} with route-paths {} in VpnRd {}",
628 vrfEntry.getDestPrefix(), vrfEntry.getRoutePaths(), rd);
633 static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance
634 getVpnInstanceToVpnId(String vpnName, long vpnId, String rd) {
635 return new VpnInstanceBuilder().setVpnId(vpnId).setVpnInstanceName(vpnName).setVrfId(rd).build();
639 static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds
640 getVpnIdToVpnInstance(long vpnId, String vpnName, String rd, boolean isExternalVpn) {
641 return new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance
642 .VpnIdsBuilder().setVpnId(vpnId).setVpnInstanceName(vpnName).setVrfId(rd).setExternalVpn(isExternalVpn)
647 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to
648 .vpn.instance.VpnIds> getVpnIdToVpnInstanceIdentifier(long vpnId) {
649 return InstanceIdentifier.builder(VpnIdToVpnInstance.class).child(org.opendaylight.yang.gen.v1.urn
650 .opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds.class,
651 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance
652 .VpnIdsKey(vpnId)).build();
656 * Retrieves the Vpn Name searching by its VPN Tag.
658 * @param vpnId Dataplane identifier of the VPN
659 * @return the Vpn instance name
661 String getVpnName(long vpnId) {
663 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn
664 .instance.VpnIds> id = getVpnIdToVpnInstanceIdentifier(vpnId);
665 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds>
667 = read(LogicalDatastoreType.CONFIGURATION, id);
668 String vpnName = null;
669 if (vpnInstance.isPresent()) {
670 vpnName = vpnInstance.get().getVpnInstanceName();
675 public static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String rd) {
676 return InstanceIdentifier.builder(VpnInstanceOpData.class)
677 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd)).build();
680 public VpnInstanceOpDataEntry getVpnInstanceOpData(String rd) {
681 InstanceIdentifier<VpnInstanceOpDataEntry> id = getVpnInstanceOpDataIdentifier(rd);
682 return read(LogicalDatastoreType.OPERATIONAL, id).orNull();
685 VpnInterface getConfiguredVpnInterface(String interfaceName) {
686 InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
687 Optional<VpnInterface> configuredVpnInterface = read(LogicalDatastoreType.CONFIGURATION, interfaceId);
688 if (configuredVpnInterface.isPresent()) {
689 return configuredVpnInterface.get();
694 boolean isVpnInterfaceConfigured(String interfaceName) {
695 InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
696 return read(LogicalDatastoreType.CONFIGURATION, interfaceId).isPresent();
699 public Optional<List<String>> getVpnHandlingIpv4AssociatedWithInterface(String interfaceName) {
700 InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
701 Optional<List<String>> vpnOptional = Optional.absent();
702 Optional<VpnInterface> optConfiguredVpnInterface = read(LogicalDatastoreType.CONFIGURATION, interfaceId);
703 if (optConfiguredVpnInterface.isPresent()) {
704 VpnInterface cfgVpnInterface = optConfiguredVpnInterface.get();
705 java.util.Optional<List<VpnInstanceNames>> optVpnInstanceList =
706 java.util.Optional.ofNullable(cfgVpnInterface.getVpnInstanceNames());
707 if (optVpnInstanceList.isPresent()) {
708 List<String> vpnList = new ArrayList<>();
709 for (VpnInstanceNames vpnInstance : optVpnInstanceList.get()) {
710 vpnList.add(vpnInstance.getVpnName());
712 vpnOptional = Optional.of(vpnList);
718 public static String getIpPrefix(String prefix) {
719 String[] prefixValues = prefix.split("/");
720 if (prefixValues.length == 1) {
721 prefix = NWUtil.toIpPrefix(prefix);
726 static final FutureCallback<Void> DEFAULT_CALLBACK =
727 new FutureCallback<Void>() {
729 public void onSuccess(Void result) {
730 LOG.debug("Success in Datastore operation");
734 public void onFailure(Throwable error) {
735 LOG.error("Error in Datastore operation", error);
741 private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType, InstanceIdentifier<T> path) {
743 return SingleTransactionDataBroker.syncReadOptional(dataBroker, datastoreType, path);
744 } catch (ReadFailedException e) {
745 throw new RuntimeException(e);
750 public <T extends DataObject> void syncWrite(LogicalDatastoreType datastoreType, InstanceIdentifier<T> path,
753 SingleTransactionDataBroker.syncWrite(dataBroker, datastoreType, path, data);
754 } catch (TransactionCommitFailedException e) {
755 LOG.error("syncWrite: Error writing to datastore (path, data) : ({}, {})", path, data, e);
756 throw new RuntimeException(e.getMessage(), e);
761 public <T extends DataObject> void syncUpdate(LogicalDatastoreType datastoreType, InstanceIdentifier<T> path,
764 SingleTransactionDataBroker.syncUpdate(dataBroker, datastoreType, path, data);
765 } catch (TransactionCommitFailedException e) {
766 LOG.error("syncUpdate: Error writing to datastore (path, data) : ({}, {})", path, data, e);
767 throw new RuntimeException(e.getMessage(), e);
771 static long getRemoteBCGroup(long elanTag) {
772 return VpnConstants.ELAN_GID_MIN + elanTag % VpnConstants.ELAN_GID_MIN * 2;
775 // interface-index-tag operational container
776 IfIndexInterface getInterfaceInfoByInterfaceTag(long interfaceTag) {
777 InstanceIdentifier<IfIndexInterface> interfaceId = getInterfaceInfoEntriesOperationalDataPath(interfaceTag);
778 Optional<IfIndexInterface> existingInterfaceInfo = read(LogicalDatastoreType.OPERATIONAL, interfaceId);
779 if (existingInterfaceInfo.isPresent()) {
780 return existingInterfaceInfo.get();
785 static InstanceIdentifier<IfIndexInterface> getInterfaceInfoEntriesOperationalDataPath(long interfaceTag) {
786 return InstanceIdentifier.builder(IfIndexesInterfaceMap.class).child(IfIndexInterface.class,
787 new IfIndexInterfaceKey((int) interfaceTag)).build();
790 ElanTagName getElanInfoByElanTag(long elanTag) {
791 InstanceIdentifier<ElanTagName> elanId = getElanInfoEntriesOperationalDataPath(elanTag);
792 Optional<ElanTagName> existingElanInfo = read(LogicalDatastoreType.OPERATIONAL, elanId);
793 if (existingElanInfo.isPresent()) {
794 return existingElanInfo.get();
799 static InstanceIdentifier<ElanTagName> getElanInfoEntriesOperationalDataPath(long elanTag) {
800 return InstanceIdentifier.builder(ElanTagNameMap.class).child(ElanTagName.class,
801 new ElanTagNameKey(elanTag)).build();
804 static void removePrefixToInterfaceForVpnId(long vpnId, @Nonnull WriteTransaction operTx) {
805 // Clean up PrefixToInterface Operational DS
806 operTx.delete(LogicalDatastoreType.OPERATIONAL,
807 InstanceIdentifier.builder(PrefixToInterface.class).child(VpnIds.class, new VpnIdsKey(vpnId)).build());
810 static void removeVpnExtraRouteForVpn(String vpnName, @Nonnull WriteTransaction operTx) {
811 // Clean up VPNExtraRoutes Operational DS
812 operTx.delete(LogicalDatastoreType.OPERATIONAL,
813 InstanceIdentifier.builder(VpnToExtraroutes.class).child(Vpn.class, new VpnKey(vpnName)).build());
816 // TODO Clean up the exception handling
817 @SuppressWarnings("checkstyle:IllegalCatch")
818 static void removeVpnOpInstance(String vpnName, @Nonnull WriteTransaction operTx) {
819 // Clean up VPNInstanceOpDataEntry
820 operTx.delete(LogicalDatastoreType.OPERATIONAL, getVpnInstanceOpDataIdentifier(vpnName));
823 static void removeVpnInstanceToVpnId(String vpnName, @Nonnull WriteTransaction confTx) {
824 confTx.delete(LogicalDatastoreType.CONFIGURATION, VpnOperDsUtils.getVpnInstanceToVpnIdIdentifier(vpnName));
827 static void removeVpnIdToVpnInstance(long vpnId, @Nonnull WriteTransaction confTx) {
828 confTx.delete(LogicalDatastoreType.CONFIGURATION, getVpnIdToVpnInstanceIdentifier(vpnId));
831 static void removeL3nexthopForVpnId(long vpnId, @Nonnull WriteTransaction operTx) {
832 // Clean up L3NextHop Operational DS
833 operTx.delete(LogicalDatastoreType.OPERATIONAL,
834 InstanceIdentifier.builder(L3nexthop.class).child(VpnNexthops.class, new VpnNexthopsKey(vpnId)).build());
837 void scheduleVpnInterfaceForRemoval(String interfaceName, BigInteger dpnId, String vpnInstanceName,
838 Boolean isScheduledToRemove, WriteTransaction writeOperTxn) {
839 InstanceIdentifier<VpnInterfaceOpDataEntry> interfaceId =
840 getVpnInterfaceOpDataEntryIdentifier(interfaceName, vpnInstanceName);
841 VpnInterfaceOpDataEntry interfaceToUpdate =
842 new VpnInterfaceOpDataEntryBuilder().withKey(new VpnInterfaceOpDataEntryKey(interfaceName,
843 vpnInstanceName)).setName(interfaceName).setDpnId(dpnId).setVpnInstanceName(vpnInstanceName)
844 .setScheduledForRemove(isScheduledToRemove).build();
845 if (writeOperTxn != null) {
846 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL, interfaceId, interfaceToUpdate, true);
848 syncUpdate(LogicalDatastoreType.OPERATIONAL, interfaceId, interfaceToUpdate);
852 void createLearntVpnVipToPort(String vpnName, String fixedIp, String portName, String macAddress,
853 WriteTransaction writeOperTxn) {
854 synchronized ((vpnName + fixedIp).intern()) {
855 InstanceIdentifier<LearntVpnVipToPort> id = buildLearntVpnVipToPortIdentifier(vpnName, fixedIp);
856 LearntVpnVipToPortBuilder builder =
857 new LearntVpnVipToPortBuilder().withKey(new LearntVpnVipToPortKey(fixedIp, vpnName)).setVpnName(
858 vpnName).setPortFixedip(fixedIp).setPortName(portName)
859 .setMacAddress(macAddress.toLowerCase(Locale.getDefault()))
860 .setCreationTime(new SimpleDateFormat("MM/dd/yyyy h:mm:ss a").format(new Date()));
861 if (writeOperTxn != null) {
862 writeOperTxn.put(LogicalDatastoreType.OPERATIONAL, id, builder.build(), true);
864 syncWrite(LogicalDatastoreType.OPERATIONAL, id, builder.build());
866 LOG.debug("createLearntVpnVipToPort: ARP/NA learned for fixedIp: {}, vpn {}, interface {}, mac {},"
867 + " added to LearntVpnVipToPort DS", fixedIp, vpnName, portName, macAddress);
871 static InstanceIdentifier<LearntVpnVipToPort> buildLearntVpnVipToPortIdentifier(String vpnName,
873 return InstanceIdentifier.builder(LearntVpnVipToPortData.class).child(LearntVpnVipToPort.class,
874 new LearntVpnVipToPortKey(fixedIp, vpnName)).build();
877 void removeLearntVpnVipToPort(String vpnName, String fixedIp, WriteTransaction writeOperTxn) {
878 synchronized ((vpnName + fixedIp).intern()) {
879 InstanceIdentifier<LearntVpnVipToPort> id = buildLearntVpnVipToPortIdentifier(vpnName, fixedIp);
880 if (writeOperTxn != null) {
881 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, id);
883 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
885 LOG.debug("removeLearntVpnVipToPort: Deleted LearntVpnVipToPort entry for fixedIp: {}, vpn {}",
890 protected static void removeVpnPortFixedIpToPort(DataBroker broker, String vpnName, String fixedIp,
891 WriteTransaction writeConfigTxn) {
892 synchronized ((vpnName + fixedIp).intern()) {
893 InstanceIdentifier<VpnPortipToPort> id = buildVpnPortipToPortIdentifier(vpnName, fixedIp);
894 if (writeConfigTxn != null) {
895 writeConfigTxn.delete(LogicalDatastoreType.CONFIGURATION, id);
897 MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, id);
899 LOG.debug("removeVpnPortFixedIpToPort: Deleted VpnPortipToPort entry for fixedIp: {}, vpn {}",
904 public void createLearntVpnVipToPortEvent(String vpnName, String srcIp, String destIP, String portName,
905 String macAddress, LearntVpnVipToPortEventAction action,
906 WriteTransaction writeOperTxn) {
907 String eventId = MicroTimestamp.INSTANCE.get();
909 InstanceIdentifier<LearntVpnVipToPortEvent> id = buildLearntVpnVipToPortEventIdentifier(eventId);
910 LearntVpnVipToPortEventBuilder builder = new LearntVpnVipToPortEventBuilder().withKey(
911 new LearntVpnVipToPortEventKey(eventId)).setVpnName(vpnName).setSrcFixedip(srcIp)
912 .setDestFixedip(destIP).setPortName(portName)
913 .setMacAddress(macAddress.toLowerCase(Locale.getDefault())).setEventAction(action);
914 if (writeOperTxn != null) {
915 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, id);
917 syncWrite(LogicalDatastoreType.OPERATIONAL, id, builder.build());
919 LOG.info("createLearntVpnVipToPortEvent: ARP learn event created for fixedIp: {}, vpn {}, interface {},"
920 + " mac {} action {} eventId {}", srcIp, vpnName, portName, macAddress, action, eventId);
923 private static InstanceIdentifier<LearntVpnVipToPortEvent> buildLearntVpnVipToPortEventIdentifier(String eventId) {
924 InstanceIdentifier<LearntVpnVipToPortEvent> id = InstanceIdentifier.builder(LearntVpnVipToPortEventData.class)
925 .child(LearntVpnVipToPortEvent.class, new LearntVpnVipToPortEventKey(eventId)).build();
929 void removeLearntVpnVipToPortEvent(String eventId, WriteTransaction writeOperTxn) {
930 InstanceIdentifier<LearntVpnVipToPortEvent> id = buildLearntVpnVipToPortEventIdentifier(eventId);
931 if (writeOperTxn != null) {
932 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, id);
934 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
936 LOG.info("removeLearntVpnVipToPortEvent: Deleted Event {}", eventId);
940 void removeMipAdjAndLearntIp(String vpnName, String vpnInterface, String prefix) {
941 synchronized ((vpnName + prefix).intern()) {
942 InstanceIdentifier<LearntVpnVipToPort> id = buildLearntVpnVipToPortIdentifier(vpnName, prefix);
943 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
944 LOG.info("removeMipAdjAndLearntIp: Delete learned ARP for fixedIp: {}, vpn {} removed from"
945 + "VpnPortipToPort DS", prefix, vpnName);
946 String ip = VpnUtil.getIpPrefix(prefix);
947 InstanceIdentifier<VpnInterfaceOpDataEntry> vpnInterfaceOpId = VpnUtil
948 .getVpnInterfaceOpDataEntryIdentifier(vpnInterface, vpnName);
949 InstanceIdentifier<AdjacenciesOp> path = vpnInterfaceOpId.augmentation(AdjacenciesOp.class);
950 Optional<AdjacenciesOp> adjacenciesOp = read(LogicalDatastoreType.OPERATIONAL, path);
951 if (adjacenciesOp.isPresent()) {
952 InstanceIdentifier<Adjacency> adjacencyIdentifier = InstanceIdentifier.builder(VpnInterfaces.class)
953 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterface)).augmentation(Adjacencies.class)
954 .child(Adjacency.class, new AdjacencyKey(ip)).build();
955 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier);
956 LOG.info("removeMipAdjAndLearntIp: Successfully Deleted Adjacency {} from interface {} vpn {}", ip,
957 vpnInterface, vpnName);
962 static InstanceIdentifier<NetworkMap> buildNetworkMapIdentifier(Uuid networkId) {
963 return InstanceIdentifier.builder(NetworkMaps.class).child(NetworkMap.class, new
964 NetworkMapKey(networkId)).build();
967 static InstanceIdentifier<SubnetOpDataEntry> buildSubnetOpDataEntryInstanceIdentifier(Uuid subnetId) {
968 return InstanceIdentifier.builder(SubnetOpData.class)
969 .child(SubnetOpDataEntry.class, new SubnetOpDataEntryKey(subnetId)).build();
972 static InstanceIdentifier<VpnPortipToPort> buildVpnPortipToPortIdentifier(String vpnName, String fixedIp) {
973 return InstanceIdentifier.builder(NeutronVpnPortipPortData.class).child(VpnPortipToPort.class,
974 new VpnPortipToPortKey(fixedIp, vpnName)).build();
977 public VpnPortipToPort getNeutronPortFromVpnPortFixedIp(String vpnName, String fixedIp) {
978 InstanceIdentifier<VpnPortipToPort> id = buildVpnPortipToPortIdentifier(vpnName, fixedIp);
979 Optional<VpnPortipToPort> vpnPortipToPortData = read(LogicalDatastoreType.CONFIGURATION, id);
980 if (vpnPortipToPortData.isPresent()) {
981 return vpnPortipToPortData.get();
986 public LearntVpnVipToPort getLearntVpnVipToPort(String vpnName, String fixedIp) {
987 InstanceIdentifier<LearntVpnVipToPort> id = buildLearntVpnVipToPortIdentifier(vpnName, fixedIp);
988 Optional<LearntVpnVipToPort> learntVpnVipToPort = read(LogicalDatastoreType.OPERATIONAL, id);
989 if (learntVpnVipToPort.isPresent()) {
990 return learntVpnVipToPort.get();
996 List<BigInteger> getDpnsOnVpn(String vpnInstanceName) {
997 List<BigInteger> result = new ArrayList<>();
998 String rd = getVpnRd(vpnInstanceName);
1000 LOG.debug("getDpnsOnVpn: Could not find Route-Distinguisher for VpnName={}", vpnInstanceName);
1003 VpnInstanceOpDataEntry vpnInstanceOpData = getVpnInstanceOpData(rd);
1004 if (vpnInstanceOpData == null) {
1005 LOG.debug("getDpnsOnVpn: Could not find OpState for VpnName={}", vpnInstanceName);
1008 List<VpnToDpnList> vpnToDpnList = vpnInstanceOpData.getVpnToDpnList();
1009 if (vpnToDpnList == null) {
1010 LOG.debug("getDpnsOnVpn: Could not find DPN footprint for VpnName={}", vpnInstanceName);
1013 for (VpnToDpnList vpnToDpn : vpnToDpnList) {
1014 result.add(vpnToDpn.getDpnId());
1019 String getAssociatedExternalRouter(String extIp) {
1020 InstanceIdentifier<ExtRouters> extRouterInstanceIndentifier =
1021 InstanceIdentifier.builder(ExtRouters.class).build();
1022 Optional<ExtRouters> extRouterData = read(LogicalDatastoreType.CONFIGURATION, extRouterInstanceIndentifier);
1023 if (extRouterData.isPresent()) {
1024 for (Routers routerData : extRouterData.get().getRouters()) {
1025 List<ExternalIps> externalIps = routerData.getExternalIps();
1026 for (ExternalIps externalIp : externalIps) {
1027 if (externalIp.getIpAddress().equals(extIp)) {
1028 return routerData.getRouterName();
1036 static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
1037 return InstanceIdentifier.builder(ExtRouters.class).child(Routers.class, new RoutersKey(routerId)).build();
1040 Networks getExternalNetwork(Uuid networkId) {
1041 InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class)
1042 .child(Networks.class, new NetworksKey(networkId)).build();
1043 Optional<Networks> optionalNets = read(LogicalDatastoreType.CONFIGURATION, netsIdentifier);
1044 return optionalNets.isPresent() ? optionalNets.get() : null;
1047 Uuid getExternalNetworkVpnId(Uuid networkId) {
1048 Networks extNetwork = getExternalNetwork(networkId);
1049 return extNetwork != null ? extNetwork.getVpnid() : null;
1052 List<Uuid> getExternalNetworkRouterIds(Uuid networkId) {
1053 Networks extNetwork = getExternalNetwork(networkId);
1054 return extNetwork != null ? extNetwork.getRouterIds() : Collections.emptyList();
1057 Routers getExternalRouter(String routerId) {
1058 InstanceIdentifier<Routers> id = InstanceIdentifier.builder(ExtRouters.class).child(Routers.class,
1059 new RoutersKey(routerId)).build();
1060 Optional<Routers> routerData = read(LogicalDatastoreType.CONFIGURATION, id);
1061 return routerData.isPresent() ? routerData.get() : null;
1064 static InstanceIdentifier<Subnetmaps> buildSubnetMapsWildCardPath() {
1065 return InstanceIdentifier.create(Subnetmaps.class);
1068 FlowEntity buildL3vpnGatewayFlow(BigInteger dpId, String gwMacAddress, long vpnId,
1070 List<MatchInfo> mkMatches = new ArrayList<>();
1071 Subnetmap smap = null;
1072 mkMatches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
1073 mkMatches.add(new MatchEthernetDestination(new MacAddress(gwMacAddress)));
1074 List<InstructionInfo> mkInstructions = new ArrayList<>();
1075 mkInstructions.add(new InstructionGotoTable(NwConstants.L3_FIB_TABLE));
1076 if (subnetVpnId != VpnConstants.INVALID_ID) {
1077 String vpnName = getVpnName(subnetVpnId);
1078 if (vpnName != null) {
1079 smap = getSubnetmapFromItsUuid(Uuid.getDefaultInstance(vpnName));
1080 if (smap != null && smap.getSubnetIp() != null) {
1081 IpVersionChoice ipVersionChoice = getIpVersionFromString(smap.getSubnetIp());
1082 if (ipVersionChoice == IpVersionChoice.IPV4) {
1083 mkMatches.add(MatchEthernetType.IPV4);
1085 mkMatches.add(MatchEthernetType.IPV6);
1089 BigInteger subnetIdMetaData = MetaDataUtil.getVpnIdMetadata(subnetVpnId);
1090 mkInstructions.add(new InstructionWriteMetadata(subnetIdMetaData, MetaDataUtil.METADATA_MASK_VRFID));
1092 String flowId = getL3VpnGatewayFlowRef(NwConstants.L3_GW_MAC_TABLE, dpId, vpnId, gwMacAddress, subnetVpnId);
1093 return MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_GW_MAC_TABLE,
1094 flowId, 20, flowId, 0, 0, NwConstants.COOKIE_L3_GW_MAC_TABLE, mkMatches, mkInstructions);
1097 static String getL3VpnGatewayFlowRef(short l3GwMacTable, BigInteger dpId, long vpnId, String gwMacAddress,
1099 return gwMacAddress + NwConstants.FLOWID_SEPARATOR + vpnId + NwConstants.FLOWID_SEPARATOR + dpId
1100 + NwConstants.FLOWID_SEPARATOR + l3GwMacTable + NwConstants.FLOWID_SEPARATOR + subnetVpnId;
1103 void lockSubnet(String subnetId) {
1104 TryLockInput input =
1105 new TryLockInputBuilder().setLockName(subnetId).setTime(3000L).setTimeUnit(TimeUnits.Milliseconds).build();
1106 Future<RpcResult<TryLockOutput>> result = lockManager.tryLock(input);
1108 if (result != null && result.get().isSuccessful()) {
1109 LOG.debug("lockSubnet: Acquired lock for {}", subnetId);
1111 LOG.error("Unable to get lock for subnet {}", subnetId);
1112 throw new RuntimeException("Unable to get lock for subnet " + subnetId);
1114 } catch (InterruptedException | ExecutionException e) {
1115 LOG.error("Unable to get lock for subnet {}", subnetId, e);
1116 throw new RuntimeException("Unable to get lock for subnet " + subnetId, e);
1120 // We store the cause, which is what we really care about
1121 @SuppressWarnings("checkstyle:AvoidHidingCauseException")
1122 public void unlockSubnet(String subnetId) {
1123 UnlockInput input = new UnlockInputBuilder().setLockName(subnetId).build();
1124 Future<RpcResult<UnlockOutput>> result = lockManager.unlock(input);
1126 if (result != null && result.get().isSuccessful()) {
1127 LOG.debug("unlockSubnet: Unlocked {}", subnetId);
1129 LOG.debug("unlockSubnet: Unable to unlock subnet {}", subnetId);
1131 } catch (InterruptedException | ExecutionException e) {
1132 LOG.error("unlockSubnet: Unable to unlock subnet {}", subnetId);
1133 throw new RuntimeException(String.format("Unable to unlock subnetId %s", subnetId), e.getCause());
1137 Optional<IpAddress> getIpv4GatewayAddressFromInterface(String srcInterface) {
1138 Optional<IpAddress> gatewayIp = Optional.absent();
1139 if (neutronVpnService != null) {
1140 //TODO(Gobinath): Need to fix this as assuming port will belong to only one Subnet would be incorrect"
1141 Port port = neutronVpnService.getNeutronPort(srcInterface);
1142 if (port != null && port.getFixedIps() != null) {
1143 for (FixedIps portIp: port.getFixedIps()) {
1144 if (portIp.getIpAddress().getIpv6Address() != null) {
1145 // Skip IPv6 address
1148 gatewayIp = Optional.of(
1149 neutronVpnService.getNeutronSubnet(portIp.getSubnetId()).getGatewayIp());
1153 LOG.error("getGatewayIpAddressFromInterface: neutron vpn service is not configured."
1154 + " Failed for interface {}.", srcInterface);
1159 Optional<String> getGWMacAddressFromInterface(MacEntry macEntry, IpAddress gatewayIp) {
1160 Optional<String> gatewayMac = Optional.absent();
1161 long vpnId = getVpnId(macEntry.getVpnName());
1162 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn
1164 vpnIdsInstanceIdentifier = VpnUtil.getVpnIdToVpnInstanceIdentifier(vpnId);
1165 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds>
1166 vpnIdsOptional = read(LogicalDatastoreType.CONFIGURATION, vpnIdsInstanceIdentifier);
1167 if (!vpnIdsOptional.isPresent()) {
1168 LOG.error("getGWMacAddressFromInterface: VPN {} not configured", vpnId);
1171 VpnPortipToPort vpnTargetIpToPort = getNeutronPortFromVpnPortFixedIp(macEntry.getVpnName(),
1172 gatewayIp.getIpv4Address().getValue());
1173 if (vpnTargetIpToPort != null && vpnTargetIpToPort.isSubnetIp()) {
1174 gatewayMac = Optional.of(vpnTargetIpToPort.getMacAddress());
1176 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
1177 .vpn.id.to.vpn.instance.VpnIds vpnIds = vpnIdsOptional.get();
1178 if (vpnIds.isExternalVpn()) {
1179 gatewayMac = InterfaceUtils.getMacAddressForInterface(dataBroker, macEntry.getInterfaceName());
1185 void setupGwMacIfExternalVpn(BigInteger dpnId, String interfaceName, long vpnId, WriteTransaction writeInvTxn,
1186 int addOrRemove, String gwMac) {
1187 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance
1188 .VpnIds> vpnIdsInstanceIdentifier = getVpnIdToVpnInstanceIdentifier(vpnId);
1189 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance
1190 .VpnIds> vpnIdsOptional = read(LogicalDatastoreType.CONFIGURATION, vpnIdsInstanceIdentifier);
1191 if (vpnIdsOptional.isPresent() && vpnIdsOptional.get().isExternalVpn()) {
1192 if (gwMac == null) {
1193 LOG.error("setupGwMacIfExternalVpn: Failed to get gwMacAddress for interface {} on dpn {} vpn {}",
1194 interfaceName, dpnId.toString(), vpnIdsOptional.get().getVpnInstanceName());
1197 FlowEntity flowEntity = buildL3vpnGatewayFlow(dpnId, gwMac, vpnId, VpnConstants.INVALID_ID);
1198 if (addOrRemove == NwConstants.ADD_FLOW) {
1199 mdsalManager.addFlowToTx(flowEntity, writeInvTxn);
1200 } else if (addOrRemove == NwConstants.DEL_FLOW) {
1201 mdsalManager.removeFlowToTx(flowEntity, writeInvTxn);
1206 public Optional<String> getVpnSubnetGatewayIp(final Uuid subnetUuid) {
1207 Optional<String> gwIpAddress = Optional.absent();
1208 final SubnetKey subnetkey = new SubnetKey(subnetUuid);
1209 final InstanceIdentifier<Subnet> subnetidentifier = InstanceIdentifier.create(Neutron.class)
1210 .child(Subnets.class)
1211 .child(Subnet.class, subnetkey);
1212 final Optional<Subnet> subnet = read(LogicalDatastoreType.CONFIGURATION, subnetidentifier);
1213 if (subnet.isPresent()) {
1214 Class<? extends IpVersionBase> ipVersionBase = subnet.get().getIpVersion();
1215 if (ipVersionBase.equals(IpVersionV4.class)) {
1216 Subnetmap subnetmap = getSubnetmapFromItsUuid(subnetUuid);
1217 if (subnetmap != null && subnetmap.getRouterInterfaceFixedIp() != null) {
1218 LOG.trace("getVpnSubnetGatewayIp: Obtained subnetMap {} for vpn interface",
1219 subnetmap.getId().getValue());
1220 gwIpAddress = Optional.of(subnetmap.getRouterInterfaceFixedIp());
1222 //For direct L3VPN to network association (no router) continue to use subnet-gateway IP
1223 IpAddress gwIp = subnet.get().getGatewayIp();
1224 if (gwIp != null && gwIp.getIpv4Address() != null) {
1225 gwIpAddress = Optional.of(gwIp.getIpv4Address().getValue());
1228 LOG.trace("getVpnSubnetGatewayIp: Obtained subnet-gw ip {} for vpn interface",
1235 RouterToNaptSwitch getRouterToNaptSwitch(String routerName) {
1236 InstanceIdentifier<RouterToNaptSwitch> id = InstanceIdentifier.builder(NaptSwitches.class)
1237 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerName)).build();
1238 Optional<RouterToNaptSwitch> routerToNaptSwitchData = read(LogicalDatastoreType.CONFIGURATION, id);
1239 return routerToNaptSwitchData.isPresent() ? routerToNaptSwitchData.get() : null;
1242 static InstanceIdentifier<Subnetmap> buildSubnetmapIdentifier(Uuid subnetId) {
1243 return InstanceIdentifier.builder(Subnetmaps.class)
1244 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
1248 BigInteger getPrimarySwitchForRouter(String routerName) {
1249 RouterToNaptSwitch routerToNaptSwitch = getRouterToNaptSwitch(routerName);
1250 return routerToNaptSwitch != null ? routerToNaptSwitch.getPrimarySwitchId() : null;
1253 static boolean isL3VpnOverVxLan(Long l3Vni) {
1254 return l3Vni != null && l3Vni != 0;
1258 * Retrieves the primary rd of a vpn instance
1259 * Primary rd will be the first rd in the list of rds configured for a vpn instance
1260 * If rd list is empty, primary rd will be vpn instance name
1261 * Use this function only during create operation cycles. For other operations, use getVpnRd() method.
1263 * @param vpnName Name of the VPN
1264 * @return the primary rd of the VPN
1266 public String getPrimaryRd(String vpnName) {
1267 // Retrieves the VPN Route Distinguisher by its Vpn instance name
1268 String rd = getVpnRd(vpnName);
1272 InstanceIdentifier<VpnInstance> id = getVpnInstanceIdentifier(vpnName);
1273 Optional<VpnInstance> vpnInstance = read(LogicalDatastoreType.CONFIGURATION, id);
1274 if (vpnInstance.isPresent()) {
1275 return getPrimaryRd(vpnInstance.get());
1281 * Retrieves the primary rd of a vpn instance
1282 * Primary rd will be the first rd in the list of rds configured for a vpn instance
1283 * If rd list is empty, primary rd will be vpn instance name
1284 * Use this function only during create operation cycles. For other operations, use getVpnRd() method.
1286 * @param vpnInstance Config Vpn Instance Object
1287 * @return the primary rd of the VPN
1289 static String getPrimaryRd(VpnInstance vpnInstance) {
1290 List<String> rds = null;
1291 if (vpnInstance != null) {
1292 rds = getListOfRdsFromVpnInstance(vpnInstance);
1294 return rds == null || rds.isEmpty() ? vpnInstance.getVpnInstanceName() : rds.get(0);
1297 static boolean isBgpVpn(String vpnName, String primaryRd) {
1298 return !vpnName.equals(primaryRd);
1301 java.util.Optional<String> allocateRdForExtraRouteAndUpdateUsedRdsMap(long vpnId, @Nullable Long parentVpnId,
1302 String prefix, String vpnName,
1303 String nextHop, BigInteger dpnId) {
1304 //Check if rd is already allocated for this extraroute behind the same VM. If yes, reuse it.
1305 //This is particularly useful during reboot scenarios.
1306 java.util.Optional<String> allocatedRd = VpnExtraRouteHelper
1307 .getRdAllocatedForExtraRoute(dataBroker, vpnId, prefix, nextHop);
1308 if (allocatedRd.isPresent()) {
1312 //Check if rd is already allocated for this extraroute behind the same CSS. If yes, reuse it
1313 List<String> usedRds = VpnExtraRouteHelper.getUsedRds(dataBroker, vpnId, prefix);
1314 for (String usedRd : usedRds) {
1315 Optional<Routes> vpnExtraRoutes = VpnExtraRouteHelper.getVpnExtraroutes(dataBroker,
1316 vpnName, usedRd, prefix);
1317 if (vpnExtraRoutes.isPresent()) {
1318 String nextHopIp = vpnExtraRoutes.get().getNexthopIpList().get(0);
1319 // In case of VPN importing the routes, the interface is not present in the VPN
1320 // and has to be fetched from the VPN from which it imports
1321 Optional<Prefixes> prefixToInterface =
1322 getPrefixToInterface(parentVpnId != null ? parentVpnId : vpnId, nextHopIp);
1323 if (prefixToInterface.isPresent() && dpnId.equals(prefixToInterface.get().getDpnId())) {
1324 syncUpdate(LogicalDatastoreType.CONFIGURATION,
1325 VpnExtraRouteHelper.getUsedRdsIdentifier(vpnId, prefix, nextHop),
1326 getRdsBuilder(nextHop, usedRd).build());
1327 return java.util.Optional.of(usedRd);
1331 List<String> availableRds = getVpnRdsFromVpnInstanceConfig(vpnName);
1333 if (availableRds.isEmpty()) {
1334 rd = dpnId.toString();
1335 LOG.debug("Internal vpn {} Returning DpnId {} as rd", vpnName, rd);
1337 LOG.trace("Removing used rds {} from available rds {} vpnid {} . prefix is {} , vpname- {}, dpnId- {}",
1338 usedRds, availableRds, vpnId, prefix, vpnName, dpnId);
1339 availableRds.removeAll(usedRds);
1340 if (availableRds.isEmpty()) {
1341 LOG.error("No rd available from VpnInstance to allocate for prefix {}", prefix);
1342 return java.util.Optional.empty();
1344 // If rd is not allocated for this prefix or if extra route is behind different OVS, select a new rd.
1345 rd = availableRds.get(0);
1347 syncUpdate(LogicalDatastoreType.CONFIGURATION,
1348 VpnExtraRouteHelper.getUsedRdsIdentifier(vpnId, prefix, nextHop), getRdsBuilder(nextHop, rd).build());
1349 return java.util.Optional.ofNullable(rd);
1352 static String getVpnNamePrefixKey(String vpnName, String prefix) {
1353 return vpnName + VpnConstants.SEPARATOR + prefix;
1356 static InstanceIdentifier<Adjacency> getAdjacencyIdentifier(String vpnInterfaceName, String ipAddress) {
1357 return InstanceIdentifier.builder(VpnInterfaces.class)
1358 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName))
1359 .augmentation(Adjacencies.class).child(Adjacency.class, new AdjacencyKey(ipAddress)).build();
1362 public static List<String> getIpsListFromExternalIps(List<ExternalIps> externalIps) {
1363 if (externalIps == null) {
1364 return Collections.emptyList();
1367 return externalIps.stream().map(ExternalIps::getIpAddress).collect(Collectors.toList());
1370 void bindService(final String vpnInstanceName, final String interfaceName, boolean isTunnelInterface) {
1371 jobCoordinator.enqueueJob(interfaceName,
1372 () -> Collections.singletonList(
1373 txRunner.callWithNewReadWriteTransactionAndSubmit(tx -> {
1374 BoundServices serviceInfo = isTunnelInterface
1375 ? VpnUtil.getBoundServicesForTunnelInterface(vpnInstanceName, interfaceName)
1376 : getBoundServicesForVpnInterface(vpnInstanceName, interfaceName);
1377 tx.put(LogicalDatastoreType.CONFIGURATION, InterfaceUtils.buildServiceId(interfaceName,
1378 ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME,
1379 NwConstants.L3VPN_SERVICE_INDEX)),
1380 serviceInfo, WriteTransaction.CREATE_MISSING_PARENTS);
1381 })), SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries());
1384 BoundServices getBoundServicesForVpnInterface(String vpnName, String interfaceName) {
1385 List<Instruction> instructions = new ArrayList<>();
1386 int instructionKey = 0;
1387 final long vpnId = getVpnId(vpnName);
1388 List<Action> actions = Collections.singletonList(
1389 new ActionRegLoad(0, VpnConstants.VPN_REG_ID, 0, VpnConstants.VPN_ID_LENGTH, vpnId).buildAction());
1390 instructions.add(MDSALUtil.buildApplyActionsInstruction(actions, ++instructionKey));
1392 MDSALUtil.buildAndGetWriteMetadaInstruction(MetaDataUtil.getVpnIdMetadata(vpnId),
1393 MetaDataUtil.METADATA_MASK_VRFID, ++instructionKey));
1394 instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(NwConstants.L3_GW_MAC_TABLE,
1396 BoundServices serviceInfo = InterfaceUtils.getBoundServices(
1397 String.format("%s.%s.%s", "vpn", vpnName, interfaceName),
1398 ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME, NwConstants.L3VPN_SERVICE_INDEX),
1399 VpnConstants.DEFAULT_FLOW_PRIORITY, NwConstants.COOKIE_VM_INGRESS_TABLE, instructions);
1403 static BoundServices getBoundServicesForTunnelInterface(String vpnName, String interfaceName) {
1404 int instructionKey = 0;
1405 List<Instruction> instructions = new ArrayList<>();
1406 instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(
1407 NwConstants.L3VNI_EXTERNAL_TUNNEL_DEMUX_TABLE, ++instructionKey));
1408 BoundServices serviceInfo = InterfaceUtils.getBoundServices(String.format("%s.%s.%s", "vpn",
1409 vpnName, interfaceName),
1410 ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME,
1411 NwConstants.L3VNI_EXTERNAL_TUNNEL_DEMUX_TABLE), VpnConstants.DEFAULT_FLOW_PRIORITY,
1412 NwConstants.COOKIE_VM_INGRESS_TABLE, instructions);
1416 void unbindService(final String vpnInterfaceName, boolean isInterfaceStateDown) {
1417 if (!isInterfaceStateDown) {
1418 jobCoordinator.enqueueJob(vpnInterfaceName,
1419 () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
1420 tx.delete(LogicalDatastoreType.CONFIGURATION,
1421 InterfaceUtils.buildServiceId(vpnInterfaceName,
1422 ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME,
1423 NwConstants.L3VPN_SERVICE_INDEX))))),
1424 SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries());
1428 static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId) {
1429 return new FlowEntityBuilder().setDpnId(dpnId).setTableId(tableId).setFlowId(flowId).build();
1432 static VrfEntryBase.EncapType getEncapType(boolean isVxLan) {
1433 return isVxLan ? VrfEntryBase.EncapType.Vxlan : VrfEntryBase.EncapType.Mplsgre;
1436 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.Subnets
1437 getExternalSubnet(Uuid subnetId) {
1438 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets
1439 .Subnets> subnetsIdentifier = InstanceIdentifier.builder(ExternalSubnets.class)
1440 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets
1441 .Subnets.class, new SubnetsKey(subnetId)).build();
1442 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.Subnets>
1443 optionalSubnets = read(LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
1444 return optionalSubnets.isPresent() ? optionalSubnets.get() : null;
1447 Uuid getSubnetFromExternalRouterByIp(Uuid routerId, String ip) {
1448 Routers externalRouter = getExternalRouter(routerId.getValue());
1449 if (externalRouter != null && externalRouter.getExternalIps() != null) {
1450 for (ExternalIps externalIp : externalRouter.getExternalIps()) {
1451 if (externalIp.getIpAddress().equals(ip)) {
1452 return externalIp.getSubnetId();
1459 static boolean isExternalSubnetVpn(String vpnName, String subnetId) {
1460 return vpnName.equals(subnetId);
1463 static Boolean getIsExternal(Network network) {
1464 return network.augmentation(NetworkL3Extension.class) != null
1465 && network.augmentation(NetworkL3Extension.class).isExternal();
1468 @SuppressWarnings("checkstyle:linelength")
1469 Network getNeutronNetwork(Uuid networkId) {
1470 Network network = null;
1471 LOG.debug("getNeutronNetwork for {}", networkId.getValue());
1472 InstanceIdentifier<Network> inst = InstanceIdentifier.create(Neutron.class).child(
1473 org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.Networks.class).child(
1474 Network.class, new NetworkKey(networkId));
1475 Optional<Network> net = read(LogicalDatastoreType.CONFIGURATION, inst);
1476 if (net.isPresent()) {
1477 network = net.get();
1482 public static boolean isEligibleForBgp(String rd, String vpnName, BigInteger dpnId, String networkName) {
1484 if (vpnName != null && rd.equals(vpnName)) {
1487 if (dpnId != null && rd.equals(dpnId.toString())) {
1490 if (networkName != null && rd.equals(networkName)) {
1498 static String getFibFlowRef(BigInteger dpnId, short tableId, String vpnName, int priority) {
1499 return VpnConstants.FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId
1500 + NwConstants.FLOWID_SEPARATOR + vpnName + NwConstants.FLOWID_SEPARATOR + priority;
1503 void removeExternalTunnelDemuxFlows(String vpnName) {
1504 LOG.info("Removing external tunnel flows for vpn {}", vpnName);
1505 for (BigInteger dpnId: NWUtil.getOperativeDPNs(dataBroker)) {
1506 LOG.debug("Removing external tunnel flows for vpn {} from dpn {}", vpnName, dpnId);
1507 String flowRef = getFibFlowRef(dpnId, NwConstants.L3VNI_EXTERNAL_TUNNEL_DEMUX_TABLE,
1508 vpnName, VpnConstants.DEFAULT_FLOW_PRIORITY);
1509 FlowEntity flowEntity = VpnUtil.buildFlowEntity(dpnId,
1510 NwConstants.L3VNI_EXTERNAL_TUNNEL_DEMUX_TABLE, flowRef);
1511 mdsalManager.removeFlow(flowEntity);
1515 public boolean isVpnPendingDelete(String rd) {
1516 VpnInstanceOpDataEntry vpnInstanceOpData = getVpnInstanceOpData(rd);
1517 boolean isVpnPendingDelete = false;
1518 if (vpnInstanceOpData == null
1519 || vpnInstanceOpData.getVpnState() == VpnInstanceOpDataEntry.VpnState.PendingDelete) {
1520 isVpnPendingDelete = true;
1522 return isVpnPendingDelete;
1525 public List<VpnInstanceOpDataEntry> getVpnsImportingMyRoute(final String vpnName) {
1526 List<VpnInstanceOpDataEntry> vpnsToImportRoute = new ArrayList<>();
1527 final String vpnRd = getVpnRd(vpnName);
1528 if (vpnRd == null) {
1529 LOG.error("getVpnsImportingMyRoute: vpn {} not present in config DS.", vpnName);
1530 return vpnsToImportRoute;
1532 final VpnInstanceOpDataEntry vpnInstanceOpDataEntry = getVpnInstanceOpData(vpnRd);
1533 if (vpnInstanceOpDataEntry == null) {
1534 LOG.error("getVpnsImportingMyRoute: Could not retrieve vpn instance op data for {}"
1535 + " to check for vpns importing the routes", vpnName);
1536 return vpnsToImportRoute;
1538 Predicate<VpnInstanceOpDataEntry> excludeVpn = input -> {
1539 if (input.getVpnInstanceName() == null) {
1540 LOG.error("getVpnsImportingMyRoute.excludeVpn: Received vpn instance with rd {} without a name.",
1544 return !input.getVpnInstanceName().equals(vpnName);
1546 Predicate<VpnInstanceOpDataEntry> matchRTs = input -> {
1547 Iterable<String> commonRTs =
1548 intersection(getRts(vpnInstanceOpDataEntry, VpnTarget.VrfRTType.ExportExtcommunity),
1549 getRts(input, VpnTarget.VrfRTType.ImportExtcommunity));
1550 return Iterators.size(commonRTs.iterator()) > 0;
1552 vpnsToImportRoute = getAllVpnInstanceOpData().stream().filter(excludeVpn).filter(matchRTs)
1553 .collect(Collectors.toList());
1554 return vpnsToImportRoute;
1557 static List<String> getRts(VpnInstanceOpDataEntry vpnInstance, VpnTarget.VrfRTType rtType) {
1558 String name = vpnInstance.getVpnInstanceName();
1559 List<String> rts = new ArrayList<>();
1560 VpnTargets targets = vpnInstance.getVpnTargets();
1561 if (targets == null) {
1562 LOG.info("getRts: vpn targets not available for {}", name);
1565 List<VpnTarget> vpnTargets = targets.getVpnTarget();
1566 if (vpnTargets == null) {
1567 LOG.info("getRts: vpnTarget values not available for {}", name);
1570 for (VpnTarget target : vpnTargets) {
1571 //TODO: Check for RT type is Both
1572 if (target.getVrfRTType().equals(rtType) || target.getVrfRTType().equals(VpnTarget.VrfRTType.Both)) {
1573 String rtValue = target.getVrfRTValue();
1580 static <T> Iterable<T> intersection(final Collection<T> collection1, final Collection<T> collection2) {
1581 Set<T> intersection = new HashSet<>(collection1);
1582 intersection.retainAll(collection2);
1583 return intersection;
1586 /** Get Subnetmap from its Uuid.
1587 * @param subnetUuid the subnet's Uuid
1588 * @return the Subnetmap of Uuid or null if it is not found
1590 Subnetmap getSubnetmapFromItsUuid(Uuid subnetUuid) {
1591 Subnetmap sn = null;
1592 InstanceIdentifier<Subnetmap> id = buildSubnetmapIdentifier(subnetUuid);
1593 Optional<Subnetmap> optionalSn = read(LogicalDatastoreType.CONFIGURATION, id);
1594 if (optionalSn.isPresent()) {
1595 sn = optionalSn.get();
1600 boolean isAdjacencyEligibleToVpnInternet(Adjacency adjacency) {
1601 // returns true if BGPVPN Internet and adjacency is IPv6, false otherwise
1602 boolean adjacencyEligible = true;
1603 if (adjacency.getAdjacencyType() == AdjacencyType.ExtraRoute) {
1604 if (FibHelper.isIpv6Prefix(adjacency.getIpAddress())) {
1605 return adjacencyEligible;
1608 } else if (adjacency.getSubnetId() == null) {
1609 return adjacencyEligible;
1611 Subnetmap sn = getSubnetmapFromItsUuid(adjacency.getSubnetId());
1612 if (sn != null && sn.getInternetVpnId() != null) {
1613 adjacencyEligible = false;
1615 return adjacencyEligible;
1618 boolean isAdjacencyEligibleToVpn(Adjacency adjacency, String vpnName) {
1619 // returns true if BGPVPN Internet and adjacency is IPv6, false otherwise
1620 boolean adjacencyEligible = true;
1621 // if BGPVPN internet, return false if subnetmap has not internetVpnId() filled in
1622 if (isBgpVpnInternet(vpnName)) {
1623 return isAdjacencyEligibleToVpnInternet(adjacency);
1625 return adjacencyEligible;
1628 String getInternetVpnFromVpnInstanceList(List<VpnInstanceNames> vpnInstanceList) {
1629 for (VpnInstanceNames vpnInstance : vpnInstanceList) {
1630 String vpnName = vpnInstance.getVpnName();
1631 if (isBgpVpnInternet(vpnName)) {
1638 /** Get boolean true if vpn is bgpvpn internet, false otherwise.
1639 * @param vpnName name of the input VPN
1640 * @return true or false
1642 boolean isBgpVpnInternet(String vpnName) {
1643 String primaryRd = getVpnRd(vpnName);
1644 if (primaryRd == null) {
1645 LOG.error("isBgpVpnInternet VPN {}."
1646 + "Primary RD not found", vpnName);
1649 InstanceIdentifier<VpnInstanceOpDataEntry> id = InstanceIdentifier.builder(VpnInstanceOpData.class)
1650 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(primaryRd)).build();
1652 Optional<VpnInstanceOpDataEntry> vpnInstanceOpDataEntryOptional = read(LogicalDatastoreType.OPERATIONAL, id);
1653 if (!vpnInstanceOpDataEntryOptional.isPresent()) {
1654 LOG.error("isBgpVpnInternet VPN {}."
1655 + "VpnInstanceOpDataEntry not found", vpnName);
1658 LOG.debug("isBgpVpnInternet VPN {}."
1659 + "Successfully VpnInstanceOpDataEntry.getBgpvpnType {}",
1660 vpnName, vpnInstanceOpDataEntryOptional.get().getBgpvpnType());
1661 if (vpnInstanceOpDataEntryOptional.get().getBgpvpnType() == VpnInstanceOpDataEntry
1662 .BgpvpnType.BGPVPNInternet) {
1668 /**Get IpVersionChoice from String IP like x.x.x.x or an representation IPv6.
1669 * @param ipAddress String of an representation IP address V4 or V6
1670 * @return the IpVersionChoice of the version or IpVersionChoice.UNDEFINED otherwise
1672 public static IpVersionChoice getIpVersionFromString(String ipAddress) {
1673 IpVersionChoice ipchoice = IpVersionChoice.UNDEFINED;
1674 int indexIpAddress = ipAddress.indexOf('/');
1675 if (indexIpAddress >= 0) {
1676 ipAddress = ipAddress.substring(0, indexIpAddress);
1679 InetAddress address = InetAddress.getByName(ipAddress);
1680 if (address instanceof Inet4Address) {
1681 return IpVersionChoice.IPV4;
1682 } else if (address instanceof Inet6Address) {
1683 return IpVersionChoice.IPV6;
1685 } catch (UnknownHostException | SecurityException e) {
1686 ipchoice = IpVersionChoice.UNDEFINED;
1691 ListenableFuture<Void> unsetScheduledToRemoveForVpnInterface(String interfaceName) {
1692 VpnInterfaceBuilder builder = new VpnInterfaceBuilder().withKey(new VpnInterfaceKey(interfaceName))
1693 .setScheduledForRemove(false);
1694 return txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> tx.merge(LogicalDatastoreType.OPERATIONAL,
1695 VpnUtil.getVpnInterfaceIdentifier(interfaceName), builder.build(),
1696 WriteTransaction.CREATE_MISSING_PARENTS));
1700 * Adds router port for all elan network of type VLAN which is a part of vpnName in the DPN with dpnId.
1701 * This will create the vlan footprint in the DPN's which are member of the VPN.
1703 * @param vpnName the vpnName
1704 * @param dpnId the DPN id
1706 void addRouterPortToElanForVlanInDpn(String vpnName, BigInteger dpnId) {
1707 Map<String,String> elanInstanceRouterPortMap = getElanInstanceRouterPortMap(vpnName);
1708 for (Entry<String, String> elanInstanceRouterEntry : elanInstanceRouterPortMap.entrySet()) {
1709 addRouterPortToElanDpn(elanInstanceRouterEntry.getKey(), elanInstanceRouterEntry.getValue(), dpnId);
1714 * Removes router port for all elan network of type VLAN which is a part of vpnName in the DPN with dpnId.
1715 * This will remove the vlan footprint in all the DPN's which are member of the VPN.
1717 * @param vpnName the vpn name
1718 * @param dpnId the DPN id
1720 void removeRouterPortFromElanForVlanInDpn(String vpnName, BigInteger dpnId) {
1721 Map<String,String> elanInstanceRouterPortMap = getElanInstanceRouterPortMap(vpnName);
1722 for (Entry<String, String> elanInstanceRouterEntry : elanInstanceRouterPortMap.entrySet()) {
1723 removeRouterPortFromElanDpn(elanInstanceRouterEntry.getKey(), elanInstanceRouterEntry.getValue(),
1729 * Adds router port for all elan network of type VLAN which is a part of vpnName in all the DPN which has a port
1730 * This will create the vlan footprint in all the DPN's which are member of the VPN.
1732 * @param vpnName the vpn name
1734 void addRouterPortToElanDpnListForVlaninAllDpn(String vpnName) {
1735 Map<String,String> elanInstanceRouterPortMap = getElanInstanceRouterPortMap(vpnName);
1736 Set<BigInteger> dpnList = getDpnInElan(elanInstanceRouterPortMap);
1737 for (BigInteger dpnId : dpnList) {
1738 for (Entry<String, String> elanInstanceRouterEntry : elanInstanceRouterPortMap.entrySet()) {
1739 addRouterPortToElanDpn(elanInstanceRouterEntry.getKey(), elanInstanceRouterEntry.getValue(), dpnId);
1744 /**Removes router port for all elan network of type VLAN which is a part of vpnName in all the DPN which has a port
1745 * This will remove the vlan footprint in all the DPN's which are member of the VPN.
1747 * @param routerInterfacePortId this will add the current subnet router port id to the map for removal
1748 * @param elanInstanceName the current elanstance being removed this will be added to map for removal
1749 * @param vpnName the vpn name
1751 void removeRouterPortFromElanDpnListForVlanInAllDpn(String elanInstanceName,
1752 String routerInterfacePortId, String vpnName) {
1753 Map<String,String> elanInstanceRouterPortMap = getElanInstanceRouterPortMap(vpnName);
1754 elanInstanceRouterPortMap.put(elanInstanceName, routerInterfacePortId);
1755 Set<BigInteger> dpnList = getDpnInElan(elanInstanceRouterPortMap);
1756 for (BigInteger dpnId : dpnList) {
1757 for (Entry<String, String> elanInstanceRouterEntry : elanInstanceRouterPortMap.entrySet()) {
1758 removeRouterPortFromElanDpn(elanInstanceRouterEntry.getKey(), elanInstanceRouterEntry.getValue(),
1765 Set<BigInteger> getDpnInElan(Map<String,String> elanInstanceRouterPortMap) {
1766 Set<BigInteger> dpnIdSet = new HashSet<>();
1767 for (String elanInstanceName : elanInstanceRouterPortMap.keySet()) {
1768 InstanceIdentifier<ElanDpnInterfacesList> elanDpnInterfaceId = getElanDpnOperationalDataPath(
1770 Optional<ElanDpnInterfacesList> dpnInElanInterfaces = read(LogicalDatastoreType.OPERATIONAL,
1771 elanDpnInterfaceId);
1772 if (dpnInElanInterfaces.isPresent()) {
1773 List<DpnInterfaces> dpnInterfaces = dpnInElanInterfaces.get().getDpnInterfaces();
1774 for (DpnInterfaces dpnInterface : dpnInterfaces) {
1775 dpnIdSet.add(dpnInterface.getDpId());
1782 void addRouterPortToElanDpn(String elanInstanceName, String routerInterfacePortId, BigInteger dpnId) {
1783 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
1784 elanInstanceName,dpnId);
1785 synchronized (elanInstanceName.intern()) {
1786 Optional<DpnInterfaces> dpnInElanInterfaces = read(LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
1787 List<String> elanInterfaceList;
1788 DpnInterfaces dpnInterface;
1789 if (!dpnInElanInterfaces.isPresent()) {
1790 elanInterfaceList = new ArrayList<>();
1792 dpnInterface = dpnInElanInterfaces.get();
1793 elanInterfaceList = dpnInterface.getInterfaces();
1795 if (!elanInterfaceList.contains(routerInterfacePortId)) {
1796 elanInterfaceList.add(routerInterfacePortId);
1797 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
1798 .withKey(new DpnInterfacesKey(dpnId)).build();
1799 syncWrite(LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId, dpnInterface);
1805 void removeRouterPortFromElanDpn(String elanInstanceName, String routerInterfacePortId,
1806 String vpnName, BigInteger dpnId) {
1807 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
1808 elanInstanceName,dpnId);
1809 synchronized (elanInstanceName.intern()) {
1810 Optional<DpnInterfaces> dpnInElanInterfaces = read(LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
1811 List<String> elanInterfaceList;
1812 DpnInterfaces dpnInterface;
1813 if (!dpnInElanInterfaces.isPresent()) {
1814 LOG.info("No interface in any dpn for {}", vpnName);
1817 dpnInterface = dpnInElanInterfaces.get();
1818 elanInterfaceList = dpnInterface.getInterfaces();
1820 if (!elanInterfaceList.contains(routerInterfacePortId)) {
1821 LOG.info("Router port not present in DPN {} for VPN {}", dpnId, vpnName);
1824 elanInterfaceList.remove(routerInterfacePortId);
1825 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
1826 .withKey(new DpnInterfacesKey(dpnId)).build();
1827 syncWrite(LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId, dpnInterface);
1832 ElanInterface getElanInterfaceByElanInterfaceName(String elanInterfaceName) {
1833 InstanceIdentifier<ElanInterface> elanInterfaceId = getElanInterfaceConfigurationDataPathId(elanInterfaceName);
1834 return read(LogicalDatastoreType.CONFIGURATION, elanInterfaceId).orNull();
1837 static InstanceIdentifier<ElanInterface> getElanInterfaceConfigurationDataPathId(String interfaceName) {
1838 return InstanceIdentifier.builder(ElanInterfaces.class)
1839 .child(ElanInterface.class, new ElanInterfaceKey(interfaceName)).build();
1842 DpnInterfaces getElanInterfaceInfoByElanDpn(String elanInstanceName, BigInteger dpId) {
1843 InstanceIdentifier<DpnInterfaces> elanDpnInterfacesId = getElanDpnInterfaceOperationalDataPath(elanInstanceName,
1845 return read(LogicalDatastoreType.OPERATIONAL, elanDpnInterfacesId).orNull();
1848 String getExternalElanInterface(String elanInstanceName, BigInteger dpnId) {
1849 DpnInterfaces dpnInterfaces = getElanInterfaceInfoByElanDpn(elanInstanceName, dpnId);
1850 if (dpnInterfaces == null || dpnInterfaces.getInterfaces() == null) {
1851 LOG.info("Elan {} does not have interfaces in DPN {}", elanInstanceName, dpnId);
1855 for (String dpnInterface : dpnInterfaces.getInterfaces()) {
1856 if (interfaceManager.isExternalInterface(dpnInterface)) {
1857 return dpnInterface;
1863 static boolean isVlan(ElanInstance elanInstance) {
1864 return elanInstance != null && elanInstance.getSegmentType() != null
1865 && elanInstance.getSegmentType().isAssignableFrom(SegmentTypeVlan.class)
1866 && elanInstance.getSegmentationId() != null && elanInstance.getSegmentationId() != 0;
1869 boolean isVlan(String interfaceName) {
1870 ElanInterface elanInterface = getElanInterfaceByElanInterfaceName(interfaceName);
1871 if (elanInterface == null) {
1874 ElanInstance elanInstance = getElanInstanceByName(elanInterface.getElanInstanceName());
1875 return isVlan(elanInstance);
1878 ElanInstance getElanInstanceByName(String elanInstanceName) {
1879 InstanceIdentifier<ElanInstance> elanIdentifierId =
1880 ElanHelper.getElanInstanceConfigurationDataPath(elanInstanceName);
1881 return read(LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
1884 String getVpnNameFromElanIntanceName(String elanInstanceName) {
1885 Optional<Subnetmaps> subnetMapsData = read(LogicalDatastoreType.CONFIGURATION, buildSubnetMapsWildCardPath());
1886 if (subnetMapsData.isPresent()) {
1887 List<Subnetmap> subnetMapList = subnetMapsData.get().getSubnetmap();
1888 if (subnetMapList != null && !subnetMapList.isEmpty()) {
1889 for (Subnetmap subnet : subnetMapList) {
1890 if (subnet.getNetworkId().getValue().equals(elanInstanceName)) {
1891 if (subnet.getVpnId() != null) {
1892 return subnet.getVpnId().getValue();
1901 Map<String, String> getElanInstanceRouterPortMap(String vpnName) {
1902 Map<String, String> elanInstanceRouterPortMap = new HashMap<>();
1903 Optional<Subnetmaps> subnetMapsData = read(LogicalDatastoreType.CONFIGURATION, buildSubnetMapsWildCardPath());
1904 if (subnetMapsData.isPresent()) {
1905 List<Subnetmap> subnetMapList = subnetMapsData.get().getSubnetmap();
1906 if (subnetMapList != null && !subnetMapList.isEmpty()) {
1907 for (Subnetmap subnet : subnetMapList) {
1908 if (subnet.getVpnId() != null && subnet.getVpnId().getValue().equals(vpnName)
1909 && subnet.getNetworkType().equals(NetworkType.VLAN)) {
1910 if (subnet.getRouterInterfacePortId() == null || subnet.getNetworkId() == null) {
1911 LOG.warn("The RouterInterfacePortId or NetworkId is null");
1914 String routerInterfacePortUuid = subnet.getRouterInterfacePortId().getValue();
1915 if (routerInterfacePortUuid != null && !routerInterfacePortUuid.isEmpty()) {
1916 elanInstanceRouterPortMap.put(subnet.getNetworkId().getValue(),routerInterfacePortUuid);
1922 return elanInstanceRouterPortMap;
1925 String getRouterPordIdFromElanInstance(String elanInstanceName) {
1926 Optional<Subnetmaps> subnetMapsData = read(LogicalDatastoreType.CONFIGURATION, buildSubnetMapsWildCardPath());
1927 if (subnetMapsData.isPresent()) {
1928 List<Subnetmap> subnetMapList = subnetMapsData.get().getSubnetmap();
1929 if (subnetMapList != null && !subnetMapList.isEmpty()) {
1930 for (Subnetmap subnet : subnetMapList) {
1931 if (subnet.getNetworkId().getValue().equals(elanInstanceName)) {
1932 if (subnet.getRouterInterfacePortId() != null) {
1933 return subnet.getRouterInterfacePortId().getValue();
1942 boolean shouldPopulateFibForVlan(String vpnName, String elanInstanceName, BigInteger dpnId) {
1943 Map<String,String> elanInstanceRouterPortMap = getElanInstanceRouterPortMap(vpnName);
1944 boolean shouldPopulateFibForVlan = false;
1945 if (!elanInstanceRouterPortMap.isEmpty()) {
1946 shouldPopulateFibForVlan = true;
1948 for (Entry<String, String> elanInstanceRouterEntry : elanInstanceRouterPortMap
1950 String currentElanInstance = elanInstanceRouterEntry.getKey();
1951 if (elanInstanceName != null && elanInstanceName.equals(currentElanInstance)) {
1954 String externalinterface = getExternalElanInterface(currentElanInstance ,dpnId);
1955 if (externalinterface == null) {
1956 shouldPopulateFibForVlan = false;
1960 return shouldPopulateFibForVlan;
1963 public static InstanceIdentifier<DpnInterfaces> getElanDpnInterfaceOperationalDataPath(String elanInstanceName,
1965 return InstanceIdentifier.builder(ElanDpnInterfaces.class)
1966 .child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName))
1967 .child(DpnInterfaces.class, new DpnInterfacesKey(dpId)).build();
1970 public static InstanceIdentifier<ElanDpnInterfacesList> getElanDpnOperationalDataPath(String elanInstanceName) {
1971 return InstanceIdentifier.builder(ElanDpnInterfaces.class)
1972 .child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName))
1976 public static boolean isMatchedPrefixToInterface(Prefixes prefix, VpnInterfaceOpDataEntry vpnInterface) {
1977 if (prefix != null && vpnInterface != null) {
1978 if (prefix.getDpnId() != null && vpnInterface.getDpnId() != null) {
1979 if (prefix.getVpnInterfaceName() != null && vpnInterface.getName() != null) {
1980 return prefix.getDpnId().equals(vpnInterface.getDpnId())
1981 && prefix.getVpnInterfaceName().equalsIgnoreCase(vpnInterface.getName());
1988 void removePrefixToInterfaceAdj(Adjacency adj, long vpnId, VpnInterfaceOpDataEntry vpnInterfaceOpDataEntry,
1989 WriteTransaction writeOperTxn) {
1990 if (writeOperTxn == null) {
1991 ListenableFutures.addErrorLogging(
1992 txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx ->
1993 removePrefixToInterfaceAdj(adj, vpnId, vpnInterfaceOpDataEntry, tx)), LOG,
1994 "Error removing prefix");
1998 Optional<Prefixes> prefix = read(LogicalDatastoreType.OPERATIONAL,
1999 VpnUtil.getPrefixToInterfaceIdentifier(vpnId, VpnUtil.getIpPrefix(adj.getIpAddress())));
2000 List<Prefixes> prefixToInterface = new ArrayList<>();
2001 List<Prefixes> prefixToInterfaceLocal = new ArrayList<>();
2002 if (prefix.isPresent()) {
2003 prefixToInterfaceLocal.add(prefix.get());
2005 if (prefixToInterfaceLocal.isEmpty()) {
2006 for (String nh : adj.getNextHopIpList()) {
2007 prefix = read(LogicalDatastoreType.OPERATIONAL, VpnUtil.getPrefixToInterfaceIdentifier(vpnId,
2008 VpnUtil.getIpPrefix(nh)));
2009 if (prefix.isPresent()) {
2010 prefixToInterfaceLocal.add(prefix.get());
2014 if (!prefixToInterfaceLocal.isEmpty()) {
2015 prefixToInterface.addAll(prefixToInterfaceLocal);
2017 for (Prefixes pref : prefixToInterface) {
2018 if (VpnUtil.isMatchedPrefixToInterface(pref, vpnInterfaceOpDataEntry)) {
2019 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL,
2020 VpnUtil.getPrefixToInterfaceIdentifier(vpnId, pref.getIpAddress()));
2025 public static void sendNeighborSolicationToOfGroup(Ipv6NdUtilService ipv6NdUtilService, Ipv6Address srcIpv6Address,
2026 MacAddress srcMac, Ipv6Address dstIpv6Address, Long ofGroupId, BigInteger dpId) {
2027 SendNeighborSolicitationToOfGroupInput input = new SendNeighborSolicitationToOfGroupInputBuilder()
2028 .setSourceIpv6(srcIpv6Address).setSourceLlAddress(srcMac).setTargetIpAddress(dstIpv6Address)
2029 .setOfGroupId(ofGroupId).setDpId(dpId).build();
2031 Future<RpcResult<SendNeighborSolicitationToOfGroupOutput>> result = ipv6NdUtilService
2032 .sendNeighborSolicitationToOfGroup(input);
2033 RpcResult<SendNeighborSolicitationToOfGroupOutput> rpcResult = result.get();
2034 if (!rpcResult.isSuccessful()) {
2035 LOG.error("sendNeighborSolicitationToOfGroup: RPC Call failed for input={} and Errors={}", input,
2036 rpcResult.getErrors());
2038 } catch (InterruptedException | ExecutionException e) {
2039 LOG.error("Failed to send NS packet to ELAN group, input={}", input, e);
2043 Set<org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTarget>
2044 getRtListForVpn(String vpnName) {
2045 Set<org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets
2046 .VpnTarget> rtList = new HashSet<>();
2047 InstanceIdentifier<VpnInstance> vpnInstanceId = InstanceIdentifier.builder(VpnInstances.class)
2048 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
2049 Optional<VpnInstance> vpnInstanceOptional = read(LogicalDatastoreType.CONFIGURATION, vpnInstanceId);
2050 if (vpnInstanceOptional.isPresent()) {
2051 org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargets
2052 vpnTargets = vpnInstanceOptional.get().getIpv4Family().getVpnTargets();
2053 if (vpnTargets != null && vpnTargets.getVpnTarget() != null) {
2054 rtList.addAll(vpnTargets.getVpnTarget());
2058 LOG.error("getRtListForVpn: Vpn Instance {} not present in config DS", vpnName);
2063 static InstanceIdentifier<AssociatedVpn> getAssociatedSubnetAndVpnIdentifier(String rt, RouteTarget.RtType rtType,
2064 String cidr, String vpnName) {
2065 return InstanceIdentifier.builder(SubnetsAssociatedToRouteTargets.class).child(RouteTarget.class,
2066 new RouteTargetKey(rt, rtType)).child(AssociatedSubnet.class, new AssociatedSubnetKey(cidr))
2067 .child(AssociatedVpn.class, new AssociatedVpnKey(vpnName)).build();
2070 static InstanceIdentifier<AssociatedSubnet> getAssociatedSubnetIdentifier(String rt, RouteTarget.RtType rtType,
2072 return InstanceIdentifier.builder(SubnetsAssociatedToRouteTargets.class).child(RouteTarget.class,
2073 new RouteTargetKey(rt, rtType)).child(AssociatedSubnet.class, new AssociatedSubnetKey(cidr)).build();
2076 static AssociatedVpn buildAssociatedSubnetAndVpn(String vpnName) {
2077 return new AssociatedVpnBuilder().setName(vpnName).build();
2080 static InstanceIdentifier<RouteTarget> getRouteTargetsIdentifier(String rt, RouteTarget.RtType rtType) {
2081 return InstanceIdentifier.builder(SubnetsAssociatedToRouteTargets.class)
2082 .child(RouteTarget.class, new RouteTargetKey(rt, rtType)).build();
2085 Set<RouteTarget> getRouteTargetSet(Set<org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815
2086 .vpn.af.config.vpntargets.VpnTarget> vpnTargets) {
2087 Set<RouteTarget> routeTargetSet = new HashSet<>();
2088 for (org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets
2089 .VpnTarget rt : vpnTargets) {
2090 String rtValue = rt.getVrfRTValue();
2091 switch (rt.getVrfRTType()) {
2092 case ImportExtcommunity: {
2093 Optional<RouteTarget> exportRouteTargetOptional = read(LogicalDatastoreType.OPERATIONAL,
2094 getRouteTargetsIdentifier(rtValue, RouteTarget.RtType.ERT));
2095 if (exportRouteTargetOptional.isPresent()) {
2096 routeTargetSet.add(exportRouteTargetOptional.get());
2100 case ExportExtcommunity: {
2101 Optional<RouteTarget> importRouteTargetOptional = read(LogicalDatastoreType.OPERATIONAL,
2102 getRouteTargetsIdentifier(rtValue, RouteTarget.RtType.IRT));
2103 if (importRouteTargetOptional.isPresent()) {
2104 routeTargetSet.add(importRouteTargetOptional.get());
2109 Optional<RouteTarget> exportRouteTargetOptional = read(LogicalDatastoreType.OPERATIONAL,
2110 getRouteTargetsIdentifier(rtValue, RouteTarget.RtType.ERT));
2111 if (exportRouteTargetOptional.isPresent()) {
2112 routeTargetSet.add(exportRouteTargetOptional.get());
2114 Optional<RouteTarget> importRouteTargetOptional = read(LogicalDatastoreType.OPERATIONAL,
2115 getRouteTargetsIdentifier(rtValue, RouteTarget.RtType.IRT));
2116 if (importRouteTargetOptional.isPresent()) {
2117 routeTargetSet.add(importRouteTargetOptional.get());
2122 LOG.error("getRouteTargetSet: Invalid rt-type {}", rt.getVrfRTType());
2125 return routeTargetSet;
2129 TODO: (vivek/kiran): Subnet overlap in a VPN detection logic should use subnet allocation pools if available
2130 rather than only CIDR.
2131 Also the Subnet overlap in a VPN detection logic to be addressed for router-based-l3vpns.
2133 static boolean areSubnetsOverlapping(String cidr1, String cidr2) {
2134 String[] ipaddressValues1 = cidr1.split("/");
2135 int address1 = InetAddresses.coerceToInteger(InetAddresses.forString(ipaddressValues1[0]));
2136 int cidrPart1 = Integer.parseInt(ipaddressValues1[1]);
2137 String[] ipaddressValues2 = cidr2.split("/");
2138 int address2 = InetAddresses.coerceToInteger(InetAddresses.forString(ipaddressValues2[0]));
2139 int cidrPart2 = Integer.parseInt(ipaddressValues2[1]);
2140 int comparedValue = 0;
2142 if (cidrPart1 <= cidrPart2) {
2143 for (int j = 0; j < cidrPart1; ++j) {
2144 netmask |= (1 << 31 - j);
2146 int prefix = address2 & netmask;
2147 comparedValue = address1 ^ prefix;
2149 for (int j = 0; j < cidrPart2; ++j) {
2150 netmask |= (1 << 31 - j);
2152 int prefix = address1 & netmask;
2153 comparedValue = address2 ^ prefix;
2155 if (comparedValue == 0) {