summaryrefslogtreecommitdiff
path: root/proto/bgp/packets.c
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2018-09-18 17:29:00 +0200
committerOndrej Zajicek (work) <santiago@crfreenet.org>2018-09-18 17:50:45 +0200
commitc0fc3e67185c1e0ff2d083572c6ad3983ba4ef25 (patch)
tree9fe17603f4fec18b7f9fbd8d8efc1f13a9bef8ee /proto/bgp/packets.c
parentafa14f1868f2c753efdc81ce8e2c2d44e6bdd80e (diff)
The MRT protocol
The new MRT protocol is responsible for periodic RIB table dumps in the MRT format (RFC 6396). Also the existing code for BGP4MP MRT dumps is refactored and splitted between BGP to MRT protocols, will be more integrated into MRT in the future. Example: protocol mrt { table "*"; filename "%N_%F_%T.mrt"; period 60; } It is partially based on the old MRT code from Pavel Tvrdik.
Diffstat (limited to 'proto/bgp/packets.c')
-rw-r--r--proto/bgp/packets.c96
1 files changed, 30 insertions, 66 deletions
diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c
index a39670ef..2248b9f9 100644
--- a/proto/bgp/packets.c
+++ b/proto/bgp/packets.c
@@ -13,7 +13,7 @@
#include "nest/protocol.h"
#include "nest/route.h"
#include "nest/attrs.h"
-#include "nest/mrtdump.h"
+#include "proto/mrt/mrt.h"
#include "conf/conf.h"
#include "lib/unaligned.h"
#include "lib/socket.h"
@@ -38,81 +38,45 @@ static byte fsm_err_subcode[BS_MAX] = {
[BS_ESTABLISHED] = 3
};
-/*
- * MRT Dump format is not semantically specified.
- * We will use these values in appropriate fields:
- *
- * Local AS, Remote AS - configured AS numbers for given BGP instance.
- * Local IP, Remote IP - IP addresses of the TCP connection (0 if no connection)
- *
- * We dump two kinds of MRT messages: STATE_CHANGE (for BGP state
- * changes) and MESSAGE (for received BGP messages).
- *
- * STATE_CHANGE uses always AS4 variant, but MESSAGE uses AS4 variant
- * only when AS4 session is established and even in that case MESSAGE
- * does not use AS4 variant for initial OPEN message. This strange
- * behavior is here for compatibility with Quagga and Bgpdump,
- */
-
-static byte *
-mrt_put_bgp4_hdr(byte *buf, struct bgp_conn *conn, int as4)
+static void
+init_mrt_bgp_data(struct bgp_conn *conn, struct mrt_bgp_data *d)
{
struct bgp_proto *p = conn->bgp;
-
- if (as4)
- {
- put_u32(buf+0, p->remote_as);
- put_u32(buf+4, p->local_as);
- buf+=8;
- }
- else
- {
- put_u16(buf+0, (p->remote_as <= 0xFFFF) ? p->remote_as : AS_TRANS);
- put_u16(buf+2, (p->local_as <= 0xFFFF) ? p->local_as : AS_TRANS);
- buf+=4;
- }
-
- put_u16(buf+0, (p->neigh && p->neigh->iface) ? p->neigh->iface->index : 0);
- put_u16(buf+2, BGP_AF);
- buf+=4;
- buf = put_ipa(buf, conn->sk ? conn->sk->daddr : IPA_NONE);
- buf = put_ipa(buf, conn->sk ? conn->sk->saddr : IPA_NONE);
-
- return buf;
+ int p_ok = conn->state >= BS_OPENCONFIRM;
+
+ memset(d, 0, sizeof(struct mrt_bgp_data));
+ d->peer_as = p->remote_as;
+ d->local_as = p->local_as;
+ d->index = (p->neigh && p->neigh->iface) ? p->neigh->iface->index : 0;
+ d->af = BGP_AF;
+ d->peer_ip = conn->sk ? conn->sk->daddr : IPA_NONE;
+ d->local_ip = conn->sk ? conn->sk->saddr : IPA_NONE;
+ d->as4 = p_ok ? p->as4_session : 0;
+ d->add_path = p_ok ? p->add_path_rx : 0;
}
static void
-mrt_dump_bgp_packet(struct bgp_conn *conn, byte *pkt, unsigned len)
+bgp_dump_message(struct bgp_conn *conn, byte *pkt, uint len)
{
- byte *buf = alloca(128+len); /* 128 is enough for MRT headers */
- byte *bp = buf + MRTDUMP_HDR_LENGTH;
- int as4 = conn->bgp->as4_session;
-
- bp = mrt_put_bgp4_hdr(bp, conn, as4);
- memcpy(bp, pkt, len);
- bp += len;
- mrt_dump_message(&conn->bgp->p, BGP4MP, as4 ? BGP4MP_MESSAGE_AS4 : BGP4MP_MESSAGE,
- buf, bp-buf);
-}
+ struct mrt_bgp_data d;
+ init_mrt_bgp_data(conn, &d);
-static inline u16
-convert_state(unsigned state)
-{
- /* Convert state from our BS_* values to values used in MRTDump */
- return (state == BS_CLOSE) ? 1 : state + 1;
+ d.message = pkt;
+ d.msg_len = len;
+
+ mrt_dump_bgp_message(&d);
}
void
-mrt_dump_bgp_state_change(struct bgp_conn *conn, unsigned old, unsigned new)
+bgp_dump_state_change(struct bgp_conn *conn, uint old, uint new)
{
- byte buf[128];
- byte *bp = buf + MRTDUMP_HDR_LENGTH;
-
- bp = mrt_put_bgp4_hdr(bp, conn, 1);
- put_u16(bp+0, convert_state(old));
- put_u16(bp+2, convert_state(new));
- bp += 4;
- mrt_dump_message(&conn->bgp->p, BGP4MP, BGP4MP_STATE_CHANGE_AS4, buf, bp-buf);
+ struct mrt_bgp_data d;
+ init_mrt_bgp_data(conn, &d);
+
+ d.old_state = old;
+ d.new_state = new;
+
+ mrt_dump_bgp_state_change(&d);
}
static byte *
@@ -1764,7 +1728,7 @@ bgp_rx_packet(struct bgp_conn *conn, byte *pkt, unsigned len)
DBG("BGP: Got packet %02x (%d bytes)\n", type, len);
if (conn->bgp->p.mrtdump & MD_MESSAGES)
- mrt_dump_bgp_packet(conn, pkt, len);
+ bgp_dump_message(conn, pkt, len);
switch (type)
{