Fix ODL itr rloc for supporting LISP CP over admin
[groupbasedpolicy.git] / renderers / vpp / src / main / java / org / opendaylight / groupbasedpolicy / renderer / vpp / lisp / util / ConfigManagerHelper.java
1 /*
2  * Copyright (c) 2017 Cisco Systems. All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.util;
10
11 import com.google.common.base.Optional;
12 import com.google.common.base.Preconditions;
13 import com.google.common.util.concurrent.Futures;
14 import com.google.common.util.concurrent.ListenableFuture;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.groupbasedpolicy.renderer.vpp.config.ConfigUtil;
18 import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.VppPathMapper;
19 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.EndpointHost;
20 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.HostRelatedInfoContainer;
21 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.LispState;
22 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.LispStateManager;
23 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.exception.LispNotFoundException;
24 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.PhysicalInterfaces;
25 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.GbpNetconfTransaction;
26 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.InterfaceUtil;
27 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.LispUtil;
28 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;
29 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.EthernetCsmacd;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface2;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.Address;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.address.subnet.PrefixLength;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.Ipv4Afi;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.network.containment.Containment;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.network.containment.containment.NetworkDomainContainment;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.LocationType;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCase;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpoint;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.ExternalLocation;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.IpPrefixType;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.MacAddressType;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.ParentEndpointChoice;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.ParentEndpointCase;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpoint;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.L3Context;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.HmacKeyType;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.dp.subtable.grouping.local.mappings.local.mapping.Eid;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.hmac.key.grouping.HmacKey;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.interfaces._interface.Routing;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.interfaces._interface.RoutingBuilder;
62 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
63 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
64 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
65 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
66 import org.slf4j.Logger;
67 import org.slf4j.LoggerFactory;
68
69 import javax.annotation.Nonnull;
70 import java.util.List;
71 import java.util.Map;
72 import java.util.Set;
73
74
75 /**
76  * Created by Shakib Ahmed on 3/31/17.
77  */
78 public class ConfigManagerHelper {
79     private static final Logger LOG = LoggerFactory.getLogger(ConfigManagerHelper.class);
80
81     private MountedDataBrokerProvider mountedDataBrokerProvider;
82
83     public ConfigManagerHelper(MountedDataBrokerProvider mountedDataBrokerProvider) {
84         this.mountedDataBrokerProvider = mountedDataBrokerProvider;
85     }
86
87     public EndpointHost getEndpointHostInformation(AddressEndpointWithLocation addressEpWithLoc) {
88         DataBroker endpointHostDataBroker = getPotentialExternalDataBroker(addressEpWithLoc).get();
89         String hostName = getHostName(addressEpWithLoc).get();
90         return new EndpointHost(endpointHostDataBroker, hostName);
91     }
92
93     public Optional<DataBroker> getPotentialExternalDataBroker(AddressEndpointWithLocation addressEpWithLoc) {
94         ExternalLocationCase externalLocationCase = resolveAndValidateLocation(addressEpWithLoc);
95         InstanceIdentifier<?> vppNodeIid = externalLocationCase.getExternalNodeMountPoint();
96         String interfacePath = externalLocationCase.getExternalNodeConnector();
97
98         Optional<DataBroker>
99                 potentialVppDataProvider = mountedDataBrokerProvider.getDataBrokerForMountPoint(vppNodeIid);
100
101         Preconditions.checkArgument(potentialVppDataProvider.isPresent(),
102                 "Cannot resolve data broker for interface path: {}", interfacePath);
103
104         return potentialVppDataProvider;
105     }
106
107     public Optional<DataBroker> getPotentialExternalDataBroker(ExternalLocation externalLocation) {
108         InstanceIdentifier<?> vppNodeIid = externalLocation.getExternalNodeMountPoint();
109
110         Optional<DataBroker> potentialVppDataProvider;
111         potentialVppDataProvider = mountedDataBrokerProvider.getDataBrokerForMountPoint(vppNodeIid);
112
113         Preconditions.checkState(potentialVppDataProvider.isPresent(), "Data Broker missing");
114
115         return potentialVppDataProvider;
116     }
117
118     public Optional<DataBroker> getPotentialExternalDataBroker(VppEndpoint vppEp) {
119         InstanceIdentifier<Node> vppNodeIid = VppIidFactory.getNetconfNodeIid(vppEp.getVppNodeId());
120         Optional<DataBroker> potentialVppDataProvider =
121                 mountedDataBrokerProvider.getDataBrokerForMountPoint(vppNodeIid);
122
123         Preconditions.checkArgument(potentialVppDataProvider.isPresent(),
124                 "Cannot resolve data broker for Vpp Endpoint: {}", vppEp);
125         return potentialVppDataProvider;
126     }
127
128     public Optional<DataBroker> getPotentialExternalDataBroker(String hostId) {
129         InstanceIdentifier<Node> nodeIid = VppIidFactory.getNetconfNodeIid(new NodeId(hostId));
130         Optional<DataBroker> potentialVppDataProvider = mountedDataBrokerProvider.getDataBrokerForMountPoint(nodeIid);
131         Preconditions.checkArgument(potentialVppDataProvider.isPresent(),
132                 "Data Broker not found for {}", hostId);
133         return potentialVppDataProvider;
134     }
135
136     public Optional<String> getHostName(AddressEndpointWithLocation addrEp) {
137         ExternalLocationCase locationCase = resolveAndValidateLocation(addrEp);
138         NodeKey nodeKey = locationCase.getExternalNodeMountPoint().firstKeyOf(Node.class);
139         String hostId = Preconditions.checkNotNull(nodeKey.getNodeId().getValue(),
140                 "Host Id extraction failed from address endpoint: {}", addrEp);
141         return Optional.fromNullable(hostId);
142     }
143
144     public Optional<String> getHostName(ExternalLocation externalLocation) {
145         NodeKey nodeKey = externalLocation.getExternalNodeMountPoint().firstKeyOf(Node.class);
146         String hostId = Preconditions.checkNotNull(nodeKey.getNodeId().getValue(),
147                 "Host Id extraction failed from address endpoint: {}", externalLocation);
148
149         return Optional.fromNullable(hostId);
150     }
151
152     public ExternalLocationCase resolveAndValidateLocation(AddressEndpointWithLocation addrEpWithLoc) {
153         Preconditions.checkNotNull(addrEpWithLoc.getAbsoluteLocation(), "Absolute location for " +
154                 "AddressEndpointWithLocation missing: " + addrEpWithLoc.toString() );
155         LocationType locationType = addrEpWithLoc.getAbsoluteLocation().getLocationType();
156         if (!(locationType instanceof ExternalLocationCase)) {
157             throw new IllegalArgumentException("Endpoint does not have external location " + addrEpWithLoc);
158         }
159         ExternalLocationCase result = (ExternalLocationCase) locationType;
160         if (result.getExternalNodeMountPoint() == null || result.getExternalNodeConnector() == null) {
161             throw new IllegalArgumentException(
162                     "Endpoint does not have external-node-mount-point or external-node-connector " + addrEpWithLoc);
163         }
164         return result;
165     }
166
167     //This is almost identical to VBD's equivalent method
168     public ListenableFuture<String> getLispDataRlocInterfaceName(@Nonnull String hostName,
169                                                                  @Nonnull DataBroker vppDataBroker) {
170         Preconditions.checkNotNull(hostName, "Hostname is null!");
171         Preconditions.checkNotNull(vppDataBroker, "Vpp DataBroker is null!");
172
173         PhysicalInterfaces physicalInterfaces = HostRelatedInfoContainer.getInstance()
174                 .getPhysicalInterfaceState(hostName);
175
176         String publicInterfaceName = physicalInterfaces == null ? "" : physicalInterfaces
177                 .getName(PhysicalInterfaces.PhysicalInterfaceType.PUBLIC);
178
179         final Optional<InterfacesState> opInterfaceState = GbpNetconfTransaction.read(vppDataBroker,
180                 LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(InterfacesState.class),
181                 GbpNetconfTransaction.RETRY_COUNT);
182
183         if (!opInterfaceState.isPresent()) {
184             LOG.debug("There appear to be no interfaces on node {}.", hostName);
185             return Futures.immediateFailedFuture(new LispNotFoundException("No interfaces found"));
186         }
187
188         String interfaceName = null;
189         for(Interface intf: opInterfaceState.get().getInterface()) {
190             if(!ipAddressPresent(intf)) {
191                 continue;
192             }
193             interfaceName = intf.getName();
194         }
195
196         final Optional<Interfaces> opInterfaces =
197                 GbpNetconfTransaction.read(vppDataBroker, LogicalDatastoreType.CONFIGURATION,
198                         InstanceIdentifier.create(Interfaces.class), GbpNetconfTransaction.RETRY_COUNT);
199
200
201         if (opInterfaces.isPresent()) {
202
203             List<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.
204                     interfaces.Interface> hostInterfaceFromOpDS = opInterfaces.get().getInterface();
205
206             for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.
207                     interfaces.Interface intf : hostInterfaceFromOpDS) {
208                 if (Constants.TENANT_INTERFACE.equals(intf.getDescription())
209                         && ipAddressPresent(intf)
210                         && intf.getType().equals(EthernetCsmacd.class)) {
211                     return Futures.immediateFuture(intf.getName());
212                 }
213             }
214
215             for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.
216                     interfaces.Interface intf : hostInterfaceFromOpDS) {
217                 if (ipAddressPresent(intf)
218                         && intf.getType().equals(EthernetCsmacd.class)
219                         && !intf.getName().equalsIgnoreCase(publicInterfaceName)) {
220                     return Futures.immediateFuture(intf.getName());
221                 }
222             }
223         }
224
225         if (interfaceName == null) {
226             LOG.warn("No interface with IP found for host {}", hostName);
227             return Futures.immediateFailedFuture(new LispNotFoundException("No interface with Ip address found!"));
228         }
229         return Futures.immediateFuture(interfaceName);
230     }
231
232     private boolean ipAddressPresent(Interface intf) {
233         Interface2 augIntf = intf.getAugmentation(Interface2.class);
234
235         if (augIntf == null) {
236             return false;
237         }
238
239         Ipv4 ipv4 = augIntf.getIpv4();
240
241         if (ipv4 == null) {
242             return false;
243         }
244
245         final List<Address> addresses = ipv4.getAddress();
246
247         if (addresses == null || addresses.isEmpty()) {
248             return false;
249         }
250
251         final Ipv4AddressNoZone ip = addresses.iterator().next().getIp();
252         return ip != null;
253     }
254
255     private String ipCidr(Interface intf) {
256         Interface2 augIntf = intf.getAugmentation(Interface2.class);
257
258         if (augIntf == null) {
259             return null;
260         }
261
262         Ipv4 ipv4 = augIntf.getIpv4();
263
264         if (ipv4 == null) {
265             return null;
266         }
267
268         final List<Address> addresses = ipv4.getAddress();
269
270         if (addresses == null || addresses.isEmpty()) {
271             return null;
272         }
273
274         Address firstAddress = addresses.get(0);
275         String ipString = firstAddress.getIp().getValue();
276         String length = "";
277         if (firstAddress.getSubnet().getImplementedInterface().equals(PrefixLength.class)) {
278             length = "" + ((PrefixLength)firstAddress.getSubnet()).getPrefixLength();
279         }
280
281         if (length.isEmpty()) {
282             return null;
283         }
284
285         return ipString + "/" + length;
286     }
287
288     private boolean ipAddressPresent(final org.opendaylight.yang.gen.v1.urn.ietf.
289             params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface intf) {
290         final Interface1 augIntf = intf.getAugmentation(Interface1.class);
291
292         if (augIntf == null) {
293             LOG.debug("Cannot get Interface1 augmentation for intf {}", intf);
294             return false;
295         }
296
297         final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4 ipv4 =
298                 augIntf.getIpv4();
299         if (ipv4 == null) {
300             return false;
301         }
302
303         final List<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address> addresses =
304                 ipv4.getAddress();
305         if (addresses == null || addresses.isEmpty()) {
306             return false;
307         }
308
309         final Ipv4AddressNoZone ip = addresses.iterator().next().getIp();
310         return ip != null;
311     }
312
313     public String getLispCpRlocInterfaceName(@Nonnull DataBroker vppDataBroker) {
314         List<Interface> operationalInterfaceList = InterfaceUtil.getOperationalInterfaces(vppDataBroker);
315
316         if (operationalInterfaceList == null) {
317             return null;
318         } else {
319             int maxLen = -1;
320             String outgoingInterface = "";
321
322             for (Interface intf : operationalInterfaceList) {
323                 String ipCidr = ipCidr(intf);
324
325                 if (ipCidr == null) {
326                     continue;
327                 }
328
329                 if (IpAddressUtil.ipInRange(ConfigUtil.getInstance().getOdlIp().getIpv4Address(),
330                         IpAddressUtil.startIpOfSubnet(ipCidr), IpAddressUtil.endIpOfSubnet(ipCidr))) {
331                     int tmpLen = IpAddressUtil.maskLen(ipCidr);
332                     if (tmpLen > maxLen) {
333                         maxLen = tmpLen;
334                         outgoingInterface = intf.getName();
335                     }
336                 }
337             }
338             return outgoingInterface;
339         }
340     }
341
342     public String constructLocatorSetName(int locatorSetCount) {
343         return LispStateManager.DEFAULT_LOCATOR_SET_NAME_PREFIX + (locatorSetCount + 1);
344     }
345
346     public String constructLocatorSetNameForItrRloc() {
347         return LispStateManager.DEFAULT_LOCATOR_SET_NAME_PREFIX + "_itr_rloc";
348     }
349
350     public String constructEidMappingName(AddressEndpointWithLocation addressEp) {
351         String interfaceName = getInterfaceName(addressEp).get();
352         String ipAddress = getInterfaceIp(addressEp).getValue();
353         return LispStateManager.DEFAULT_MAPPINGRECORD_NAME_PREFIX + interfaceName + "_" + ipAddress;
354     }
355
356     public String getSubnet(AddressEndpointWithLocation addressEp) {
357         String subnetUuid = null;
358         Containment containment = addressEp.getNetworkContainment().getContainment();
359         if (containment instanceof NetworkDomainContainment) {
360             NetworkDomainContainment networkDomainContainment = (NetworkDomainContainment) containment;
361             subnetUuid = networkDomainContainment.getNetworkDomainId().getValue();
362         }
363         return subnetUuid;
364     }
365
366     public Eid getEid(AddressEndpointWithLocation addressEp, long vni) {
367         String ipPrefix = getIpWithPrefixOfEndpoint(addressEp);
368         return LispUtil.toEid(LispUtil.toIpv4(ipPrefix), vni, Ipv4Afi.class);
369     }
370
371     public String getIpWithPrefixOfEndpoint(AddressEndpointWithLocation addressEp) {
372         String ipPrefix = null;
373         if (addressEp.getAddressType().equals(IpPrefixType.class)) {
374             ipPrefix = addressEp.getAddress();
375         } else if (addressEp.getAddressType().equals(MacAddressType.class)) {
376             ParentEndpointChoice parentEndpointChoice = addressEp.getParentEndpointChoice();
377             if (parentEndpointChoice instanceof ParentEndpointCase) {
378                 java.util.Optional<ParentEndpoint> endpointOptional =
379                     ((ParentEndpointCase) parentEndpointChoice).getParentEndpoint().stream()
380                         .filter(choice -> choice.getAddressType().equals(IpPrefixType.class))
381                         .filter(choice -> choice.getContextType().equals(L3Context.class)).findFirst();
382                 if (endpointOptional.isPresent()) {
383                     ipPrefix = endpointOptional.get().getAddress();
384                 }
385             }
386         }
387         return Preconditions.checkNotNull(ipPrefix, "No IP address found for Address Endpoint: {}", addressEp);
388     }
389
390     public Ipv4Address getInterfaceIp(AddressEndpointWithLocation addressEp) {
391         String ipPrefix = getIpWithPrefixOfEndpoint(addressEp);
392         return LispUtil.toIpv4(ipPrefix).getIpv4();
393     }
394
395     public Ipv4Prefix getInterfaceIpAsPrefix(AddressEndpointWithLocation addressEp) {
396         if (getInterfaceIp(addressEp).getValue().contains("/")) {
397             return new Ipv4Prefix(getInterfaceIp(addressEp).getValue());
398         }
399         else {
400             return new Ipv4Prefix(getInterfaceIp(addressEp).getValue() + "/32");
401         }
402     }
403
404     public String getFirstLocatorSetName(LispState lispState) {
405         Set<Map.Entry<String, String >> locatorSet = lispState.getLocatorSetEntry();
406         Preconditions.checkNotNull(locatorSet, "No locator set found!");
407         if (!locatorSet.iterator().hasNext()) {
408             return null;
409         }
410
411         return locatorSet.iterator().next().getValue();
412     }
413
414     public Optional<String> getInterfaceName(AddressEndpointWithLocation addedEp) {
415         ExternalLocationCase epLoc = resolveAndValidateLocation(addedEp);
416         String interfacePath = epLoc.getExternalNodeConnector();
417
418         return VppPathMapper.interfacePathToInterfaceName(interfacePath);
419     }
420
421     public Optional<String> getInterfaceName(ExternalLocation externalLocation) {
422         String interfacePath = externalLocation.getExternalNodeConnector();
423         return VppPathMapper.interfacePathToInterfaceName(interfacePath);
424     }
425
426     public HmacKey getDefaultHmacKey() {
427         return LispUtil.toHmacKey(HmacKeyType.Sha196Key, LispStateManager.DEFAULT_XTR_KEY);
428     }
429
430     public String getPhysicalAddress(AddressEndpointWithLocation addressEp) {
431         String physicalAddress = null;
432
433         if (addressEp.getAddressType().equals(MacAddressType.class)) {
434             physicalAddress = addressEp.getAddress();
435         } else {
436             List<ChildEndpoint> childEndpoints = addressEp.getChildEndpoint();
437             for (ChildEndpoint childEndpoint : childEndpoints) {
438                 if (childEndpoint.getAddressType().equals(MacAddressType.class)) {
439                     physicalAddress = childEndpoint.getAddress();
440                     break;
441                 }
442             }
443         }
444         return Preconditions.checkNotNull(physicalAddress, "Physical address not found " +
445                 "in address endpoint: " + addressEp);
446     }
447
448     public boolean hasRelativeLocations(AddressEndpointWithLocation addedEp) {
449         return addedEp.getRelativeLocations() != null && addedEp.getRelativeLocations().getExternalLocation() != null;
450     }
451
452     public boolean isMetadataPort(AddressEndpointWithLocation addressEp) {
453         return hasRelativeLocations(addressEp) || IpAddressUtil.isMetadataIp(getInterfaceIp(addressEp));
454     }
455
456     public String getGatewayInterfaceName(String gwNamePrefix, String subnetUuid) {
457         return gwNamePrefix + subnetUuid;
458     }
459
460     public Routing getRouting(long vrf) {
461         return new RoutingBuilder().setIpv4VrfId(vrf).build();
462     }
463 }