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