OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
bgp_session.cc
Go to the documentation of this file.
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"
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 int BgpMessageReader::MsgLength(Buffer buffer, int offset) {
23  size_t size = TcpSession::BufferSize(buffer);
24  int remain = size - offset;
25  if (remain < BgpMessageReader::kHeaderLenSize) {
26  return -1;
27  }
28  const uint8_t *data = TcpSession::BufferData(buffer) + offset;
29  data += 16;
30  int length = get_value(data, 2);
32  assert(length <= 4096);
33  return length;
34 }
35 
37  ReceiveCallback callback)
38  : TcpMessageReader(session, callback) {
39 }
40 
42 }
43 
45  : TcpSession(session_mgr, socket),
46  session_mgr_(session_mgr),
47  peer_(NULL),
48  task_instance_(-1),
49  reader_(new BgpMessageReader(this,
50  boost::bind(&BgpSession::ReceiveMsg, this, _1, _2))) {
51 }
52 
54 }
55 
56 //
57 // Concurrency: called in the context of io::Reader task.
58 //
59 bool BgpSession::ReceiveMsg(const u_int8_t *msg, size_t size) {
60  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 //
72  if (!peer_)
73  return;
75  BgpUpdateSender *sender = server->update_sender();
76  sender->PeerSendReady(peer_);
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 void BgpSession::WriteReady(const boost::system::error_code &error) {
92  if (error)
93  return;
95 }
96 
97 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  if (code == BgpProto::Notification::Cease &&
103  BGP_LOG(BgpPeerNotification, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
104  peer_key, direction, code, subcode, msg.ToString());
105  } else {
106  BGP_LOG(BgpPeerNotificationNotice, SandeshLevel::SYS_NOTICE,
107  BGP_LOG_FLAG_ALL, peer_key, direction, code, subcode,
108  msg.ToString());
109  }
110 }
111 
112 void BgpSession::SendNotification(int code, int subcode,
113  const string &data) {
115  msg.error = code;
116  msg.subcode = subcode;
117  msg.data = data;
118  uint8_t buf[BgpProto::kMaxMessageSize];
119  int msglen = BgpProto::Encode(&msg, buf, sizeof(buf));
120 
121  LogNotification(code, subcode, BGP_PEER_DIR_OUT,
122  peer_ ? peer_->ToUVEKey() : ToString(), msg);
123  if (msglen > BgpProto::kMinMessageSize) {
124  Send(buf, msglen, NULL);
125  }
126 }
127 
129  peer_ = peer;
131 }
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 //
139  peer_ = NULL;
140 }
virtual void WriteReady(const boost::system::error_code &error)
Definition: bgp_session.cc:91
virtual bool ReceiveMsg(BgpSession *session, const u_int8_t *msg, size_t size)
Definition: bgp_peer.cc:2261
#define BGP_LOG(obj, level, flags,...)
Definition: bgp_log.h:59
boost::function< bool(const uint8_t *, size_t)> ReceiveCallback
Definition: tcp_session.h:311
void ProcessWriteReady()
Definition: bgp_session.cc:71
virtual std::string ToString() const
Definition: tcp_session.h:83
static size_t BufferSize(const Buffer &buffer)
Definition: tcp_session.h:116
BgpSessionManager * session_mgr_
Definition: bgp_session.h:67
void set_peer(BgpPeer *peer)
Definition: bgp_session.cc:128
int GetTaskInstance() const
Definition: bgp_peer.cc:2383
virtual bool Send(const uint8_t *data, size_t size, size_t *sent)
Definition: tcp_session.cc:428
static uint64_t get_value(const uint8_t *data, int size)
Definition: parse_object.h:39
static const int kMinMessageSize
Definition: bgp_proto.h:440
boost::asio::ip::tcp::socket Socket
Definition: tcp_session.h:60
virtual ~BgpSession()
Definition: bgp_session.cc:53
virtual BgpServer * server()
Definition: bgp_peer.h:157
void SetSendReady()
Definition: bgp_peer.cc:2216
virtual int MsgLength(Buffer buffer, int offset)
Definition: bgp_session.cc:22
static int Encode(const BgpMessage *msg, uint8_t *data, size_t size, EncodeOffsets *offsets=NULL, bool as4=false)
Definition: bgp_proto.cc:2107
bool unit_test()
Definition: bgp_log.cc:53
boost::asio::const_buffer Buffer
Definition: tcp_session.h:310
bool ReceiveMsg(const u_int8_t *msg, size_t size)
Definition: bgp_session.cc:59
#define BGP_PEER_DIR_OUT
Definition: bgp_log.h:138
virtual ~BgpMessageReader()
Definition: bgp_session.cc:41
BgpPeer * peer()
Definition: bgp_session.h:53
int task_instance_
Definition: bgp_session.h:69
static const int kHeaderLenSize
Definition: bgp_session.h:35
virtual const std::string & ToUVEKey() const
Definition: bgp_peer.h:101
virtual const std::string ToString() const
Definition: bgp_proto.cc:343
static const int kMaxMessageSize
Definition: bgp_proto.h:441
BgpUpdateSender * update_sender()
Definition: bgp_server.h:98
void clear_peer()
Definition: bgp_session.cc:138
BgpPeer * peer_
Definition: bgp_session.h:68
TcpServer * server()
Definition: tcp_session.h:88
void LogNotification(int code, int subcode, const std::string &direction, const std::string &peer_key, const BgpProto::Notification &msg) const
Definition: bgp_session.cc:97
void PeerSendReady(IPeerUpdate *peer)
void SendNotification(int code, int subcode, const std::string &data=std::string())
Definition: bgp_session.cc:112
BgpMessageReader(TcpSession *session, ReceiveCallback callback)
Definition: bgp_session.cc:36
static const uint8_t * BufferData(const Buffer &buffer)
Definition: tcp_session.h:113
void EnqueueWriteReady(BgpSession *session)
BgpSession(BgpSessionManager *session_mgr, Socket *socket)
Definition: bgp_session.cc:44
#define BGP_LOG_FLAG_ALL
Definition: bgp_log.h:44