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: 50 62 80.6 %
Date: 2026-10-05 02:12:29 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       21023 : int BgpMessageReader::MsgLength(Buffer buffer, int offset) {
      23       21023 :     size_t size = TcpSession::BufferSize(buffer);
      24       21021 :     int remain = size - offset;
      25       21021 :     if (remain < BgpMessageReader::kHeaderLenSize) {
      26           0 :         return -1;
      27             :     }
      28       21021 :     const uint8_t *data = TcpSession::BufferData(buffer) + offset;
      29       21020 :     data += 16;
      30       21020 :     int length = get_value(data, 2);
      31       21019 :     if (bgp_log_test::unit_test())
      32       21019 :         assert(length <= 4096);
      33       21019 :     return length;
      34             : }
      35             : 
      36        2305 : BgpMessageReader::BgpMessageReader(TcpSession *session,
      37        2305 :     ReceiveCallback callback)
      38        2305 :     : TcpMessageReader(session, callback) {
      39        2294 : }
      40             : 
      41        4610 : BgpMessageReader::~BgpMessageReader() {
      42        4610 : }
      43             : 
      44        2303 : BgpSession::BgpSession(BgpSessionManager *session_mgr, Socket *socket)
      45             :     : TcpSession(session_mgr, socket),
      46        2305 :       session_mgr_(session_mgr),
      47        2305 :       peer_(NULL),
      48        2305 :       task_instance_(-1),
      49        4599 :       reader_(new BgpMessageReader(this,
      50        4608 :               boost::bind(&BgpSession::ReceiveMsg, this, _1, _2))) {
      51        2294 : }
      52             : 
      53        4610 : BgpSession::~BgpSession() {
      54        4610 : }
      55             : 
      56             : //
      57             : // Concurrency: called in the context of io::Reader task.
      58             : //
      59       21019 : bool BgpSession::ReceiveMsg(const u_int8_t *msg, size_t size) {
      60       21019 :     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        2242 : 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        2242 :     if (code == BgpProto::Notification::Cease &&
     102             :         subcode == BgpProto::Notification::ConnectionCollision) {
     103         333 :         BGP_LOG(BgpPeerNotification, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
     104             :                 peer_key, direction, code, subcode, msg.ToString());
     105             :     } else {
     106        1909 :         BGP_LOG(BgpPeerNotificationNotice, SandeshLevel::SYS_NOTICE,
     107             :                 BGP_LOG_FLAG_ALL, peer_key, direction, code, subcode,
     108             :                 msg.ToString());
     109             :     }
     110        2242 : }
     111             : 
     112        1239 : void BgpSession::SendNotification(int code, int subcode,
     113             :                                   const string &data) {
     114        1239 :     BgpProto::Notification msg;
     115        1237 :     msg.error = code;
     116        1237 :     msg.subcode = subcode;
     117        1237 :     msg.data = data;
     118             :     uint8_t buf[BgpProto::kMaxMessageSize];
     119        1237 :     int msglen = BgpProto::Encode(&msg, buf, sizeof(buf));
     120             : 
     121        1234 :     LogNotification(code, subcode, BGP_PEER_DIR_OUT,
     122        2470 :                     peer_ ? peer_->ToUVEKey() : ToString(), msg);
     123        1237 :     if (msglen > BgpProto::kMinMessageSize) {
     124        1237 :         Send(buf, msglen, NULL);
     125             :     }
     126        1240 : }
     127             : 
     128        1893 : void BgpSession::set_peer(BgpPeer *peer) {
     129        1893 :     peer_ = peer;
     130        1893 :     task_instance_ = peer_->GetTaskInstance();
     131        1893 : }
     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        1115 : void BgpSession::clear_peer() {
     139        1115 :     peer_ = NULL;
     140        1115 : }

Generated by: LCOV version 1.14