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.flat.overlay;
12 import com.google.common.base.Optional;
13 import com.google.common.base.Preconditions;
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.StaticArpCommand;
17 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.mappers.HostIdToMetadataInterfaceMapper;
18 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.mappers.HostVrfRoutingInformationMapper;
19 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.mappers.InterfaceNameToStaticInfoMapper;
20 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.mappers.NeutronTenantToVniMapper;
21 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.util.ConfigManagerHelper;
22 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.GbpNetconfTransaction;
23 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General;
24 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;
25 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;
26 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.Config;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425._interface.attributes._interface.type.choice.TapCase;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.interfaces._interface.Routing;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.interfaces._interface.RoutingBuilder;
38 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
42 import javax.annotation.Nonnull;
45 * Created by Shakib Ahmed on 5/2/17.
47 public class FlatOverlayManager {
48 private static final Logger LOG = LoggerFactory.getLogger(FlatOverlayManager.class);
50 private ConfigManagerHelper overlayHelper;
51 private DataBroker dataBroker;
53 private NeutronTenantToVniMapper neutronTenantToVniMapper = NeutronTenantToVniMapper.getInstance();
54 private HostVrfRoutingInformationMapper hostVrfInfo = HostVrfRoutingInformationMapper.getInstance();
55 private HostIdToMetadataInterfaceMapper
56 hostIdToMetadataInterfaceMapper = HostIdToMetadataInterfaceMapper.getInstance();
58 private InterfaceNameToStaticInfoMapper interfaceNameToStaticInfoMapper;
60 private StaticRoutingHelper staticRoutingHelper;
62 public FlatOverlayManager(@Nonnull DataBroker dataBroker, @Nonnull MountedDataBrokerProvider mountedDataBrokerProvider) {
63 this.overlayHelper = new ConfigManagerHelper(mountedDataBrokerProvider);
64 this.interfaceNameToStaticInfoMapper = InterfaceNameToStaticInfoMapper.getInstance();
65 staticRoutingHelper = new StaticRoutingHelper(interfaceNameToStaticInfoMapper);
66 this.dataBroker = dataBroker;
69 public void configureEndpointForFlatOverlay(AddressEndpointWithLocation addressEp) {
70 if (!overlayHelper.isMetadataPort(addressEp)) {
71 configureInterfaceForFlatOverlay(addressEp);
72 addStaticArp(addressEp);
73 addStaticRoute(addressEp);
75 Ipv4Address metadataIp = overlayHelper.getInterfaceIp(addressEp);
76 Ipv4Prefix metadataIpPrefix = overlayHelper.getInterfaceIpAsPrefix(addressEp);
77 addressEp.getRelativeLocations().getExternalLocation().forEach(externalLocation -> {
78 String hostName = overlayHelper.getHostName(externalLocation).get();
79 String metadataInterfaceName = overlayHelper.getInterfaceName(externalLocation).get();
81 long vrf = getVni(addressEp.getTenant().getValue());
83 if (!hostIdToMetadataInterfaceMapper.isMetadataInterfaceConfigured(hostName, metadataInterfaceName)) {
84 DataBroker vppDataBroker = overlayHelper.getPotentialExternalDataBroker(externalLocation).get();
85 addInterfaceInVrf(vppDataBroker, metadataInterfaceName, vrf);
86 String physicalAddress = resolvePhysicalAddress(hostName, metadataInterfaceName);
87 addStaticArp(vppDataBroker, hostName, metadataInterfaceName, physicalAddress, metadataIp);
88 addStaticRoute(vppDataBroker, hostName, vrf, metadataIp, metadataIpPrefix, metadataInterfaceName);
89 hostIdToMetadataInterfaceMapper.addMetadataInterfaceInHost(hostName, metadataInterfaceName);
95 private String resolvePhysicalAddress(String hostName, String metadataInterfaceName) {
96 String physAddress = null;
97 Optional<Config> configOptional =
98 DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, VppIidFactory.getVppRendererConfig(),
99 dataBroker.newReadOnlyTransaction());
100 if (configOptional.isPresent() && configOptional.get().getVppEndpoint() != null) {
101 java.util.Optional<VppEndpoint> vppEndpointOptional = configOptional.get().getVppEndpoint().stream()
102 .filter(vppEndpoint -> vppEndpoint.getVppNodeId().getValue().equals(hostName))
103 .filter(vppEndpoint -> vppEndpoint.getVppInterfaceName().equals(metadataInterfaceName))
105 if (vppEndpointOptional.isPresent() && vppEndpointOptional.get()
106 .getInterfaceTypeChoice() instanceof TapCase) {
107 TapCase tapCase = (TapCase) vppEndpointOptional.get().getInterfaceTypeChoice();
108 physAddress = tapCase.getPhysicalAddress().getValue();
109 LOG.trace("Resolved PhysicalAddress : {} for metadataInterfaceName: {}, on node: {}", physAddress
110 , metadataInterfaceName, hostName);
112 LOG.warn("PhysicalAddress was not resolved for metadataInterfaceName: {}, on node: {}",
113 metadataInterfaceName, hostName);
120 public void handleEndpointDeleteForFlatOverlay(AddressEndpointWithLocation addressEp) {
121 deleteStaticRoute(addressEp);
124 private void configureInterfaceForFlatOverlay(AddressEndpointWithLocation addressEp) {
125 addInterfaceInVrf(addressEp);
128 private void addInterfaceInVrf(AddressEndpointWithLocation addressEp) {
129 DataBroker vppDataBroker = overlayHelper.getPotentialExternalDataBroker(addressEp).get();
130 long vni = getVni(addressEp.getTenant().getValue());
132 Optional<String> interfaceNameOptional = overlayHelper.getInterfaceName(addressEp);
134 Preconditions.checkArgument(interfaceNameOptional.isPresent());
136 addInterfaceInVrf(vppDataBroker, interfaceNameOptional.get(), vrf);
139 private void addInterfaceInVrf(DataBroker vppDataBroker, String interfaceName, long vrf) {
140 if (!putVrfInInterface(vppDataBroker, interfaceName, vrf)) {
141 LOG.warn("Failed to put interface {} to vrf {}", interfaceName, vrf);
143 LOG.debug("Added interface {} to vrf {}", interfaceName, vrf);
147 private boolean putVrfInInterface(DataBroker vppDataBroker,
148 String interfaceName,
150 InstanceIdentifier<Routing> iid = VppIidFactory.getRoutingIid(new InterfaceKey(interfaceName));
151 RoutingBuilder builder = new RoutingBuilder();
152 builder.setIpv4VrfId(vrf);
153 return GbpNetconfTransaction.netconfSyncedWrite(vppDataBroker, iid, builder.build(), GbpNetconfTransaction.RETRY_COUNT);
156 private void addStaticArp(AddressEndpointWithLocation addressEp) {
157 DataBroker vppDataBroker = overlayHelper.getPotentialExternalDataBroker(addressEp).get();
158 String hostName = overlayHelper.getHostName(addressEp).get();
159 String physicalAddress = overlayHelper.getPhysicalAddress(addressEp);
160 Optional<String> interfaceNameOptional = overlayHelper.getInterfaceName(addressEp);
162 Preconditions.checkArgument(interfaceNameOptional.isPresent());
164 String interfaceName = interfaceNameOptional.get();
166 addStaticArp(vppDataBroker, hostName, interfaceName, physicalAddress, overlayHelper.getInterfaceIp(addressEp));
169 private void addStaticArp(DataBroker vppDataBroker,
171 String interfaceName,
172 String physicalAddress,
173 Ipv4Address ipv4Address) {
174 Ipv4AddressNoZone ip = new Ipv4AddressNoZone(ipv4Address);
175 InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
176 if (!putStaticArp(vppDataBroker,
178 new PhysAddress(physicalAddress),
180 LOG.warn("Failed to put static arp with interface {} for ip={} and physical-address={}",
181 interfaceName, ip, physicalAddress);
183 LOG.debug("Added Static arp ({} {}) in host {} for interface {}", ip, physicalAddress, hostName,
188 private boolean putStaticArp(DataBroker vppDataBroker,
189 InterfaceKey interfaceKey,
190 PhysAddress physAddress,
191 Ipv4AddressNoZone ip) {
192 StaticArpCommand.StaticArpCommandBuilder staticArpCommandBuilder = new StaticArpCommand.StaticArpCommandBuilder();
194 staticArpCommandBuilder.setOperation(General.Operations.PUT);
195 staticArpCommandBuilder.setInterfaceKey(interfaceKey);
196 staticArpCommandBuilder.setIp(ip);
197 staticArpCommandBuilder.setLinkLayerAddress(physAddress);
199 return GbpNetconfTransaction.netconfSyncedWrite(vppDataBroker,
200 staticArpCommandBuilder.build(), GbpNetconfTransaction.RETRY_COUNT);
203 private void addStaticRoute(AddressEndpointWithLocation addressEp) {
204 DataBroker vppDataBroker = overlayHelper.getPotentialExternalDataBroker(addressEp).get();
205 String hostName = overlayHelper.getHostName(addressEp).get();
207 long vni = getVni(addressEp.getTenant().getValue());
210 String outgoingInterfaceName = overlayHelper.getInterfaceName(addressEp).get();
211 Ipv4Address ipWithoutPrefix = overlayHelper.getInterfaceIp(addressEp);
212 Ipv4Prefix ipv4Prefix = overlayHelper.getInterfaceIpAsPrefix(addressEp);
214 addStaticRoute(vppDataBroker, hostName, vrf, ipWithoutPrefix, ipv4Prefix, outgoingInterfaceName);
217 private void addStaticRoute(DataBroker vppDataBroker, String hostName, long vrf, Ipv4Address ipWithoutPrefix,
218 Ipv4Prefix ipv4Prefix, String outgoingInterfaceName) {
220 if (!hostVrfInfo.vrfExists(hostName, vrf)) {
221 if (!staticRoutingHelper.addRoutingProtocolForVrf(vppDataBroker, hostName, vrf)) {
222 LOG.warn("Failed to add Routing protocol for host {} and vrf {}!", hostName, vrf);
226 if (staticRoutingHelper.endPointRoutingExists(outgoingInterfaceName, ipWithoutPrefix)) {
230 if (staticRoutingHelper.routeAlreadyExistsInHostVrf(hostName, vrf, ipWithoutPrefix)) {
231 LOG.warn("Ip already exists in host {} vrf {} ip {}", hostName, vrf, ipWithoutPrefix);
235 if (!staticRoutingHelper.addSingleStaticRouteInRoutingProtocol(vppDataBroker,
240 outgoingInterfaceName)) {
241 LOG.warn("Failed to add routing ({} via {}) in vrf {} in compute host {}!",
242 ipv4Prefix, outgoingInterfaceName, vrf, hostName);
244 LOG.debug("Added route ({} via {}) in vrf {} in compute host {}",
245 ipv4Prefix, outgoingInterfaceName, vrf, hostName);
249 private void deleteStaticRoute(AddressEndpointWithLocation addressEp) {
250 DataBroker vppDataBroker = overlayHelper.getPotentialExternalDataBroker(addressEp).get();
251 String hostName = overlayHelper.getHostName(addressEp).get();
252 String interfaceName = overlayHelper.getInterfaceName(addressEp).get();
254 long vni = getVni(addressEp.getTenant().getValue());
257 Ipv4Address ipWithoutPrefix = overlayHelper.getInterfaceIp(addressEp);
259 if (!staticRoutingHelper.deleteSingleStaticRouteFromRoutingProtocol(vppDataBroker,
263 LOG.warn("Failed to delete route ({} via {}) from vrf {} from host{}",
264 ipWithoutPrefix, interfaceName, vrf, hostName);
267 LOG.debug("Delete Static Route ({} via {}) from vrf {} from host {}",
268 ipWithoutPrefix, interfaceName, vrf, hostName);
272 private long getVni(String tenantUuid) {
273 return neutronTenantToVniMapper.getVni(tenantUuid);