Fix lisp route for public interfaces
[groupbasedpolicy.git] / renderers / vpp / src / main / java / org / opendaylight / groupbasedpolicy / renderer / vpp / lisp / flat / overlay / StaticRoutingHelper.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 package org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.flat.overlay;
9
10 import com.google.common.base.Preconditions;
11
12 import java.util.Collections;
13 import java.util.List;
14
15 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.HostRelatedInfoContainer;
16 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.PortInterfaces;
17 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.PortRouteState;
18 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.VrfHolder;
19 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.VrfState;
20 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.util.Constants;
21 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.GbpNetconfTransaction;
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.Ipv4Prefix;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev170917.StaticRoutes1;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev170917.routing.routing.instance.routing.protocols.routing.protocol._static.routes.Ipv4;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev170917.routing.routing.instance.routing.protocols.routing.protocol._static.routes.Ipv4Builder;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev170917.routing.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.Route;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev170917.routing.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.RouteBuilder;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev170917.routing.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.RouteKey;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev170917.routing.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.route.next.hop.options.SimpleNextHopBuilder;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev170917.routing.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.route.next.hop.options.TableLookupBuilder;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev170917.routing.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.route.next.hop.options.table.lookup.TableLookupParamsBuilder;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.Static;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.routing.protocols.RoutingProtocol;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.routing.protocols.RoutingProtocolBuilder;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.routing.protocols.RoutingProtocolKey;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.routing.protocols.routing.protocol.StaticRoutes;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev170917.RoutingProtocolVppAttr;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev170917.RoutingProtocolVppAttrBuilder;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev170917.VniReference;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev170917.routing.routing.instance.routing.protocols.routing.protocol.VppProtocolAttributesBuilder;
43 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
44 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
45 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48
49 class StaticRoutingHelper {
50     private static final Logger LOG = LoggerFactory.getLogger(StaticRoutingHelper.class);
51
52     private HostRelatedInfoContainer hostRelatedInfoContainer = HostRelatedInfoContainer.getInstance();
53
54     synchronized boolean addRoutingProtocolForVrf(InstanceIdentifier<Node> nodeIid, long vrfId,
55         VrfHolder vrfHolderOfHost) {
56         String routingProtocolName = getRoutingProtocolName(vrfId);
57         RoutingProtocolBuilder builder = new RoutingProtocolBuilder();
58         builder.setKey(new RoutingProtocolKey(routingProtocolName));
59         builder.setName(routingProtocolName);
60         builder.setType(Static.class);
61         builder.setDescription(Constants.DEFAULT_ROUTING_DESCRIPTION);
62         RoutingProtocolVppAttrBuilder vppAugmentationBuilder = new RoutingProtocolVppAttrBuilder();
63
64         vppAugmentationBuilder.
65                 setVppProtocolAttributes(new VppProtocolAttributesBuilder()
66                                                 .setPrimaryVrf(new VniReference(vrfId)).build());
67
68         builder.addAugmentation(RoutingProtocolVppAttr.class, vppAugmentationBuilder.build());
69
70         InstanceIdentifier<RoutingProtocol> iid = VppIidFactory
71                 .getRoutingInstanceIid(builder.getKey());
72         if (GbpNetconfTransaction.netconfSyncedWrite(nodeIid, iid, builder.build(),
73                 GbpNetconfTransaction.RETRY_COUNT)) {
74             vrfHolderOfHost.initializeVrfState(vrfId, routingProtocolName);
75             return true;
76         }
77
78         return false;
79     }
80
81     synchronized boolean addSingleStaticRouteInRoutingProtocol(String hostName, long portVrfId, String portSubnetUuid,
82         Ipv4Address nextHopAddress, Ipv4Prefix ipPrefix, String outgoingInterface, VniReference secondaryVrf) {
83         RouteBuilder builder = new RouteBuilder();
84
85         VrfState hostVrfStateForPortVrf = hostRelatedInfoContainer
86                                                     .getVrfStateOfHost(hostName)
87                                                     .getVrfState(portVrfId);
88
89         PortInterfaces hostPortInterfaces = hostRelatedInfoContainer
90                                                     .getPortInterfaceStateOfHost(hostName);
91
92         if (!hostPortInterfaces.isRoutingContextForInterfaceInitialized(outgoingInterface)) {
93             hostRelatedInfoContainer.getPortInterfaceStateOfHost(hostName).
94                 initializeRoutingContextForInterface(outgoingInterface, portVrfId);
95         }
96
97         Preconditions.checkNotNull(hostVrfStateForPortVrf, "Vrf has not been initialized yet");
98
99         long routeId = hostVrfStateForPortVrf.getNextRouteId();
100
101         builder.setId(routeId);
102         builder.setDestinationPrefix(ipPrefix);
103         builder.setKey(new RouteKey(builder.getId()));
104
105         if (secondaryVrf != null) {
106             builder.setNextHopOptions(new TableLookupBuilder().setTableLookupParams(
107                 new TableLookupParamsBuilder().setSecondaryVrf(secondaryVrf).build()).build());
108         } else {
109             builder.setNextHopOptions(
110                 new SimpleNextHopBuilder().setNextHop(nextHopAddress).setOutgoingInterface(outgoingInterface).build());
111         }
112
113         List<Route> routes = Collections.singletonList(builder.build());
114
115         Ipv4 ipv4Route = new Ipv4Builder().setRoute(routes).build();
116
117         InstanceIdentifier<Ipv4> iid = VppIidFactory
118                 .getRoutingInstanceIid(new RoutingProtocolKey(hostVrfStateForPortVrf.getProtocolName()))
119                 .child(StaticRoutes.class)
120                 .augmentation(StaticRoutes1.class)
121                 .child(Ipv4.class);
122
123         RoutingProtocolKey routingProtocolKey = new RoutingProtocolKey(hostVrfStateForPortVrf.getProtocolName());
124         boolean routingProtocol =
125             GbpNetconfTransaction.netconfSyncedMerge(VppIidFactory.getNetconfNodeIid(new NodeId(hostName)),
126                 VppIidFactory.getRoutingInstanceIid(routingProtocolKey),
127                 new RoutingProtocolBuilder().setKey(routingProtocolKey).setType(Static.class).build(),
128                 GbpNetconfTransaction.RETRY_COUNT);
129
130         if (routingProtocol && GbpNetconfTransaction.netconfSyncedMerge(
131             VppIidFactory.getNetconfNodeIid(new NodeId(hostName)), iid, ipv4Route, GbpNetconfTransaction.RETRY_COUNT)) {
132             hostVrfStateForPortVrf.addNewPortIpInVrf(portSubnetUuid, nextHopAddress);
133             hostPortInterfaces.addRouteToPortInterface(outgoingInterface, portSubnetUuid, nextHopAddress, routeId);
134             return true;
135         }
136
137         return false;
138     }
139
140     synchronized boolean deleteSingleStaticRouteFromRoutingProtocol(String hostName, long vrfId,
141         String outgoingInterfaceName, Long routeId) {
142         VrfState vrfState = hostRelatedInfoContainer.getVrfStateOfHost(hostName).getVrfState(vrfId);
143
144         Preconditions.checkNotNull(vrfState, "Vrf has not been initialized");
145
146         InstanceIdentifier<Route> iid = VppIidFactory
147                 .getRoutingInstanceIid(new RoutingProtocolKey(vrfState.getProtocolName()))
148                 .child(StaticRoutes.class)
149                 .augmentation(StaticRoutes1.class)
150                 .child(Ipv4.class)
151                 .child(Route.class, new RouteKey(routeId));
152
153         if (!GbpNetconfTransaction.netconfSyncedDelete(VppIidFactory.getNetconfNodeIid(new NodeId(hostName)), iid,
154                 GbpNetconfTransaction.RETRY_COUNT)) {
155             LOG.warn("Route delete failed for interface {} from {}", outgoingInterfaceName, hostName);
156             return false;
157         }
158         return true;
159     }
160
161     synchronized void deleteAllRoutesThroughInterface(String hostName, String outgoingInterfaceName) {
162         PortRouteState portRouteState = hostRelatedInfoContainer
163                                             .getPortInterfaceStateOfHost(hostName)
164                                             .getPortRouteState(outgoingInterfaceName);
165
166         long vrfId = hostRelatedInfoContainer.getPortInterfaceStateOfHost(hostName)
167                 .getInterfaceVrfId(outgoingInterfaceName);
168         if(vrfId == -1) {
169             LOG.error("VrfID was not resolved when removing routes from interface. hostname: {}, interface: {}",
170                 hostName, outgoingInterfaceName);
171             return;
172         }
173
174         List<Ipv4Address> ipThroughInterface = portRouteState.getAllIps();
175
176         for (Ipv4Address ip : ipThroughInterface) {
177             long routeId = portRouteState.getRouteIdOfIp(ip);
178             String subnetUuidOfIp = portRouteState.getSubnetUuidOfIp(ip);
179             boolean ok = deleteSingleStaticRouteFromRoutingProtocol(hostName, vrfId,
180                     outgoingInterfaceName, routeId);
181
182             if (ok) {
183                 portRouteState.removeIp(ip);
184                 hostRelatedInfoContainer
185                         .getVrfStateOfHost(hostName)
186                         .getVrfState(vrfId)
187                         .removePortIpFromVrf(subnetUuidOfIp, ip);
188             }
189         }
190     }
191
192     private static String getRoutingProtocolName(long vrf) {
193         return Constants.ROUTING_PROTOCOL_NAME_PREFIX + vrf;
194     }
195 }