}
static void
-bmp_schedule_tx_packet(struct bmp_proto *p, const byte *payload, size_t size)
+bmp_schedule_tx_packet(struct bmp_proto *p, buffer *msg)
{
+ const byte *payload = msg->start;
+ size_t size = msg->pos - msg->start;
+
ASSERT(p->started);
while (size)
bmp_put_u32(stream, ts_usec);
}
-/* [4.6] Route Monitoring */
-static byte *
-bmp_route_monitor_msg_serialize(struct bmp_proto *p, const struct bmp_peer_hdr_info *peer,
- byte *update_msg, size_t update_msg_length)
-{
- ASSERT_DIE(update_msg < &p->msgbuf[sizeof p->msgbuf]);
-
- buffer stream;
- STACK_BUFFER_INIT(stream, BMP_PER_PEER_HDR_SIZE + BMP_COMMON_HDR_SIZE);
-
- const size_t data_size = BMP_PER_PEER_HDR_SIZE + update_msg_length;
- bmp_put_common_hdr(&stream, BMP_ROUTE_MONITOR, BMP_COMMON_HDR_SIZE + data_size);
- bmp_put_per_peer_hdr(&stream, peer);
-
- size_t hdr_sz = stream.pos - stream.start;
- ASSERT_DIE(update_msg >= &p->msgbuf[hdr_sz]);
-
- byte *begin = &update_msg[-hdr_sz];
- memcpy(begin, stream.start, hdr_sz);
- return begin;
-}
-
static void
bmp_peer_up_notif_msg_serialize(buffer *stream, const struct bmp_peer_hdr_info *peer,
const ip_addr local_addr, const u16 local_port, const u16 remote_port,
buffer payload = bmp_default_buffer(p);
bmp_peer_up_notif_msg_serialize(&payload, &peer, sk->saddr, sk->sport, sk->dport,
tx_data, tx_data_size, rx_data, rx_data_size);
- bmp_schedule_tx_packet(p, payload.start, payload.pos - payload.start);
+ bmp_schedule_tx_packet(p, &payload);
}
static void
-bmp_route_monitor_put_update(struct bmp_proto *p, struct bmp_stream *bs, byte *data, size_t length, btime timestamp)
+bmp_route_monitor_notify(struct bmp_proto *p, struct bmp_stream *bs,
+ const net_addr *n, const struct rte *new, const struct rte_src *src)
{
struct bgp_proto *bgp = bs->bgp;
+ struct bgp_channel *c = bs->sender;
+
+ btime delta_t = new ? current_time() - new->lastmod : 0;
struct bmp_peer_hdr_info peer = {
.address = bgp->remote_ip,
.id = bgp->remote_id,
.global = bmp_is_peer_global_instance(bgp),
.policy = bmp_stream_policy(bs),
- .timestamp = timestamp,
+ .timestamp = current_real_time() - delta_t,
};
- const byte *start = bmp_route_monitor_msg_serialize(p, &peer, data, length);
- bmp_schedule_tx_packet(p, start, (data - start) + length);
-}
-
-static void
-bmp_route_monitor_notify(struct bmp_proto *p, struct bmp_stream *bs,
- const net_addr *n, const struct rte *new, const struct rte_src *src)
-{
- byte *bufend = &p->msgbuf[sizeof p->msgbuf];
- byte *begin = bufend - BGP_MAX_EXT_MSG_LENGTH;
- byte *end = bgp_bmp_encode_rte(bs->sender, begin, bufend, n, new, src);
-
- btime delta_t = new ? current_time() - new->lastmod : 0;
- btime timestamp = current_real_time() - delta_t;
+ buffer msg = bmp_default_buffer(p);
+ bmp_put_common_hdr(&msg, BMP_ROUTE_MONITOR, 0);
+ bmp_put_per_peer_hdr(&msg, &peer);
- if (end)
- bmp_route_monitor_put_update(p, bs, begin, end - begin, timestamp);
- else
+ bmp_buffer_need(&msg, BGP_MAX_EXT_MSG_LENGTH);
+ byte *pos = bgp_bmp_encode_rte(c, msg.pos + BGP_HEADER_LENGTH, msg.end, n, new, src);
+ if (!pos)
+ {
log(L_WARN "%s: Cannot encode update for %N", p->p.name, n);
+ return;
+ }
+ bmp_put_bgp_hdr(&msg, PKT_UPDATE, pos - msg.pos);
+ msg.pos = pos;
+
+ bmp_fix_common_hdr(&msg);
+ bmp_schedule_tx_packet(p, &msg);
}
static void
bmp_route_monitor_end_of_rib(struct bmp_proto *p, struct bmp_stream *bs)
{
- TRACE(D_PACKETS, "Sending END-OF-RIB for %s.%s", bs->bgp->p.name, bs->sender->c.name);
+ struct bgp_proto *bgp = bs->bgp;
+ struct bgp_channel *c = bs->sender;
+
+ struct bmp_peer_hdr_info peer = {
+ .address = bgp->remote_ip,
+ .as = bgp->remote_as,
+ .id = bgp->remote_id,
+ .global = bmp_is_peer_global_instance(bgp),
+ .policy = bmp_stream_policy(bs),
+ .timestamp = current_real_time(),
+ };
+
+ TRACE(D_PACKETS, "Sending END-OF-RIB for %s.%s", bgp->p.name, c->c.name);
+
+ buffer msg = bmp_default_buffer(p);
+ bmp_put_common_hdr(&msg, BMP_ROUTE_MONITOR, 0);
+ bmp_put_per_peer_hdr(&msg, &peer);
- byte *rx_end_payload = p->msgbuf + BMP_PER_PEER_HDR_SIZE + BMP_COMMON_HDR_SIZE;
- byte *pos = bgp_create_end_mark_(bs->sender, rx_end_payload + BGP_HEADER_LENGTH);
- memset(rx_end_payload + BGP_MSG_HDR_MARKER_POS, 0xff,
- BGP_MSG_HDR_MARKER_SIZE); // BGP UPDATE MSG marker
- put_u16(rx_end_payload + BGP_MSG_HDR_LENGTH_POS, pos - rx_end_payload);
- put_u8(rx_end_payload + BGP_MSG_HDR_TYPE_POS, PKT_UPDATE);
+ bmp_buffer_need(&msg, BGP_MAX_EXT_MSG_LENGTH);
+ byte *pos = bgp_create_end_mark_(c, msg.pos + BGP_HEADER_LENGTH);
+ bmp_put_bgp_hdr(&msg, PKT_UPDATE, pos - msg.pos);
+ msg.pos = pos;
- bmp_route_monitor_put_update(p, bs, rx_end_payload, pos - rx_end_payload, current_real_time());
+ bmp_fix_common_hdr(&msg);
+ bmp_schedule_tx_packet(p, &msg);
}
static void
buffer payload = bmp_default_buffer(p);
bmp_peer_down_notif_msg_serialize(&payload, &peer, info);
- bmp_schedule_tx_packet(p, payload.start, payload.pos - payload.start);
+ bmp_schedule_tx_packet(p, &payload);
}
static void
/* Send initiation message */
buffer payload = bmp_default_buffer(p);
bmp_init_msg_serialize(&payload, p->sys_descr, p->sys_name);
- bmp_schedule_tx_packet(p, payload.start, payload.pos - payload.start);
+ bmp_schedule_tx_packet(p, &payload);
/* Send Peer Up messages */
struct proto *peer;