MRI version bumpup for Aluminium
[netvirt.git] / bgpmanager / impl / src / main / java / org / opendaylight / netvirt / bgpmanager / BgpManager.java
1 /*
2  * Copyright © 2015, 2017 Ericsson India Global Services Pvt Ltd. and others.  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.netvirt.bgpmanager;
9
10 import com.google.common.util.concurrent.FutureCallback;
11 import com.google.common.util.concurrent.Futures;
12 import com.google.common.util.concurrent.MoreExecutors;
13 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.Collections;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.Optional;
20 import javax.annotation.PostConstruct;
21 import javax.annotation.PreDestroy;
22 import javax.inject.Inject;
23 import javax.inject.Singleton;
24 import org.apache.thrift.TException;
25 import org.eclipse.jdt.annotation.Nullable;
26 import org.opendaylight.mdsal.binding.api.DataBroker;
27 import org.opendaylight.mdsal.binding.api.ReadTransaction;
28 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
29 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
30 import org.opendaylight.netvirt.bgpmanager.oam.BgpAlarmErrorCodes;
31 import org.opendaylight.netvirt.bgpmanager.oam.BgpConstants;
32 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpRouterException;
33 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_afi;
34 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_safi;
35 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
36 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.AddressFamily;
37 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.Bgp;
38 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.TcpMd5SignaturePasswordType;
39 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NetworksContainer;
40 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.Neighbors;
41 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.NeighborsKey;
42 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.networkscontainer.Networks;
43 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.networkscontainer.NetworksKey;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
45 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
46 import org.opendaylight.yangtools.yang.common.Uint32;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50 @Singleton
51 public class BgpManager implements AutoCloseable, IBgpManager {
52     private static final Logger LOG = LoggerFactory.getLogger(BgpManager.class);
53     private final BgpConfigurationManager bcm;
54
55     private final FibDSWriter fibDSWriter;
56     private final DataBroker dataBroker;
57     private volatile long qbgprestartTS = 0;
58
59     @Inject
60     public BgpManager(final BgpConfigurationManager bcm, final FibDSWriter fibDSWriter, final DataBroker dataBroker) {
61         this.bcm = bcm;
62         this.fibDSWriter = fibDSWriter;
63         this.dataBroker = dataBroker;
64     }
65
66     @PostConstruct
67     public void init() {
68         LOG.info("{} start", getClass().getSimpleName());
69     }
70
71     @Override
72     @PreDestroy
73     public void close() {
74         LOG.info("{} close", getClass().getSimpleName());
75     }
76
77     public BgpConfigurationManager getBgpConfigurationManager() {
78         return bcm;
79     }
80
81     public void configureGR(int stalepathTime) {
82         bcm.addGracefulRestart(stalepathTime);
83     }
84
85     public void delGracefulRestart() {
86         bcm.delGracefulRestart();
87     }
88
89     public void addNeighbor(String ipAddress, long asNum,
90             @Nullable final TcpMd5SignaturePasswordType md5Password) {
91         bcm.addNeighbor(ipAddress, asNum, md5Password);
92     }
93
94     public void addEbgpMultihop(String ipAddress, int nhops) {
95         bcm.addEbgpMultihop(ipAddress, nhops);
96     }
97
98     public void addUpdateSource(String ipAddress, String srcIp) {
99         bcm.addUpdateSource(ipAddress, srcIp);
100     }
101
102     public void addAddressFamily(String ipAddress, af_afi afi, af_safi safi) {
103         bcm.addAddressFamily(ipAddress, afi.getValue(), safi.getValue());
104     }
105
106     public void deleteNeighbor(String ipAddress) {
107         bcm.delNeighbor(ipAddress);
108     }
109
110     @Override
111     public void addVrf(String rd, Collection<String> importRts, Collection<String> exportRts,
112             AddressFamily addressFamily) {
113         bcm.addVrf(rd, new ArrayList<>(importRts), new ArrayList<>(exportRts),  addressFamily);
114     }
115
116     @Override
117       public void deleteVrf(String rd, boolean removeFibTable, AddressFamily addressFamily) {
118         boolean ret = false;
119         if (removeFibTable) {
120             LOG.info("deleteVrf: suppressing FIB from rd {} with {}", rd, addressFamily);
121             fibDSWriter.removeVrfSubFamilyFromDS(rd, addressFamily);
122         }
123         ret = bcm.delVrf(rd, addressFamily);
124         if (ret && removeFibTable) {
125             fibDSWriter.removeVrfFromDS(rd);
126         }
127     }
128
129     public  void getAllPeerStatus() {
130         Map<NeighborsKey, Neighbors> keyNeighborsMap = null;
131         Bgp bgp = getConfig();
132         if (bgp != null && bgp.getNeighborsContainer() != null) {
133             keyNeighborsMap = bgp.getNeighborsContainer().getNeighbors();
134         } else {
135             LOG.error("BGP Neighbor configuration NOT exist");
136             return;
137         }
138         if (keyNeighborsMap == null) {
139             return;
140         }
141
142         for (Neighbors nbr : keyNeighborsMap.values()) {
143             try {
144                 LOG.trace("nbr {} checking status, AS num: {}", nbr.getAddress().getValue(), nbr.getRemoteAs());
145                 bcm.getPeerStatus(nbr.getAddress().getValue(), nbr.getRemoteAs().toJava());
146                 LOG.trace("nbr {} status is: PEER UP", nbr.getAddress().getValue());
147             } catch (BgpRouterException bre) {
148                 if (bre.getErrorCode() == BgpRouterException.BGP_PEER_DOWN) {
149                     LOG.trace("nbr {} status is: DOWN", nbr.getAddress().getValue());
150                 } else if (bre.getErrorCode() == BgpRouterException.BGP_PEER_NOTCONFIGURED) {
151                     LOG.trace("nbr {} status is: NOT CONFIGURED", nbr.getAddress().getValue());
152                 } else if (bre.getErrorCode() == BgpRouterException.BGP_PEER_UNKNOWN) {
153                     LOG.info("nbr {} status is: Unknown", nbr.getAddress().getValue());
154                 } else {
155                     LOG.info("nbr {} status is: Unknown, invalid BgpRouterException:",
156                             nbr.getAddress().getValue(), bre);
157                 }
158             } catch (TException tae) {
159                 LOG.error("nbr {} status is: Unknown, received TException ", nbr.getAddress().getValue(), tae);
160             }
161         }
162     }
163
164     @Override
165     public void addPrefix(String rd, String macAddress, String prefix, List<String> nextHopList,
166                           VrfEntry.EncapType encapType, Uint32 vpnLabel, Uint32 l3vni,
167                           String gatewayMac, RouteOrigin origin) {
168         fibDSWriter.addFibEntryToDS(rd, prefix, nextHopList,
169                 encapType, vpnLabel, l3vni, gatewayMac, origin);
170         bcm.addPrefix(rd, macAddress, prefix, nextHopList,
171                 encapType, vpnLabel, l3vni, Uint32.ZERO /*l2vni*/, gatewayMac);
172     }
173
174     @Override
175     public void addPrefix(String rd, String macAddress, String prefix, String nextHop, VrfEntry.EncapType encapType,
176                           Uint32 vpnLabel, Uint32 l3vni, String gatewayMac, RouteOrigin origin) {
177         addPrefix(rd, macAddress, prefix, Collections.singletonList(nextHop), encapType, vpnLabel, l3vni,
178                 gatewayMac, origin);
179     }
180
181     @Override
182     public void deletePrefix(String rd, String prefix) {
183         fibDSWriter.removeFibEntryFromDS(rd, prefix);
184         bcm.delPrefix(rd, prefix);
185     }
186
187     @Override
188     public void advertisePrefix(String rd, String macAddress, String prefix, List<String> nextHopList,
189                                 VrfEntry.EncapType encapType, Uint32 vpnLabel, Uint32 l3vni, Uint32 l2vni,
190                                 String gatewayMac) {
191         LOG.info("Advertise Prefix: Adding Prefix rd {} prefix {} label {} l3vni {} l2vni {}",
192                 rd, prefix, vpnLabel, l3vni, l2vni);
193         bcm.addPrefix(rd, macAddress, prefix, nextHopList,
194                 encapType, vpnLabel, l3vni, l2vni, gatewayMac);
195         LOG.info("Advertise Prefix: Added Prefix rd {} prefix {} label {} l3vni {} l2vni {}",
196                 rd, prefix, vpnLabel, l3vni, l2vni);
197     }
198
199     @Override
200     public void advertisePrefix(String rd, String macAddress, String prefix, String nextHop,
201                                 VrfEntry.EncapType encapType, Uint32 vpnLabel, Uint32 l3vni, Uint32 l2vni,
202                                 String gatewayMac) {
203         LOG.info("ADVERTISE: Adding Prefix rd {} prefix {} nexthop {} label {} l3vni {} l2vni {}",
204                 rd, prefix, nextHop, vpnLabel, l3vni, l2vni);
205         bcm.addPrefix(rd, macAddress, prefix, Collections.singletonList(nextHop), encapType,
206                 vpnLabel, l3vni, l2vni, gatewayMac);
207         LOG.info("ADVERTISE: Added Prefix rd {} prefix {} nexthop {} label {} l3vni {} l2vni {}",
208                 rd, prefix, nextHop, vpnLabel, l3vni, l2vni);
209     }
210
211     @Override
212     public void withdrawPrefix(String rd, String prefix) {
213         LOG.info("WITHDRAW: Removing Prefix rd {} prefix {}", rd, prefix);
214         bcm.delPrefix(rd, prefix);
215         LOG.info("WITHDRAW: Removed Prefix rd {} prefix {}", rd, prefix);
216     }
217
218     @Override
219     public void withdrawPrefixIfPresent(String rd, String prefix) {
220         InstanceIdentifier<Networks> networksId = InstanceIdentifier.builder(Bgp.class)
221                 .child(NetworksContainer.class)
222                 .child(Networks.class,
223                 new NetworksKey(rd, prefix)).build();
224         try (ReadTransaction tx = dataBroker.newReadOnlyTransaction()) {
225             Futures.addCallback(tx.read(LogicalDatastoreType.CONFIGURATION, networksId),
226                 new FutureCallback<Optional<Networks>>() {
227                     @Override
228                     public void onSuccess(@Nullable Optional<Networks> networks) {
229                         if (networks != null && networks.isPresent()) {
230                             LOG.info("withdrawPrefixIfPresent: ebgp networks present for rd {} prefix {}"
231                                     + ". Withdrawing..", networks.get().getRd(), networks.get().getPrefixLen());
232                             withdrawPrefix(rd, prefix);
233                         } else {
234                             LOG.error("withdrawPrefixIfPresent: ebgp networks not found for rd {} prefix {}",
235                                     rd, prefix);
236                         }
237                     }
238
239                     @Override
240                     public void onFailure(Throwable throwable) {
241                         LOG.error("withdrwaPrefixIfPresent: Failed to retrieve ebgp networks for rd {} prefix {}",
242                                 rd, prefix, throwable);
243                     }
244                 }, MoreExecutors.directExecutor());
245         }
246     }
247
248     @Override
249     public void setQbgpLog(String fileName, String debugLevel) {
250         bcm.addLogging(fileName, debugLevel);
251     }
252
253     public void delLogging() {
254         bcm.delLogging();
255     }
256
257     public void startBgp(long asn, String routerId, int spt, boolean fbit) {
258         bcm.startBgp(asn, routerId, spt, fbit);
259     }
260
261     public void stopBgp() {
262         bcm.stopBgp();
263     }
264
265     public void startConfig(String host, int port) {
266         bcm.startConfig(host, port);
267     }
268
269     public void stopConfig() {
270         bcm.stopConfig();
271     }
272
273     public Bgp getConfig() {
274         return bcm.getConfig();
275     }
276
277     public void startBfd(int detectMult, int minRx, int minTx, boolean multiHop) {
278         bcm.startBfd(detectMult, minRx, minTx, multiHop);
279     }
280
281     public void stopBfd() {
282         bcm.stopBfd();
283     }
284
285     public void addDcgwTep(String dcgwIp, String tepIp) {
286         bcm.addDcgwTep(dcgwIp, tepIp);
287     }
288
289     public void delDcgwTep(String dcgwIp, String tepIp) {
290         bcm.delDcgwTep(dcgwIp, tepIp);
291     }
292
293     public void enableMultipath(af_afi afi, af_safi safi) {
294         bcm.setMultipathStatus(afi, safi,true);
295     }
296
297     public void disableMultipath(af_afi afi, af_safi safi) {
298         bcm.setMultipathStatus(afi, safi, false);
299     }
300
301     public void setMultipaths(String rd, int maxpath) {
302         bcm.setMultipaths(rd, maxpath);
303     }
304
305     @Override
306     public String getDCGwIP() {
307         Bgp conf = bcm.getConfig();
308         if (conf == null) {
309             return null;
310         }
311         List<Neighbors> nbrs = conf.getNeighborsContainer() == null ? null
312                 : new ArrayList<Neighbors>(conf.getNeighborsContainer().getNeighbors().values());
313         if (nbrs == null) {
314             return null;
315         }
316         return nbrs.get(0).getAddress().getValue();
317     }
318
319     @Override
320     // This method doesn't actually do any real work currently but may at some point so suppress FindBugs violation.
321     @SuppressFBWarnings("UC_USELESS_VOID_METHOD")
322     public synchronized void sendNotificationEvent(int code, int subcode) {
323         if (code != BgpConstants.BGP_NOTIFY_CEASE_CODE) {
324             // CEASE Notifications alone have to be reported to the CBA.
325             // Silently return here. No need to log because tons
326             // of non-alarm notifications will be sent to the SDNc.
327             return;
328         }
329         BgpAlarmErrorCodes errorSubCode = BgpAlarmErrorCodes.checkErrorSubcode(subcode);
330         if (errorSubCode == BgpAlarmErrorCodes.ERROR_IGNORE) {
331             // Need to report only those subcodes, defined in
332             // BgpAlarmErrorCodes enum class.
333             return;
334         }
335     }
336
337     public FibDSWriter getFibWriter() {
338         return fibDSWriter;
339     }
340
341     public String getConfigHost() {
342         return bcm.getConfigHost();
343     }
344
345     public int getConfigPort() {
346         return bcm.getConfigPort();
347     }
348
349
350     @Override
351     public void bgpRestarted() {
352         bcm.bgpRestarted();
353     }
354
355     public BgpManager getBgpManager() {
356         return this;
357     }
358
359     public boolean isBgpConnected() {
360         return bcm.isBgpConnected();
361     }
362
363     public long getLastConnectedTS() {
364         return bcm.getLastConnectedTS();
365     }
366
367     public long getConnectTS() {
368         return bcm.getConnectTS();
369     }
370
371     public long getStartTS() {
372         return bcm.getStartTS();
373     }
374
375     public long getQbgprestartTS() {
376         return qbgprestartTS;
377     }
378
379     @Override
380     public void setQbgprestartTS(long qbgprestartTS) {
381         this.qbgprestartTS = qbgprestartTS;
382     }
383
384     public long getStaleStartTime() {
385         return bcm.getStaleStartTime();
386     }
387
388     public long getStaleEndTime() {
389         return bcm.getStaleEndTime();
390     }
391
392     public long getCfgReplayStartTime() {
393         return bcm.getCfgReplayStartTime();
394     }
395
396     public long getCfgReplayEndTime() {
397         return bcm.getCfgReplayEndTime();
398     }
399
400     public long getStaleCleanupTime() {
401         return bcm.getStaleCleanupTime();
402     }
403
404
405 }