91d9c6edd9b48a014a6628a7f7050eebc24df659
[groupbasedpolicy.git] / renderers / vpp / src / main / java / org / opendaylight / groupbasedpolicy / renderer / vpp / lisp / flat / overlay / FlatOverlayManager.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.flat.overlay;
10
11
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.groupbasedpolicy.renderer.vpp.commands.StaticArpCommand;
16 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.mappers.HostVrfRoutingInformationMapper;
17 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.mappers.NeutronTenantToVniMapper;
18 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.util.ConfigManagerHelper;
19 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.GbpNetconfTransaction;
20 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General;
21 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;
22 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.interfaces._interface.Routing;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170607.interfaces._interface.RoutingBuilder;
31 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 import javax.annotation.Nonnull;
36
37 /**
38  * Created by Shakib Ahmed on 5/2/17.
39  */
40 public class FlatOverlayManager {
41     private static final Logger LOG = LoggerFactory.getLogger(FlatOverlayManager.class);
42
43     private ConfigManagerHelper overlayHelper;
44
45     private NeutronTenantToVniMapper neutronTenantToVniMapper = NeutronTenantToVniMapper.getInstance();
46     private HostVrfRoutingInformationMapper hostVrfInfo = HostVrfRoutingInformationMapper.getInstance();
47
48     private StaticRoutingHelper staticRoutingHelper;
49
50     public FlatOverlayManager(@Nonnull MountedDataBrokerProvider mountedDataBrokerProvider) {
51         this.overlayHelper = new ConfigManagerHelper(mountedDataBrokerProvider);
52         staticRoutingHelper = new StaticRoutingHelper();
53     }
54
55     public void configureEndpointForFlatOverlay(AddressEndpointWithLocation addressEp) {
56         configureInterfaceForFlatOverlay(addressEp);
57         addStaticArp(addressEp);
58         addStaticRoute(addressEp);
59     }
60
61     public void handleEndpointDeleteForFlatOverlay(AddressEndpointWithLocation addressEp) {
62         deleteStaticRoute(addressEp);
63     }
64
65     private void configureInterfaceForFlatOverlay(AddressEndpointWithLocation addressEp) {
66         addInterfaceInVrf(addressEp);
67     }
68
69     private void addInterfaceInVrf(AddressEndpointWithLocation addressEp) {
70         DataBroker vppDataBroker = overlayHelper.getPotentialExternalDataBroker(addressEp).get();
71         long vni = getVni(addressEp.getTenant().getValue());
72         long vrf = vni;
73         Optional<String> interfaceNameOptional = overlayHelper.getInterfaceName(addressEp);
74
75         Preconditions.checkArgument(interfaceNameOptional.isPresent());
76
77         if (!putVrfInInterface(vppDataBroker, interfaceNameOptional.get(), vrf)) {
78             LOG.warn("Failed to put interface {} to vrf {}", interfaceNameOptional.get(), vrf);
79         } else {
80             LOG.debug("Added interface {} to vrf {}", interfaceNameOptional.get(), vrf);
81         }
82     }
83
84     private boolean putVrfInInterface(DataBroker vppDataBroker,
85                                   String interfaceName,
86                                   Long vrf) {
87         InstanceIdentifier<Routing> iid = VppIidFactory.getRoutingIid(new InterfaceKey(interfaceName));
88         RoutingBuilder builder = new RoutingBuilder();
89         builder.setIpv4VrfId(vrf);
90         return GbpNetconfTransaction.netconfSyncedWrite(vppDataBroker, iid, builder.build(), GbpNetconfTransaction.RETRY_COUNT);
91     }
92
93     private void addStaticArp(AddressEndpointWithLocation addressEp) {
94         DataBroker vppDataBroker = overlayHelper.getPotentialExternalDataBroker(addressEp).get();
95         String hostName = overlayHelper.getHostName(addressEp).get();
96         String physicalAddress = overlayHelper.getPhysicalAddress(addressEp);
97         Optional<String> interfaceNameOptional = overlayHelper.getInterfaceName(addressEp);
98
99         Preconditions.checkArgument(interfaceNameOptional.isPresent());
100
101         String interfaceName = interfaceNameOptional.get();
102         InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
103
104         Ipv4AddressNoZone ip = new Ipv4AddressNoZone(overlayHelper.getInterfaceIp(addressEp));
105
106         if (!putIpv4Neighbor(vppDataBroker, interfaceKey, new PhysAddress(physicalAddress), ip)) {
107             LOG.warn("Failed to put static arp with interface {} for ip={} and physical-address={}", interfaceName,
108                     ip, physicalAddress);
109         } else {
110             LOG.debug("Added Static arp ({} {}) in host {} for interface {}", ip, physicalAddress, hostName,
111                     interfaceName);
112         }
113     }
114
115     private boolean putIpv4Neighbor(DataBroker vppDataBroker,
116                                  InterfaceKey interfaceKey,
117                                  PhysAddress physAddress,
118                                  Ipv4AddressNoZone ip) {
119         StaticArpCommand.NeighborCommandBuilder neighborCommandBuilder = new StaticArpCommand.NeighborCommandBuilder();
120
121         neighborCommandBuilder.setOperation(General.Operations.PUT);
122         neighborCommandBuilder.setInterfaceKey(interfaceKey);
123         neighborCommandBuilder.setIp(ip);
124         neighborCommandBuilder.setLinkLayerAddress(physAddress);
125
126         return GbpNetconfTransaction.netconfSyncedWrite(vppDataBroker,
127                 neighborCommandBuilder.build(), GbpNetconfTransaction.RETRY_COUNT);
128     }
129
130     private void addStaticRoute(AddressEndpointWithLocation addressEp) {
131         DataBroker vppDataBroker = overlayHelper.getPotentialExternalDataBroker(addressEp).get();
132         String hostName = overlayHelper.getHostName(addressEp).get();
133
134         long vni = getVni(addressEp.getTenant().getValue());
135         long vrf = vni;
136
137         if (!hostVrfInfo.vrfExists(hostName, vrf)) {
138             if (!staticRoutingHelper.addRoutingProtocolForVrf(vppDataBroker, hostName, vrf)) {
139                 LOG.warn("Failed to add Routing protocol for host {} and vrf {}!", hostName, vrf);
140             }
141         }
142
143         String outgoingInterfaceName = overlayHelper.getInterfaceName(addressEp).get();
144         Ipv4Address ipWithoutPrefix = overlayHelper.getInterfaceIp(addressEp);
145
146         if (staticRoutingHelper.endPointRoutingExists(outgoingInterfaceName, ipWithoutPrefix)) {
147             return;
148         }
149
150         Ipv4Prefix ipv4Prefix = overlayHelper.getInterfaceIpAsPrefix(addressEp);
151
152         if (!staticRoutingHelper.addSingleStaticRouteInRoutingProtocol(vppDataBroker,
153                                                                   hostName,
154                                                                   vrf,
155                                                                   ipWithoutPrefix,
156                                                                   ipv4Prefix,
157                                                                   outgoingInterfaceName)) {
158             LOG.warn("Failed to add routing ({} via {}) in vrf {} in compute host {}!",
159                     ipv4Prefix, outgoingInterfaceName, vrf, hostName);
160         } else {
161             LOG.debug("Added route ({} via {}) in vrf {} in compute host {}",
162                     ipv4Prefix, outgoingInterfaceName, vrf, hostName);
163         }
164     }
165
166     private void deleteStaticRoute(AddressEndpointWithLocation addressEp) {
167         DataBroker vppDataBroker = overlayHelper.getPotentialExternalDataBroker(addressEp).get();
168         String hostName = overlayHelper.getHostName(addressEp).get();
169         String interfaceName = overlayHelper.getInterfaceName(addressEp).get();
170
171         long vni = getVni(addressEp.getTenant().getValue());
172         long vrf = vni;
173
174         Ipv4Address ipWithoutPrefix = overlayHelper.getInterfaceIp(addressEp);
175
176         if (!staticRoutingHelper.deleteSingleStaticRouteFromRoutingProtocol(vppDataBroker,
177                                                                        hostName,
178                                                                        vrf,
179                                                                        interfaceName)) {
180             LOG.warn("Failed to delete route ({} via {}) from vrf {} from host{}",
181                     ipWithoutPrefix, interfaceName, vrf, hostName);
182
183         } else {
184             LOG.debug("Delete Static Route ({} via {}) from vrf {} from host {}",
185                     ipWithoutPrefix, interfaceName, vrf, hostName);
186         }
187     }
188
189     private long getVni(String tenantUuid) {
190         return neutronTenantToVniMapper.getVni(tenantUuid);
191     }
192 }