BGP documented.
This commit is contained in:
parent
3560cf8e0b
commit
54e55169da
4 changed files with 163 additions and 0 deletions
|
@ -0,0 +1,3 @@
|
||||||
|
S bgp.c
|
||||||
|
S packets.c
|
||||||
|
S attrs.c
|
|
@ -170,6 +170,17 @@ bgp_attach_attr(ea_list **to, struct linpool *pool, unsigned attr, unsigned val)
|
||||||
return bgp_set_attr(a->attrs, pool, attr, val);
|
return bgp_set_attr(a->attrs, pool, attr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bgp_encode_attrs - encode BGP attributes
|
||||||
|
* @w: buffer
|
||||||
|
* @attrs: a list of extended attributes
|
||||||
|
* @remains: remaining space in the buffer
|
||||||
|
*
|
||||||
|
* The bgp_encode_attrs() function takes a list of extended attributes
|
||||||
|
* and converts it to its BGP representation (a part of an Update message).
|
||||||
|
*
|
||||||
|
* Result: Length of the attribute block generated.
|
||||||
|
*/
|
||||||
unsigned int
|
unsigned int
|
||||||
bgp_encode_attrs(byte *w, ea_list *attrs, int remains)
|
bgp_encode_attrs(byte *w, ea_list *attrs, int remains)
|
||||||
{
|
{
|
||||||
|
@ -715,6 +726,18 @@ bgp_path_loopy(struct bgp_proto *p, eattr *a)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bgp_decode_attrs - check and decode BGP attributes
|
||||||
|
* @conn: connection
|
||||||
|
* @attr: start of attribute block
|
||||||
|
* @len: length of attribute block
|
||||||
|
* @pool: linear pool to make all the allocations in
|
||||||
|
* @mandatory: 1 iff presence of mandatory attributes has to be checked
|
||||||
|
*
|
||||||
|
* This function takes a BGP attribute block (a part of an Update message), checks
|
||||||
|
* its consistency and converts it to a list of BIRD route attributes represented
|
||||||
|
* by a &rta.
|
||||||
|
*/
|
||||||
struct rta *
|
struct rta *
|
||||||
bgp_decode_attrs(struct bgp_conn *conn, byte *attr, unsigned int len, struct linpool *pool, int mandatory)
|
bgp_decode_attrs(struct bgp_conn *conn, byte *attr, unsigned int len, struct linpool *pool, int mandatory)
|
||||||
{
|
{
|
||||||
|
|
101
proto/bgp/bgp.c
101
proto/bgp/bgp.c
|
@ -6,6 +6,53 @@
|
||||||
* Can be freely distributed and used under the terms of the GNU GPL.
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOC: Border Gateway Protocol
|
||||||
|
*
|
||||||
|
* The BGP protocol is implemented in three parts: |bgp.c| which takes care of the
|
||||||
|
* connection and most of the interface with BIRD core, |packets.c| handling
|
||||||
|
* both incoming and outgoing BGP packets and |attrs.c| containing functions for
|
||||||
|
* manipulation with BGP attribute lists.
|
||||||
|
*
|
||||||
|
* As opposed to the other existing routing daemons, BIRD has a sophisticated core
|
||||||
|
* architecture which is able to keep all the information needed by BGP in the
|
||||||
|
* primary routing table, therefore no complex data structures like a central
|
||||||
|
* BGP table are needed. This increases memory footprint of a BGP router with
|
||||||
|
* many connections, but not too much and, which is more important, it makes
|
||||||
|
* BGP much easier to implement.
|
||||||
|
*
|
||||||
|
* Each instance of BGP (corresponding to one BGP peer) is described by a &bgp_proto
|
||||||
|
* structure to which are attached individual connections represented by &bgp_connection
|
||||||
|
* (usually, there exists only one connection, but during BGP session setup, there
|
||||||
|
* can be more of them). The connections are handled according to the BGP state machine
|
||||||
|
* defined in the RFC with all the timers and all the parameters configurable.
|
||||||
|
*
|
||||||
|
* In incoming direction, we listen on the connection's socket and each time we receive
|
||||||
|
* some input, we pass it to bgp_rx(). It decodes packet headers and the markers and
|
||||||
|
* passes complete packets to bgp_rx_packet() which distributes the packet according
|
||||||
|
* to its type.
|
||||||
|
*
|
||||||
|
* In outgoing direction, we gather all the routing updates and sort them to buckets
|
||||||
|
* (&bgp_bucket) according to their attributes (we keep a hash table for fast comparison
|
||||||
|
* of &rta's and a &fib which helps us to find if we already have another route for
|
||||||
|
* the same destination queued for sending, so that we can replace it with the new one
|
||||||
|
* immediately instead of sending both updates). There also exists a special bucket holding
|
||||||
|
* all the route withdrawals which cannot be queued anywhere else as they don't have any
|
||||||
|
* attributes. If we have any packet to send (due to either new routes or the connection
|
||||||
|
* tracking code wanting to send a Open, KeepAlive or Notification message), we call
|
||||||
|
* bgp_schedule_packet() which sets the corresponding bit in a @packet_to_send
|
||||||
|
* bit field in &bgp_conn and as soon as the transmit socket buffer becomes empty,
|
||||||
|
* we call bgp_fire_tx(). It inspects state of all the packet type bits and calls
|
||||||
|
* the corresponding bgp_create_xx() functions, eventually rescheduling the same packet
|
||||||
|
* type if we have more data of the same type to send.
|
||||||
|
*
|
||||||
|
* The processing of attributes consists of two functions: bgp_decode_attrs() for checking
|
||||||
|
* of the attribute blocks and translating them to the language of BIRD's extended attributes
|
||||||
|
* and bgp_encode_attrs() which does the converse. Both functions are built around a
|
||||||
|
* @bgp_attr_table array describing all important characteristics of all known attributes.
|
||||||
|
* Unknown transitive attributes are attached to the route as %EAF_TYPE_OPAQUE byte streams.
|
||||||
|
*/
|
||||||
|
|
||||||
#undef LOCAL_DEBUG
|
#undef LOCAL_DEBUG
|
||||||
|
|
||||||
#include "nest/bird.h"
|
#include "nest/bird.h"
|
||||||
|
@ -42,6 +89,15 @@ bgp_close(struct bgp_proto *p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bgp_start_timer - start a BGP timer
|
||||||
|
* @t: timer
|
||||||
|
* @value: time to fire (0 to disable the timer)
|
||||||
|
*
|
||||||
|
* This functions calls tm_start() on @t with time @value and the
|
||||||
|
* amount of randomization suggested by the BGP standard. Please use
|
||||||
|
* it for all BGP timers.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
bgp_start_timer(timer *t, int value)
|
bgp_start_timer(timer *t, int value)
|
||||||
{
|
{
|
||||||
|
@ -55,6 +111,19 @@ bgp_start_timer(timer *t, int value)
|
||||||
tm_stop(t);
|
tm_stop(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bgp_close_conn - close a BGP connection
|
||||||
|
* @conn: connection to close
|
||||||
|
*
|
||||||
|
* This function takes a connection described by the &bgp_conn structure,
|
||||||
|
* closes its socket and frees all resources associated with it.
|
||||||
|
*
|
||||||
|
* If the connection is being closed due to a protocol error, adjust
|
||||||
|
* the connection restart timer as well according to the error recovery
|
||||||
|
* policy set in the configuration.
|
||||||
|
*
|
||||||
|
* If the connection was marked as primary, it shuts down the protocol as well.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
bgp_close_conn(struct bgp_conn *conn)
|
bgp_close_conn(struct bgp_conn *conn)
|
||||||
{
|
{
|
||||||
|
@ -231,6 +300,14 @@ bgp_setup_sk(struct bgp_proto *p, struct bgp_conn *conn, sock *s)
|
||||||
conn->sk = s;
|
conn->sk = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bgp_connect - initiate an outgoing connection
|
||||||
|
* @p: BGP instance
|
||||||
|
*
|
||||||
|
* The bgp_connect() function creates a new &bgp_conn and initiates
|
||||||
|
* a TCP connection to the peer. The rest of connection setup is governed
|
||||||
|
* by the BGP state machine as described in the standard.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
bgp_connect(struct bgp_proto *p) /* Enter Connect state and start establishing connection */
|
bgp_connect(struct bgp_proto *p) /* Enter Connect state and start establishing connection */
|
||||||
{
|
{
|
||||||
|
@ -279,6 +356,18 @@ bgp_initiate(struct bgp_proto *p)
|
||||||
bgp_connect(p);
|
bgp_connect(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bgp_incoming_connection - handle an incoming connection
|
||||||
|
* @sk: TCP socket
|
||||||
|
* @dummy: unused
|
||||||
|
*
|
||||||
|
* This function serves as a socket hook for accepting of new BGP
|
||||||
|
* connections. It searches a BGP instance corresponding to the peer
|
||||||
|
* which has connected and if such an instance exists, it creates a
|
||||||
|
* &bgp_conn structure, attaches it to the instance and either sends
|
||||||
|
* an Open message or (if there already is an active connection) it
|
||||||
|
* closes the new connection by sending a Notification message.
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
bgp_incoming_connection(sock *sk, int dummy)
|
bgp_incoming_connection(sock *sk, int dummy)
|
||||||
{
|
{
|
||||||
|
@ -473,6 +562,18 @@ bgp_init(struct proto_config *C)
|
||||||
return P;
|
return P;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bgp_error - report a protocol error
|
||||||
|
* @c: connection
|
||||||
|
* @code: error code (according to the RFC)
|
||||||
|
* @subcode: error subcode
|
||||||
|
* @data: data to be passed in the Notification message
|
||||||
|
* @len: length of the data
|
||||||
|
*
|
||||||
|
* bgp_error() sends a notification packet to tell the other side that a protocol
|
||||||
|
* error has occured (including the data considered erroneous if possible) and
|
||||||
|
* closes the connection.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
bgp_error(struct bgp_conn *c, unsigned code, unsigned subcode, byte *data, int len)
|
bgp_error(struct bgp_conn *c, unsigned code, unsigned subcode, byte *data, int len)
|
||||||
{
|
{
|
||||||
|
|
|
@ -236,6 +236,16 @@ bgp_create_header(byte *buf, unsigned int len, unsigned int type)
|
||||||
buf[18] = type;
|
buf[18] = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bgp_fire_tx - transmit packets
|
||||||
|
* @conn: connection
|
||||||
|
*
|
||||||
|
* Whenever the transmit buffers of the underlying TCP connection
|
||||||
|
* are free and we have any packets queued for sending, the socket functions
|
||||||
|
* call bgp_fire_tx() which takes care of selecting the highest priority packet
|
||||||
|
* queued (Notification > Keepalive > Open > Update), assembling its header
|
||||||
|
* and body and sending it to the connection.
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
bgp_fire_tx(struct bgp_conn *conn)
|
bgp_fire_tx(struct bgp_conn *conn)
|
||||||
{
|
{
|
||||||
|
@ -295,6 +305,13 @@ bgp_fire_tx(struct bgp_conn *conn)
|
||||||
return sk_send(sk, end - buf);
|
return sk_send(sk, end - buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bgp_schedule_packet - schedule a packet for transmission
|
||||||
|
* @conn: connection
|
||||||
|
* @type: packet type
|
||||||
|
*
|
||||||
|
* Schedule a packet of type @type to be sent as soon as possible.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
bgp_schedule_packet(struct bgp_conn *conn, int type)
|
bgp_schedule_packet(struct bgp_conn *conn, int type)
|
||||||
{
|
{
|
||||||
|
@ -770,6 +787,15 @@ bgp_rx_keepalive(struct bgp_conn *conn, byte *pkt, unsigned len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bgp_rx_packet - handle a received packet
|
||||||
|
* @conn: BGP connection
|
||||||
|
* @pkt: start of the packet
|
||||||
|
* @len: packet size
|
||||||
|
*
|
||||||
|
* bgp_rx_packet() takes a newly received packet and calls the corresponding
|
||||||
|
* packet handler according to the packet type.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
bgp_rx_packet(struct bgp_conn *conn, byte *pkt, unsigned len)
|
bgp_rx_packet(struct bgp_conn *conn, byte *pkt, unsigned len)
|
||||||
{
|
{
|
||||||
|
@ -784,6 +810,16 @@ bgp_rx_packet(struct bgp_conn *conn, byte *pkt, unsigned len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bgp_rx - handle received data
|
||||||
|
* @sk: socket
|
||||||
|
* @size: amount of data received
|
||||||
|
*
|
||||||
|
* bgp_rx() is called by the socket layer whenever new data arrive from
|
||||||
|
* the underlying TCP connection. It assembles the data fragments to packets,
|
||||||
|
* checks their headers and framing and passes complete packets to
|
||||||
|
* bgp_rx_packet().
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
bgp_rx(sock *sk, int size)
|
bgp_rx(sock *sk, int size)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue