LCOV - code coverage report
Current view: top level - bgp - bgp_session.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 51 62 82.3 %
Date: 2026-06-04 02:06:09 Functions: 12 14 85.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include "bgp/bgp_session.h"
       6             : 
       7             : #include <algorithm>
       8             : #include <string>
       9             : 
      10             : #include "bgp/bgp_log.h"
      11             : #include "bgp/bgp_peer.h"
      12             : #include "bgp/bgp_server.h"
      13             : #include "bgp/bgp_session_manager.h"
      14             : #include "bgp/bgp_update_sender.h"
      15             : 
      16             : using std::string;
      17             : 
      18             : using boost::asio::mutable_buffer;
      19             : 
      20             : // Extract the total BGP message length. This is a 2 byte field after the
      21             : // 16 byte marker. If the buffer doesn't have 18 bytes available return -1.
      22      175735 : int BgpMessageReader::MsgLength(Buffer buffer, int offset) {
      23      175735 :     size_t size = TcpSession::BufferSize(buffer);
      24      175735 :     int remain = size - offset;
      25      175735 :     if (remain < BgpMessageReader::kHeaderLenSize) {
      26           4 :         return -1;
      27             :     }
      28      175731 :     const uint8_t *data = TcpSession::BufferData(buffer) + offset;
      29      175730 :     data += 16;
      30      175730 :     int length = get_value(data, 2);
      31      175731 :     if (bgp_log_test::unit_test())
      32      175730 :         assert(length <= 4096);
      33      175730 :     return length;
      34             : }
      35             : 
      36       14197 : BgpMessageReader::BgpMessageReader(TcpSession *session,
      37       14197 :     ReceiveCallback callback)
      38       14197 :     : TcpMessageReader(session, callback) {
      39       14189 : }
      40             : 
      41       28394 : BgpMessageReader::~BgpMessageReader() {
      42       28394 : }
      43             : 
      44       14192 : BgpSession::BgpSession(BgpSessionManager *session_mgr, Socket *socket)
      45             :     : TcpSession(session_mgr, socket),
      46       14197 :       session_mgr_(session_mgr),
      47       14197 :       peer_(NULL),
      48       14197 :       task_instance_(-1),
      49       28384 :       reader_(new BgpMessageReader(this,
      50       28387 :               boost::bind(&BgpSession::ReceiveMsg, this, _1, _2))) {
      51       14189 : }
      52             : 
      53       27299 : BgpSession::~BgpSession() {
      54       27299 : }
      55             : 
      56             : //
      57             : // Concurrency: called in the context of io::Reader task.
      58             : //
      59      175724 : bool BgpSession::ReceiveMsg(const u_int8_t *msg, size_t size) {
      60      175724 :     return (peer_ ? peer_->ReceiveMsg(this, msg, size) : false);
      61             : }
      62             : 
      63             : //
      64             : // Concurrency: called in the context of bgp::Config task.
      65             : //
      66             : // Process write ready callback.
      67             : //
      68             : // 1. Tell BgpUpdateSender that the IPeer is send ready.
      69             : // 2. Tell BgpPeer that it's send ready so that it can resume Keepalives.
      70             : //
      71           0 : void BgpSession::ProcessWriteReady() {
      72           0 :     if (!peer_)
      73           0 :         return;
      74           0 :     BgpServer *server = peer_->server();
      75           0 :     BgpUpdateSender *sender = server->update_sender();
      76           0 :     sender->PeerSendReady(peer_);
      77           0 :     peer_->SetSendReady();
      78             : }
      79             : 
      80             : //
      81             : // Concurrency: called in the context of io thread.
      82             : //
      83             : // Handle write ready callback.  Enqueue the session to a WorkQueue in the
      84             : // BgpSessionManager.  The WorkQueue gets processed in the context of the
      85             : // bgp::Config task.  This ensures that we don't access the BgpPeer while
      86             : // the BgpPeer is trying to clear our back pointer to it.
      87             : //
      88             : // We can ignore any errors since the StateMachine will get informed of the
      89             : // TcpSession close independently and react to it.
      90             : //
      91           0 : void BgpSession::WriteReady(const boost::system::error_code &error) {
      92           0 :     if (error)
      93           0 :         return;
      94           0 :     session_mgr_->EnqueueWriteReady(this);
      95             : }
      96             : 
      97       11996 : void BgpSession::LogNotification(int code, int subcode, const string &direction,
      98             :                                  const string &peer_key,
      99             :                                  const BgpProto::Notification &msg) const {
     100             :     // Use SYS_DEBUG for connection collision, SYS_NOTICE for the rest.
     101       11996 :     if (code == BgpProto::Notification::Cease &&
     102             :         subcode == BgpProto::Notification::ConnectionCollision) {
     103        1668 :         BGP_LOG(BgpPeerNotification, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
     104             :                 peer_key, direction, code, subcode, msg.ToString());
     105             :     } else {
     106       10328 :         BGP_LOG(BgpPeerNotificationNotice, SandeshLevel::SYS_NOTICE,
     107             :                 BGP_LOG_FLAG_ALL, peer_key, direction, code, subcode,
     108             :                 msg.ToString());
     109             :     }
     110       11996 : }
     111             : 
     112        7297 : void BgpSession::SendNotification(int code, int subcode,
     113             :                                   const string &data) {
     114        7297 :     BgpProto::Notification msg;
     115        7296 :     msg.error = code;
     116        7296 :     msg.subcode = subcode;
     117        7296 :     msg.data = data;
     118             :     uint8_t buf[BgpProto::kMaxMessageSize];
     119        7296 :     int msglen = BgpProto::Encode(&msg, buf, sizeof(buf));
     120             : 
     121        7294 :     LogNotification(code, subcode, BGP_PEER_DIR_OUT,
     122       14586 :                     peer_ ? peer_->ToUVEKey() : ToString(), msg);
     123        7293 :     if (msglen > BgpProto::kMinMessageSize) {
     124        7293 :         Send(buf, msglen, NULL);
     125             :     }
     126        7297 : }
     127             : 
     128       11086 : void BgpSession::set_peer(BgpPeer *peer) {
     129       11086 :     peer_ = peer;
     130       11086 :     task_instance_ = peer_->GetTaskInstance();
     131       11086 : }
     132             : 
     133             : //
     134             : // Dissociate the peer from the this BgpSession.
     135             : // Do not invalidate the task_instance since it can be used to spawn an
     136             : // io::ReaderTask while this method is being executed.
     137             : //
     138        6215 : void BgpSession::clear_peer() {
     139        6215 :     peer_ = NULL;
     140        6215 : }

Generated by: LCOV version 1.14