Basic analysis of UPDATE packets.
This commit is contained in:
parent
b552ecc4d7
commit
973399ae2c
3 changed files with 83 additions and 2 deletions
|
@ -15,12 +15,15 @@
|
||||||
#include "nest/locks.h"
|
#include "nest/locks.h"
|
||||||
#include "conf/conf.h"
|
#include "conf/conf.h"
|
||||||
#include "lib/socket.h"
|
#include "lib/socket.h"
|
||||||
|
#include "lib/resource.h"
|
||||||
|
|
||||||
#include "bgp.h"
|
#include "bgp.h"
|
||||||
|
|
||||||
|
struct linpool *bgp_linpool; /* Global temporary pool */
|
||||||
static sock *bgp_listen_sk; /* Global listening socket */
|
static sock *bgp_listen_sk; /* Global listening socket */
|
||||||
static int bgp_counter; /* Number of protocol instances using the listening socket */
|
static int bgp_counter; /* Number of protocol instances using the listening socket */
|
||||||
static list bgp_list; /* List of active BGP instances */
|
static list bgp_list; /* List of active BGP instances */
|
||||||
|
static char *bgp_state_names[] = { "Idle", "Connect", "Active", "OpenSent", "OpenConfirm", "Established" };
|
||||||
|
|
||||||
static void bgp_connect(struct bgp_proto *p);
|
static void bgp_connect(struct bgp_proto *p);
|
||||||
static void bgp_setup_sk(struct bgp_proto *p, struct bgp_conn *conn, sock *s);
|
static void bgp_setup_sk(struct bgp_proto *p, struct bgp_conn *conn, sock *s);
|
||||||
|
@ -56,6 +59,8 @@ bgp_close(struct bgp_proto *p)
|
||||||
{
|
{
|
||||||
rfree(bgp_listen_sk);
|
rfree(bgp_listen_sk);
|
||||||
bgp_listen_sk = NULL;
|
bgp_listen_sk = NULL;
|
||||||
|
rfree(bgp_linpool);
|
||||||
|
bgp_linpool = NULL;
|
||||||
}
|
}
|
||||||
/* FIXME: Automatic restart after errors? */
|
/* FIXME: Automatic restart after errors? */
|
||||||
}
|
}
|
||||||
|
@ -275,6 +280,8 @@ bgp_start_locked(struct object_lock *lock)
|
||||||
else
|
else
|
||||||
bgp_listen_sk = s;
|
bgp_listen_sk = s;
|
||||||
}
|
}
|
||||||
|
if (!bgp_linpool)
|
||||||
|
bgp_linpool = lp_new(&root_pool, 4080);
|
||||||
add_tail(&bgp_list, &p->bgp_node);
|
add_tail(&bgp_list, &p->bgp_node);
|
||||||
bgp_connect(p); /* FIXME: Use neighbor cache for fast up/down transitions? */
|
bgp_connect(p); /* FIXME: Use neighbor cache for fast up/down transitions? */
|
||||||
}
|
}
|
||||||
|
@ -385,16 +392,25 @@ bgp_check(struct bgp_config *c)
|
||||||
cf_error("Neighbor must be configured");
|
cf_error("Neighbor must be configured");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
bgp_get_status(struct proto *P, byte *buf)
|
||||||
|
{
|
||||||
|
struct bgp_proto *p = (struct bgp_proto *) P;
|
||||||
|
|
||||||
|
strcpy(buf, bgp_state_names[MAX(p->incoming_conn.state, p->outgoing_conn.state)]);
|
||||||
|
}
|
||||||
|
|
||||||
struct protocol proto_bgp = {
|
struct protocol proto_bgp = {
|
||||||
name: "BGP",
|
name: "BGP",
|
||||||
template: "bgp%d",
|
template: "bgp%d",
|
||||||
init: bgp_init,
|
init: bgp_init,
|
||||||
start: bgp_start,
|
start: bgp_start,
|
||||||
shutdown: bgp_shutdown,
|
shutdown: bgp_shutdown,
|
||||||
|
get_status: bgp_get_status,
|
||||||
#if 0
|
#if 0
|
||||||
dump: bgp_dump,
|
dump: bgp_dump,
|
||||||
get_status: bgp_get_status,
|
|
||||||
get_route_info: bgp_get_route_info,
|
get_route_info: bgp_get_route_info,
|
||||||
show_route_data: bgp_show_route_data
|
show_route_data: bgp_show_route_data
|
||||||
|
/* FIXME: Reconfiguration */
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -54,6 +54,8 @@ struct bgp_proto {
|
||||||
#define BGP_RX_BUFFER_SIZE 4096
|
#define BGP_RX_BUFFER_SIZE 4096
|
||||||
#define BGP_TX_BUFFER_SIZE BGP_MAX_PACKET_LENGTH
|
#define BGP_TX_BUFFER_SIZE BGP_MAX_PACKET_LENGTH
|
||||||
|
|
||||||
|
extern struct linpool *bgp_linpool;
|
||||||
|
|
||||||
void bgp_start_timer(struct timer *t, int value);
|
void bgp_start_timer(struct timer *t, int value);
|
||||||
void bgp_check(struct bgp_config *c);
|
void bgp_check(struct bgp_config *c);
|
||||||
void bgp_error(struct bgp_conn *c, unsigned code, unsigned subcode, unsigned data, unsigned len);
|
void bgp_error(struct bgp_conn *c, unsigned code, unsigned subcode, unsigned data, unsigned len);
|
||||||
|
|
|
@ -215,14 +215,77 @@ bgp_rx_open(struct bgp_conn *conn, byte *pkt, int len)
|
||||||
conn->state = BS_OPENCONFIRM;
|
conn->state = BS_OPENCONFIRM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DECODE_PREFIX(pp, ll) do { \
|
||||||
|
int b = *pp++; \
|
||||||
|
int q; \
|
||||||
|
ip_addr temp; \
|
||||||
|
ll--; \
|
||||||
|
if (b > BITS_PER_IP_ADDRESS) { bgp_error(conn, 3, 10, b, 0); return; } \
|
||||||
|
q = (b+7) / 8; \
|
||||||
|
if (ll < q) goto too_small; \
|
||||||
|
memcpy(&temp, pp, q); \
|
||||||
|
pp += q; \
|
||||||
|
ll -= q; \
|
||||||
|
n.n.prefix = ipa_and(ipa_ntoh(temp), ipa_mkmask(b)); \
|
||||||
|
n.n.pxlen = b; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bgp_rx_update(struct bgp_conn *conn, byte *pkt, int len)
|
bgp_rx_update(struct bgp_conn *conn, byte *pkt, int len)
|
||||||
{
|
{
|
||||||
|
byte *withdrawn, *attrs, *nlri;
|
||||||
|
int withdrawn_len, attr_len, nlri_len;
|
||||||
|
net n;
|
||||||
|
rte e;
|
||||||
|
|
||||||
|
DBG("BGP: UPDATE\n");
|
||||||
if (conn->state != BS_ESTABLISHED)
|
if (conn->state != BS_ESTABLISHED)
|
||||||
{ bgp_error(conn, 5, 0, conn->state, 0); return; }
|
{ bgp_error(conn, 5, 0, conn->state, 0); return; }
|
||||||
bgp_start_timer(conn->hold_timer, conn->hold_time);
|
bgp_start_timer(conn->hold_timer, conn->hold_time);
|
||||||
|
|
||||||
DBG("BGP: UPDATE (ignored)\n");
|
/* Find parts of the packet and check sizes */
|
||||||
|
if (len < 23)
|
||||||
|
{
|
||||||
|
too_small:
|
||||||
|
bgp_error(conn, 1, 2, len, 2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
withdrawn = pkt + 21;
|
||||||
|
withdrawn_len = get_u16(pkt + 19);
|
||||||
|
if (withdrawn_len + 23 > len)
|
||||||
|
goto too_small;
|
||||||
|
attrs = withdrawn + withdrawn_len + 2;
|
||||||
|
attr_len = get_u16(attrs - 2);
|
||||||
|
if (withdrawn_len + attr_len + 23 > len)
|
||||||
|
goto too_small;
|
||||||
|
nlri = attrs + attr_len;
|
||||||
|
nlri_len = len - withdrawn_len - attr_len - 23;
|
||||||
|
if (!attr_len && nlri_len)
|
||||||
|
goto too_small;
|
||||||
|
DBG("Sizes: withdrawn=%d, attrs=%d, NLRI=%d\n", withdrawn_len, attr_len, nlri_len);
|
||||||
|
|
||||||
|
/* Withdraw routes */
|
||||||
|
while (withdrawn_len)
|
||||||
|
{
|
||||||
|
DECODE_PREFIX(withdrawn, withdrawn_len);
|
||||||
|
DBG("Withdraw %I/%d\n", n.n.prefix, n.n.pxlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nlri_len)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
rta *a = bgp_decode_attrs(conn, attrs, attr_len, bgp_linpool);
|
||||||
|
if (a)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
while (nlri_len)
|
||||||
|
{
|
||||||
|
DECODE_PREFIX(nlri, nlri_len);
|
||||||
|
DBG("Add %I/%d\n", n.n.prefix, n.n.pxlen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lp_flush(bgp_linpool);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in a new issue