Merge "Simplify overlay information mappers and managers"
[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 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
12 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.HostRelatedInfoContainer;
13 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.PortInterfaces;
14 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.PortRouteState;
15 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.VrfHolder;
16 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.info.container.states.VrfState;
17 import org.opendaylight.groupbasedpolicy.renderer.vpp.lisp.util.Constants;
18 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.GbpNetconfTransaction;
19 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev140524.StaticRoutes1;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev140524.routing.routing.instance.routing.protocols.routing.protocol._static.routes.Ipv4;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev140524.routing.routing.instance.routing.protocols.routing.protocol._static.routes.Ipv4Builder;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev140524.routing.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.Route;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev140524.routing.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.RouteBuilder;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev140524.routing.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.RouteKey;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ipv4.unicast.routing.rev140524.routing.routing.instance.routing.protocols.routing.protocol._static.routes.ipv4.route.next.hop.options.SimpleNextHopBuilder;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.Static;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.routing.protocols.RoutingProtocol;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.routing.protocols.RoutingProtocolBuilder;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.routing.protocols.RoutingProtocolKey;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev140524.routing.routing.instance.routing.protocols.routing.protocol.StaticRoutes;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev161214.RoutingProtocolVppAttr;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev161214.RoutingProtocolVppAttrBuilder;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev161214.VniReference;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.vpp.routing.rev161214.routing.routing.instance.routing.protocols.routing.protocol.VppProtocolAttributesBuilder;
38 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42 import java.util.Arrays;
43 import java.util.List;
44
45 /**
46  * Created by Shakib Ahmed on 5/4/17.
47  */
48 public class StaticRoutingHelper {
49     private static final Logger LOG = LoggerFactory.getLogger(StaticRoutingHelper.class);
50
51     private HostRelatedInfoContainer hostRelatedInfoContainer = HostRelatedInfoContainer.getInstance();
52
53     public synchronized boolean addRoutingProtocolForVrf(DataBroker vppDataBroker,
54                                                          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(vppDataBroker,
73                 iid, builder.build(), GbpNetconfTransaction.RETRY_COUNT)) {
74             vrfHolderOfHost.initializeVrfState(vrfId, routingProtocolName);
75             return true;
76         }
77
78         return false;
79     }
80
81     public synchronized boolean addSingleStaticRouteInRoutingProtocol(DataBroker vppDataBroker,
82                                                                       String hostName,
83                                                                       long portVrfId,
84                                                                       String portSubnetUuid,
85                                                                       Ipv4Address nextHopAddress,
86                                                                       Ipv4Prefix ipPrefix,
87                                                                       String outgoingInterface) {
88         RouteBuilder builder = new RouteBuilder();
89
90         VrfState hostVrfStateForPortVrf = hostRelatedInfoContainer
91                                                     .getVrfStateOfHost(hostName)
92                                                     .getVrfState(portVrfId);
93
94         PortInterfaces hostPortInterfaces = hostRelatedInfoContainer
95                                                     .getPortInterfaceStateOfHost(hostName);
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         builder.setNextHopOptions(new SimpleNextHopBuilder()
105                                         .setNextHop(nextHopAddress)
106                                         .setOutgoingInterface(outgoingInterface)
107                                         .build());
108
109         List<Route> routes = Arrays.asList(builder.build());
110
111         Ipv4 ipv4Route = new Ipv4Builder().setRoute(routes).build();
112
113         InstanceIdentifier<Ipv4> iid = VppIidFactory
114                 .getRoutingInstanceIid(new RoutingProtocolKey(hostVrfStateForPortVrf.getProtocolName()))
115                 .child(StaticRoutes.class)
116                 .augmentation(StaticRoutes1.class)
117                 .child(Ipv4.class);
118
119         if (GbpNetconfTransaction
120                 .netconfSyncedMerge(vppDataBroker, iid, ipv4Route,
121                         GbpNetconfTransaction.RETRY_COUNT)) {
122             hostVrfStateForPortVrf.addNewPortIpInVrf(portSubnetUuid, nextHopAddress);
123             hostPortInterfaces.addRouteToPortInterface(outgoingInterface, portSubnetUuid,
124                     nextHopAddress, routeId);
125             return true;
126         }
127
128         return false;
129     }
130
131     public synchronized boolean deleteSingleStaticRouteFromRoutingProtocol(DataBroker vppDataBroker,
132                                                                            String hostName,
133                                                                            long vrfId,
134                                                                            String outgoingInterfaceName,
135                                                                            Long routeId) {
136         VrfState vrfState = hostRelatedInfoContainer.getVrfStateOfHost(hostName).getVrfState(vrfId);
137
138         Preconditions.checkNotNull(vrfState, "Vrf has not been initialized");
139
140         InstanceIdentifier<Route> iid = VppIidFactory
141                 .getRoutingInstanceIid(new RoutingProtocolKey(vrfState.getProtocolName()))
142                 .child(StaticRoutes.class)
143                 .augmentation(StaticRoutes1.class)
144                 .child(Ipv4.class)
145                 .child(Route.class, new RouteKey(routeId));
146
147         if (!GbpNetconfTransaction.netconfSyncedDelete(vppDataBroker, iid, GbpNetconfTransaction.RETRY_COUNT)) {
148             LOG.warn("Route delete failed for interface {} from {}", outgoingInterfaceName, hostName);
149             return false;
150         }
151         return true;
152     }
153
154     public synchronized boolean deleteAllRoutesThroughInterface(DataBroker vppDataBroker,
155                                                                 String hostName,
156                                                                 String outgoingInterfaceName) {
157         PortRouteState portRouteState = hostRelatedInfoContainer
158                                             .getPortInterfaceStateOfHost(hostName)
159                                             .getPortRouteState(outgoingInterfaceName);
160
161         long vrfId = hostRelatedInfoContainer.getPortInterfaceStateOfHost(hostName)
162                 .getInterfaceVrfId(outgoingInterfaceName);
163
164         List<Ipv4Address> ipThroughInterface = portRouteState.getAllIps();
165
166         boolean allOk = true;
167
168         for (Ipv4Address ip : ipThroughInterface) {
169             long routeId = portRouteState.getRouteIdOfIp(ip);
170             String subnetUuidOfIp = portRouteState.getSubnetUuidOfIp(ip);
171             boolean ok = deleteSingleStaticRouteFromRoutingProtocol(vppDataBroker, hostName, vrfId,
172                     outgoingInterfaceName, routeId);
173
174             if (ok) {
175                 portRouteState.removeIp(ip);
176                 hostRelatedInfoContainer
177                         .getVrfStateOfHost(hostName)
178                         .getVrfState(vrfId)
179                         .removePortIpFromVrf(subnetUuidOfIp, ip);
180             }
181         }
182
183         return allOk;
184     }
185
186     public static String getRoutingProtocolName(long vrf) {
187         return Constants.ROUTING_PROTOCOL_NAME_PREFIX + vrf;
188     }
189 }