version 1.1.1.4, 2013/07/21 23:54:37
|
version 1.1.1.5, 2016/11/02 10:09:10
|
Line 28 Software Foundation, Inc., 59 Temple Place - Suite 330
|
Line 28 Software Foundation, Inc., 59 Temple Place - Suite 330
|
#include "log.h" |
#include "log.h" |
#include "memory.h" |
#include "memory.h" |
#include "sockunion.h" /* for inet_ntop () */ |
#include "sockunion.h" /* for inet_ntop () */ |
|
#include "sockopt.h" |
#include "linklist.h" |
#include "linklist.h" |
#include "plist.h" |
#include "plist.h" |
|
#include "filter.h" |
|
|
#include "bgpd/bgpd.h" |
#include "bgpd/bgpd.h" |
#include "bgpd/bgp_table.h" |
#include "bgpd/bgp_table.h" |
Line 45 Software Foundation, Inc., 59 Temple Place - Suite 330
|
Line 47 Software Foundation, Inc., 59 Temple Place - Suite 330
|
#include "bgpd/bgp_ecommunity.h" |
#include "bgpd/bgp_ecommunity.h" |
#include "bgpd/bgp_network.h" |
#include "bgpd/bgp_network.h" |
#include "bgpd/bgp_mplsvpn.h" |
#include "bgpd/bgp_mplsvpn.h" |
|
#include "bgpd/bgp_encap.h" |
#include "bgpd/bgp_advertise.h" |
#include "bgpd/bgp_advertise.h" |
#include "bgpd/bgp_vty.h" |
#include "bgpd/bgp_vty.h" |
|
|
int stream_put_prefix (struct stream *, struct prefix *); |
int stream_put_prefix (struct stream *, struct prefix *); |
| |
/* Set up BGP packet marker and packet type. */ |
/* Set up BGP packet marker and packet type. */ |
static int |
static int |
bgp_packet_set_marker (struct stream *s, u_char type) |
bgp_packet_set_marker (struct stream *s, u_char type) |
Line 142 static struct stream *
|
Line 145 static struct stream *
|
bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi) |
bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi) |
{ |
{ |
struct stream *s; |
struct stream *s; |
|
struct stream *snlri; |
struct bgp_adj_out *adj; |
struct bgp_adj_out *adj; |
struct bgp_advertise *adv; |
struct bgp_advertise *adv; |
struct stream *packet; |
struct stream *packet; |
struct bgp_node *rn = NULL; |
struct bgp_node *rn = NULL; |
struct bgp_info *binfo = NULL; |
struct bgp_info *binfo = NULL; |
bgp_size_t total_attr_len = 0; |
bgp_size_t total_attr_len = 0; |
unsigned long pos; | unsigned long attrlen_pos = 0; |
| size_t mpattrlen_pos = 0; |
| size_t mpattr_pos = 0; |
|
|
s = peer->work; |
s = peer->work; |
stream_reset (s); |
stream_reset (s); |
|
snlri = peer->scratch; |
|
stream_reset (snlri); |
|
|
adv = FIFO_HEAD (&peer->sync[afi][safi]->update); | adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update); |
|
|
while (adv) |
while (adv) |
{ |
{ |
Line 164 bgp_update_packet (struct peer *peer, afi_t afi, safi_
|
Line 172 bgp_update_packet (struct peer *peer, afi_t afi, safi_
|
binfo = adv->binfo; |
binfo = adv->binfo; |
|
|
/* When remaining space can't include NLRI and it's length. */ |
/* When remaining space can't include NLRI and it's length. */ |
if (STREAM_REMAIN (s) <= BGP_NLRI_LENGTH + PSIZE (rn->p.prefixlen)) | if (STREAM_CONCAT_REMAIN (s, snlri, STREAM_SIZE(s)) <= |
| (BGP_NLRI_LENGTH + bgp_packet_mpattr_prefix_size(afi,safi,&rn->p))) |
break; |
break; |
|
|
/* If packet is empty, set attribute. */ |
/* If packet is empty, set attribute. */ |
Line 173 bgp_update_packet (struct peer *peer, afi_t afi, safi_
|
Line 182 bgp_update_packet (struct peer *peer, afi_t afi, safi_
|
struct prefix_rd *prd = NULL; |
struct prefix_rd *prd = NULL; |
u_char *tag = NULL; |
u_char *tag = NULL; |
struct peer *from = NULL; |
struct peer *from = NULL; |
| |
if (rn->prn) |
if (rn->prn) |
prd = (struct prefix_rd *) &rn->prn->p; |
prd = (struct prefix_rd *) &rn->prn->p; |
if (binfo) |
if (binfo) |
Line 182 bgp_update_packet (struct peer *peer, afi_t afi, safi_
|
Line 191 bgp_update_packet (struct peer *peer, afi_t afi, safi_
|
if (binfo->extra) |
if (binfo->extra) |
tag = binfo->extra->tag; |
tag = binfo->extra->tag; |
} |
} |
| |
| /* 1: Write the BGP message header - 16 bytes marker, 2 bytes length, |
| * one byte message type. |
| */ |
bgp_packet_set_marker (s, BGP_MSG_UPDATE); |
bgp_packet_set_marker (s, BGP_MSG_UPDATE); |
stream_putw (s, 0); | |
pos = stream_get_endp (s); | /* 2: withdrawn routes length */ |
stream_putw (s, 0); |
stream_putw (s, 0); |
total_attr_len = bgp_packet_attribute (NULL, peer, s, | |
| /* 3: total attributes length - attrlen_pos stores the position */ |
| attrlen_pos = stream_get_endp (s); |
| stream_putw (s, 0); |
| |
| /* 4: if there is MP_REACH_NLRI attribute, that should be the first |
| * attribute, according to draft-ietf-idr-error-handling. Save the |
| * position. |
| */ |
| mpattr_pos = stream_get_endp(s); |
| |
| /* 5: Encode all the attributes, except MP_REACH_NLRI attr. */ |
| total_attr_len = bgp_packet_attribute (NULL, peer, s, |
adv->baa->attr, |
adv->baa->attr, |
&rn->p, afi, safi, | ((afi == AFI_IP && safi == SAFI_UNICAST) ? |
| &rn->p : NULL), |
| afi, safi, |
from, prd, tag); |
from, prd, tag); |
stream_putw_at (s, pos, total_attr_len); |
|
} |
} |
|
|
if (afi == AFI_IP && safi == SAFI_UNICAST) |
if (afi == AFI_IP && safi == SAFI_UNICAST) |
stream_put_prefix (s, &rn->p); |
stream_put_prefix (s, &rn->p); |
| else |
| { |
| /* Encode the prefix in MP_REACH_NLRI attribute */ |
| struct prefix_rd *prd = NULL; |
| u_char *tag = NULL; |
| |
| if (rn->prn) |
| prd = (struct prefix_rd *) &rn->prn->p; |
| if (binfo && binfo->extra) |
| tag = binfo->extra->tag; |
| |
| if (stream_empty(snlri)) |
| mpattrlen_pos = bgp_packet_mpattr_start(snlri, afi, safi, |
| adv->baa->attr); |
| bgp_packet_mpattr_prefix(snlri, afi, safi, &rn->p, prd, tag); |
| } |
if (BGP_DEBUG (update, UPDATE_OUT)) |
if (BGP_DEBUG (update, UPDATE_OUT)) |
{ |
{ |
char buf[INET6_BUFSIZ]; |
char buf[INET6_BUFSIZ]; |
Line 216 bgp_update_packet (struct peer *peer, afi_t afi, safi_
|
Line 256 bgp_update_packet (struct peer *peer, afi_t afi, safi_
|
adj->attr = bgp_attr_intern (adv->baa->attr); |
adj->attr = bgp_attr_intern (adv->baa->attr); |
|
|
adv = bgp_advertise_clean (peer, adj, afi, safi); |
adv = bgp_advertise_clean (peer, adj, afi, safi); |
|
|
if (! (afi == AFI_IP && safi == SAFI_UNICAST)) |
|
break; |
|
} |
} |
| |
if (! stream_empty (s)) |
if (! stream_empty (s)) |
{ |
{ |
bgp_packet_set_size (s); | if (!stream_empty(snlri)) |
packet = stream_dup (s); | { |
| bgp_packet_mpattr_end(snlri, mpattrlen_pos); |
| total_attr_len += stream_get_endp(snlri); |
| } |
| |
| /* set the total attribute length correctly */ |
| stream_putw_at (s, attrlen_pos, total_attr_len); |
| |
| if (!stream_empty(snlri)) |
| packet = stream_dupcat(s, snlri, mpattr_pos); |
| else |
| packet = stream_dup (s); |
| bgp_packet_set_size (packet); |
bgp_packet_add (peer, packet); |
bgp_packet_add (peer, packet); |
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd); |
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd); |
stream_reset (s); |
stream_reset (s); |
|
stream_reset (snlri); |
return packet; |
return packet; |
} |
} |
return NULL; |
return NULL; |
Line 237 static struct stream *
|
Line 287 static struct stream *
|
bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi) |
bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi) |
{ |
{ |
struct stream *s; |
struct stream *s; |
struct stream *packet; |
|
|
|
if (DISABLE_BGP_ANNOUNCE) |
if (DISABLE_BGP_ANNOUNCE) |
return NULL; |
return NULL; |
Line 270 bgp_update_packet_eor (struct peer *peer, afi_t afi, s
|
Line 319 bgp_update_packet_eor (struct peer *peer, afi_t afi, s
|
} |
} |
|
|
bgp_packet_set_size (s); |
bgp_packet_set_size (s); |
packet = stream_dup (s); | bgp_packet_add (peer, s); |
bgp_packet_add (peer, packet); | return s; |
stream_free (s); | |
return packet; | |
} |
} |
|
|
/* Make BGP withdraw packet. */ |
/* Make BGP withdraw packet. */ |
|
/* For ipv4 unicast: |
|
16-octet marker | 2-octet length | 1-octet type | |
|
2-octet withdrawn route length | withdrawn prefixes | 2-octet attrlen (=0) |
|
*/ |
|
/* For other afi/safis: |
|
16-octet marker | 2-octet length | 1-octet type | |
|
2-octet withdrawn route length (=0) | 2-octet attrlen | |
|
mp_unreach attr type | attr len | afi | safi | withdrawn prefixes |
|
*/ |
static struct stream * |
static struct stream * |
bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi) |
bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi) |
{ |
{ |
Line 285 bgp_withdraw_packet (struct peer *peer, afi_t afi, saf
|
Line 341 bgp_withdraw_packet (struct peer *peer, afi_t afi, saf
|
struct bgp_adj_out *adj; |
struct bgp_adj_out *adj; |
struct bgp_advertise *adv; |
struct bgp_advertise *adv; |
struct bgp_node *rn; |
struct bgp_node *rn; |
unsigned long pos; |
|
bgp_size_t unfeasible_len; |
bgp_size_t unfeasible_len; |
bgp_size_t total_attr_len; |
bgp_size_t total_attr_len; |
|
size_t mp_start = 0; |
|
size_t attrlen_pos = 0; |
|
size_t mplen_pos = 0; |
|
u_char first_time = 1; |
|
|
s = peer->work; |
s = peer->work; |
stream_reset (s); |
stream_reset (s); |
|
|
while ((adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL) | while ((adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL) |
{ |
{ |
assert (adv->rn); |
assert (adv->rn); |
adj = adv->adj; |
adj = adv->adj; |
rn = adv->rn; |
rn = adv->rn; |
|
|
if (STREAM_REMAIN (s) | if (STREAM_REMAIN (s) |
< (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN + PSIZE (rn->p.prefixlen))) |
< (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN + PSIZE (rn->p.prefixlen))) |
break; |
break; |
|
|
if (stream_empty (s)) |
if (stream_empty (s)) |
{ |
{ |
bgp_packet_set_marker (s, BGP_MSG_UPDATE); |
bgp_packet_set_marker (s, BGP_MSG_UPDATE); |
stream_putw (s, 0); | stream_putw (s, 0); /* unfeasible routes length */ |
} |
} |
|
else |
|
first_time = 0; |
|
|
if (afi == AFI_IP && safi == SAFI_UNICAST) |
if (afi == AFI_IP && safi == SAFI_UNICAST) |
stream_put_prefix (s, &rn->p); |
stream_put_prefix (s, &rn->p); |
else |
else |
{ |
{ |
struct prefix_rd *prd = NULL; |
struct prefix_rd *prd = NULL; |
| |
if (rn->prn) |
if (rn->prn) |
prd = (struct prefix_rd *) &rn->prn->p; |
prd = (struct prefix_rd *) &rn->prn->p; |
pos = stream_get_endp (s); | |
stream_putw (s, 0); | /* If first time, format the MP_UNREACH header */ |
total_attr_len | if (first_time) |
= bgp_packet_withdraw (peer, s, &rn->p, afi, safi, prd, NULL); | { |
| attrlen_pos = stream_get_endp (s); |
/* Set total path attribute length. */ | /* total attr length = 0 for now. reevaluate later */ |
stream_putw_at (s, pos, total_attr_len); | stream_putw (s, 0); |
| mp_start = stream_get_endp (s); |
| mplen_pos = bgp_packet_mpunreach_start(s, afi, safi); |
| } |
| |
| bgp_packet_mpunreach_prefix(s, &rn->p, afi, safi, prd, NULL); |
} |
} |
|
|
if (BGP_DEBUG (update, UPDATE_OUT)) |
if (BGP_DEBUG (update, UPDATE_OUT)) |
Line 339 bgp_withdraw_packet (struct peer *peer, afi_t afi, saf
|
Line 405 bgp_withdraw_packet (struct peer *peer, afi_t afi, saf
|
|
|
bgp_adj_out_remove (rn, adj, peer, afi, safi); |
bgp_adj_out_remove (rn, adj, peer, afi, safi); |
bgp_unlock_node (rn); |
bgp_unlock_node (rn); |
|
|
if (! (afi == AFI_IP && safi == SAFI_UNICAST)) |
|
break; |
|
} |
} |
|
|
if (! stream_empty (s)) |
if (! stream_empty (s)) |
{ |
{ |
if (afi == AFI_IP && safi == SAFI_UNICAST) |
if (afi == AFI_IP && safi == SAFI_UNICAST) |
{ |
{ |
unfeasible_len | unfeasible_len |
= stream_get_endp (s) - BGP_HEADER_SIZE - BGP_UNFEASIBLE_LEN; |
= stream_get_endp (s) - BGP_HEADER_SIZE - BGP_UNFEASIBLE_LEN; |
stream_putw_at (s, BGP_HEADER_SIZE, unfeasible_len); |
stream_putw_at (s, BGP_HEADER_SIZE, unfeasible_len); |
stream_putw (s, 0); |
stream_putw (s, 0); |
} |
} |
|
else |
|
{ |
|
/* Set the mp_unreach attr's length */ |
|
bgp_packet_mpunreach_end(s, mplen_pos); |
|
|
|
/* Set total path attribute length. */ |
|
total_attr_len = stream_get_endp(s) - mp_start; |
|
stream_putw_at (s, attrlen_pos, total_attr_len); |
|
} |
bgp_packet_set_size (s); |
bgp_packet_set_size (s); |
packet = stream_dup (s); |
packet = stream_dup (s); |
bgp_packet_add (peer, packet); |
bgp_packet_add (peer, packet); |
Line 368 bgp_default_update_send (struct peer *peer, struct att
|
Line 440 bgp_default_update_send (struct peer *peer, struct att
|
afi_t afi, safi_t safi, struct peer *from) |
afi_t afi, safi_t safi, struct peer *from) |
{ |
{ |
struct stream *s; |
struct stream *s; |
struct stream *packet; |
|
struct prefix p; |
struct prefix p; |
unsigned long pos; |
unsigned long pos; |
bgp_size_t total_attr_len; |
bgp_size_t total_attr_len; |
Line 378 bgp_default_update_send (struct peer *peer, struct att
|
Line 449 bgp_default_update_send (struct peer *peer, struct att
|
|
|
if (afi == AFI_IP) |
if (afi == AFI_IP) |
str2prefix ("0.0.0.0/0", &p); |
str2prefix ("0.0.0.0/0", &p); |
#ifdef HAVE_IPV6 |
|
else |
else |
str2prefix ("::/0", &p); |
str2prefix ("::/0", &p); |
#endif /* HAVE_IPV6 */ |
|
|
|
/* Logging the attribute. */ |
/* Logging the attribute. */ |
if (BGP_DEBUG (update, UPDATE_OUT)) |
if (BGP_DEBUG (update, UPDATE_OUT)) |
Line 419 bgp_default_update_send (struct peer *peer, struct att
|
Line 488 bgp_default_update_send (struct peer *peer, struct att
|
/* Set size. */ |
/* Set size. */ |
bgp_packet_set_size (s); |
bgp_packet_set_size (s); |
|
|
packet = stream_dup (s); |
|
stream_free (s); |
|
|
|
/* Dump packet if debug option is set. */ |
/* Dump packet if debug option is set. */ |
#ifdef DEBUG |
#ifdef DEBUG |
/* bgp_packet_dump (packet); */ |
/* bgp_packet_dump (packet); */ |
#endif /* DEBUG */ |
#endif /* DEBUG */ |
|
|
/* Add packet to the peer. */ |
/* Add packet to the peer. */ |
bgp_packet_add (peer, packet); | bgp_packet_add (peer, s); |
|
|
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd); |
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd); |
} |
} |
Line 437 void
|
Line 503 void
|
bgp_default_withdraw_send (struct peer *peer, afi_t afi, safi_t safi) |
bgp_default_withdraw_send (struct peer *peer, afi_t afi, safi_t safi) |
{ |
{ |
struct stream *s; |
struct stream *s; |
struct stream *packet; |
|
struct prefix p; |
struct prefix p; |
unsigned long pos; | unsigned long attrlen_pos = 0; |
unsigned long cp; |
unsigned long cp; |
bgp_size_t unfeasible_len; |
bgp_size_t unfeasible_len; |
bgp_size_t total_attr_len; |
bgp_size_t total_attr_len; |
|
size_t mp_start = 0; |
|
size_t mplen_pos = 0; |
|
|
if (DISABLE_BGP_ANNOUNCE) |
if (DISABLE_BGP_ANNOUNCE) |
return; |
return; |
|
|
if (afi == AFI_IP) |
if (afi == AFI_IP) |
str2prefix ("0.0.0.0/0", &p); |
str2prefix ("0.0.0.0/0", &p); |
#ifdef HAVE_IPV6 |
|
else |
else |
str2prefix ("::/0", &p); |
str2prefix ("::/0", &p); |
#endif /* HAVE_IPV6 */ |
|
|
|
total_attr_len = 0; |
total_attr_len = 0; |
pos = 0; |
|
|
|
if (BGP_DEBUG (update, UPDATE_OUT)) |
if (BGP_DEBUG (update, UPDATE_OUT)) |
{ |
{ |
Line 490 bgp_default_withdraw_send (struct peer *peer, afi_t af
|
Line 554 bgp_default_withdraw_send (struct peer *peer, afi_t af
|
} |
} |
else |
else |
{ |
{ |
pos = stream_get_endp (s); | attrlen_pos = stream_get_endp (s); |
stream_putw (s, 0); |
stream_putw (s, 0); |
total_attr_len = bgp_packet_withdraw (peer, s, &p, afi, safi, NULL, NULL); | mp_start = stream_get_endp (s); |
| mplen_pos = bgp_packet_mpunreach_start(s, afi, safi); |
| bgp_packet_mpunreach_prefix(s, &p, afi, safi, NULL, NULL); |
|
|
|
/* Set the mp_unreach attr's length */ |
|
bgp_packet_mpunreach_end(s, mplen_pos); |
|
|
/* Set total path attribute length. */ |
/* Set total path attribute length. */ |
stream_putw_at (s, pos, total_attr_len); | total_attr_len = stream_get_endp(s) - mp_start; |
| stream_putw_at (s, attrlen_pos, total_attr_len); |
} |
} |
|
|
bgp_packet_set_size (s); |
bgp_packet_set_size (s); |
|
|
packet = stream_dup (s); |
|
stream_free (s); |
|
|
|
/* Add packet to the peer. */ |
/* Add packet to the peer. */ |
bgp_packet_add (peer, packet); | bgp_packet_add (peer, s); |
|
|
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd); |
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd); |
} |
} |
Line 525 bgp_write_packet (struct peer *peer)
|
Line 592 bgp_write_packet (struct peer *peer)
|
for (afi = AFI_IP; afi < AFI_MAX; afi++) |
for (afi = AFI_IP; afi < AFI_MAX; afi++) |
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) |
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) |
{ |
{ |
adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw); | adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->withdraw); |
if (adv) |
if (adv) |
{ |
{ |
s = bgp_withdraw_packet (peer, afi, safi); |
s = bgp_withdraw_packet (peer, afi, safi); |
Line 537 bgp_write_packet (struct peer *peer)
|
Line 604 bgp_write_packet (struct peer *peer)
|
for (afi = AFI_IP; afi < AFI_MAX; afi++) |
for (afi = AFI_IP; afi < AFI_MAX; afi++) |
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) |
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) |
{ |
{ |
adv = FIFO_HEAD (&peer->sync[afi][safi]->update); | adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update); |
if (adv) |
if (adv) |
{ |
{ |
if (adv->binfo && adv->binfo->uptime < peer->synctime) |
if (adv->binfo && adv->binfo->uptime < peer->synctime) |
{ |
{ |
if (CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_RCV) |
if (CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_RCV) |
&& CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_ADV) |
&& CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_ADV) |
|
&& ! (CHECK_FLAG (adv->binfo->peer->cap, |
|
PEER_CAP_RESTART_BIT_RCV) && |
|
CHECK_FLAG (adv->binfo->peer->cap, |
|
PEER_CAP_RESTART_BIT_ADV)) |
&& ! CHECK_FLAG (adv->binfo->flags, BGP_INFO_STALE) |
&& ! CHECK_FLAG (adv->binfo->flags, BGP_INFO_STALE) |
&& safi != SAFI_MPLS_VPN) |
&& safi != SAFI_MPLS_VPN) |
{ |
{ |
Line 593 bgp_write_proceed (struct peer *peer)
|
Line 664 bgp_write_proceed (struct peer *peer)
|
|
|
for (afi = AFI_IP; afi < AFI_MAX; afi++) |
for (afi = AFI_IP; afi < AFI_MAX; afi++) |
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) |
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) |
if ((adv = FIFO_HEAD (&peer->sync[afi][safi]->update)) != NULL) | if ((adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update)) != NULL) |
if (adv->binfo->uptime < peer->synctime) |
if (adv->binfo->uptime < peer->synctime) |
return 1; |
return 1; |
|
|
Line 719 bgp_write_notify (struct peer *peer)
|
Line 790 bgp_write_notify (struct peer *peer)
|
return 0; |
return 0; |
assert (stream_get_endp (s) >= BGP_HEADER_SIZE); |
assert (stream_get_endp (s) >= BGP_HEADER_SIZE); |
|
|
/* Put socket in blocking mode. */ |
|
val = fcntl (peer->fd, F_GETFL, 0); |
|
fcntl (peer->fd, F_SETFL, val & ~O_NONBLOCK); |
|
|
|
/* Stop collecting data within the socket */ |
/* Stop collecting data within the socket */ |
sockopt_cork (peer->fd, 0); |
sockopt_cork (peer->fd, 0); |
|
|
|
/* socket is in nonblocking mode, if we can't deliver the NOTIFY, well, |
|
* we only care about getting a clean shutdown at this point. */ |
ret = write (peer->fd, STREAM_DATA (s), stream_get_endp (s)); |
ret = write (peer->fd, STREAM_DATA (s), stream_get_endp (s)); |
|
|
|
/* only connection reset/close gets counted as TCP_fatal_error, failure |
|
* to write the entire NOTIFY doesn't get different FSM treatment */ |
if (ret <= 0) |
if (ret <= 0) |
{ |
{ |
BGP_EVENT_ADD (peer, TCP_fatal_error); |
BGP_EVENT_ADD (peer, TCP_fatal_error); |
Line 903 bgp_notify_send_with_data (struct peer *peer, u_char c
|
Line 975 bgp_notify_send_with_data (struct peer *peer, u_char c
|
} |
} |
} |
} |
bgp_notify_print (peer, &bgp_notify, "sending"); |
bgp_notify_print (peer, &bgp_notify, "sending"); |
|
|
if (bgp_notify.data) |
if (bgp_notify.data) |
XFREE (MTYPE_TMP, bgp_notify.data); | { |
| XFREE (MTYPE_TMP, bgp_notify.data); |
| bgp_notify.data = NULL; |
| bgp_notify.length = 0; |
| } |
} |
} |
|
|
if (BGP_DEBUG (normal, NORMAL)) |
if (BGP_DEBUG (normal, NORMAL)) |
Line 954 bgp_route_refresh_send (struct peer *peer, afi_t afi,
|
Line 1031 bgp_route_refresh_send (struct peer *peer, afi_t afi,
|
u_char orf_type, u_char when_to_refresh, int remove) |
u_char orf_type, u_char when_to_refresh, int remove) |
{ |
{ |
struct stream *s; |
struct stream *s; |
struct stream *packet; |
|
int length; |
int length; |
struct bgp_filter *filter; |
struct bgp_filter *filter; |
int orf_refresh = 0; |
int orf_refresh = 0; |
Line 1035 bgp_route_refresh_send (struct peer *peer, afi_t afi,
|
Line 1111 bgp_route_refresh_send (struct peer *peer, afi_t afi,
|
BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length); |
BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length); |
} |
} |
|
|
/* Make real packet. */ |
|
packet = stream_dup (s); |
|
stream_free (s); |
|
|
|
/* Add packet to the peer. */ |
/* Add packet to the peer. */ |
bgp_packet_add (peer, packet); | bgp_packet_add (peer, s); |
|
|
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd); |
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd); |
} |
} |
Line 1051 bgp_capability_send (struct peer *peer, afi_t afi, saf
|
Line 1123 bgp_capability_send (struct peer *peer, afi_t afi, saf
|
int capability_code, int action) |
int capability_code, int action) |
{ |
{ |
struct stream *s; |
struct stream *s; |
struct stream *packet; |
|
int length; |
int length; |
|
|
/* Adjust safi code. */ |
/* Adjust safi code. */ |
Line 1082 bgp_capability_send (struct peer *peer, afi_t afi, saf
|
Line 1153 bgp_capability_send (struct peer *peer, afi_t afi, saf
|
/* Set packet size. */ |
/* Set packet size. */ |
length = bgp_packet_set_size (s); |
length = bgp_packet_set_size (s); |
|
|
/* Make real packet. */ |
|
packet = stream_dup (s); |
|
stream_free (s); |
|
|
|
/* Add packet to the peer. */ |
/* Add packet to the peer. */ |
bgp_packet_add (peer, packet); | bgp_packet_add (peer, s); |
|
|
if (BGP_DEBUG (normal, NORMAL)) |
if (BGP_DEBUG (normal, NORMAL)) |
zlog_debug ("%s send message type %d, length (incl. header) %d", |
zlog_debug ("%s send message type %d, length (incl. header) %d", |
Line 1095 bgp_capability_send (struct peer *peer, afi_t afi, saf
|
Line 1163 bgp_capability_send (struct peer *peer, afi_t afi, saf
|
|
|
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd); |
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd); |
} |
} |
| |
/* RFC1771 6.8 Connection collision detection. */ |
/* RFC1771 6.8 Connection collision detection. */ |
static int |
static int |
bgp_collision_detect (struct peer *new, struct in_addr remote_id) |
bgp_collision_detect (struct peer *new, struct in_addr remote_id) |
Line 1485 bgp_open_receive (struct peer *peer, bgp_size_t size)
|
Line 1553 bgp_open_receive (struct peer *peer, bgp_size_t size)
|
{ |
{ |
bgp_notify_send (peer, |
bgp_notify_send (peer, |
BGP_NOTIFY_OPEN_ERR, |
BGP_NOTIFY_OPEN_ERR, |
BGP_NOTIFY_OPEN_UNACEP_HOLDTIME); | BGP_NOTIFY_OPEN_UNSPECIFIC); |
return ret; |
return ret; |
} |
} |
} |
} |
Line 1512 bgp_open_receive (struct peer *peer, bgp_size_t size)
|
Line 1580 bgp_open_receive (struct peer *peer, bgp_size_t size)
|
|
|
/* Get sockname. */ |
/* Get sockname. */ |
bgp_getsockname (peer); |
bgp_getsockname (peer); |
|
peer->rtt = sockopt_tcp_rtt (peer->fd); |
|
|
BGP_EVENT_ADD (peer, Receive_OPEN_message); |
BGP_EVENT_ADD (peer, Receive_OPEN_message); |
|
|
Line 1522 bgp_open_receive (struct peer *peer, bgp_size_t size)
|
Line 1591 bgp_open_receive (struct peer *peer, bgp_size_t size)
|
return 0; |
return 0; |
} |
} |
|
|
|
/* Frontend for NLRI parsing, to fan-out to AFI/SAFI specific parsers */ |
|
int |
|
bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet) |
|
{ |
|
switch (packet->safi) |
|
{ |
|
case SAFI_UNICAST: |
|
case SAFI_MULTICAST: |
|
return bgp_nlri_parse_ip (peer, attr, packet); |
|
case SAFI_MPLS_VPN: |
|
case SAFI_MPLS_LABELED_VPN: |
|
return bgp_nlri_parse_vpn (peer, attr, packet); |
|
case SAFI_ENCAP: |
|
return bgp_nlri_parse_encap (peer, attr, packet); |
|
} |
|
return -1; |
|
} |
|
|
/* Parse BGP Update packet and make attribute object. */ |
/* Parse BGP Update packet and make attribute object. */ |
static int |
static int |
bgp_update_receive (struct peer *peer, bgp_size_t size) |
bgp_update_receive (struct peer *peer, bgp_size_t size) |
{ |
{ |
int ret; | int ret, nlri_ret; |
u_char *end; |
u_char *end; |
struct stream *s; |
struct stream *s; |
struct attr attr; |
struct attr attr; |
Line 1534 bgp_update_receive (struct peer *peer, bgp_size_t size
|
Line 1621 bgp_update_receive (struct peer *peer, bgp_size_t size
|
bgp_size_t attribute_len; |
bgp_size_t attribute_len; |
bgp_size_t update_len; |
bgp_size_t update_len; |
bgp_size_t withdraw_len; |
bgp_size_t withdraw_len; |
struct bgp_nlri update; | int i; |
struct bgp_nlri withdraw; | |
struct bgp_nlri mp_update; | enum NLRI_TYPES { |
struct bgp_nlri mp_withdraw; | NLRI_UPDATE, |
| NLRI_WITHDRAW, |
| NLRI_MP_UPDATE, |
| NLRI_MP_WITHDRAW, |
| NLRI_TYPE_MAX, |
| }; |
| struct bgp_nlri nlris[NLRI_TYPE_MAX]; |
|
|
/* Status must be Established. */ |
/* Status must be Established. */ |
if (peer->status != Established) |
if (peer->status != Established) |
Line 1551 bgp_update_receive (struct peer *peer, bgp_size_t size
|
Line 1644 bgp_update_receive (struct peer *peer, bgp_size_t size
|
/* Set initial values. */ |
/* Set initial values. */ |
memset (&attr, 0, sizeof (struct attr)); |
memset (&attr, 0, sizeof (struct attr)); |
memset (&extra, 0, sizeof (struct attr_extra)); |
memset (&extra, 0, sizeof (struct attr_extra)); |
memset (&update, 0, sizeof (struct bgp_nlri)); | memset (&nlris, 0, sizeof nlris); |
memset (&withdraw, 0, sizeof (struct bgp_nlri)); | |
memset (&mp_update, 0, sizeof (struct bgp_nlri)); | |
memset (&mp_withdraw, 0, sizeof (struct bgp_nlri)); | |
attr.extra = &extra; |
attr.extra = &extra; |
|
|
s = peer->ibuf; |
s = peer->ibuf; |
Line 1591 bgp_update_receive (struct peer *peer, bgp_size_t size
|
Line 1681 bgp_update_receive (struct peer *peer, bgp_size_t size
|
/* Unfeasible Route packet format check. */ |
/* Unfeasible Route packet format check. */ |
if (withdraw_len > 0) |
if (withdraw_len > 0) |
{ |
{ |
ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), withdraw_len); | nlris[NLRI_WITHDRAW].afi = AFI_IP; |
if (ret < 0) | nlris[NLRI_WITHDRAW].safi = SAFI_UNICAST; |
return -1; | nlris[NLRI_WITHDRAW].nlri = stream_pnt (s); |
| nlris[NLRI_WITHDRAW].length = withdraw_len; |
| |
if (BGP_DEBUG (packet, PACKET_RECV)) |
if (BGP_DEBUG (packet, PACKET_RECV)) |
zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host); |
zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host); |
|
|
withdraw.afi = AFI_IP; |
|
withdraw.safi = SAFI_UNICAST; |
|
withdraw.nlri = stream_pnt (s); |
|
withdraw.length = withdraw_len; |
|
stream_forward_getp (s, withdraw_len); |
stream_forward_getp (s, withdraw_len); |
} |
} |
|
|
Line 1647 bgp_update_receive (struct peer *peer, bgp_size_t size
|
Line 1734 bgp_update_receive (struct peer *peer, bgp_size_t size
|
if (attribute_len) |
if (attribute_len) |
{ |
{ |
attr_parse_ret = bgp_attr_parse (peer, &attr, attribute_len, |
attr_parse_ret = bgp_attr_parse (peer, &attr, attribute_len, |
&mp_update, &mp_withdraw); | &nlris[NLRI_MP_UPDATE], &nlris[NLRI_MP_WITHDRAW]); |
if (attr_parse_ret == BGP_ATTR_PARSE_ERROR) |
if (attr_parse_ret == BGP_ATTR_PARSE_ERROR) |
return -1; | { |
| bgp_attr_unintern_sub (&attr); |
| bgp_attr_flush (&attr); |
| return -1; |
| } |
} |
} |
|
|
/* Logging the attribute. */ |
/* Logging the attribute. */ |
Line 1678 bgp_update_receive (struct peer *peer, bgp_size_t size
|
Line 1769 bgp_update_receive (struct peer *peer, bgp_size_t size
|
|
|
if (update_len) |
if (update_len) |
{ |
{ |
/* Check NLRI packet format and prefix length. */ |
|
ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), update_len); |
|
if (ret < 0) |
|
{ |
|
bgp_attr_unintern_sub (&attr); |
|
return -1; |
|
} |
|
|
|
/* Set NLRI portion to structure. */ |
/* Set NLRI portion to structure. */ |
update.afi = AFI_IP; | nlris[NLRI_UPDATE].afi = AFI_IP; |
update.safi = SAFI_UNICAST; | nlris[NLRI_UPDATE].safi = SAFI_UNICAST; |
update.nlri = stream_pnt (s); | nlris[NLRI_UPDATE].nlri = stream_pnt (s); |
update.length = update_len; | nlris[NLRI_UPDATE].length = update_len; |
| |
stream_forward_getp (s, update_len); |
stream_forward_getp (s, update_len); |
} |
} |
| |
/* NLRI is processed only when the peer is configured specific | /* Parse any given NLRIs */ |
Address Family and Subsequent Address Family. */ | for (i = NLRI_UPDATE; i < NLRI_TYPE_MAX; i++) |
if (peer->afc[AFI_IP][SAFI_UNICAST]) | |
{ |
{ |
if (withdraw.length) | /* We use afi and safi as indices into tables and what not. It would |
bgp_nlri_parse (peer, NULL, &withdraw); | * be impossible, at this time, to support unknown afi/safis. And |
| * anyway, the peer needs to be configured to enable the afi/safi |
if (update.length) | * explicitly which requires UI support. |
{ | * |
/* We check well-known attribute only for IPv4 unicast | * Ignore unknown afi/safi NLRIs. |
update. */ | * |
ret = bgp_attr_check (peer, &attr); | * Note: this means nlri[x].afi/safi still can not be trusted for |
if (ret < 0) | * indexing later in this function! |
{ | * |
bgp_attr_unintern_sub (&attr); | * Note2: This will also remap the wire code-point for VPN safi to the |
return -1; | * internal safi_t point, as needs be. |
} | */ |
| if (!bgp_afi_safi_valid_indices (nlris[i].afi, &nlris[i].safi)) |
bgp_nlri_parse (peer, NLRI_ATTR_ARG, &update); | { |
} | plog_info (peer->log, |
| "%s [Info] UPDATE with unsupported AFI/SAFI %u/%u", |
if (mp_update.length | peer->host, nlris[i].afi, nlris[i].safi); |
&& mp_update.afi == AFI_IP | continue; |
&& mp_update.safi == SAFI_UNICAST) | } |
bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update); | |
| /* NLRI is processed only when the peer is configured specific |
if (mp_withdraw.length | Address Family and Subsequent Address Family. */ |
&& mp_withdraw.afi == AFI_IP | if (!peer->afc[nlris[i].afi][nlris[i].safi]) |
&& mp_withdraw.safi == SAFI_UNICAST) | { |
bgp_nlri_parse (peer, NULL, &mp_withdraw); | plog_info (peer->log, |
| "%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u", |
if (! attribute_len && ! withdraw_len) | peer->host, nlris[i].afi, nlris[i].safi); |
{ | continue; |
/* End-of-RIB received */ | } |
SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST], | |
PEER_STATUS_EOR_RECEIVED); | /* EoR handled later */ |
| if (nlris[i].length == 0) |
/* NSF delete stale route */ | continue; |
if (peer->nsf[AFI_IP][SAFI_UNICAST]) | |
bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST); | switch (i) |
| { |
if (BGP_DEBUG (normal, NORMAL)) | case NLRI_UPDATE: |
zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Unicast from %s", | case NLRI_MP_UPDATE: |
peer->host); | nlri_ret = bgp_nlri_parse (peer, NLRI_ATTR_ARG, &nlris[i]); |
} | break; |
| case NLRI_WITHDRAW: |
| case NLRI_MP_WITHDRAW: |
| nlri_ret = bgp_nlri_parse (peer, NULL, &nlris[i]); |
| } |
| |
| if (nlri_ret < 0) |
| { |
| plog_err (peer->log, |
| "%s [Error] Error parsing NLRI", peer->host); |
| if (peer->status == Established) |
| bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, |
| i <= NLRI_WITHDRAW |
| ? BGP_NOTIFY_UPDATE_INVAL_NETWORK |
| : BGP_NOTIFY_UPDATE_OPT_ATTR_ERR); |
| bgp_attr_unintern_sub (&attr); |
| return -1; |
| } |
} |
} |
if (peer->afc[AFI_IP][SAFI_MULTICAST]) | |
| /* EoR checks. |
| * |
| * Non-MP IPv4/Unicast EoR is a completely empty UPDATE |
| * and MP EoR should have only an empty MP_UNREACH |
| */ |
| if (!update_len && !withdraw_len |
| && nlris[NLRI_MP_UPDATE].length == 0) |
{ |
{ |
if (mp_update.length | afi_t afi = 0; |
&& mp_update.afi == AFI_IP | safi_t safi; |
&& mp_update.safi == SAFI_MULTICAST) | |
bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update); | /* Non-MP IPv4/Unicast is a completely empty UPDATE - already |
| * checked update and withdraw NLRI lengths are 0. |
if (mp_withdraw.length | */ |
&& mp_withdraw.afi == AFI_IP | if (!attribute_len) |
&& mp_withdraw.safi == SAFI_MULTICAST) | { |
bgp_nlri_parse (peer, NULL, &mp_withdraw); | afi = AFI_IP; |
| safi = SAFI_UNICAST; |
if (! withdraw_len | } |
&& mp_withdraw.afi == AFI_IP | /* otherwise MP AFI/SAFI is an empty update, other than an empty |
&& mp_withdraw.safi == SAFI_MULTICAST | * MP_UNREACH_NLRI attr (with an AFI/SAFI we recognise). |
&& mp_withdraw.length == 0) | */ |
{ | else if (attr.flag == BGP_ATTR_MP_UNREACH_NLRI |
| && nlris[NLRI_MP_WITHDRAW].length == 0 |
| && bgp_afi_safi_valid_indices (nlris[NLRI_MP_WITHDRAW].afi, |
| &nlris[NLRI_MP_WITHDRAW].safi)) |
| { |
| afi = nlris[NLRI_MP_WITHDRAW].afi; |
| safi = nlris[NLRI_MP_WITHDRAW].safi; |
| } |
| |
| if (afi && peer->afc[afi][safi]) |
| { |
/* End-of-RIB received */ |
/* End-of-RIB received */ |
SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST], | SET_FLAG (peer->af_sflags[afi][safi], |
PEER_STATUS_EOR_RECEIVED); |
PEER_STATUS_EOR_RECEIVED); |
|
|
/* NSF delete stale route */ |
/* NSF delete stale route */ |
if (peer->nsf[AFI_IP][SAFI_MULTICAST]) | if (peer->nsf[afi][safi]) |
bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST); | bgp_clear_stale_route (peer, afi, safi); |
|
|
if (BGP_DEBUG (normal, NORMAL)) |
if (BGP_DEBUG (normal, NORMAL)) |
zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Multicast from %s", | zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for %s from %s", |
peer->host); | peer->host, afi_safi_print (afi, safi)); |
} | } |
} |
} |
if (peer->afc[AFI_IP6][SAFI_UNICAST]) | |
{ | |
if (mp_update.length | |
&& mp_update.afi == AFI_IP6 | |
&& mp_update.safi == SAFI_UNICAST) | |
bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update); | |
| |
if (mp_withdraw.length | |
&& mp_withdraw.afi == AFI_IP6 | |
&& mp_withdraw.safi == SAFI_UNICAST) | |
bgp_nlri_parse (peer, NULL, &mp_withdraw); | |
| |
if (! withdraw_len | |
&& mp_withdraw.afi == AFI_IP6 | |
&& mp_withdraw.safi == SAFI_UNICAST | |
&& mp_withdraw.length == 0) | |
{ | |
/* End-of-RIB received */ | |
SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED); | |
| |
/* NSF delete stale route */ | |
if (peer->nsf[AFI_IP6][SAFI_UNICAST]) | |
bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST); | |
| |
if (BGP_DEBUG (normal, NORMAL)) | |
zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Unicast from %s", | |
peer->host); | |
} | |
} | |
if (peer->afc[AFI_IP6][SAFI_MULTICAST]) | |
{ | |
if (mp_update.length | |
&& mp_update.afi == AFI_IP6 | |
&& mp_update.safi == SAFI_MULTICAST) | |
bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update); | |
| |
if (mp_withdraw.length | |
&& mp_withdraw.afi == AFI_IP6 | |
&& mp_withdraw.safi == SAFI_MULTICAST) | |
bgp_nlri_parse (peer, NULL, &mp_withdraw); | |
| |
if (! withdraw_len | |
&& mp_withdraw.afi == AFI_IP6 | |
&& mp_withdraw.safi == SAFI_MULTICAST | |
&& mp_withdraw.length == 0) | |
{ | |
/* End-of-RIB received */ | |
| |
/* NSF delete stale route */ | |
if (peer->nsf[AFI_IP6][SAFI_MULTICAST]) | |
bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST); | |
| |
if (BGP_DEBUG (update, UPDATE_IN)) | |
zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Multicast from %s", | |
peer->host); | |
} | |
} | |
if (peer->afc[AFI_IP][SAFI_MPLS_VPN]) | |
{ | |
if (mp_update.length | |
&& mp_update.afi == AFI_IP | |
&& mp_update.safi == SAFI_MPLS_LABELED_VPN) | |
bgp_nlri_parse_vpnv4 (peer, NLRI_ATTR_ARG, &mp_update); | |
| |
if (mp_withdraw.length | |
&& mp_withdraw.afi == AFI_IP | |
&& mp_withdraw.safi == SAFI_MPLS_LABELED_VPN) | |
bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw); | |
| |
if (! withdraw_len | |
&& mp_withdraw.afi == AFI_IP | |
&& mp_withdraw.safi == SAFI_MPLS_LABELED_VPN | |
&& mp_withdraw.length == 0) | |
{ | |
/* End-of-RIB received */ | |
| |
if (BGP_DEBUG (update, UPDATE_IN)) | |
zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s", | |
peer->host); | |
} | |
} | |
| |
/* Everything is done. We unintern temporary structures which |
/* Everything is done. We unintern temporary structures which |
interned in bgp_attr_parse(). */ |
interned in bgp_attr_parse(). */ |
bgp_attr_unintern_sub (&attr); |
bgp_attr_unintern_sub (&attr); |
|
bgp_attr_flush (&attr); |
|
|
/* If peering is stopped due to some reason, do not generate BGP |
/* If peering is stopped due to some reason, do not generate BGP |
event. */ |
event. */ |
Line 1926 bgp_notify_receive (struct peer *peer, bgp_size_t size
|
Line 1963 bgp_notify_receive (struct peer *peer, bgp_size_t size
|
|
|
bgp_notify_print(peer, &bgp_notify, "received"); |
bgp_notify_print(peer, &bgp_notify, "received"); |
if (bgp_notify.data) |
if (bgp_notify.data) |
XFREE (MTYPE_TMP, bgp_notify.data); | { |
| XFREE (MTYPE_TMP, bgp_notify.data); |
| bgp_notify.data = NULL; |
| bgp_notify.length = 0; |
| } |
} |
} |
|
|
/* peer count update */ |
/* peer count update */ |
Line 1962 bgp_route_refresh_receive (struct peer *peer, bgp_size
|
Line 2003 bgp_route_refresh_receive (struct peer *peer, bgp_size
|
{ |
{ |
afi_t afi; |
afi_t afi; |
safi_t safi; |
safi_t safi; |
u_char reserved; |
|
struct stream *s; |
struct stream *s; |
|
|
/* If peer does not have the capability, send notification. */ |
/* If peer does not have the capability, send notification. */ |
Line 1990 bgp_route_refresh_receive (struct peer *peer, bgp_size
|
Line 2030 bgp_route_refresh_receive (struct peer *peer, bgp_size
|
|
|
/* Parse packet. */ |
/* Parse packet. */ |
afi = stream_getw (s); |
afi = stream_getw (s); |
reserved = stream_getc (s); | /* reserved byte */ |
| stream_getc (s); |
safi = stream_getc (s); |
safi = stream_getc (s); |
|
|
if (BGP_DEBUG (normal, NORMAL)) |
if (BGP_DEBUG (normal, NORMAL)) |
Line 2042 bgp_route_refresh_receive (struct peer *peer, bgp_size
|
Line 2083 bgp_route_refresh_receive (struct peer *peer, bgp_size
|
if (orf_type == ORF_TYPE_PREFIX |
if (orf_type == ORF_TYPE_PREFIX |
|| orf_type == ORF_TYPE_PREFIX_OLD) |
|| orf_type == ORF_TYPE_PREFIX_OLD) |
{ |
{ |
u_char *p_pnt = stream_pnt (s); | uint8_t *p_pnt = stream_pnt (s); |
u_char *p_end = stream_pnt (s) + orf_len; | uint8_t *p_end = stream_pnt (s) + orf_len; |
struct orf_prefix orfp; |
struct orf_prefix orfp; |
u_char common = 0; |
u_char common = 0; |
u_int32_t seq; |
u_int32_t seq; |
Line 2080 bgp_route_refresh_receive (struct peer *peer, bgp_size
|
Line 2121 bgp_route_refresh_receive (struct peer *peer, bgp_size
|
{ |
{ |
if (BGP_DEBUG (normal, NORMAL)) |
if (BGP_DEBUG (normal, NORMAL)) |
zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host); |
zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host); |
prefix_bgp_orf_remove_all (name); | prefix_bgp_orf_remove_all (afi, name); |
break; |
break; |
} |
} |
ok = ((p_end - p_pnt) >= sizeof(u_int32_t)) ; | ok = ((size_t)(p_end - p_pnt) >= sizeof(u_int32_t)) ; |
if (ok) |
if (ok) |
{ |
{ |
memcpy (&seq, p_pnt, sizeof (u_int32_t)); |
memcpy (&seq, p_pnt, sizeof (u_int32_t)); |
Line 2135 bgp_route_refresh_receive (struct peer *peer, bgp_size
|
Line 2176 bgp_route_refresh_receive (struct peer *peer, bgp_size
|
ret = prefix_bgp_orf_set (name, afi, &orfp, |
ret = prefix_bgp_orf_set (name, afi, &orfp, |
(common & ORF_COMMON_PART_DENY ? 0 : 1 ), |
(common & ORF_COMMON_PART_DENY ? 0 : 1 ), |
(common & ORF_COMMON_PART_REMOVE ? 0 : 1)); |
(common & ORF_COMMON_PART_REMOVE ? 0 : 1)); |
| |
if (!ok || (ret != CMD_SUCCESS)) | if (!ok || (ok && ret != CMD_SUCCESS)) |
{ |
{ |
if (BGP_DEBUG (normal, NORMAL)) |
if (BGP_DEBUG (normal, NORMAL)) |
zlog_debug ("%s Received misformatted prefixlist ORF." |
zlog_debug ("%s Received misformatted prefixlist ORF." |
" Remove All pfxlist", peer->host); |
" Remove All pfxlist", peer->host); |
prefix_bgp_orf_remove_all (name); | prefix_bgp_orf_remove_all (afi, name); |
break; |
break; |
} |
} |
} |
} |
peer->orf_plist[afi][safi] = |
peer->orf_plist[afi][safi] = |
prefix_list_lookup (AFI_ORF_PREFIX, name); | prefix_bgp_orf_lookup (afi, name); |
} |
} |
stream_forward_getp (s, orf_len); |
stream_forward_getp (s, orf_len); |
} |
} |
Line 2172 bgp_capability_msg_parse (struct peer *peer, u_char *p
|
Line 2213 bgp_capability_msg_parse (struct peer *peer, u_char *p
|
struct capability_mp_data mpc; |
struct capability_mp_data mpc; |
struct capability_header *hdr; |
struct capability_header *hdr; |
u_char action; |
u_char action; |
struct bgp *bgp; |
|
afi_t afi; |
afi_t afi; |
safi_t safi; |
safi_t safi; |
|
|
bgp = peer->bgp; |
|
end = pnt + length; |
end = pnt + length; |
|
|
while (pnt < end) |
while (pnt < end) |
Line 2310 bgp_capability_receive (struct peer *peer, bgp_size_t
|
Line 2349 bgp_capability_receive (struct peer *peer, bgp_size_t
|
/* Parse packet. */ |
/* Parse packet. */ |
return bgp_capability_msg_parse (peer, pnt, size); |
return bgp_capability_msg_parse (peer, pnt, size); |
} |
} |
| |
/* BGP read utility function. */ |
/* BGP read utility function. */ |
static int |
static int |
bgp_read_packet (struct peer *peer) |
bgp_read_packet (struct peer *peer) |