2 * Copyright © 2015, 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
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
8 package org.opendaylight.netvirt.bgpmanager;
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;
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;
51 public class BgpManager implements AutoCloseable, IBgpManager {
52 private static final Logger LOG = LoggerFactory.getLogger(BgpManager.class);
53 private final BgpConfigurationManager bcm;
55 private final FibDSWriter fibDSWriter;
56 private final DataBroker dataBroker;
57 private volatile long qbgprestartTS = 0;
60 public BgpManager(final BgpConfigurationManager bcm, final FibDSWriter fibDSWriter, final DataBroker dataBroker) {
62 this.fibDSWriter = fibDSWriter;
63 this.dataBroker = dataBroker;
68 LOG.info("{} start", getClass().getSimpleName());
74 LOG.info("{} close", getClass().getSimpleName());
77 public BgpConfigurationManager getBgpConfigurationManager() {
81 public void configureGR(int stalepathTime) {
82 bcm.addGracefulRestart(stalepathTime);
85 public void delGracefulRestart() {
86 bcm.delGracefulRestart();
89 public void addNeighbor(String ipAddress, long asNum,
90 @Nullable final TcpMd5SignaturePasswordType md5Password) {
91 bcm.addNeighbor(ipAddress, asNum, md5Password);
94 public void addEbgpMultihop(String ipAddress, int nhops) {
95 bcm.addEbgpMultihop(ipAddress, nhops);
98 public void addUpdateSource(String ipAddress, String srcIp) {
99 bcm.addUpdateSource(ipAddress, srcIp);
102 public void addAddressFamily(String ipAddress, af_afi afi, af_safi safi) {
103 bcm.addAddressFamily(ipAddress, afi.getValue(), safi.getValue());
106 public void deleteNeighbor(String ipAddress) {
107 bcm.delNeighbor(ipAddress);
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);
117 public void deleteVrf(String rd, boolean removeFibTable, AddressFamily addressFamily) {
119 if (removeFibTable) {
120 LOG.info("deleteVrf: suppressing FIB from rd {} with {}", rd, addressFamily);
121 fibDSWriter.removeVrfSubFamilyFromDS(rd, addressFamily);
123 ret = bcm.delVrf(rd, addressFamily);
124 if (ret && removeFibTable) {
125 fibDSWriter.removeVrfFromDS(rd);
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();
135 LOG.error("BGP Neighbor configuration NOT exist");
138 if (keyNeighborsMap == null) {
142 for (Neighbors nbr : keyNeighborsMap.values()) {
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());
155 LOG.info("nbr {} status is: Unknown, invalid BgpRouterException:",
156 nbr.getAddress().getValue(), bre);
158 } catch (TException tae) {
159 LOG.error("nbr {} status is: Unknown, received TException ", nbr.getAddress().getValue(), tae);
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);
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,
182 public void deletePrefix(String rd, String prefix) {
183 fibDSWriter.removeFibEntryFromDS(rd, prefix);
184 bcm.delPrefix(rd, prefix);
188 public void advertisePrefix(String rd, String macAddress, String prefix, List<String> nextHopList,
189 VrfEntry.EncapType encapType, Uint32 vpnLabel, Uint32 l3vni, Uint32 l2vni,
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);
200 public void advertisePrefix(String rd, String macAddress, String prefix, String nextHop,
201 VrfEntry.EncapType encapType, Uint32 vpnLabel, Uint32 l3vni, Uint32 l2vni,
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);
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);
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>>() {
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);
234 LOG.error("withdrawPrefixIfPresent: ebgp networks not found for rd {} prefix {}",
240 public void onFailure(Throwable throwable) {
241 LOG.error("withdrwaPrefixIfPresent: Failed to retrieve ebgp networks for rd {} prefix {}",
242 rd, prefix, throwable);
244 }, MoreExecutors.directExecutor());
249 public void setQbgpLog(String fileName, String debugLevel) {
250 bcm.addLogging(fileName, debugLevel);
253 public void delLogging() {
257 public void startBgp(long asn, String routerId, int spt, boolean fbit) {
258 bcm.startBgp(asn, routerId, spt, fbit);
261 public void stopBgp() {
265 public void startConfig(String host, int port) {
266 bcm.startConfig(host, port);
269 public void stopConfig() {
273 public Bgp getConfig() {
274 return bcm.getConfig();
277 public void startBfd(int detectMult, int minRx, int minTx, boolean multiHop) {
278 bcm.startBfd(detectMult, minRx, minTx, multiHop);
281 public void stopBfd() {
285 public void addDcgwTep(String dcgwIp, String tepIp) {
286 bcm.addDcgwTep(dcgwIp, tepIp);
289 public void delDcgwTep(String dcgwIp, String tepIp) {
290 bcm.delDcgwTep(dcgwIp, tepIp);
293 public void enableMultipath(af_afi afi, af_safi safi) {
294 bcm.setMultipathStatus(afi, safi,true);
297 public void disableMultipath(af_afi afi, af_safi safi) {
298 bcm.setMultipathStatus(afi, safi, false);
301 public void setMultipaths(String rd, int maxpath) {
302 bcm.setMultipaths(rd, maxpath);
306 public String getDCGwIP() {
307 Bgp conf = bcm.getConfig();
311 List<Neighbors> nbrs = conf.getNeighborsContainer() == null ? null
312 : new ArrayList<Neighbors>(conf.getNeighborsContainer().getNeighbors().values());
316 return nbrs.get(0).getAddress().getValue();
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.
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.
337 public FibDSWriter getFibWriter() {
341 public String getConfigHost() {
342 return bcm.getConfigHost();
345 public int getConfigPort() {
346 return bcm.getConfigPort();
351 public void bgpRestarted() {
355 public BgpManager getBgpManager() {
359 public boolean isBgpConnected() {
360 return bcm.isBgpConnected();
363 public long getLastConnectedTS() {
364 return bcm.getLastConnectedTS();
367 public long getConnectTS() {
368 return bcm.getConnectTS();
371 public long getStartTS() {
372 return bcm.getStartTS();
375 public long getQbgprestartTS() {
376 return qbgprestartTS;
380 public void setQbgprestartTS(long qbgprestartTS) {
381 this.qbgprestartTS = qbgprestartTS;
384 public long getStaleStartTime() {
385 return bcm.getStaleStartTime();
388 public long getStaleEndTime() {
389 return bcm.getStaleEndTime();
392 public long getCfgReplayStartTime() {
393 return bcm.getCfgReplayStartTime();
396 public long getCfgReplayEndTime() {
397 return bcm.getCfgReplayEndTime();
400 public long getStaleCleanupTime() {
401 return bcm.getStaleCleanupTime();