2 * Copyright (c) 2017 Cisco Systems. 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.groupbasedpolicy.renderer.vpp.lisp.util;
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.iface.VppPathMapper;
18 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.LispState;
19 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.LispStateManager;
20 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.exception.LispNotFoundException;
21 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.GbpNetconfTransaction;
22 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.LispUtil;
23 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;
24 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.EthernetCsmacd;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface2;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.Ipv4;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces.state._interface.ipv4.Address;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.Ipv4Afi;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.network.containment.Containment;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.network.containment.containment.NetworkDomainContainment;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.LocationType;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCase;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpoint;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.ExternalLocation;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.IpPrefixType;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.MacAddressType;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.ParentEndpointChoice;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.ParentEndpointCase;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpoint;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.L3Context;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.HmacKeyType;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.dp.subtable.grouping.local.mappings.local.mapping.Eid;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev170315.hmac.key.grouping.HmacKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.interfaces._interface.Routing;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.interfaces._interface.RoutingBuilder;
56 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
57 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
58 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
59 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
60 import org.slf4j.Logger;
61 import org.slf4j.LoggerFactory;
63 import javax.annotation.Nonnull;
64 import java.util.List;
70 * Created by Shakib Ahmed on 3/31/17.
72 public class ConfigManagerHelper {
73 private static final Logger LOG = LoggerFactory.getLogger(ConfigManagerHelper.class);
75 private static final String TENANT_INTERFACE = "tenant-interface";
76 private MountedDataBrokerProvider mountedDataBrokerProvider;
78 public ConfigManagerHelper(MountedDataBrokerProvider mountedDataBrokerProvider) {
79 this.mountedDataBrokerProvider = mountedDataBrokerProvider;
82 public Optional<DataBroker> getPotentialExternalDataBroker(AddressEndpointWithLocation addressEpWithLoc) {
83 ExternalLocationCase externalLocationCase = resolveAndValidateLocation(addressEpWithLoc);
84 InstanceIdentifier<?> vppNodeIid = externalLocationCase.getExternalNodeMountPoint();
85 String interfacePath = externalLocationCase.getExternalNodeConnector();
87 Optional<DataBroker> potentialVppDataProvider = mountedDataBrokerProvider.getDataBrokerForMountPoint(vppNodeIid);
89 Preconditions.checkArgument(potentialVppDataProvider.isPresent(),
90 "Cannot resolve data broker for interface path: {}", interfacePath);
92 return potentialVppDataProvider;
95 public Optional<DataBroker> getPotentialExternalDataBroker(ExternalLocation externalLocation) {
96 InstanceIdentifier<?> vppNodeIid = externalLocation.getExternalNodeMountPoint();
98 Optional<DataBroker> potentialVppDataProvider;
99 potentialVppDataProvider = mountedDataBrokerProvider.getDataBrokerForMountPoint(vppNodeIid);
101 Preconditions.checkState(potentialVppDataProvider.isPresent(), "Data Broker missing");
103 return potentialVppDataProvider;
106 public Optional<DataBroker> getPotentialExternalDataBroker(VppEndpoint vppEp) {
107 InstanceIdentifier<Node> vppNodeIid = VppIidFactory.getNetconfNodeIid(vppEp.getVppNodeId());
108 Optional<DataBroker> potentialVppDataProvider =
109 mountedDataBrokerProvider.getDataBrokerForMountPoint(vppNodeIid);
111 Preconditions.checkArgument(potentialVppDataProvider.isPresent(),
112 "Cannot resolve data broker for Vpp Endpoint: {}", vppEp);
113 return potentialVppDataProvider;
116 public Optional<DataBroker> getPotentialExternalDataBroker(String hostId) {
117 InstanceIdentifier<Node> nodeIid = VppIidFactory.getNetconfNodeIid(new NodeId(hostId));
118 Optional<DataBroker> potentialVppDataProvider = mountedDataBrokerProvider.getDataBrokerForMountPoint(nodeIid);
119 Preconditions.checkArgument(potentialVppDataProvider.isPresent(),
120 "Data Broker not found for {}", hostId);
121 return potentialVppDataProvider;
124 public Optional<String> getHostName(AddressEndpointWithLocation addrEp) {
125 ExternalLocationCase locationCase = resolveAndValidateLocation(addrEp);
126 NodeKey nodeKey = locationCase.getExternalNodeMountPoint().firstKeyOf(Node.class);
127 String hostId = Preconditions.checkNotNull(nodeKey.getNodeId().getValue(),
128 "Host Id extraction failed from address endpoint: {}", addrEp);
129 return Optional.fromNullable(hostId);
132 public Optional<String> getHostName(ExternalLocation externalLocation) {
133 NodeKey nodeKey = externalLocation.getExternalNodeMountPoint().firstKeyOf(Node.class);
134 String hostId = Preconditions.checkNotNull(nodeKey.getNodeId().getValue(),
135 "Host Id extraction failed from address endpoint: {}", externalLocation);
137 return Optional.fromNullable(hostId);
140 public ExternalLocationCase resolveAndValidateLocation(AddressEndpointWithLocation addrEpWithLoc) {
141 Preconditions.checkNotNull(addrEpWithLoc.getAbsoluteLocation(), "Absolute location for " +
142 "AddressEndpointWithLocation missing: " + addrEpWithLoc.toString() );
143 LocationType locationType = addrEpWithLoc.getAbsoluteLocation().getLocationType();
144 if (!(locationType instanceof ExternalLocationCase)) {
145 throw new IllegalArgumentException("Endpoint does not have external location " + addrEpWithLoc);
147 ExternalLocationCase result = (ExternalLocationCase) locationType;
148 if (result.getExternalNodeMountPoint() == null || result.getExternalNodeConnector() == null) {
149 throw new IllegalArgumentException(
150 "Endpoint does not have external-node-mount-point or external-node-connector " + addrEpWithLoc);
155 //This is almost identical to VBD's equivalent method
156 public ListenableFuture<String> readRlocInterface(@Nonnull String hostName, @Nonnull DataBroker vppDataBroker) {
157 Preconditions.checkNotNull(hostName, "Hostname is null!");
158 Preconditions.checkNotNull(vppDataBroker, "Vpp DataBroker is null!");
159 final Optional<InterfacesState> opInterfaceState = GbpNetconfTransaction.read(vppDataBroker,
160 LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(InterfacesState.class),
161 GbpNetconfTransaction.RETRY_COUNT);
163 if (!opInterfaceState.isPresent()) {
164 LOG.debug("There appear to be no interfaces on node {}.", hostName);
165 return Futures.immediateFailedFuture(new LispNotFoundException("No interfaces found"));
168 String interfaceName = null;
169 for(Interface intf: opInterfaceState.get().getInterface()) {
170 if(!ipAddressPresent(intf)) {
173 interfaceName = intf.getName();
176 final Optional<Interfaces> opInterfaces =
177 GbpNetconfTransaction.read(vppDataBroker, LogicalDatastoreType.CONFIGURATION,
178 InstanceIdentifier.create(Interfaces.class), GbpNetconfTransaction.RETRY_COUNT);
181 if (opInterfaces.isPresent()) {
182 for (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.
183 interfaces.Interface intf : opInterfaces.get().getInterface()) {
184 if (TENANT_INTERFACE.equals(intf.getDescription())
185 && ipAddressPresent(intf)
186 && intf.getType().equals(EthernetCsmacd.class)) {
187 return Futures.immediateFuture(intf.getName());
192 if (interfaceName == null) {
193 LOG.warn("No interface with IP found for host {}", hostName);
194 return Futures.immediateFailedFuture(new LispNotFoundException("No interface with Ip address found!"));
196 return Futures.immediateFuture(interfaceName);
199 private boolean ipAddressPresent(Interface intf) {
200 Interface2 augIntf = intf.getAugmentation(Interface2.class);
202 if (augIntf == null) {
206 Ipv4 ipv4 = augIntf.getIpv4();
212 final List<Address> addresses = ipv4.getAddress();
214 if (addresses == null || addresses.isEmpty()) {
218 final Ipv4AddressNoZone ip = addresses.iterator().next().getIp();
222 private boolean ipAddressPresent(final org.opendaylight.yang.gen.v1.urn.ietf.
223 params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface intf) {
224 final Interface1 augIntf = intf.getAugmentation(Interface1.class);
226 if (augIntf == null) {
227 LOG.debug("Cannot get Interface1 augmentation for intf {}", intf);
231 final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4 ipv4 =
237 final List<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address> addresses =
239 if (addresses == null || addresses.isEmpty()) {
243 final Ipv4AddressNoZone ip = addresses.iterator().next().getIp();
247 public String constructLocatorSetName(int locatorSetCount) {
248 return LispStateManager.DEFAULT_LOCATOR_SET_NAME_PREFIX + (locatorSetCount + 1);
251 public String constructMappingName(int presentMappingCount) {
252 return LispStateManager.DEFAULT_MAPPINGRECORD_NAME_PREFIX + (presentMappingCount + 1);
255 public String getSubnet(AddressEndpointWithLocation addressEp) {
256 String subnetUuid = null;
257 Containment containment = addressEp.getNetworkContainment().getContainment();
258 if (containment instanceof NetworkDomainContainment) {
259 NetworkDomainContainment networkDomainContainment = (NetworkDomainContainment) containment;
260 subnetUuid = networkDomainContainment.getNetworkDomainId().getValue();
265 public Eid getEid(AddressEndpointWithLocation addressEp, long vni) {
266 String ipPrefix = getIpWithPrefixOfEndpoint(addressEp);
267 return LispUtil.toEid(LispUtil.toIpv4(ipPrefix), vni, Ipv4Afi.class);
270 public String getIpWithPrefixOfEndpoint(AddressEndpointWithLocation addressEp) {
271 String ipPrefix = null;
272 if (addressEp.getAddressType().equals(IpPrefixType.class)) {
273 ipPrefix = addressEp.getAddress();
274 } else if (addressEp.getAddressType().equals(MacAddressType.class)) {
275 ParentEndpointChoice parentEndpointChoice = addressEp.getParentEndpointChoice();
276 if (parentEndpointChoice instanceof ParentEndpointCase) {
277 java.util.Optional<ParentEndpoint> endpointOptional =
278 ((ParentEndpointCase) parentEndpointChoice).getParentEndpoint().stream()
279 .filter(choice -> choice.getAddressType().equals(IpPrefixType.class))
280 .filter(choice -> choice.getContextType().equals(L3Context.class)).findFirst();
281 if (endpointOptional.isPresent()) {
282 ipPrefix = endpointOptional.get().getAddress();
286 return Preconditions.checkNotNull(ipPrefix, "No IP address found for Address Endpoint: {}", addressEp);
289 public Ipv4Address getInterfaceIp(AddressEndpointWithLocation addressEp) {
290 String ipPrefix = getIpWithPrefixOfEndpoint(addressEp);
291 return LispUtil.toIpv4(ipPrefix).getIpv4();
294 public Ipv4Prefix getInterfaceIpAsPrefix(AddressEndpointWithLocation addressEp) {
295 if (getInterfaceIp(addressEp).getValue().contains("/")) {
296 return new Ipv4Prefix(getInterfaceIp(addressEp).getValue());
299 return new Ipv4Prefix(getInterfaceIp(addressEp).getValue() + "/32");
303 public String getFirstLocatorSetName(LispState lispState) {
304 Set<Map.Entry<String, String >> locatorSet = lispState.getLocatorSetEntry();
305 Preconditions.checkNotNull(locatorSet, "No locator set found!");
306 if (!locatorSet.iterator().hasNext()) {
310 return locatorSet.iterator().next().getValue();
313 public Optional<String> getInterfaceName(AddressEndpointWithLocation addedEp) {
314 ExternalLocationCase epLoc = resolveAndValidateLocation(addedEp);
315 String interfacePath = epLoc.getExternalNodeConnector();
317 return VppPathMapper.interfacePathToInterfaceName(interfacePath);
320 public Optional<String> getInterfaceName(ExternalLocation externalLocation) {
321 String interfacePath = externalLocation.getExternalNodeConnector();
322 return VppPathMapper.interfacePathToInterfaceName(interfacePath);
325 public HmacKey getDefaultHmacKey() {
326 return LispUtil.toHmacKey(HmacKeyType.Sha196Key, LispStateManager.DEFAULT_XTR_KEY);
329 public String getPhysicalAddress(AddressEndpointWithLocation addressEp) {
330 String physicalAddress = null;
332 if (addressEp.getAddressType().equals(MacAddressType.class)) {
333 physicalAddress = addressEp.getAddress();
335 List<ChildEndpoint> childEndpoints = addressEp.getChildEndpoint();
336 for (ChildEndpoint childEndpoint : childEndpoints) {
337 if (childEndpoint.getAddressType().equals(MacAddressType.class)) {
338 physicalAddress = childEndpoint.getAddress();
343 return Preconditions.checkNotNull(physicalAddress, "Physical address not found " +
344 "in address endpoint: " + addressEp);
347 public boolean isMetadataPort(AddressEndpointWithLocation addedEp) {
348 return addedEp.getRelativeLocations() != null && addedEp.getRelativeLocations().getExternalLocation() != null;
351 public Routing getRouting(long vrf) {
352 return new RoutingBuilder().setIpv4VrfId(vrf).build();