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.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c
index ac697be1..d126fe5f 100644
--- a/proto/bgp/packets.c
+++ b/proto/bgp/packets.c
@@ -234,7 +234,7 @@ bgp_create_update(struct bgp_conn *conn, byte *buf)
{
struct bgp_proto *p = conn->bgp;
struct bgp_bucket *buck;
- int size;
+ int size, second;
int remains = BGP_MAX_PACKET_LENGTH - BGP_HEADER_LENGTH - 4;
byte *w, *tmp, *tstart;
ip_addr *ipp, ip, ip_ll;
@@ -292,7 +292,9 @@ bgp_create_update(struct bgp_conn *conn, byte *buf)
nh = ea_find(buck->eattrs, EA_CODE(EAP_BGP, BA_NEXT_HOP));
ASSERT(nh);
- /* We have two addresses here in 'nh'. Really. */
+ /* We have two addresses here in 'nh'. Really.
+ Unless NEXT_HOP was modified by filter */
+ second = (nh->u.ptr->length == NEXT_HOP_LENGTH);
ipp = (ip_addr *) nh->u.ptr->data;
ip = ipp[0];
ip_ll = IPA_NONE;
@@ -316,7 +318,7 @@ bgp_create_update(struct bgp_conn *conn, byte *buf)
n = neigh_find(&p->p, &ip, 0);
if (n && n->iface == p->neigh->iface)
{
- if (ipa_nonzero(ipp[1]))
+ if (second && ipa_nonzero(ipp[1]))
ip_ll = ipp[1];
else
{
@@ -569,7 +571,6 @@ bgp_rx_open(struct bgp_conn *conn, byte *pkt, int len)
{
struct bgp_conn *other;
struct bgp_proto *p = conn->bgp;
- struct bgp_config *cf = p->cf;
unsigned hold;
u16 base_as;
u32 id;
@@ -601,7 +602,17 @@ bgp_rx_open(struct bgp_conn *conn, byte *pkt, int len)
log(L_WARN "%s: Peer advertised inconsistent AS numbers", p->p.name);
if (conn->advertised_as != p->remote_as)
- { bgp_error(conn, 2, 2, (byte *) &(conn->advertised_as), -4); return; }
+ {
+ if (conn->peer_as4_support)
+ {
+ u32 val = htonl(conn->advertised_as);
+ bgp_error(conn, 2, 2, (byte *) &val, 4);
+ }
+ else
+ bgp_error(conn, 2, 2, pkt+20, 2);
+
+ return;
+ }
/* Check the other connection */
other = (conn == &p->outgoing_conn) ? &p->incoming_conn : &p->outgoing_conn;
@@ -973,11 +984,19 @@ bgp_log_error(struct bgp_proto *p, u8 class, char *msg, unsigned code, unsigned
{
*t++ = ':';
*t++ = ' ';
+
+ if ((code == 2) && (subcode == 2) && ((len == 2) || (len == 4)))
+ {
+ /* Bad peer AS - we would like to print the AS */
+ t += bsprintf(t, "%d", (len == 2) ? get_u16(data) : get_u32(data));
+ goto done;
+ }
if (len > 16)
len = 16;
for (i=0; i<len; i++)
t += bsprintf(t, "%02x", data[i]);
}
+ done:
*t = 0;
log(L_REMOTE "%s: %s: %s%s", p->p.name, msg, name, argbuf);
}