summaryrefslogtreecommitdiff
path: root/proto/bgp/packets.c
diff options
context:
space:
mode:
Diffstat (limited to 'proto/bgp/packets.c')
-rw-r--r--proto/bgp/packets.c84
1 files changed, 51 insertions, 33 deletions
diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c
index 66f243bd..ee98115d 100644
--- a/proto/bgp/packets.c
+++ b/proto/bgp/packets.c
@@ -167,7 +167,6 @@ bgp_create_notification(struct bgp_conn *conn, byte *buf)
buf[0] = conn->notify_code;
buf[1] = conn->notify_subcode;
memcpy(buf+2, conn->notify_data, conn->notify_size);
- bmp_peer_down(p, BE_NONE, buf, conn->notify_size + 2);
return buf + 2 + conn->notify_size;
}
@@ -777,6 +776,14 @@ err:
}
static byte *
+bgp_copy_open(struct bgp_proto *p, const byte *pkt, uint len)
+{
+ char *buf = mb_alloc(p->p.pool, len - BGP_HEADER_LENGTH);
+ memcpy(buf, pkt + BGP_HEADER_LENGTH, len - BGP_HEADER_LENGTH);
+ return buf;
+}
+
+static byte *
bgp_create_open(struct bgp_conn *conn, byte *buf)
{
struct bgp_proto *p = conn->bgp;
@@ -850,6 +857,9 @@ bgp_rx_open(struct bgp_conn *conn, byte *pkt, uint len)
id = get_u32(pkt+24);
BGP_TRACE(D_PACKETS, "Got OPEN(as=%d,hold=%d,id=%R)", asn, hold, id);
+ conn->remote_open_msg = bgp_copy_open(p, pkt, len);
+ conn->remote_open_length = len - BGP_HEADER_LENGTH;
+
if (bgp_read_options(conn, pkt+29, pkt[28], len-29) < 0)
return;
@@ -981,7 +991,6 @@ bgp_rx_open(struct bgp_conn *conn, byte *pkt, uint len)
bgp_schedule_packet(conn, NULL, PKT_KEEPALIVE);
bgp_start_timer(conn->hold_timer, conn->hold_time);
bgp_conn_enter_openconfirm_state(conn);
- bmp_put_recv_bgp_open_msg(p, pkt, len);
}
@@ -2419,15 +2428,20 @@ bgp_create_update_bmp(struct bgp_channel *c, byte *buf, struct bgp_bucket *buck,
{
struct bgp_proto *p = (void *) c->c.proto;
byte *end = buf + (BGP_MAX_EXT_MSG_LENGTH - BGP_HEADER_LENGTH);
+ byte *res = NULL;
/* FIXME: must be a bit shorter */
+ struct lp_state tmpp;
+ lp_save(tmp_linpool, &tmpp);
+
struct bgp_caps *peer = p->conn->remote_caps;
const struct bgp_af_caps *rem = bgp_find_af_caps(peer, c->afi);
+
struct bgp_write_state s = {
.proto = p,
.channel = c,
.pool = tmp_linpool,
- .mp_reach = (c->afi != BGP_AF_IPV4) || rem->ext_next_hop,
+ .mp_reach = (c->afi != BGP_AF_IPV4) || (rem && rem->ext_next_hop),
.as4_session = 1,
.add_path = c->add_path_rx,
.mpls = c->desc->mpls,
@@ -2436,16 +2450,20 @@ bgp_create_update_bmp(struct bgp_channel *c, byte *buf, struct bgp_bucket *buck,
if (!update)
{
- return !s.mp_reach ?
+ res = !s.mp_reach ?
bgp_create_ip_unreach(&s, buck, buf, end):
bgp_create_mp_unreach(&s, buck, buf, end);
}
else
{
- return !s.mp_reach ?
+ res = !s.mp_reach ?
bgp_create_ip_reach(&s, buck, buf, end):
bgp_create_mp_reach(&s, buck, buf, end);
}
+
+ lp_restore(tmp_linpool, &tmpp);
+
+ return res;
}
static byte *
@@ -2458,14 +2476,11 @@ bgp_bmp_prepare_bgp_hdr(byte *buf, const u16 msg_size, const u8 msg_type)
return buf + BGP_MSG_HDR_TYPE_POS + BGP_MSG_HDR_TYPE_SIZE;
}
-void
-bgp_rte_update_in_notify(struct channel *C, const net_addr *n,
- const struct rte *new, const struct rte_src *src)
+byte *
+bgp_bmp_encode_rte(struct bgp_channel *c, byte *buf, const net_addr *n,
+ const struct rte *new, const struct rte_src *src)
{
-// struct bgp_proto *p = (void *) C->proto;
- struct bgp_channel *c = (void *) C;
-
- byte buf[BGP_MAX_EXT_MSG_LENGTH];
+// struct bgp_proto *p = (void *) c->c.proto;
byte *pkt = buf + BGP_HEADER_LENGTH;
ea_list *attrs = new ? new->attrs->eattrs : NULL;
@@ -2489,11 +2504,11 @@ bgp_rte_update_in_notify(struct channel *C, const net_addr *n,
add_tail(&b->prefixes, &px->buck_node);
byte *end = bgp_create_update_bmp(c, pkt, b, !!new);
- if (!end)
- return;
- bgp_bmp_prepare_bgp_hdr(buf, end - buf, PKT_UPDATE);
- bmp_route_monitor_put_update_in_pre_msg(buf, end - buf);
+ if (end)
+ bgp_bmp_prepare_bgp_hdr(buf, end - buf, PKT_UPDATE);
+
+ return end;
}
#endif /* CONFIG_BMP */
@@ -2600,6 +2615,14 @@ bgp_create_mp_end_mark(struct bgp_channel *c, byte *buf)
}
byte *
+bgp_create_end_mark_(struct bgp_channel *c, byte *buf)
+{
+ return (c->afi == BGP_AF_IPV4) ?
+ bgp_create_ip_end_mark(c, buf):
+ bgp_create_mp_end_mark(c, buf);
+}
+
+static byte *
bgp_create_end_mark(struct bgp_channel *c, byte *buf)
{
struct bgp_proto *p = (void *) c->c.proto;
@@ -2607,9 +2630,7 @@ bgp_create_end_mark(struct bgp_channel *c, byte *buf)
BGP_TRACE(D_PACKETS, "Sending END-OF-RIB");
p->stats.tx_updates++;
- return (c->afi == BGP_AF_IPV4) ?
- bgp_create_ip_end_mark(c, buf):
- bgp_create_mp_end_mark(c, buf);
+ return bgp_create_end_mark_(c, buf);
}
static inline void
@@ -2750,8 +2771,6 @@ bgp_rx_update(struct bgp_conn *conn, byte *pkt, uint len)
s.ip_reach_len = len - pos;
s.ip_reach_nlri = pkt + pos;
- bmp_route_monitor_update_in_pre_begin();
-
if (s.attr_len)
ea = bgp_decode_attrs(&s, s.attrs, s.attr_len);
else
@@ -2782,9 +2801,6 @@ bgp_rx_update(struct bgp_conn *conn, byte *pkt, uint len)
bgp_decode_nlri(&s, s.mp_reach_af, s.mp_reach_nlri, s.mp_reach_len,
ea, s.mp_next_hop_data, s.mp_next_hop_len);
- bmp_route_monitor_update_in_pre_commit(p);
- bmp_route_monitor_update_in_pre_end();
-
done:
rta_free(s.cached_rta);
lp_restore(tmp_linpool, &tmpp);
@@ -2988,7 +3004,7 @@ bgp_send(struct bgp_conn *conn, uint type, uint len)
conn->bgp->stats.tx_messages++;
conn->bgp->stats.tx_bytes += len;
- memset(buf, 0xff, 16); /* Marker */
+ memset(buf, 0xff, BGP_HDR_MARKER_LENGTH);
put_u16(buf+16, len);
buf[18] = type;
@@ -3036,12 +3052,11 @@ bgp_fire_tx(struct bgp_conn *conn)
{
conn->packets_to_send &= ~(1 << PKT_OPEN);
end = bgp_create_open(conn, pkt);
- int rv = bgp_send(conn, PKT_OPEN, end - buf);
- if (rv >= 0)
- {
- bmp_put_sent_bgp_open_msg(p, pkt, end - buf);
- }
- return rv;
+
+ conn->local_open_msg = bgp_copy_open(p, buf, end - buf);
+ conn->local_open_length = end - buf - BGP_HEADER_LENGTH;
+
+ return bgp_send(conn, PKT_OPEN, end - buf);
}
else if (s & (1 << PKT_KEEPALIVE))
{
@@ -3322,6 +3337,11 @@ bgp_rx_notification(struct bgp_conn *conn, byte *pkt, uint len)
bgp_log_error(p, BE_BGP_RX, "Received", code, subcode, pkt+21, len-21);
bgp_store_error(p, conn, BE_BGP_RX, (code << 16) | subcode);
+ conn->notify_code = code;
+ conn->notify_subcode = subcode;
+ conn->notify_data = pkt+21;
+ conn->notify_size = len-21;
+
bgp_conn_enter_close_state(conn);
bgp_schedule_packet(conn, NULL, PKT_SCHEDULE_CLOSE);
@@ -3340,8 +3360,6 @@ bgp_rx_notification(struct bgp_conn *conn, byte *pkt, uint len)
p->p.disabled = 1;
}
}
-
- bmp_peer_down(p, BE_NONE, pkt, len);
}
static void