blob: 51ab68bef490e92df63079dff46e8a100019eedd [file] [log] [blame]
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.bgp.controller.impl;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Service;
import org.onosproject.bgp.controller.BgpCfg;
import org.onosproject.bgp.controller.BgpController;
import org.onosproject.bgp.controller.BgpId;
import org.onosproject.bgp.controller.BgpLocalRib;
import org.onosproject.bgp.controller.BgpPeer;
import org.onosproject.bgp.controller.BgpNodeListener;
import org.onosproject.bgp.controller.BgpPeerManager;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.onosproject.bgpio.protocol.BgpMessage;
import org.onosproject.bgpio.protocol.BgpUpdateMsg;
import org.onosproject.bgpio.types.BgpValueType;
import org.onosproject.bgpio.types.MpReachNlri;
import org.onosproject.bgpio.types.MpUnReachNlri;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Component(immediate = true)
@Service
public class BgpControllerImpl implements BgpController {
private static final Logger log = LoggerFactory.getLogger(BgpControllerImpl.class);
protected ConcurrentHashMap<BgpId, BgpPeer> connectedPeers = new ConcurrentHashMap<BgpId, BgpPeer>();
protected BgpPeerManagerImpl peerManager = new BgpPeerManagerImpl();
private BgpLocalRib bgplocalRIB = new BgpLocalRibImpl(this);
private BgpLocalRib bgplocalRIBVpn = new BgpLocalRibImpl(this);
protected Set<BgpNodeListener> bgpNodeListener = new CopyOnWriteArraySet<>();
final Controller ctrl = new Controller(this);
private BgpConfig bgpconfig = new BgpConfig(this);
@Activate
public void activate() {
this.ctrl.start();
log.info("Started");
}
@Deactivate
public void deactivate() {
// Close all connected peers
closeConnectedPeers();
this.ctrl.stop();
log.info("Stopped");
}
@Override
public Iterable<BgpPeer> getPeers() {
return this.connectedPeers.values();
}
@Override
public BgpPeer getPeer(BgpId bgpId) {
return this.connectedPeers.get(bgpId);
}
@Override
public void addListener(BgpNodeListener listener) {
this.bgpNodeListener.add(listener);
}
@Override
public void removeListener(BgpNodeListener listener) {
this.bgpNodeListener.remove(listener);
}
@Override
public Set<BgpNodeListener> listener() {
return bgpNodeListener;
}
@Override
public void writeMsg(BgpId bgpId, BgpMessage msg) {
this.getPeer(bgpId).sendMessage(msg);
}
@Override
public void processBGPPacket(BgpId bgpId, BgpMessage msg) throws BgpParseException {
BgpPeer peer = getPeer(bgpId);
switch (msg.getType()) {
case OPEN:
// TODO: Process Open message
break;
case KEEP_ALIVE:
// TODO: Process keepalive message
break;
case NOTIFICATION:
// TODO: Process notificatoin message
break;
case UPDATE:
BgpUpdateMsg updateMsg = (BgpUpdateMsg) msg;
List<BgpValueType> pathAttr = updateMsg.bgpPathAttributes().pathAttributes();
if (pathAttr == null) {
log.debug("llPathAttr is null, cannot process update message");
break;
}
Iterator<BgpValueType> listIterator = pathAttr.iterator();
boolean isLinkstate = false;
while (listIterator.hasNext()) {
BgpValueType attr = listIterator.next();
if ((attr instanceof MpReachNlri) || (attr instanceof MpUnReachNlri)) {
isLinkstate = true;
}
}
if (isLinkstate) {
peer.buildAdjRibIn(pathAttr);
}
break;
default:
// TODO: Process other message
break;
}
}
@Override
public void closeConnectedPeers() {
BgpPeer bgpPeer;
for (BgpId id : this.connectedPeers.keySet()) {
bgpPeer = getPeer(id);
bgpPeer.disconnectPeer();
}
}
/**
* Implementation of an BGP Peer which is responsible for keeping track of connected peers and the state in which
* they are.
*/
public class BgpPeerManagerImpl implements BgpPeerManager {
private final Logger log = LoggerFactory.getLogger(BgpPeerManagerImpl.class);
private final Lock peerLock = new ReentrantLock();
@Override
public boolean addConnectedPeer(BgpId bgpId, BgpPeer bgpPeer) {
if (connectedPeers.get(bgpId) != null) {
this.log.error("Trying to add connectedPeer but found previous " + "value for bgp ip: {}",
bgpId.toString());
return false;
} else {
this.log.debug("Added Peer {}", bgpId.toString());
connectedPeers.put(bgpId, bgpPeer);
return true;
}
}
@Override
public boolean isPeerConnected(BgpId bgpId) {
if (connectedPeers.get(bgpId) == null) {
this.log.error("Is peer connected: bgpIp {}.", bgpId.toString());
return false;
}
return true;
}
@Override
public void removeConnectedPeer(BgpId bgpId) {
connectedPeers.remove(bgpId);
}
@Override
public BgpPeer getPeer(BgpId bgpId) {
return connectedPeers.get(bgpId);
}
/**
* Gets bgp peer instance.
*
* @param bgpController controller instance.
* @param sessionInfo bgp session info.
* @param pktStats packet statistics.
* @return BGPPeer peer instance.
*/
public BgpPeer getBgpPeerInstance(BgpController bgpController, BgpSessionInfoImpl sessionInfo,
BgpPacketStatsImpl pktStats) {
BgpPeer bgpPeer = new BgpPeerImpl(bgpController, sessionInfo, pktStats);
return bgpPeer;
}
}
/**
* Returns controller.
*
* @return controller
*/
public Controller controller() {
return this.ctrl;
}
@Override
public ConcurrentHashMap<BgpId, BgpPeer> connectedPeers() {
return connectedPeers;
}
@Override
public BgpPeerManagerImpl peerManager() {
return peerManager;
}
@Override
public BgpCfg getConfig() {
return this.bgpconfig;
}
@Override
public int connectedPeerCount() {
return connectedPeers.size();
}
/**
* Gets the BGP local RIB.
*
* @return bgplocalRIB BGP local RIB.
*/
@Override
public BgpLocalRib bgpLocalRib() {
return bgplocalRIB;
}
/**
* Gets the BGP local RIB with VPN.
*
* @return bgplocalRIBVpn BGP VPN local RIB .
*/
@Override
public BgpLocalRib bgpLocalRibVpn() {
return bgplocalRIBVpn;
}
}