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