7159c704b41c9f5ad4996c4d126618d5dfb2f4a7
[bgpcep.git] / bgp / rib-impl / src / main / java / org / opendaylight / protocol / bgp / rib / impl / config / BgpPeer.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. 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
9 package org.opendaylight.protocol.bgp.rib.impl.config;
10
11 import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.getHoldTimer;
12 import static org.opendaylight.protocol.bgp.rib.impl.config.OpenConfigMappingUtil.getPeerAs;
13
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.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.BgpParameters;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.BgpParametersBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.bgp.parameters.OptionalCapabilities;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.bgp.parameters.OptionalCapabilitiesBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.bgp.parameters.optional.capabilities.CParametersBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.bgp.parameters.optional.capabilities.c.parameters.As4BytesCapabilityBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.CParameters1;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.CParameters1Builder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.mp.capabilities.AddPathCapabilityBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.mp.capabilities.MultiprotocolCapabilityBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.mp.capabilities.add.path.capability.AddressFamilies;
47 import org.osgi.framework.ServiceRegistration;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50
51
52 public class BgpPeer implements PeerBean, BGPPeerRuntimeMXBean {
53
54     private static final Logger LOG = LoggerFactory.getLogger(BgpPeer.class);
55
56     private final RpcProviderRegistry rpcRegistry;
57     private final BGPPeerRegistry peerRegistry;
58     private BGPPeer bgpPeer;
59
60     private Future<Void> connection;
61
62     private ServiceRegistration<?> serviceRegistration;
63     private Neighbor currentConfiguration;
64
65     public BgpPeer(final RpcProviderRegistry rpcRegistry, final BGPPeerRegistry peerRegistry) {
66         this.rpcRegistry = rpcRegistry;
67         this.peerRegistry = peerRegistry;
68     }
69
70     @Override
71     public void start(final RIB rib, final Neighbor neighbor, final BGPOpenConfigMappingService mappingService) {
72         Preconditions.checkState(this.bgpPeer == null, "Previous peer instance {} was not closed.");
73         this.currentConfiguration = Preconditions.checkNotNull(neighbor);
74         final IpAddress neighborAddress = neighbor.getNeighborAddress();
75         this.bgpPeer = new BGPPeer(Ipv4Util.toStringIP(neighborAddress), rib,
76                 mappingService.toPeerRole(neighbor), this.rpcRegistry);
77         final List<BgpParameters> bgpParameters = getBgpParameters(neighbor, rib, mappingService);
78         final KeyMapping key = OpenConfigMappingUtil.getNeighborKey(neighbor);
79         final BGPSessionPreferences prefs = new BGPSessionPreferences(rib.getLocalAs(),
80                 getHoldTimer(neighbor), rib.getBgpIdentifier(), getPeerAs(neighbor, rib), bgpParameters, getPassword(key));
81         this.peerRegistry.addPeer(neighborAddress, this.bgpPeer, prefs);
82         if (OpenConfigMappingUtil.isActive(neighbor)) {
83             this.connection = rib.getDispatcher().createReconnectingClient(
84                     Ipv4Util.toInetSocketAddress(neighborAddress, OpenConfigMappingUtil.getPort(neighbor)), this.peerRegistry,
85                     OpenConfigMappingUtil.getRetryTimer(neighbor), Optional.fromNullable(key));
86         }
87
88     }
89
90     @Override
91     public void restart(final RIB rib, final BGPOpenConfigMappingService mappingService) {
92         Preconditions.checkState(this.currentConfiguration != null);
93         start(rib, this.currentConfiguration, mappingService);
94     }
95
96     @Override
97     public void close() {
98         if (this.bgpPeer != null) {
99             if (this.connection != null) {
100                 this.connection.cancel(true);
101                 this.connection = null;
102             }
103             this.bgpPeer.close();
104             this.bgpPeer = null;
105             this.peerRegistry.removePeer(this.currentConfiguration.getNeighborAddress());
106             this.currentConfiguration = null;
107             if (this.serviceRegistration != null) {
108                 this.serviceRegistration.unregister();
109                 this.serviceRegistration = null;
110             }
111         }
112     }
113
114     private static List<BgpParameters> getBgpParameters(final Neighbor neighbor, final RIB rib,
115             final BGPOpenConfigMappingService mappingService) {
116         final List<BgpParameters> tlvs = new ArrayList<>();
117         final List<OptionalCapabilities> caps = new ArrayList<>();
118         caps.add(new OptionalCapabilitiesBuilder().setCParameters(new CParametersBuilder().setAs4BytesCapability(
119                 new As4BytesCapabilityBuilder().setAsNumber(rib.getLocalAs()).build()).build()).build());
120
121         caps.add(new OptionalCapabilitiesBuilder().setCParameters(BgpExtendedMessageUtil.EXTENDED_MESSAGE_CAPABILITY).build());
122         caps.add(new OptionalCapabilitiesBuilder().setCParameters(MultiprotocolCapabilitiesUtil.RR_CAPABILITY).build());
123
124         final List<AddressFamilies> addPathCapability = mappingService.toAddPathCapability(neighbor.getAfiSafis().getAfiSafi());
125         if (!addPathCapability.isEmpty()) {
126             caps.add(new OptionalCapabilitiesBuilder().setCParameters(new CParametersBuilder().addAugmentation(CParameters1.class,
127                     new CParameters1Builder().setAddPathCapability(
128                             new AddPathCapabilityBuilder().setAddressFamilies(addPathCapability).build()).build()).build()).build());
129         }
130
131         final List<BgpTableType> tableTypes = mappingService.toTableTypes(neighbor.getAfiSafis().getAfiSafi());
132         for (final BgpTableType tableType : tableTypes) {
133             if (!rib.getLocalTables().contains(tableType)) {
134                 LOG.info("RIB instance does not list {} in its local tables. Incoming data will be dropped.", tableType);
135             }
136
137             caps.add(new OptionalCapabilitiesBuilder().setCParameters(
138                     new CParametersBuilder().addAugmentation(CParameters1.class,
139                             new CParameters1Builder().setMultiprotocolCapability(
140                                     new MultiprotocolCapabilityBuilder(tableType).build()).build()).build()).build());
141         }
142         tlvs.add(new BgpParametersBuilder().setOptionalCapabilities(caps).build());
143         return tlvs;
144     }
145
146     private static Optional<byte[]> getPassword(final KeyMapping key) {
147         if (key != null) {
148             return Optional.of(Iterables.getOnlyElement(key.values()));
149         }
150         return Optional.absent();
151     }
152
153     @Override
154     public BgpPeerState getBgpPeerState() {
155         return this.bgpPeer.getBgpPeerState();
156     }
157
158     @Override
159     public BgpSessionState getBgpSessionState() {
160         return this.bgpPeer.getBgpSessionState();
161     }
162
163     @Override
164     public void resetStats() {
165         this.bgpPeer.resetStats();
166
167     }
168
169     @Override
170     public void resetSession() {
171         this.bgpPeer.resetSession();
172
173     }
174
175     public void setServiceRegistration(final ServiceRegistration<?> serviceRegistration) {
176         this.serviceRegistration = serviceRegistration;
177     }
178
179 }