2 * Copyright (c) 2016 Cisco Systems, Inc. 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
9 package org.opendaylight.protocol.bgp.rib.impl.config;
11 import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.getHoldTimer;
12 import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.getPeerAs;
14 import com.google.common.base.Optional;
15 import com.google.common.base.Preconditions;
16 import com.google.common.collect.Iterables;
17 import io.netty.util.concurrent.Future;
18 import java.util.ArrayList;
19 import java.util.List;
20 import org.opendaylight.controller.config.yang.bgp.rib.impl.BGPPeerRuntimeMXBean;
21 import org.opendaylight.controller.config.yang.bgp.rib.impl.BgpPeerState;
22 import org.opendaylight.controller.config.yang.bgp.rib.impl.BgpSessionState;
23 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
24 import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigMappingService;
25 import org.opendaylight.protocol.bgp.parser.BgpExtendedMessageUtil;
26 import org.opendaylight.protocol.bgp.parser.spi.MultiprotocolCapabilitiesUtil;
27 import org.opendaylight.protocol.bgp.rib.impl.BGPPeer;
28 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry;
29 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPSessionPreferences;
30 import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
31 import org.opendaylight.protocol.concepts.KeyMapping;
32 import org.opendaylight.protocol.util.Ipv4Util;
33 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.Neighbor;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.BgpParameters;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.BgpParametersBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.bgp.parameters.OptionalCapabilities;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.bgp.parameters.OptionalCapabilitiesBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.bgp.parameters.optional.capabilities.CParametersBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.bgp.parameters.optional.capabilities.c.parameters.As4BytesCapabilityBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.CParameters1;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.CParameters1Builder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.mp.capabilities.AddPathCapabilityBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.mp.capabilities.MultiprotocolCapabilityBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.mp.capabilities.add.path.capability.AddressFamilies;
48 import org.osgi.framework.ServiceRegistration;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
53 public class BgpPeer implements PeerBean, BGPPeerRuntimeMXBean {
55 //FIXME make configurable
56 private static final PortNumber PORT = new PortNumber(179);
58 private static final Logger LOG = LoggerFactory.getLogger(BgpPeer.class);
60 private final RpcProviderRegistry rpcRegistry;
61 private final BGPPeerRegistry peerRegistry;
62 private BGPPeer bgpPeer;
64 private Future<Void> connection;
66 private ServiceRegistration<?> serviceRegistration;
67 private Neighbor currentConfiguration;
69 public BgpPeer(final RpcProviderRegistry rpcRegistry, final BGPPeerRegistry peerRegistry) {
70 this.rpcRegistry = rpcRegistry;
71 this.peerRegistry = peerRegistry;
75 public void start(final RIB rib, final Neighbor neighbor, final BGPOpenConfigMappingService mappingService) {
76 Preconditions.checkState(this.bgpPeer == null, "Previous peer instance {} was not closed.");
77 this.currentConfiguration = Preconditions.checkNotNull(neighbor);
78 final IpAddress neighborAddress = neighbor.getNeighborAddress();
79 this.bgpPeer = new BGPPeer(Ipv4Util.toStringIP(neighborAddress), rib,
80 mappingService.toPeerRole(neighbor), this.rpcRegistry);
81 final List<BgpParameters> bgpParameters = getBgpParameters(neighbor, rib, mappingService);
82 final KeyMapping key = OpenConfigMappingUtil.getNeighborKey(neighbor);
83 final BGPSessionPreferences prefs = new BGPSessionPreferences(rib.getLocalAs(),
84 getHoldTimer(neighbor), rib.getBgpIdentifier(), getPeerAs(neighbor, rib), bgpParameters, getPassword(key));
85 this.peerRegistry.addPeer(neighborAddress, this.bgpPeer, prefs);
86 if (OpenConfigMappingUtil.isActive(neighbor)) {
87 this.connection = rib.getDispatcher().createReconnectingClient(
88 Ipv4Util.toInetSocketAddress(neighborAddress, PORT), this.peerRegistry,
89 OpenConfigMappingUtil.getRetryTimer(neighbor), Optional.fromNullable(key));
95 public void restart(final RIB rib, final BGPOpenConfigMappingService mappingService) {
96 Preconditions.checkState(this.currentConfiguration != null);
97 start(rib, this.currentConfiguration, mappingService);
101 public void close() {
102 if (this.bgpPeer != null) {
103 if (this.connection != null) {
104 this.connection.cancel(true);
105 this.connection = null;
107 this.bgpPeer.close();
109 this.peerRegistry.removePeer(this.currentConfiguration.getNeighborAddress());
110 this.currentConfiguration = null;
111 if (this.serviceRegistration != null) {
112 this.serviceRegistration.unregister();
113 this.serviceRegistration = null;
118 private static List<BgpParameters> getBgpParameters(final Neighbor neighbor, final RIB rib,
119 final BGPOpenConfigMappingService mappingService) {
120 final List<BgpParameters> tlvs = new ArrayList<>();
121 final List<OptionalCapabilities> caps = new ArrayList<>();
122 caps.add(new OptionalCapabilitiesBuilder().setCParameters(new CParametersBuilder().setAs4BytesCapability(
123 new As4BytesCapabilityBuilder().setAsNumber(rib.getLocalAs()).build()).build()).build());
125 caps.add(new OptionalCapabilitiesBuilder().setCParameters(BgpExtendedMessageUtil.EXTENDED_MESSAGE_CAPABILITY).build());
126 caps.add(new OptionalCapabilitiesBuilder().setCParameters(MultiprotocolCapabilitiesUtil.RR_CAPABILITY).build());
128 final List<AddressFamilies> addPathCapability = mappingService.toAddPathCapability(neighbor.getAfiSafis().getAfiSafi());
129 if (!addPathCapability.isEmpty()) {
130 caps.add(new OptionalCapabilitiesBuilder().setCParameters(new CParametersBuilder().addAugmentation(CParameters1.class,
131 new CParameters1Builder().setAddPathCapability(
132 new AddPathCapabilityBuilder().setAddressFamilies(addPathCapability).build()).build()).build()).build());
135 final List<BgpTableType> tableTypes = mappingService.toTableTypes(neighbor.getAfiSafis().getAfiSafi());
136 for (final BgpTableType tableType : tableTypes) {
137 if (!rib.getLocalTables().contains(tableType)) {
138 LOG.info("RIB instance does not list {} in its local tables. Incoming data will be dropped.", tableType);
141 caps.add(new OptionalCapabilitiesBuilder().setCParameters(
142 new CParametersBuilder().addAugmentation(CParameters1.class,
143 new CParameters1Builder().setMultiprotocolCapability(
144 new MultiprotocolCapabilityBuilder(tableType).build()).build()).build()).build());
146 tlvs.add(new BgpParametersBuilder().setOptionalCapabilities(caps).build());
150 private static Optional<byte[]> getPassword(final KeyMapping key) {
152 return Optional.of(Iterables.getOnlyElement(key.values()));
154 return Optional.absent();
158 public BgpPeerState getBgpPeerState() {
159 return this.bgpPeer.getBgpPeerState();
163 public BgpSessionState getBgpSessionState() {
164 return this.bgpPeer.getBgpSessionState();
168 public void resetStats() {
169 this.bgpPeer.resetStats();
174 public void resetSession() {
175 this.bgpPeer.resetSession();
179 public void setServiceRegistration(final ServiceRegistration<?> serviceRegistration) {
180 this.serviceRegistration = serviceRegistration;