summaryrefslogtreecommitdiff
path: root/proto/bgp
diff options
context:
space:
mode:
Diffstat (limited to 'proto/bgp')
-rw-r--r--proto/bgp/attrs.c7
-rw-r--r--proto/bgp/bgp.c2
-rw-r--r--proto/bgp/bgp.h2
-rw-r--r--proto/bgp/packets.c96
4 files changed, 36 insertions, 71 deletions
diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c
index 3b88791d..05fcfe72 100644
--- a/proto/bgp/attrs.c
+++ b/proto/bgp/attrs.c
@@ -471,7 +471,7 @@ bgp_get_attr_len(eattr *a)
/**
* bgp_encode_attrs - encode BGP attributes
- * @p: BGP instance
+ * @p: BGP instance (or NULL)
* @w: buffer
* @attrs: a list of extended attributes
* @remains: remaining space in the buffer
@@ -485,6 +485,7 @@ uint
bgp_encode_attrs(struct bgp_proto *p, byte *w, ea_list *attrs, int remains)
{
uint i, code, type, flags;
+ int as4_session = p ? p->as4_session : 1;
byte *start = w;
int len, rv;
@@ -504,7 +505,7 @@ bgp_encode_attrs(struct bgp_proto *p, byte *w, ea_list *attrs, int remains)
* we have to convert our 4B AS_PATH to 2B AS_PATH and send our AS_PATH
* as optional AS4_PATH attribute.
*/
- if ((code == BA_AS_PATH) && (! p->as4_session))
+ if ((code == BA_AS_PATH) && !as4_session)
{
len = a->u.ptr->length;
@@ -546,7 +547,7 @@ bgp_encode_attrs(struct bgp_proto *p, byte *w, ea_list *attrs, int remains)
}
/* The same issue with AGGREGATOR attribute */
- if ((code == BA_AGGREGATOR) && (! p->as4_session))
+ if ((code == BA_AGGREGATOR) && !as4_session)
{
int new_used;
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
index a4b37691..d4b056be 100644
--- a/proto/bgp/bgp.c
+++ b/proto/bgp/bgp.c
@@ -352,7 +352,7 @@ static inline void
bgp_conn_set_state(struct bgp_conn *conn, unsigned new_state)
{
if (conn->bgp->p.mrtdump & MD_STATES)
- mrt_dump_bgp_state_change(conn, conn->state, new_state);
+ bgp_dump_state_change(conn, conn->state, new_state);
conn->state = new_state;
}
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h
index 2ff61834..d76f7f22 100644
--- a/proto/bgp/bgp.h
+++ b/proto/bgp/bgp.h
@@ -288,7 +288,7 @@ inline static void bgp_attach_attr_ip(struct ea_list **to, struct linpool *pool,
/* packets.c */
-void mrt_dump_bgp_state_change(struct bgp_conn *conn, unsigned old, unsigned new);
+void bgp_dump_state_change(struct bgp_conn *conn, uint old, uint new);
void bgp_schedule_packet(struct bgp_conn *conn, int type);
void bgp_kick_tx(void *vconn);
void bgp_tx(struct birdsock *sk);
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)
{