blob: b497e4546ea929bac57ea0c001341286eafd6839 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* BGP packet management routine.
2 Copyright (C) 1999 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include <zebra.h>
22
23#include "thread.h"
24#include "stream.h"
25#include "network.h"
26#include "prefix.h"
27#include "command.h"
28#include "log.h"
29#include "memory.h"
30#include "sockunion.h" /* for inet_ntop () */
Timo Teräsef757702015-04-29 09:43:04 +030031#include "sockopt.h"
paul718e3742002-12-13 20:15:29 +000032#include "linklist.h"
33#include "plist.h"
Donald Sharp04907292016-01-07 10:03:01 -050034#include "filter.h"
paul718e3742002-12-13 20:15:29 +000035
36#include "bgpd/bgpd.h"
37#include "bgpd/bgp_table.h"
38#include "bgpd/bgp_dump.h"
39#include "bgpd/bgp_attr.h"
40#include "bgpd/bgp_debug.h"
41#include "bgpd/bgp_fsm.h"
42#include "bgpd/bgp_route.h"
43#include "bgpd/bgp_packet.h"
44#include "bgpd/bgp_open.h"
45#include "bgpd/bgp_aspath.h"
46#include "bgpd/bgp_community.h"
47#include "bgpd/bgp_ecommunity.h"
48#include "bgpd/bgp_network.h"
49#include "bgpd/bgp_mplsvpn.h"
Lou Berger298cc2f2016-01-12 13:42:02 -050050#include "bgpd/bgp_encap.h"
paul718e3742002-12-13 20:15:29 +000051#include "bgpd/bgp_advertise.h"
hasso93406d82005-02-02 14:40:33 +000052#include "bgpd/bgp_vty.h"
paul718e3742002-12-13 20:15:29 +000053
54int stream_put_prefix (struct stream *, struct prefix *);
David Lamparter6b0655a2014-06-04 06:53:35 +020055
paul718e3742002-12-13 20:15:29 +000056/* Set up BGP packet marker and packet type. */
57static int
58bgp_packet_set_marker (struct stream *s, u_char type)
59{
60 int i;
61
62 /* Fill in marker. */
63 for (i = 0; i < BGP_MARKER_SIZE; i++)
64 stream_putc (s, 0xff);
65
66 /* Dummy total length. This field is should be filled in later on. */
67 stream_putw (s, 0);
68
69 /* BGP packet type. */
70 stream_putc (s, type);
71
72 /* Return current stream size. */
paul9985f832005-02-09 15:51:56 +000073 return stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +000074}
75
76/* Set BGP packet header size entry. If size is zero then use current
77 stream size. */
78static int
79bgp_packet_set_size (struct stream *s)
80{
81 int cp;
82
83 /* Preserve current pointer. */
paul9985f832005-02-09 15:51:56 +000084 cp = stream_get_endp (s);
85 stream_putw_at (s, BGP_MARKER_SIZE, cp);
paul718e3742002-12-13 20:15:29 +000086
87 return cp;
88}
89
90/* Add new packet to the peer. */
paul94f2b392005-06-28 12:44:16 +000091static void
paul718e3742002-12-13 20:15:29 +000092bgp_packet_add (struct peer *peer, struct stream *s)
93{
94 /* Add packet to the end of list. */
95 stream_fifo_push (peer->obuf, s);
96}
97
98/* Free first packet. */
paul94f2b392005-06-28 12:44:16 +000099static void
paul718e3742002-12-13 20:15:29 +0000100bgp_packet_delete (struct peer *peer)
101{
102 stream_free (stream_fifo_pop (peer->obuf));
103}
104
paul718e3742002-12-13 20:15:29 +0000105/* Check file descriptor whether connect is established. */
Paul Jakma743dd422016-09-30 13:55:47 +0100106static void
107bgp_connect_check (struct peer *peer)
paul718e3742002-12-13 20:15:29 +0000108{
109 int status;
paul5228ad22004-06-04 17:58:18 +0000110 socklen_t slen;
paul718e3742002-12-13 20:15:29 +0000111 int ret;
112
113 /* Anyway I have to reset read and write thread. */
114 BGP_READ_OFF (peer->t_read);
115 BGP_WRITE_OFF (peer->t_write);
116
117 /* Check file descriptor. */
118 slen = sizeof (status);
pauleb821182004-05-01 08:44:08 +0000119 ret = getsockopt(peer->fd, SOL_SOCKET, SO_ERROR, (void *) &status, &slen);
paul718e3742002-12-13 20:15:29 +0000120
121 /* If getsockopt is fail, this is fatal error. */
122 if (ret < 0)
123 {
124 zlog (peer->log, LOG_INFO, "can't get sockopt for nonblocking connect");
125 BGP_EVENT_ADD (peer, TCP_fatal_error);
Paul Jakma743dd422016-09-30 13:55:47 +0100126 return;
paul718e3742002-12-13 20:15:29 +0000127 }
128
129 /* When status is 0 then TCP connection is established. */
130 if (status == 0)
131 {
132 BGP_EVENT_ADD (peer, TCP_connection_open);
133 }
134 else
135 {
136 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +0000137 plog_debug (peer->log, "%s [Event] Connect failed (%s)",
ajs6099b3b2004-11-20 02:06:59 +0000138 peer->host, safe_strerror (errno));
Paul Jakma743dd422016-09-30 13:55:47 +0100139 BGP_EVENT_ADD (peer, TCP_connection_open_failed);
paul718e3742002-12-13 20:15:29 +0000140 }
141}
142
143/* Make BGP update packet. */
paul94f2b392005-06-28 12:44:16 +0000144static struct stream *
paul718e3742002-12-13 20:15:29 +0000145bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi)
146{
147 struct stream *s;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000148 struct stream *snlri;
paul718e3742002-12-13 20:15:29 +0000149 struct bgp_adj_out *adj;
150 struct bgp_advertise *adv;
151 struct stream *packet;
152 struct bgp_node *rn = NULL;
153 struct bgp_info *binfo = NULL;
154 bgp_size_t total_attr_len = 0;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000155 unsigned long attrlen_pos = 0;
Daniel Walton5bcd7542015-05-19 17:58:10 -0700156 int space_remaining = 0;
157 int space_needed = 0;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000158 size_t mpattrlen_pos = 0;
159 size_t mpattr_pos = 0;
paul718e3742002-12-13 20:15:29 +0000160
161 s = peer->work;
162 stream_reset (s);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000163 snlri = peer->scratch;
164 stream_reset (snlri);
paul718e3742002-12-13 20:15:29 +0000165
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100166 adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update);
paul718e3742002-12-13 20:15:29 +0000167
168 while (adv)
169 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000170 assert (adv->rn);
171 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000172 adj = adv->adj;
173 if (adv->binfo)
174 binfo = adv->binfo;
paul718e3742002-12-13 20:15:29 +0000175
Daniel Walton5bcd7542015-05-19 17:58:10 -0700176 space_remaining = STREAM_CONCAT_REMAIN (s, snlri, STREAM_SIZE(s)) -
177 BGP_MAX_PACKET_SIZE_OVERFLOW;
178 space_needed = BGP_NLRI_LENGTH + bgp_packet_mpattr_prefix_size (afi, safi, &rn->p);
179
paul718e3742002-12-13 20:15:29 +0000180 /* When remaining space can't include NLRI and it's length. */
Daniel Walton5bcd7542015-05-19 17:58:10 -0700181 if (space_remaining < space_needed)
paul718e3742002-12-13 20:15:29 +0000182 break;
183
184 /* If packet is empty, set attribute. */
185 if (stream_empty (s))
186 {
Lou Berger050defe2016-01-12 13:41:59 -0500187 struct prefix_rd *prd = NULL;
188 u_char *tag = NULL;
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000189 struct peer *from = NULL;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000190
Lou Berger050defe2016-01-12 13:41:59 -0500191 if (rn->prn)
192 prd = (struct prefix_rd *) &rn->prn->p;
Greg Troxeld3ddb222010-09-17 10:47:49 -0400193 if (binfo)
Lou Berger050defe2016-01-12 13:41:59 -0500194 {
195 from = binfo->peer;
196 if (binfo->extra)
197 tag = binfo->extra->tag;
198 }
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000199
200 /* 1: Write the BGP message header - 16 bytes marker, 2 bytes length,
201 * one byte message type.
202 */
paul718e3742002-12-13 20:15:29 +0000203 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000204
205 /* 2: withdrawn routes length */
paul718e3742002-12-13 20:15:29 +0000206 stream_putw (s, 0);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000207
208 /* 3: total attributes length - attrlen_pos stores the position */
209 attrlen_pos = stream_get_endp (s);
210 stream_putw (s, 0);
211
212 /* 4: if there is MP_REACH_NLRI attribute, that should be the first
213 * attribute, according to draft-ietf-idr-error-handling. Save the
214 * position.
215 */
216 mpattr_pos = stream_get_endp(s);
217
218 /* 5: Encode all the attributes, except MP_REACH_NLRI attr. */
219 total_attr_len = bgp_packet_attribute (NULL, peer, s,
paul5228ad22004-06-04 17:58:18 +0000220 adv->baa->attr,
Lou Berger298cc2f2016-01-12 13:42:02 -0500221 ((afi == AFI_IP && safi == SAFI_UNICAST) ?
222 &rn->p : NULL),
223 afi, safi,
Lou Berger050defe2016-01-12 13:41:59 -0500224 from, prd, tag);
Daniel Walton5bcd7542015-05-19 17:58:10 -0700225 space_remaining = STREAM_CONCAT_REMAIN (s, snlri, STREAM_SIZE(s)) -
226 BGP_MAX_PACKET_SIZE_OVERFLOW;
227 space_needed = BGP_NLRI_LENGTH + bgp_packet_mpattr_prefix_size (afi, safi, &rn->p);;
228
229 /* If the attributes alone do not leave any room for NLRI then
230 * return */
231 if (space_remaining < space_needed)
232 {
233 zlog_err ("%s cannot send UPDATE, the attributes do not leave "
234 "room for NLRI", peer->host);
235 /* Flush the FIFO update queue */
236 while (adv)
237 adv = bgp_advertise_clean (peer, adv->adj, afi, safi);
238 return NULL;
239 }
240
paul718e3742002-12-13 20:15:29 +0000241 }
242
243 if (afi == AFI_IP && safi == SAFI_UNICAST)
244 stream_put_prefix (s, &rn->p);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000245 else
246 {
247 /* Encode the prefix in MP_REACH_NLRI attribute */
248 struct prefix_rd *prd = NULL;
249 u_char *tag = NULL;
250
251 if (rn->prn)
252 prd = (struct prefix_rd *) &rn->prn->p;
253 if (binfo && binfo->extra)
254 tag = binfo->extra->tag;
255
256 if (stream_empty(snlri))
257 mpattrlen_pos = bgp_packet_mpattr_start(snlri, afi, safi,
258 adv->baa->attr);
259 bgp_packet_mpattr_prefix(snlri, afi, safi, &rn->p, prd, tag);
260 }
paul718e3742002-12-13 20:15:29 +0000261 if (BGP_DEBUG (update, UPDATE_OUT))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000262 {
263 char buf[INET6_BUFSIZ];
264
265 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d",
266 peer->host,
267 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, INET6_BUFSIZ),
268 rn->p.prefixlen);
269 }
paul718e3742002-12-13 20:15:29 +0000270
271 /* Synchnorize attribute. */
272 if (adj->attr)
Paul Jakmaf6f434b2010-11-23 21:28:03 +0000273 bgp_attr_unintern (&adj->attr);
paul718e3742002-12-13 20:15:29 +0000274 else
275 peer->scount[afi][safi]++;
276
277 adj->attr = bgp_attr_intern (adv->baa->attr);
278
279 adv = bgp_advertise_clean (peer, adj, afi, safi);
paul718e3742002-12-13 20:15:29 +0000280 }
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000281
paul718e3742002-12-13 20:15:29 +0000282 if (! stream_empty (s))
283 {
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000284 if (!stream_empty(snlri))
285 {
286 bgp_packet_mpattr_end(snlri, mpattrlen_pos);
287 total_attr_len += stream_get_endp(snlri);
288 }
289
290 /* set the total attribute length correctly */
291 stream_putw_at (s, attrlen_pos, total_attr_len);
292
293 if (!stream_empty(snlri))
294 packet = stream_dupcat(s, snlri, mpattr_pos);
295 else
296 packet = stream_dup (s);
297 bgp_packet_set_size (packet);
paul718e3742002-12-13 20:15:29 +0000298 bgp_packet_add (peer, packet);
pauleb821182004-05-01 08:44:08 +0000299 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000300 stream_reset (s);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000301 stream_reset (snlri);
paul718e3742002-12-13 20:15:29 +0000302 return packet;
303 }
304 return NULL;
hasso93406d82005-02-02 14:40:33 +0000305}
paul718e3742002-12-13 20:15:29 +0000306
paul94f2b392005-06-28 12:44:16 +0000307static struct stream *
hasso93406d82005-02-02 14:40:33 +0000308bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
309{
310 struct stream *s;
hasso93406d82005-02-02 14:40:33 +0000311
Paul Jakma750e8142008-07-22 21:11:48 +0000312 if (DISABLE_BGP_ANNOUNCE)
313 return NULL;
hasso93406d82005-02-02 14:40:33 +0000314
315 if (BGP_DEBUG (normal, NORMAL))
316 zlog_debug ("send End-of-RIB for %s to %s", afi_safi_print (afi, safi), peer->host);
317
318 s = stream_new (BGP_MAX_PACKET_SIZE);
319
320 /* Make BGP update packet. */
321 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
322
323 /* Unfeasible Routes Length */
324 stream_putw (s, 0);
325
326 if (afi == AFI_IP && safi == SAFI_UNICAST)
327 {
328 /* Total Path Attribute Length */
329 stream_putw (s, 0);
330 }
331 else
332 {
333 /* Total Path Attribute Length */
334 stream_putw (s, 6);
335 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
336 stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
337 stream_putc (s, 3);
338 stream_putw (s, afi);
339 stream_putc (s, safi);
340 }
341
342 bgp_packet_set_size (s);
Donald Sharpa752c3b2015-08-18 08:48:53 -0400343 bgp_packet_add (peer, s);
344 return s;
paul718e3742002-12-13 20:15:29 +0000345}
346
347/* Make BGP withdraw packet. */
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000348/* For ipv4 unicast:
349 16-octet marker | 2-octet length | 1-octet type |
350 2-octet withdrawn route length | withdrawn prefixes | 2-octet attrlen (=0)
351*/
352/* For other afi/safis:
353 16-octet marker | 2-octet length | 1-octet type |
354 2-octet withdrawn route length (=0) | 2-octet attrlen |
355 mp_unreach attr type | attr len | afi | safi | withdrawn prefixes
356*/
paul94f2b392005-06-28 12:44:16 +0000357static struct stream *
paul718e3742002-12-13 20:15:29 +0000358bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi)
359{
360 struct stream *s;
361 struct stream *packet;
362 struct bgp_adj_out *adj;
363 struct bgp_advertise *adv;
364 struct bgp_node *rn;
paul718e3742002-12-13 20:15:29 +0000365 bgp_size_t unfeasible_len;
366 bgp_size_t total_attr_len;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000367 size_t mp_start = 0;
368 size_t attrlen_pos = 0;
369 size_t mplen_pos = 0;
370 u_char first_time = 1;
Daniel Walton5bcd7542015-05-19 17:58:10 -0700371 int space_remaining = 0;
372 int space_needed = 0;
paul718e3742002-12-13 20:15:29 +0000373
374 s = peer->work;
375 stream_reset (s);
376
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100377 while ((adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL)
paul718e3742002-12-13 20:15:29 +0000378 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000379 assert (adv->rn);
paul718e3742002-12-13 20:15:29 +0000380 adj = adv->adj;
381 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000382
Daniel Walton5bcd7542015-05-19 17:58:10 -0700383 space_remaining = STREAM_REMAIN (s) -
384 BGP_MAX_PACKET_SIZE_OVERFLOW;
385 space_needed = (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN +
386 bgp_packet_mpattr_prefix_size (afi, safi, &rn->p));
387
388 if (space_remaining < space_needed)
paul718e3742002-12-13 20:15:29 +0000389 break;
390
391 if (stream_empty (s))
392 {
393 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000394 stream_putw (s, 0); /* unfeasible routes length */
paul718e3742002-12-13 20:15:29 +0000395 }
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000396 else
397 first_time = 0;
paul718e3742002-12-13 20:15:29 +0000398
399 if (afi == AFI_IP && safi == SAFI_UNICAST)
400 stream_put_prefix (s, &rn->p);
401 else
402 {
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000403 struct prefix_rd *prd = NULL;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000404
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000405 if (rn->prn)
406 prd = (struct prefix_rd *) &rn->prn->p;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000407
408 /* If first time, format the MP_UNREACH header */
409 if (first_time)
410 {
411 attrlen_pos = stream_get_endp (s);
412 /* total attr length = 0 for now. reevaluate later */
413 stream_putw (s, 0);
414 mp_start = stream_get_endp (s);
415 mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
416 }
417
418 bgp_packet_mpunreach_prefix(s, &rn->p, afi, safi, prd, NULL);
paul718e3742002-12-13 20:15:29 +0000419 }
420
421 if (BGP_DEBUG (update, UPDATE_OUT))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000422 {
423 char buf[INET6_BUFSIZ];
424
425 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
426 peer->host,
427 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, INET6_BUFSIZ),
428 rn->p.prefixlen);
429 }
paul718e3742002-12-13 20:15:29 +0000430
431 peer->scount[afi][safi]--;
432
433 bgp_adj_out_remove (rn, adj, peer, afi, safi);
434 bgp_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +0000435 }
436
437 if (! stream_empty (s))
438 {
439 if (afi == AFI_IP && safi == SAFI_UNICAST)
440 {
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000441 unfeasible_len
paul9985f832005-02-09 15:51:56 +0000442 = stream_get_endp (s) - BGP_HEADER_SIZE - BGP_UNFEASIBLE_LEN;
paul718e3742002-12-13 20:15:29 +0000443 stream_putw_at (s, BGP_HEADER_SIZE, unfeasible_len);
444 stream_putw (s, 0);
445 }
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000446 else
447 {
448 /* Set the mp_unreach attr's length */
449 bgp_packet_mpunreach_end(s, mplen_pos);
450
451 /* Set total path attribute length. */
452 total_attr_len = stream_get_endp(s) - mp_start;
453 stream_putw_at (s, attrlen_pos, total_attr_len);
454 }
paul718e3742002-12-13 20:15:29 +0000455 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000456 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000457 bgp_packet_add (peer, packet);
458 stream_reset (s);
459 return packet;
460 }
461
462 return NULL;
463}
464
465void
466bgp_default_update_send (struct peer *peer, struct attr *attr,
467 afi_t afi, safi_t safi, struct peer *from)
468{
469 struct stream *s;
paul718e3742002-12-13 20:15:29 +0000470 struct prefix p;
471 unsigned long pos;
472 bgp_size_t total_attr_len;
paul718e3742002-12-13 20:15:29 +0000473
Paul Jakma750e8142008-07-22 21:11:48 +0000474 if (DISABLE_BGP_ANNOUNCE)
475 return;
paul718e3742002-12-13 20:15:29 +0000476
477 if (afi == AFI_IP)
478 str2prefix ("0.0.0.0/0", &p);
paul718e3742002-12-13 20:15:29 +0000479 else
480 str2prefix ("::/0", &p);
paul718e3742002-12-13 20:15:29 +0000481
482 /* Logging the attribute. */
483 if (BGP_DEBUG (update, UPDATE_OUT))
484 {
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000485 char attrstr[BUFSIZ];
486 char buf[INET6_BUFSIZ];
487 attrstr[0] = '\0';
488
paul718e3742002-12-13 20:15:29 +0000489 bgp_dump_attr (peer, attr, attrstr, BUFSIZ);
ajs6b514742004-12-08 21:03:23 +0000490 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d %s",
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000491 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, INET6_BUFSIZ),
paul718e3742002-12-13 20:15:29 +0000492 p.prefixlen, attrstr);
493 }
494
495 s = stream_new (BGP_MAX_PACKET_SIZE);
496
497 /* Make BGP update packet. */
498 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
499
500 /* Unfeasible Routes Length. */
501 stream_putw (s, 0);
502
503 /* Make place for total attribute length. */
paul9985f832005-02-09 15:51:56 +0000504 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000505 stream_putw (s, 0);
506 total_attr_len = bgp_packet_attribute (NULL, peer, s, attr, &p, afi, safi, from, NULL, NULL);
507
508 /* Set Total Path Attribute Length. */
509 stream_putw_at (s, pos, total_attr_len);
510
511 /* NLRI set. */
512 if (p.family == AF_INET && safi == SAFI_UNICAST)
513 stream_put_prefix (s, &p);
514
515 /* Set size. */
516 bgp_packet_set_size (s);
517
paul718e3742002-12-13 20:15:29 +0000518 /* Dump packet if debug option is set. */
519#ifdef DEBUG
jardin2d74db52005-10-01 00:07:50 +0000520 /* bgp_packet_dump (packet); */
paul718e3742002-12-13 20:15:29 +0000521#endif /* DEBUG */
522
523 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -0400524 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +0000525
pauleb821182004-05-01 08:44:08 +0000526 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000527}
528
529void
530bgp_default_withdraw_send (struct peer *peer, afi_t afi, safi_t safi)
531{
532 struct stream *s;
paul718e3742002-12-13 20:15:29 +0000533 struct prefix p;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000534 unsigned long attrlen_pos = 0;
paul718e3742002-12-13 20:15:29 +0000535 unsigned long cp;
536 bgp_size_t unfeasible_len;
537 bgp_size_t total_attr_len;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000538 size_t mp_start = 0;
539 size_t mplen_pos = 0;
paul718e3742002-12-13 20:15:29 +0000540
Paul Jakma750e8142008-07-22 21:11:48 +0000541 if (DISABLE_BGP_ANNOUNCE)
542 return;
paul718e3742002-12-13 20:15:29 +0000543
544 if (afi == AFI_IP)
545 str2prefix ("0.0.0.0/0", &p);
paul718e3742002-12-13 20:15:29 +0000546 else
547 str2prefix ("::/0", &p);
paul718e3742002-12-13 20:15:29 +0000548
549 total_attr_len = 0;
paul718e3742002-12-13 20:15:29 +0000550
551 if (BGP_DEBUG (update, UPDATE_OUT))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000552 {
553 char buf[INET6_BUFSIZ];
554
555 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
556 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, INET6_BUFSIZ),
557 p.prefixlen);
558 }
paul718e3742002-12-13 20:15:29 +0000559
560 s = stream_new (BGP_MAX_PACKET_SIZE);
561
562 /* Make BGP update packet. */
563 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
564
565 /* Unfeasible Routes Length. */;
paul9985f832005-02-09 15:51:56 +0000566 cp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000567 stream_putw (s, 0);
568
569 /* Withdrawn Routes. */
570 if (p.family == AF_INET && safi == SAFI_UNICAST)
571 {
572 stream_put_prefix (s, &p);
573
paul9985f832005-02-09 15:51:56 +0000574 unfeasible_len = stream_get_endp (s) - cp - 2;
paul718e3742002-12-13 20:15:29 +0000575
576 /* Set unfeasible len. */
577 stream_putw_at (s, cp, unfeasible_len);
578
579 /* Set total path attribute length. */
580 stream_putw (s, 0);
581 }
582 else
583 {
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000584 attrlen_pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000585 stream_putw (s, 0);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000586 mp_start = stream_get_endp (s);
587 mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
588 bgp_packet_mpunreach_prefix(s, &p, afi, safi, NULL, NULL);
589
590 /* Set the mp_unreach attr's length */
591 bgp_packet_mpunreach_end(s, mplen_pos);
paul718e3742002-12-13 20:15:29 +0000592
593 /* Set total path attribute length. */
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000594 total_attr_len = stream_get_endp(s) - mp_start;
595 stream_putw_at (s, attrlen_pos, total_attr_len);
paul718e3742002-12-13 20:15:29 +0000596 }
597
598 bgp_packet_set_size (s);
599
paul718e3742002-12-13 20:15:29 +0000600 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -0400601 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +0000602
pauleb821182004-05-01 08:44:08 +0000603 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000604}
605
606/* Get next packet to be written. */
paul94f2b392005-06-28 12:44:16 +0000607static struct stream *
paul718e3742002-12-13 20:15:29 +0000608bgp_write_packet (struct peer *peer)
609{
610 afi_t afi;
611 safi_t safi;
612 struct stream *s = NULL;
613 struct bgp_advertise *adv;
614
615 s = stream_fifo_head (peer->obuf);
616 if (s)
617 return s;
618
619 for (afi = AFI_IP; afi < AFI_MAX; afi++)
620 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
621 {
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100622 adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->withdraw);
paul718e3742002-12-13 20:15:29 +0000623 if (adv)
624 {
625 s = bgp_withdraw_packet (peer, afi, safi);
626 if (s)
627 return s;
628 }
629 }
630
631 for (afi = AFI_IP; afi < AFI_MAX; afi++)
632 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
633 {
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100634 adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update);
paul718e3742002-12-13 20:15:29 +0000635 if (adv)
636 {
637 if (adv->binfo && adv->binfo->uptime < peer->synctime)
hasso93406d82005-02-02 14:40:33 +0000638 {
639 if (CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_RCV)
640 && CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_ADV)
Vipin Kumardd49eb12014-09-30 14:36:38 -0700641 && ! (CHECK_FLAG (adv->binfo->peer->cap,
642 PEER_CAP_RESTART_BIT_RCV) &&
643 CHECK_FLAG (adv->binfo->peer->cap,
644 PEER_CAP_RESTART_BIT_ADV))
hasso93406d82005-02-02 14:40:33 +0000645 && ! CHECK_FLAG (adv->binfo->flags, BGP_INFO_STALE)
646 && safi != SAFI_MPLS_VPN)
647 {
648 if (CHECK_FLAG (adv->binfo->peer->af_sflags[afi][safi],
649 PEER_STATUS_EOR_RECEIVED))
650 s = bgp_update_packet (peer, afi, safi);
651 }
652 else
653 s = bgp_update_packet (peer, afi, safi);
654 }
paul718e3742002-12-13 20:15:29 +0000655
656 if (s)
657 return s;
658 }
hasso93406d82005-02-02 14:40:33 +0000659
660 if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV))
661 {
662 if (peer->afc_nego[afi][safi] && peer->synctime
663 && ! CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND)
664 && safi != SAFI_MPLS_VPN)
665 {
666 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND);
667 return bgp_update_packet_eor (peer, afi, safi);
668 }
669 }
paul718e3742002-12-13 20:15:29 +0000670 }
671
672 return NULL;
673}
674
675/* Is there partially written packet or updates we can send right
676 now. */
paul94f2b392005-06-28 12:44:16 +0000677static int
paul718e3742002-12-13 20:15:29 +0000678bgp_write_proceed (struct peer *peer)
679{
680 afi_t afi;
681 safi_t safi;
682 struct bgp_advertise *adv;
683
684 if (stream_fifo_head (peer->obuf))
685 return 1;
686
687 for (afi = AFI_IP; afi < AFI_MAX; afi++)
688 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
689 if (FIFO_HEAD (&peer->sync[afi][safi]->withdraw))
690 return 1;
691
692 for (afi = AFI_IP; afi < AFI_MAX; afi++)
693 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100694 if ((adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update)) != NULL)
paul718e3742002-12-13 20:15:29 +0000695 if (adv->binfo->uptime < peer->synctime)
696 return 1;
697
698 return 0;
699}
700
701/* Write packet to the peer. */
702int
703bgp_write (struct thread *thread)
704{
705 struct peer *peer;
706 u_char type;
707 struct stream *s;
708 int num;
paulfd79ac92004-10-13 05:06:08 +0000709 unsigned int count = 0;
paul718e3742002-12-13 20:15:29 +0000710
711 /* Yes first of all get peer pointer. */
712 peer = THREAD_ARG (thread);
713 peer->t_write = NULL;
714
715 /* For non-blocking IO check. */
716 if (peer->status == Connect)
717 {
Paul Jakma743dd422016-09-30 13:55:47 +0100718 bgp_connect_check (peer);
paul718e3742002-12-13 20:15:29 +0000719 return 0;
720 }
721
Stephen Hemmingereac57022010-08-05 10:26:25 -0700722 s = bgp_write_packet (peer);
723 if (!s)
724 return 0; /* nothing to send */
725
726 sockopt_cork (peer->fd, 1);
727
728 /* Nonblocking write until TCP output buffer is full. */
729 do
paul718e3742002-12-13 20:15:29 +0000730 {
731 int writenum;
paul718e3742002-12-13 20:15:29 +0000732
733 /* Number of bytes to be sent. */
734 writenum = stream_get_endp (s) - stream_get_getp (s);
735
736 /* Call write() system call. */
pauleb821182004-05-01 08:44:08 +0000737 num = write (peer->fd, STREAM_PNT (s), writenum);
Stephen Hemminger35398582010-08-05 10:26:23 -0700738 if (num < 0)
paul718e3742002-12-13 20:15:29 +0000739 {
Stephen Hemmingereac57022010-08-05 10:26:25 -0700740 /* write failed either retry needed or error */
741 if (ERRNO_IO_RETRY(errno))
742 break;
743
744 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000745 return 0;
746 }
Stephen Hemminger35398582010-08-05 10:26:23 -0700747
paul718e3742002-12-13 20:15:29 +0000748 if (num != writenum)
749 {
Stephen Hemminger35398582010-08-05 10:26:23 -0700750 /* Partial write */
paul9985f832005-02-09 15:51:56 +0000751 stream_forward_getp (s, num);
Stephen Hemmingereac57022010-08-05 10:26:25 -0700752 break;
paul718e3742002-12-13 20:15:29 +0000753 }
754
755 /* Retrieve BGP packet type. */
756 stream_set_getp (s, BGP_MARKER_SIZE + 2);
757 type = stream_getc (s);
758
759 switch (type)
760 {
761 case BGP_MSG_OPEN:
762 peer->open_out++;
763 break;
764 case BGP_MSG_UPDATE:
765 peer->update_out++;
766 break;
767 case BGP_MSG_NOTIFY:
768 peer->notify_out++;
paul718e3742002-12-13 20:15:29 +0000769
Paul Jakmaca058a32006-09-14 02:58:49 +0000770 /* Flush any existing events */
Paul Jakmab1b15792016-09-21 18:50:23 +0100771 BGP_EVENT_ADD (peer, BGP_Stop_with_error);
Stephen Hemminger3a69f742013-01-11 18:27:23 +0000772 goto done;
773
paul718e3742002-12-13 20:15:29 +0000774 case BGP_MSG_KEEPALIVE:
775 peer->keepalive_out++;
776 break;
777 case BGP_MSG_ROUTE_REFRESH_NEW:
778 case BGP_MSG_ROUTE_REFRESH_OLD:
779 peer->refresh_out++;
780 break;
781 case BGP_MSG_CAPABILITY:
782 peer->dynamic_cap_out++;
783 break;
784 }
785
786 /* OK we send packet so delete it. */
787 bgp_packet_delete (peer);
paul718e3742002-12-13 20:15:29 +0000788 }
Stephen Hemmingereac57022010-08-05 10:26:25 -0700789 while (++count < BGP_WRITE_PACKET_MAX &&
790 (s = bgp_write_packet (peer)) != NULL);
paul718e3742002-12-13 20:15:29 +0000791
792 if (bgp_write_proceed (peer))
pauleb821182004-05-01 08:44:08 +0000793 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
Stephen Hemminger3a69f742013-01-11 18:27:23 +0000794
795 done:
796 sockopt_cork (peer->fd, 0);
paul718e3742002-12-13 20:15:29 +0000797 return 0;
798}
799
800/* This is only for sending NOTIFICATION message to neighbor. */
paul94f2b392005-06-28 12:44:16 +0000801static int
paul718e3742002-12-13 20:15:29 +0000802bgp_write_notify (struct peer *peer)
803{
Stephen Hemminger35398582010-08-05 10:26:23 -0700804 int ret, val;
paul718e3742002-12-13 20:15:29 +0000805 u_char type;
806 struct stream *s;
807
808 /* There should be at least one packet. */
809 s = stream_fifo_head (peer->obuf);
810 if (!s)
811 return 0;
812 assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
813
Leonid Rosenboim86998bc2012-12-14 19:12:17 +0000814 /* Stop collecting data within the socket */
815 sockopt_cork (peer->fd, 0);
816
David Lamparter8ff202e2013-07-31 14:39:41 +0200817 /* socket is in nonblocking mode, if we can't deliver the NOTIFY, well,
818 * we only care about getting a clean shutdown at this point. */
Leonid Rosenboim86998bc2012-12-14 19:12:17 +0000819 ret = write (peer->fd, STREAM_DATA (s), stream_get_endp (s));
David Lamparter8ff202e2013-07-31 14:39:41 +0200820
821 /* only connection reset/close gets counted as TCP_fatal_error, failure
822 * to write the entire NOTIFY doesn't get different FSM treatment */
paul718e3742002-12-13 20:15:29 +0000823 if (ret <= 0)
824 {
Paul Jakmadcdf3992006-10-15 23:39:59 +0000825 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000826 return 0;
827 }
828
Leonid Rosenboim86998bc2012-12-14 19:12:17 +0000829 /* Disable Nagle, make NOTIFY packet go out right away */
830 val = 1;
831 (void) setsockopt (peer->fd, IPPROTO_TCP, TCP_NODELAY,
832 (char *) &val, sizeof (val));
833
paul718e3742002-12-13 20:15:29 +0000834 /* Retrieve BGP packet type. */
835 stream_set_getp (s, BGP_MARKER_SIZE + 2);
836 type = stream_getc (s);
837
838 assert (type == BGP_MSG_NOTIFY);
839
840 /* Type should be notify. */
841 peer->notify_out++;
842
Paul Jakmab1b15792016-09-21 18:50:23 +0100843 BGP_EVENT_ADD (peer, BGP_Stop_with_error);
paul718e3742002-12-13 20:15:29 +0000844
845 return 0;
846}
847
848/* Make keepalive packet and send it to the peer. */
849void
850bgp_keepalive_send (struct peer *peer)
851{
852 struct stream *s;
853 int length;
854
855 s = stream_new (BGP_MAX_PACKET_SIZE);
856
857 /* Make keepalive packet. */
858 bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
859
860 /* Set packet size. */
861 length = bgp_packet_set_size (s);
862
863 /* Dump packet if debug option is set. */
864 /* bgp_packet_dump (s); */
865
866 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +0000867 zlog_debug ("%s sending KEEPALIVE", peer->host);
paul718e3742002-12-13 20:15:29 +0000868 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000869 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000870 peer->host, BGP_MSG_KEEPALIVE, length);
871
872 /* Add packet to the peer. */
873 bgp_packet_add (peer, s);
874
pauleb821182004-05-01 08:44:08 +0000875 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000876}
877
878/* Make open packet and send it to the peer. */
879void
880bgp_open_send (struct peer *peer)
881{
882 struct stream *s;
883 int length;
884 u_int16_t send_holdtime;
885 as_t local_as;
886
887 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
888 send_holdtime = peer->holdtime;
889 else
890 send_holdtime = peer->bgp->default_holdtime;
891
892 /* local-as Change */
893 if (peer->change_local_as)
894 local_as = peer->change_local_as;
895 else
896 local_as = peer->local_as;
897
898 s = stream_new (BGP_MAX_PACKET_SIZE);
899
900 /* Make open packet. */
901 bgp_packet_set_marker (s, BGP_MSG_OPEN);
902
903 /* Set open packet values. */
904 stream_putc (s, BGP_VERSION_4); /* BGP version */
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000905 stream_putw (s, (local_as <= BGP_AS_MAX) ? (u_int16_t) local_as
906 : BGP_AS_TRANS);
paul718e3742002-12-13 20:15:29 +0000907 stream_putw (s, send_holdtime); /* Hold Time */
908 stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
909
910 /* Set capability code. */
911 bgp_open_capability (s, peer);
912
913 /* Set BGP packet length. */
914 length = bgp_packet_set_size (s);
915
916 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400917 zlog_debug ("%s sending OPEN, version %d, my as %u, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +0000918 peer->host, BGP_VERSION_4, local_as,
919 send_holdtime, inet_ntoa (peer->local_id));
920
921 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000922 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000923 peer->host, BGP_MSG_OPEN, length);
924
925 /* Dump packet if debug option is set. */
926 /* bgp_packet_dump (s); */
927
928 /* Add packet to the peer. */
929 bgp_packet_add (peer, s);
930
pauleb821182004-05-01 08:44:08 +0000931 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000932}
933
934/* Send BGP notify packet with data potion. */
935void
936bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
937 u_char *data, size_t datalen)
938{
939 struct stream *s;
940 int length;
941
942 /* Allocate new stream. */
943 s = stream_new (BGP_MAX_PACKET_SIZE);
944
945 /* Make nitify packet. */
946 bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
947
948 /* Set notify packet values. */
949 stream_putc (s, code); /* BGP notify code */
950 stream_putc (s, sub_code); /* BGP notify sub_code */
951
952 /* If notify data is present. */
953 if (data)
954 stream_write (s, data, datalen);
955
956 /* Set BGP packet length. */
957 length = bgp_packet_set_size (s);
958
959 /* Add packet to the peer. */
960 stream_fifo_clean (peer->obuf);
961 bgp_packet_add (peer, s);
962
963 /* For debug */
964 {
965 struct bgp_notify bgp_notify;
966 int first = 0;
967 int i;
968 char c[4];
969
970 bgp_notify.code = code;
971 bgp_notify.subcode = sub_code;
972 bgp_notify.data = NULL;
973 bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
974
975 if (bgp_notify.length)
976 {
977 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
978 for (i = 0; i < bgp_notify.length; i++)
979 if (first)
980 {
981 sprintf (c, " %02x", data[i]);
982 strcat (bgp_notify.data, c);
983 }
984 else
985 {
986 first = 1;
987 sprintf (c, "%02x", data[i]);
988 strcpy (bgp_notify.data, c);
989 }
990 }
991 bgp_notify_print (peer, &bgp_notify, "sending");
Daniel Walton363c9032015-10-21 06:42:54 -0700992
paul718e3742002-12-13 20:15:29 +0000993 if (bgp_notify.data)
Daniel Walton363c9032015-10-21 06:42:54 -0700994 {
995 XFREE (MTYPE_TMP, bgp_notify.data);
996 bgp_notify.data = NULL;
997 bgp_notify.length = 0;
998 }
paul718e3742002-12-13 20:15:29 +0000999 }
1000
1001 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001002 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001003 peer->host, BGP_MSG_NOTIFY, length);
1004
hassoe0701b72004-05-20 09:19:34 +00001005 /* peer reset cause */
1006 if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
1007 {
1008 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
heasley1212dc12011-09-12 13:27:52 +04001009 {
1010 peer->last_reset = PEER_DOWN_USER_RESET;
Paul Jakmac7986232016-09-21 17:42:37 +01001011 zlog_info ("Notification sent to neighbor %s:%u: User reset",
1012 peer->host, sockunion_get_port (&peer->su));
heasley1212dc12011-09-12 13:27:52 +04001013 }
hassoe0701b72004-05-20 09:19:34 +00001014 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
heasley1212dc12011-09-12 13:27:52 +04001015 {
1016 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
Paul Jakmac7986232016-09-21 17:42:37 +01001017 zlog_info ("Notification sent to neighbor %s:%u shutdown",
1018 peer->host, sockunion_get_port (&peer->su));
heasley1212dc12011-09-12 13:27:52 +04001019 }
hassoe0701b72004-05-20 09:19:34 +00001020 else
heasley1212dc12011-09-12 13:27:52 +04001021 {
1022 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
Paul Jakmac7986232016-09-21 17:42:37 +01001023 zlog_info ("Notification sent to neighbor %s:%u: type %u/%u",
1024 peer->host, sockunion_get_port (&peer->su),
1025 code, sub_code);
heasley1212dc12011-09-12 13:27:52 +04001026 }
hassoe0701b72004-05-20 09:19:34 +00001027 }
heasley1212dc12011-09-12 13:27:52 +04001028 else
Paul Jakmac7986232016-09-21 17:42:37 +01001029 zlog_info ("Notification sent to neighbor %s:%u: configuration change",
1030 peer->host, sockunion_get_port (&peer->su));
hassoe0701b72004-05-20 09:19:34 +00001031
Denis Ovsienko7ccf5e52011-09-10 16:53:30 +04001032 /* Call immediately. */
paul718e3742002-12-13 20:15:29 +00001033 BGP_WRITE_OFF (peer->t_write);
1034
1035 bgp_write_notify (peer);
1036}
1037
1038/* Send BGP notify packet. */
1039void
1040bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
1041{
1042 bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
1043}
1044
paul718e3742002-12-13 20:15:29 +00001045/* Send route refresh message to the peer. */
1046void
1047bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
1048 u_char orf_type, u_char when_to_refresh, int remove)
1049{
1050 struct stream *s;
paul718e3742002-12-13 20:15:29 +00001051 int length;
1052 struct bgp_filter *filter;
1053 int orf_refresh = 0;
1054
Paul Jakma750e8142008-07-22 21:11:48 +00001055 if (DISABLE_BGP_ANNOUNCE)
1056 return;
paul718e3742002-12-13 20:15:29 +00001057
1058 filter = &peer->filter[afi][safi];
1059
1060 /* Adjust safi code. */
1061 if (safi == SAFI_MPLS_VPN)
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001062 safi = SAFI_MPLS_LABELED_VPN;
paul718e3742002-12-13 20:15:29 +00001063
1064 s = stream_new (BGP_MAX_PACKET_SIZE);
1065
1066 /* Make BGP update packet. */
1067 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
1068 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
1069 else
1070 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
1071
1072 /* Encode Route Refresh message. */
1073 stream_putw (s, afi);
1074 stream_putc (s, 0);
1075 stream_putc (s, safi);
1076
1077 if (orf_type == ORF_TYPE_PREFIX
1078 || orf_type == ORF_TYPE_PREFIX_OLD)
1079 if (remove || filter->plist[FILTER_IN].plist)
1080 {
1081 u_int16_t orf_len;
1082 unsigned long orfp;
1083
1084 orf_refresh = 1;
1085 stream_putc (s, when_to_refresh);
1086 stream_putc (s, orf_type);
paul9985f832005-02-09 15:51:56 +00001087 orfp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00001088 stream_putw (s, 0);
1089
1090 if (remove)
1091 {
1092 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1093 stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
1094 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001095 zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001096 peer->host, orf_type,
1097 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1098 afi, safi);
1099 }
1100 else
1101 {
1102 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1103 prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
1104 ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
1105 ORF_COMMON_PART_DENY);
1106 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001107 zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001108 peer->host, orf_type,
1109 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1110 afi, safi);
1111 }
1112
1113 /* Total ORF Entry Len. */
paul9985f832005-02-09 15:51:56 +00001114 orf_len = stream_get_endp (s) - orfp - 2;
paul718e3742002-12-13 20:15:29 +00001115 stream_putw_at (s, orfp, orf_len);
1116 }
1117
1118 /* Set packet size. */
1119 length = bgp_packet_set_size (s);
1120
1121 if (BGP_DEBUG (normal, NORMAL))
1122 {
1123 if (! orf_refresh)
ajs6b514742004-12-08 21:03:23 +00001124 zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001125 peer->host, afi, safi);
ajs6b514742004-12-08 21:03:23 +00001126 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001127 peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
1128 BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
1129 }
1130
paul718e3742002-12-13 20:15:29 +00001131 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -04001132 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +00001133
pauleb821182004-05-01 08:44:08 +00001134 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001135}
1136
1137/* Send capability message to the peer. */
1138void
1139bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
1140 int capability_code, int action)
1141{
1142 struct stream *s;
paul718e3742002-12-13 20:15:29 +00001143 int length;
1144
1145 /* Adjust safi code. */
1146 if (safi == SAFI_MPLS_VPN)
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001147 safi = SAFI_MPLS_LABELED_VPN;
paul718e3742002-12-13 20:15:29 +00001148
1149 s = stream_new (BGP_MAX_PACKET_SIZE);
1150
1151 /* Make BGP update packet. */
1152 bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
1153
1154 /* Encode MP_EXT capability. */
1155 if (capability_code == CAPABILITY_CODE_MP)
1156 {
1157 stream_putc (s, action);
1158 stream_putc (s, CAPABILITY_CODE_MP);
1159 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1160 stream_putw (s, afi);
1161 stream_putc (s, 0);
1162 stream_putc (s, safi);
1163
1164 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001165 zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001166 peer->host, action == CAPABILITY_ACTION_SET ?
1167 "Advertising" : "Removing", afi, safi);
1168 }
1169
paul718e3742002-12-13 20:15:29 +00001170 /* Set packet size. */
1171 length = bgp_packet_set_size (s);
1172
paul718e3742002-12-13 20:15:29 +00001173
1174 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -04001175 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +00001176
1177 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001178 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001179 peer->host, BGP_MSG_CAPABILITY, length);
1180
pauleb821182004-05-01 08:44:08 +00001181 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001182}
David Lamparter6b0655a2014-06-04 06:53:35 +02001183
paul718e3742002-12-13 20:15:29 +00001184/* RFC1771 6.8 Connection collision detection. */
paul94f2b392005-06-28 12:44:16 +00001185static int
pauleb821182004-05-01 08:44:08 +00001186bgp_collision_detect (struct peer *new, struct in_addr remote_id)
paul718e3742002-12-13 20:15:29 +00001187{
pauleb821182004-05-01 08:44:08 +00001188 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +00001189 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001190 struct bgp *bgp;
1191
1192 bgp = bgp_get_default ();
1193 if (! bgp)
1194 return 0;
1195
1196 /* Upon receipt of an OPEN message, the local system must examine
1197 all of its connections that are in the OpenConfirm state. A BGP
1198 speaker may also examine connections in an OpenSent state if it
1199 knows the BGP Identifier of the peer by means outside of the
1200 protocol. If among these connections there is a connection to a
1201 remote BGP speaker whose BGP Identifier equals the one in the
1202 OPEN message, then the local system performs the following
1203 collision resolution procedure: */
1204
paul1eb8ef22005-04-07 07:30:20 +00001205 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00001206 {
Paul Jakmaac278ea2016-04-26 11:46:34 +01001207 if (peer == new)
1208 continue;
1209 if (!sockunion_same (&peer->su, &new->su))
1210 continue;
1211
1212 /* Unless allowed via configuration, a connection collision with an
1213 existing BGP connection that is in the Established state causes
1214 closing of the newly created connection. */
1215 if (peer->status == Established)
1216 {
1217 /* GR may do things slightly differently to classic RFC . Punt to
1218 * open_receive, see below
1219 */
1220 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
1221 continue;
1222
1223 if (new->fd >= 0)
Paul Jakmac7986232016-09-21 17:42:37 +01001224 {
1225 if (BGP_DEBUG (events, EVENTS))
1226 zlog_debug ("%s:%u Existing Established peer, sending NOTIFY",
1227 new->host, sockunion_get_port (&new->su));
Paul Jakmaac278ea2016-04-26 11:46:34 +01001228 bgp_notify_send (new, BGP_NOTIFY_CEASE,
1229 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
Paul Jakmac7986232016-09-21 17:42:37 +01001230 }
1231 return -1;
Paul Jakmaac278ea2016-04-26 11:46:34 +01001232 }
1233
Paul Jakma1ebafb62016-04-27 09:55:21 +01001234 /* Note: Quagga historically orders explicitly only on the processing
1235 * of the Opens, treating 'new' as the passive, inbound and connection
1236 * and 'peer' as the active outbound connection.
Paul Jakmaac278ea2016-04-26 11:46:34 +01001237 */
1238
1239 /* The local_id is always set, so we can match the given remote-ID
1240 * from the OPEN against both OpenConfirm and OpenSent peers.
1241 */
1242 if (peer->status == OpenConfirm || peer->status == OpenSent)
pauleb821182004-05-01 08:44:08 +00001243 {
Paul Jakma1ebafb62016-04-27 09:55:21 +01001244 struct peer *out = peer;
1245 struct peer *in = new;
1246 int ret_close_out = 1, ret_close_in = -1;
1247
1248 if (!CHECK_FLAG (new->sflags, PEER_STATUS_ACCEPT_PEER))
1249 {
1250 out = new;
1251 ret_close_out = -1;
1252 in = peer;
1253 ret_close_in = 1;
1254 }
1255
paul718e3742002-12-13 20:15:29 +00001256 /* 1. The BGP Identifier of the local system is compared to
1257 the BGP Identifier of the remote system (as specified in
1258 the OPEN message). */
1259
1260 if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
1261 {
1262 /* 2. If the value of the local BGP Identifier is less
1263 than the remote one, the local system closes BGP
1264 connection that already exists (the one that is
1265 already in the OpenConfirm state), and accepts BGP
1266 connection initiated by the remote system. */
1267
Paul Jakma1ebafb62016-04-27 09:55:21 +01001268 if (out->fd >= 0)
Paul Jakmac7986232016-09-21 17:42:37 +01001269 {
1270 if (BGP_DEBUG (events, EVENTS))
1271 zlog_debug ("%s Collision resolution, remote ID higher,"
1272 " closing outbound", peer->host);
1273 bgp_notify_send (out, BGP_NOTIFY_CEASE,
1274 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
1275 }
Paul Jakma1ebafb62016-04-27 09:55:21 +01001276 return ret_close_out;
paul718e3742002-12-13 20:15:29 +00001277 }
1278 else
1279 {
1280 /* 3. Otherwise, the local system closes newly created
1281 BGP connection (the one associated with the newly
1282 received OPEN message), and continues to use the
1283 existing one (the one that is already in the
1284 OpenConfirm state). */
1285
Paul Jakma1ebafb62016-04-27 09:55:21 +01001286 if (in->fd >= 0)
Paul Jakmac7986232016-09-21 17:42:37 +01001287 {
1288 if (BGP_DEBUG (events, EVENTS))
1289 zlog_debug ("%s Collision resolution, local ID higher,"
1290 " closing inbound", peer->host);
1291
1292 bgp_notify_send (in, BGP_NOTIFY_CEASE,
1293 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
1294 }
Paul Jakma1ebafb62016-04-27 09:55:21 +01001295 return ret_close_in;
paul718e3742002-12-13 20:15:29 +00001296 }
pauleb821182004-05-01 08:44:08 +00001297 }
1298 }
paul718e3742002-12-13 20:15:29 +00001299 return 0;
1300}
1301
paul94f2b392005-06-28 12:44:16 +00001302static int
paul718e3742002-12-13 20:15:29 +00001303bgp_open_receive (struct peer *peer, bgp_size_t size)
1304{
1305 int ret;
1306 u_char version;
1307 u_char optlen;
1308 u_int16_t holdtime;
1309 u_int16_t send_holdtime;
1310 as_t remote_as;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001311 as_t as4 = 0;
paul718e3742002-12-13 20:15:29 +00001312 struct peer *realpeer;
1313 struct in_addr remote_id;
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001314 int mp_capability;
paul5228ad22004-06-04 17:58:18 +00001315 u_int8_t notify_data_remote_as[2];
1316 u_int8_t notify_data_remote_id[4];
Daniel Waltonc6969872015-05-19 18:03:43 -07001317 u_int16_t *holdtime_ptr;
paul718e3742002-12-13 20:15:29 +00001318
1319 realpeer = NULL;
1320
1321 /* Parse open packet. */
1322 version = stream_getc (peer->ibuf);
1323 memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1324 remote_as = stream_getw (peer->ibuf);
Daniel Waltonc6969872015-05-19 18:03:43 -07001325 holdtime_ptr = (u_int16_t *)stream_pnt (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00001326 holdtime = stream_getw (peer->ibuf);
1327 memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1328 remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1329
1330 /* Receive OPEN message log */
1331 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001332 zlog_debug ("%s rcv OPEN, version %d, remote-as (in open) %u,"
Paul Jakmaac278ea2016-04-26 11:46:34 +01001333 " holdtime %d, id %s, %sbound connection",
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001334 peer->host, version, remote_as, holdtime,
Paul Jakmaac278ea2016-04-26 11:46:34 +01001335 inet_ntoa (remote_id),
1336 CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)
1337 ? "in" : "out");
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001338
1339 /* BEGIN to read the capability here, but dont do it yet */
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001340 mp_capability = 0;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001341 optlen = stream_getc (peer->ibuf);
1342
1343 if (optlen != 0)
1344 {
1345 /* We need the as4 capability value *right now* because
1346 * if it is there, we have not got the remote_as yet, and without
1347 * that we do not know which peer is connecting to us now.
1348 */
1349 as4 = peek_for_as4_capability (peer, optlen);
1350 }
1351
1352 /* Just in case we have a silly peer who sends AS4 capability set to 0 */
1353 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) && !as4)
1354 {
1355 zlog_err ("%s bad OPEN, got AS4 capability, but AS4 set to 0",
1356 peer->host);
1357 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1358 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1359 return -1;
1360 }
1361
1362 if (remote_as == BGP_AS_TRANS)
1363 {
1364 /* Take the AS4 from the capability. We must have received the
1365 * capability now! Otherwise we have a asn16 peer who uses
1366 * BGP_AS_TRANS, for some unknown reason.
1367 */
1368 if (as4 == BGP_AS_TRANS)
1369 {
1370 zlog_err ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
1371 peer->host);
1372 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1373 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1374 return -1;
1375 }
1376
1377 if (!as4 && BGP_DEBUG (as4, AS4))
1378 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
1379 " Odd, but proceeding.", peer->host);
1380 else if (as4 < BGP_AS_MAX && BGP_DEBUG (as4, AS4))
Paul Jakma0df7c912008-07-21 21:02:49 +00001381 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits "
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001382 "in 2-bytes, very odd peer.", peer->host, as4);
1383 if (as4)
1384 remote_as = as4;
1385 }
1386 else
1387 {
1388 /* We may have a partner with AS4 who has an asno < BGP_AS_MAX */
1389 /* If we have got the capability, peer->as4cap must match remote_as */
1390 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)
1391 && as4 != remote_as)
1392 {
1393 /* raise error, log this, close session */
1394 zlog_err ("%s bad OPEN, got AS4 capability, but remote_as %u"
1395 " mismatch with 16bit 'myasn' %u in open",
1396 peer->host, as4, remote_as);
1397 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1398 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1399 return -1;
1400 }
1401 }
1402
paul718e3742002-12-13 20:15:29 +00001403 /* Lookup peer from Open packet. */
1404 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1405 {
1406 int as = 0;
1407
1408 realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1409
1410 if (! realpeer)
1411 {
1412 /* Peer's source IP address is check in bgp_accept(), so this
1413 must be AS number mismatch or remote-id configuration
1414 mismatch. */
1415 if (as)
1416 {
1417 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001418 zlog_debug ("%s bad OPEN, wrong router identifier %s",
1419 peer->host, inet_ntoa (remote_id));
1420 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1421 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1422 notify_data_remote_id, 4);
paul718e3742002-12-13 20:15:29 +00001423 }
1424 else
1425 {
1426 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001427 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
ajs6b514742004-12-08 21:03:23 +00001428 peer->host, remote_as, peer->as);
1429 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1430 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1431 notify_data_remote_as, 2);
paul718e3742002-12-13 20:15:29 +00001432 }
1433 return -1;
1434 }
1435 }
1436
1437 /* When collision is detected and this peer is closed. Retrun
1438 immidiately. */
1439 ret = bgp_collision_detect (peer, remote_id);
1440 if (ret < 0)
1441 return ret;
1442
Paul Jakmaac278ea2016-04-26 11:46:34 +01001443 /* Bit hacky */
pauleb821182004-05-01 08:44:08 +00001444 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
Paul Jakmaac278ea2016-04-26 11:46:34 +01001445 {
1446 /* Connection FSM state is intertwined with our peer configuration
1447 * (the RFC encourages this a bit). At _this_ point we have a
1448 * 'realpeer' which represents the configuration and any earlier FSM
1449 * (outbound, unless the remote side has opened two connections to
1450 * us), and a 'peer' which here represents an inbound connection that
1451 * has not yet been reconciled with a 'realpeer'.
1452 *
1453 * As 'peer' has just sent an OPEN that reconciliation must now
1454 * happen, as only the 'realpeer' can ever proceed to Established.
1455 *
1456 * bgp_collision_detect should have resolved any collisions with
1457 * realpeers that are in states OpenSent, OpenConfirm or Established,
1458 * and may have sent a notify on the 'realpeer' connection.
1459 * bgp_accept will have rejected any connections where the 'realpeer'
1460 * is in Idle or >Established (though, that status may have changed
1461 * since).
1462 *
1463 * Need to finish off any reconciliation here, and ensure that
1464 * 'realpeer' is left holding any needed state from the appropriate
1465 * connection (fd, buffers, etc.), and any state from the other
1466 * connection is cleaned up.
1467 */
1468
1469 /* Is realpeer in some globally-down state, that precludes any and all
1470 * connections (Idle, Clearing, Deleted, etc.)?
1471 */
1472 if (realpeer->status == Idle || realpeer->status > Established)
1473 {
1474 if (BGP_DEBUG (events, EVENTS))
1475 zlog_debug ("%s peer status is %s, closing the new connection",
1476 realpeer->host,
1477 LOOKUP (bgp_status_msg, realpeer->status));
1478 return -1;
1479 }
1480
1481 /* GR does things differently, and prefers any new connection attempts
1482 * over an Established one (why not just rely on KEEPALIVE and avoid
1483 * having to special case this?) */
1484 if (realpeer->status == Established
hasso93406d82005-02-02 14:40:33 +00001485 && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1486 {
1487 realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1488 SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1489 }
Paul Jakmaac278ea2016-04-26 11:46:34 +01001490 else if (ret == 0)
pauleb821182004-05-01 08:44:08 +00001491 {
Paul Jakmaac278ea2016-04-26 11:46:34 +01001492 /* If we're here, RFC collision-detect did not reconcile the
1493 * connections, and the 'realpeer' is still available. So
1494 * 'realpeer' must be 'Active' or 'Connect'.
Paul Jakma2b2fc562008-09-06 13:09:35 +01001495 *
1496 * According to the RFC we should just let this connection (of the
1497 * accepted 'peer') continue on to Established if the other
Paul Jakmaac278ea2016-04-26 11:46:34 +01001498 * onnection (the 'realpeer') is in a more larval state, and
1499 * reconcile them when OPEN is sent on the 'realpeer'.
Paul Jakma2b2fc562008-09-06 13:09:35 +01001500 *
Paul Jakmaac278ea2016-04-26 11:46:34 +01001501 * However, the accepted 'peer' must be reconciled with 'peer' at
1502 * this point, due to the implementation, if 'peer' is to be able
1503 * to proceed. So it should be allowed to go to Established, as
1504 * long as the 'realpeer' was in Active or Connect state - which
1505 * /should/ be the case if we're here.
Paul Jakma2b2fc562008-09-06 13:09:35 +01001506 *
Paul Jakmaac278ea2016-04-26 11:46:34 +01001507 * So we should only need to sanity check that that is the case
1508 * here, and allow the code to get on with transferring the 'peer'
1509 * connection state over.
Paul Jakma2b2fc562008-09-06 13:09:35 +01001510 */
Paul Jakmaac278ea2016-04-26 11:46:34 +01001511 if (realpeer->status != Active && realpeer->status != Connect)
1512 {
1513 if (BGP_DEBUG (events, EVENTS))
1514 zlog_warn ("%s real peer status should be Active or Connect,"
1515 " but is %s",
1516 realpeer->host,
1517 LOOKUP (bgp_status_msg, realpeer->status));
1518 bgp_notify_send (realpeer, BGP_NOTIFY_CEASE,
1519 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
1520 }
pauleb821182004-05-01 08:44:08 +00001521 }
1522
1523 if (BGP_DEBUG (events, EVENTS))
Paul Jakmaac278ea2016-04-26 11:46:34 +01001524 zlog_debug ("%s:%u [Event] Transfer accept BGP peer to real (state %s)",
1525 peer->host, sockunion_get_port (&peer->su),
Paul Jakma6e199262008-09-09 17:14:33 +01001526 LOOKUP (bgp_status_msg, realpeer->status));
pauleb821182004-05-01 08:44:08 +00001527
1528 bgp_stop (realpeer);
1529
1530 /* Transfer file descriptor. */
1531 realpeer->fd = peer->fd;
1532 peer->fd = -1;
1533
1534 /* Transfer input buffer. */
1535 stream_free (realpeer->ibuf);
1536 realpeer->ibuf = peer->ibuf;
1537 realpeer->packet_size = peer->packet_size;
1538 peer->ibuf = NULL;
Paul Jakmaac278ea2016-04-26 11:46:34 +01001539
Paul Jakma2d81a7a2016-04-20 14:05:20 +01001540 /* Transfer output buffer, there may be an OPEN queued to send */
1541 stream_fifo_free (realpeer->obuf);
1542 realpeer->obuf = peer->obuf;
1543 peer->obuf = NULL;
Paul Jakmaac278ea2016-04-26 11:46:34 +01001544
Paul Jakmad023f9f2016-09-16 15:13:43 +01001545 bool open_deferred
1546 = CHECK_FLAG (peer->sflags, PEER_STATUS_OPEN_DEFERRED);
1547
pauleb821182004-05-01 08:44:08 +00001548 /* Transfer status. */
1549 realpeer->status = peer->status;
1550 bgp_stop (peer);
paul200df112005-06-01 11:17:05 +00001551
Paul Jakmaac278ea2016-04-26 11:46:34 +01001552 /* peer pointer change */
pauleb821182004-05-01 08:44:08 +00001553 peer = realpeer;
Paul Jakmad023f9f2016-09-16 15:13:43 +01001554
pauleb821182004-05-01 08:44:08 +00001555 if (peer->fd < 0)
1556 {
1557 zlog_err ("bgp_open_receive peer's fd is negative value %d",
1558 peer->fd);
1559 return -1;
1560 }
1561 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
Paul Jakma2d81a7a2016-04-20 14:05:20 +01001562 if (stream_fifo_head (peer->obuf))
1563 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
Paul Jakmad023f9f2016-09-16 15:13:43 +01001564
1565 /* hack: we may defer OPEN on accept peers, when there seems to be a
1566 * realpeer in progress, when an accept peer connection is opened. This
1567 * is to avoid interoperability issues, with test/conformance tools
1568 * particularly. See bgp_fsm.c::bgp_connect_success
1569 *
1570 * If OPEN was deferred there, then we must send it now.
1571 */
1572 if (open_deferred)
1573 bgp_open_send (peer);
pauleb821182004-05-01 08:44:08 +00001574 }
1575
paul718e3742002-12-13 20:15:29 +00001576 /* remote router-id check. */
1577 if (remote_id.s_addr == 0
Denis Ovsienko733cd9e2011-12-17 19:39:30 +04001578 || IPV4_CLASS_DE (ntohl (remote_id.s_addr))
paul718e3742002-12-13 20:15:29 +00001579 || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1580 {
1581 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001582 zlog_debug ("%s bad OPEN, wrong router identifier %s",
paul718e3742002-12-13 20:15:29 +00001583 peer->host, inet_ntoa (remote_id));
1584 bgp_notify_send_with_data (peer,
1585 BGP_NOTIFY_OPEN_ERR,
1586 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1587 notify_data_remote_id, 4);
1588 return -1;
1589 }
1590
1591 /* Set remote router-id */
1592 peer->remote_id = remote_id;
1593
1594 /* Peer BGP version check. */
1595 if (version != BGP_VERSION_4)
1596 {
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001597 u_int16_t maxver = htons(BGP_VERSION_4);
1598 /* XXX this reply may not be correct if version < 4 XXX */
paul718e3742002-12-13 20:15:29 +00001599 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001600 zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
paul718e3742002-12-13 20:15:29 +00001601 peer->host, version, BGP_VERSION_4);
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001602 /* Data must be in network byte order here */
paul718e3742002-12-13 20:15:29 +00001603 bgp_notify_send_with_data (peer,
1604 BGP_NOTIFY_OPEN_ERR,
1605 BGP_NOTIFY_OPEN_UNSUP_VERSION,
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001606 (u_int8_t *) &maxver, 2);
paul718e3742002-12-13 20:15:29 +00001607 return -1;
1608 }
1609
1610 /* Check neighbor as number. */
1611 if (remote_as != peer->as)
1612 {
1613 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001614 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
paul718e3742002-12-13 20:15:29 +00001615 peer->host, remote_as, peer->as);
1616 bgp_notify_send_with_data (peer,
1617 BGP_NOTIFY_OPEN_ERR,
1618 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1619 notify_data_remote_as, 2);
1620 return -1;
1621 }
1622
1623 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1624 calculate the value of the Hold Timer by using the smaller of its
1625 configured Hold Time and the Hold Time received in the OPEN message.
1626 The Hold Time MUST be either zero or at least three seconds. An
1627 implementation may reject connections on the basis of the Hold Time. */
1628
1629 if (holdtime < 3 && holdtime != 0)
1630 {
Daniel Waltonc6969872015-05-19 18:03:43 -07001631 bgp_notify_send_with_data (peer,
1632 BGP_NOTIFY_OPEN_ERR,
1633 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME,
1634 (u_int8_t *)holdtime_ptr, 2);
paul718e3742002-12-13 20:15:29 +00001635 return -1;
1636 }
1637
1638 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1639 would be one third of the Hold Time interval. KEEPALIVE messages
1640 MUST NOT be sent more frequently than one per second. An
1641 implementation MAY adjust the rate at which it sends KEEPALIVE
1642 messages as a function of the Hold Time interval. */
1643
1644 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1645 send_holdtime = peer->holdtime;
1646 else
1647 send_holdtime = peer->bgp->default_holdtime;
1648
1649 if (holdtime < send_holdtime)
1650 peer->v_holdtime = holdtime;
1651 else
1652 peer->v_holdtime = send_holdtime;
1653
1654 peer->v_keepalive = peer->v_holdtime / 3;
1655
1656 /* Open option part parse. */
paul718e3742002-12-13 20:15:29 +00001657 if (optlen != 0)
1658 {
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001659 if ((ret = bgp_open_option_parse (peer, optlen, &mp_capability)) < 0)
Paul Jakma58617392012-01-09 20:59:26 +00001660 {
1661 bgp_notify_send (peer,
1662 BGP_NOTIFY_OPEN_ERR,
Paul Jakma68ec4242015-11-25 17:14:34 +00001663 BGP_NOTIFY_OPEN_UNSPECIFIC);
Paul Jakma58617392012-01-09 20:59:26 +00001664 return ret;
1665 }
paul718e3742002-12-13 20:15:29 +00001666 }
1667 else
1668 {
1669 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001670 zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
paul718e3742002-12-13 20:15:29 +00001671 peer->host);
1672 }
1673
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001674 /*
1675 * Assume that the peer supports the locally configured set of
1676 * AFI/SAFIs if the peer did not send us any Mulitiprotocol
1677 * capabilities, or if 'override-capability' is configured.
1678 */
1679 if (! mp_capability ||
1680 CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
paul718e3742002-12-13 20:15:29 +00001681 {
1682 peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1683 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1684 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1685 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1686 }
1687
1688 /* Get sockname. */
1689 bgp_getsockname (peer);
Timo Teräs0edba8b2015-10-22 11:35:17 +03001690 peer->rtt = sockopt_tcp_rtt (peer->fd);
paul718e3742002-12-13 20:15:29 +00001691
1692 BGP_EVENT_ADD (peer, Receive_OPEN_message);
1693
1694 peer->packet_size = 0;
1695 if (peer->ibuf)
1696 stream_reset (peer->ibuf);
1697
1698 return 0;
1699}
1700
Paul Jakma518a4b72016-02-04 13:27:04 +00001701/* Frontend for NLRI parsing, to fan-out to AFI/SAFI specific parsers */
1702int
1703bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
1704{
1705 switch (packet->safi)
1706 {
1707 case SAFI_UNICAST:
1708 case SAFI_MULTICAST:
1709 return bgp_nlri_parse_ip (peer, attr, packet);
1710 case SAFI_MPLS_VPN:
1711 case SAFI_MPLS_LABELED_VPN:
1712 return bgp_nlri_parse_vpn (peer, attr, packet);
1713 case SAFI_ENCAP:
1714 return bgp_nlri_parse_encap (peer, attr, packet);
1715 }
1716 return -1;
1717}
1718
paul718e3742002-12-13 20:15:29 +00001719/* Parse BGP Update packet and make attribute object. */
paul94f2b392005-06-28 12:44:16 +00001720static int
paul718e3742002-12-13 20:15:29 +00001721bgp_update_receive (struct peer *peer, bgp_size_t size)
1722{
Paul Jakma518a4b72016-02-04 13:27:04 +00001723 int ret, nlri_ret;
paul718e3742002-12-13 20:15:29 +00001724 u_char *end;
1725 struct stream *s;
1726 struct attr attr;
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001727 struct attr_extra extra;
paul718e3742002-12-13 20:15:29 +00001728 bgp_size_t attribute_len;
1729 bgp_size_t update_len;
1730 bgp_size_t withdraw_len;
Paul Jakma518a4b72016-02-04 13:27:04 +00001731 int i;
1732
1733 enum NLRI_TYPES {
1734 NLRI_UPDATE,
1735 NLRI_WITHDRAW,
1736 NLRI_MP_UPDATE,
1737 NLRI_MP_WITHDRAW,
1738 NLRI_TYPE_MAX,
1739 };
1740 struct bgp_nlri nlris[NLRI_TYPE_MAX];
paul718e3742002-12-13 20:15:29 +00001741
1742 /* Status must be Established. */
1743 if (peer->status != Established)
1744 {
1745 zlog_err ("%s [FSM] Update packet received under status %s",
1746 peer->host, LOOKUP (bgp_status_msg, peer->status));
1747 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1748 return -1;
1749 }
1750
1751 /* Set initial values. */
1752 memset (&attr, 0, sizeof (struct attr));
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001753 memset (&extra, 0, sizeof (struct attr_extra));
Paul Jakma518a4b72016-02-04 13:27:04 +00001754 memset (&nlris, 0, sizeof nlris);
Paul Jakma3b847ef2016-04-22 12:48:49 +01001755
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001756 attr.extra = &extra;
paul718e3742002-12-13 20:15:29 +00001757
1758 s = peer->ibuf;
1759 end = stream_pnt (s) + size;
1760
1761 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1762 Length is too large (i.e., if Unfeasible Routes Length + Total
1763 Attribute Length + 23 exceeds the message Length), then the Error
1764 Subcode is set to Malformed Attribute List. */
1765 if (stream_pnt (s) + 2 > end)
1766 {
1767 zlog_err ("%s [Error] Update packet error"
1768 " (packet length is short for unfeasible length)",
1769 peer->host);
1770 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1771 BGP_NOTIFY_UPDATE_MAL_ATTR);
1772 return -1;
1773 }
1774
1775 /* Unfeasible Route Length. */
1776 withdraw_len = stream_getw (s);
1777
1778 /* Unfeasible Route Length check. */
1779 if (stream_pnt (s) + withdraw_len > end)
1780 {
1781 zlog_err ("%s [Error] Update packet error"
1782 " (packet unfeasible length overflow %d)",
1783 peer->host, withdraw_len);
1784 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1785 BGP_NOTIFY_UPDATE_MAL_ATTR);
1786 return -1;
1787 }
1788
1789 /* Unfeasible Route packet format check. */
1790 if (withdraw_len > 0)
1791 {
Paul Jakma518a4b72016-02-04 13:27:04 +00001792 nlris[NLRI_WITHDRAW].afi = AFI_IP;
1793 nlris[NLRI_WITHDRAW].safi = SAFI_UNICAST;
1794 nlris[NLRI_WITHDRAW].nlri = stream_pnt (s);
1795 nlris[NLRI_WITHDRAW].length = withdraw_len;
1796
paul718e3742002-12-13 20:15:29 +00001797 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001798 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001799
paul9985f832005-02-09 15:51:56 +00001800 stream_forward_getp (s, withdraw_len);
paul718e3742002-12-13 20:15:29 +00001801 }
1802
1803 /* Attribute total length check. */
1804 if (stream_pnt (s) + 2 > end)
1805 {
1806 zlog_warn ("%s [Error] Packet Error"
1807 " (update packet is short for attribute length)",
1808 peer->host);
1809 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1810 BGP_NOTIFY_UPDATE_MAL_ATTR);
1811 return -1;
1812 }
1813
1814 /* Fetch attribute total length. */
1815 attribute_len = stream_getw (s);
1816
1817 /* Attribute length check. */
1818 if (stream_pnt (s) + attribute_len > end)
1819 {
1820 zlog_warn ("%s [Error] Packet Error"
1821 " (update packet attribute length overflow %d)",
1822 peer->host, attribute_len);
1823 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1824 BGP_NOTIFY_UPDATE_MAL_ATTR);
1825 return -1;
1826 }
Paul Jakmab881c702010-11-23 16:35:42 +00001827
1828 /* Certain attribute parsing errors should not be considered bad enough
1829 * to reset the session for, most particularly any partial/optional
1830 * attributes that have 'tunneled' over speakers that don't understand
1831 * them. Instead we withdraw only the prefix concerned.
1832 *
1833 * Complicates the flow a little though..
1834 */
1835 bgp_attr_parse_ret_t attr_parse_ret = BGP_ATTR_PARSE_PROCEED;
1836 /* This define morphs the update case into a withdraw when lower levels
1837 * have signalled an error condition where this is best.
1838 */
1839#define NLRI_ATTR_ARG (attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : NULL)
paul718e3742002-12-13 20:15:29 +00001840
1841 /* Parse attribute when it exists. */
1842 if (attribute_len)
1843 {
Paul Jakmab881c702010-11-23 16:35:42 +00001844 attr_parse_ret = bgp_attr_parse (peer, &attr, attribute_len,
Paul Jakma518a4b72016-02-04 13:27:04 +00001845 &nlris[NLRI_MP_UPDATE], &nlris[NLRI_MP_WITHDRAW]);
Paul Jakmab881c702010-11-23 16:35:42 +00001846 if (attr_parse_ret == BGP_ATTR_PARSE_ERROR)
David Lamparterf80f8382014-06-04 01:00:51 +02001847 {
1848 bgp_attr_unintern_sub (&attr);
Lou Berger050defe2016-01-12 13:41:59 -05001849 bgp_attr_flush (&attr);
David Lamparterf80f8382014-06-04 01:00:51 +02001850 return -1;
1851 }
paul718e3742002-12-13 20:15:29 +00001852 }
Paul Jakmab881c702010-11-23 16:35:42 +00001853
paul718e3742002-12-13 20:15:29 +00001854 /* Logging the attribute. */
Paul Jakmab881c702010-11-23 16:35:42 +00001855 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW
1856 || BGP_DEBUG (update, UPDATE_IN))
paul718e3742002-12-13 20:15:29 +00001857 {
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +00001858 char attrstr[BUFSIZ];
1859 attrstr[0] = '\0';
1860
paule01f9cb2004-07-09 17:48:53 +00001861 ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
Paul Jakmab881c702010-11-23 16:35:42 +00001862 int lvl = (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1863 ? LOG_ERR : LOG_DEBUG;
1864
1865 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1866 zlog (peer->log, LOG_ERR,
1867 "%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
1868 peer->host);
paule01f9cb2004-07-09 17:48:53 +00001869
1870 if (ret)
Paul Jakmab881c702010-11-23 16:35:42 +00001871 zlog (peer->log, lvl, "%s rcvd UPDATE w/ attr: %s",
paule01f9cb2004-07-09 17:48:53 +00001872 peer->host, attrstr);
paul718e3742002-12-13 20:15:29 +00001873 }
Paul Jakmab881c702010-11-23 16:35:42 +00001874
paul718e3742002-12-13 20:15:29 +00001875 /* Network Layer Reachability Information. */
1876 update_len = end - stream_pnt (s);
1877
1878 if (update_len)
1879 {
Paul Jakma18ab08b2016-01-27 16:37:33 +00001880 /* Set NLRI portion to structure. */
Paul Jakma518a4b72016-02-04 13:27:04 +00001881 nlris[NLRI_UPDATE].afi = AFI_IP;
1882 nlris[NLRI_UPDATE].safi = SAFI_UNICAST;
1883 nlris[NLRI_UPDATE].nlri = stream_pnt (s);
1884 nlris[NLRI_UPDATE].length = update_len;
Paul Jakma18ab08b2016-01-27 16:37:33 +00001885
paul9985f832005-02-09 15:51:56 +00001886 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001887 }
Paul Jakma518a4b72016-02-04 13:27:04 +00001888
1889 /* Parse any given NLRIs */
1890 for (i = NLRI_UPDATE; i < NLRI_TYPE_MAX; i++)
paul718e3742002-12-13 20:15:29 +00001891 {
Paul Jakma3b847ef2016-04-22 12:48:49 +01001892 if (!nlris[i].nlri) continue;
1893
Paul Jakma518a4b72016-02-04 13:27:04 +00001894 /* We use afi and safi as indices into tables and what not. It would
1895 * be impossible, at this time, to support unknown afi/safis. And
1896 * anyway, the peer needs to be configured to enable the afi/safi
1897 * explicitly which requires UI support.
1898 *
1899 * Ignore unknown afi/safi NLRIs.
1900 *
1901 * Note: this means nlri[x].afi/safi still can not be trusted for
1902 * indexing later in this function!
1903 *
1904 * Note2: This will also remap the wire code-point for VPN safi to the
1905 * internal safi_t point, as needs be.
1906 */
1907 if (!bgp_afi_safi_valid_indices (nlris[i].afi, &nlris[i].safi))
1908 {
1909 plog_info (peer->log,
1910 "%s [Info] UPDATE with unsupported AFI/SAFI %u/%u",
1911 peer->host, nlris[i].afi, nlris[i].safi);
1912 continue;
1913 }
1914
1915 /* NLRI is processed only when the peer is configured specific
1916 Address Family and Subsequent Address Family. */
1917 if (!peer->afc[nlris[i].afi][nlris[i].safi])
1918 {
1919 plog_info (peer->log,
1920 "%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u",
1921 peer->host, nlris[i].afi, nlris[i].safi);
1922 continue;
1923 }
1924
1925 /* EoR handled later */
1926 if (nlris[i].length == 0)
1927 continue;
1928
1929 switch (i)
1930 {
1931 case NLRI_UPDATE:
1932 case NLRI_MP_UPDATE:
1933 nlri_ret = bgp_nlri_parse (peer, NLRI_ATTR_ARG, &nlris[i]);
1934 break;
1935 case NLRI_WITHDRAW:
1936 case NLRI_MP_WITHDRAW:
1937 nlri_ret = bgp_nlri_parse (peer, NULL, &nlris[i]);
1938 }
1939
1940 if (nlri_ret < 0)
1941 {
1942 plog_err (peer->log,
1943 "%s [Error] Error parsing NLRI", peer->host);
1944 if (peer->status == Established)
1945 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1946 i <= NLRI_WITHDRAW
1947 ? BGP_NOTIFY_UPDATE_INVAL_NETWORK
1948 : BGP_NOTIFY_UPDATE_OPT_ATTR_ERR);
1949 bgp_attr_unintern_sub (&attr);
1950 return -1;
1951 }
1952 }
1953
1954 /* EoR checks.
1955 *
1956 * Non-MP IPv4/Unicast EoR is a completely empty UPDATE
1957 * and MP EoR should have only an empty MP_UNREACH
1958 */
1959 if (!update_len && !withdraw_len
1960 && nlris[NLRI_MP_UPDATE].length == 0)
1961 {
1962 afi_t afi = 0;
1963 safi_t safi;
1964
1965 /* Non-MP IPv4/Unicast is a completely empty UPDATE - already
1966 * checked update and withdraw NLRI lengths are 0.
1967 */
1968 if (!attribute_len)
1969 {
1970 afi = AFI_IP;
1971 safi = SAFI_UNICAST;
1972 }
1973 /* otherwise MP AFI/SAFI is an empty update, other than an empty
1974 * MP_UNREACH_NLRI attr (with an AFI/SAFI we recognise).
1975 */
1976 else if (attr.flag == BGP_ATTR_MP_UNREACH_NLRI
1977 && nlris[NLRI_MP_WITHDRAW].length == 0
1978 && bgp_afi_safi_valid_indices (nlris[NLRI_MP_WITHDRAW].afi,
1979 &nlris[NLRI_MP_WITHDRAW].safi))
1980 {
1981 afi = nlris[NLRI_MP_WITHDRAW].afi;
1982 safi = nlris[NLRI_MP_WITHDRAW].safi;
1983 }
1984
1985 if (afi && peer->afc[afi][safi])
1986 {
paule01f9cb2004-07-09 17:48:53 +00001987 /* End-of-RIB received */
Paul Jakma518a4b72016-02-04 13:27:04 +00001988 SET_FLAG (peer->af_sflags[afi][safi],
hasso93406d82005-02-02 14:40:33 +00001989 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001990
hasso93406d82005-02-02 14:40:33 +00001991 /* NSF delete stale route */
Paul Jakma518a4b72016-02-04 13:27:04 +00001992 if (peer->nsf[afi][safi])
1993 bgp_clear_stale_route (peer, afi, safi);
hasso93406d82005-02-02 14:40:33 +00001994
1995 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma518a4b72016-02-04 13:27:04 +00001996 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for %s from %s",
1997 peer->host, afi_safi_print (afi, safi));
1998 }
paul718e3742002-12-13 20:15:29 +00001999 }
Paul Jakma518a4b72016-02-04 13:27:04 +00002000
paul718e3742002-12-13 20:15:29 +00002001 /* Everything is done. We unintern temporary structures which
2002 interned in bgp_attr_parse(). */
Paul Jakmab881c702010-11-23 16:35:42 +00002003 bgp_attr_unintern_sub (&attr);
Lou Berger050defe2016-01-12 13:41:59 -05002004 bgp_attr_flush (&attr);
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00002005
paul718e3742002-12-13 20:15:29 +00002006 /* If peering is stopped due to some reason, do not generate BGP
2007 event. */
2008 if (peer->status != Established)
2009 return 0;
2010
2011 /* Increment packet counter. */
2012 peer->update_in++;
Stephen Hemminger65957882010-01-15 16:22:10 +03002013 peer->update_time = bgp_clock ();
paul718e3742002-12-13 20:15:29 +00002014
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02002015 /* Rearm holdtime timer */
Jorge Boncompte [DTI2]6a4677b2012-05-07 16:53:07 +00002016 BGP_TIMER_OFF (peer->t_holdtime);
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02002017 bgp_timer_set (peer);
paul718e3742002-12-13 20:15:29 +00002018
2019 return 0;
2020}
2021
2022/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00002023static void
paul718e3742002-12-13 20:15:29 +00002024bgp_notify_receive (struct peer *peer, bgp_size_t size)
2025{
2026 struct bgp_notify bgp_notify;
2027
2028 if (peer->notify.data)
2029 {
2030 XFREE (MTYPE_TMP, peer->notify.data);
2031 peer->notify.data = NULL;
2032 peer->notify.length = 0;
2033 }
2034
2035 bgp_notify.code = stream_getc (peer->ibuf);
2036 bgp_notify.subcode = stream_getc (peer->ibuf);
2037 bgp_notify.length = size - 2;
2038 bgp_notify.data = NULL;
2039
2040 /* Preserv notify code and sub code. */
2041 peer->notify.code = bgp_notify.code;
2042 peer->notify.subcode = bgp_notify.subcode;
2043 /* For further diagnostic record returned Data. */
2044 if (bgp_notify.length)
2045 {
2046 peer->notify.length = size - 2;
2047 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
2048 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
2049 }
2050
2051 /* For debug */
2052 {
2053 int i;
2054 int first = 0;
2055 char c[4];
2056
2057 if (bgp_notify.length)
2058 {
2059 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
2060 for (i = 0; i < bgp_notify.length; i++)
2061 if (first)
2062 {
2063 sprintf (c, " %02x", stream_getc (peer->ibuf));
2064 strcat (bgp_notify.data, c);
2065 }
2066 else
2067 {
2068 first = 1;
2069 sprintf (c, "%02x", stream_getc (peer->ibuf));
2070 strcpy (bgp_notify.data, c);
2071 }
2072 }
2073
2074 bgp_notify_print(peer, &bgp_notify, "received");
2075 if (bgp_notify.data)
Daniel Walton363c9032015-10-21 06:42:54 -07002076 {
2077 XFREE (MTYPE_TMP, bgp_notify.data);
2078 bgp_notify.data = NULL;
2079 bgp_notify.length = 0;
2080 }
paul718e3742002-12-13 20:15:29 +00002081 }
2082
2083 /* peer count update */
2084 peer->notify_in++;
2085
hassoe0701b72004-05-20 09:19:34 +00002086 if (peer->status == Established)
2087 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
2088
paul718e3742002-12-13 20:15:29 +00002089 /* We have to check for Notify with Unsupported Optional Parameter.
2090 in that case we fallback to open without the capability option.
2091 But this done in bgp_stop. We just mark it here to avoid changing
2092 the fsm tables. */
2093 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
2094 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
2095 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
2096
paul718e3742002-12-13 20:15:29 +00002097 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
2098}
2099
2100/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00002101static void
paul718e3742002-12-13 20:15:29 +00002102bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
2103{
2104 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00002105 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00002106
2107 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
2108}
2109
2110/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00002111static void
paul718e3742002-12-13 20:15:29 +00002112bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
2113{
2114 afi_t afi;
2115 safi_t safi;
paul718e3742002-12-13 20:15:29 +00002116 struct stream *s;
2117
2118 /* If peer does not have the capability, send notification. */
2119 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
2120 {
2121 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
2122 peer->host);
2123 bgp_notify_send (peer,
2124 BGP_NOTIFY_HEADER_ERR,
2125 BGP_NOTIFY_HEADER_BAD_MESTYPE);
2126 return;
2127 }
2128
2129 /* Status must be Established. */
2130 if (peer->status != Established)
2131 {
2132 plog_err (peer->log,
2133 "%s [Error] Route refresh packet received under status %s",
2134 peer->host, LOOKUP (bgp_status_msg, peer->status));
2135 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
2136 return;
2137 }
2138
2139 s = peer->ibuf;
2140
2141 /* Parse packet. */
2142 afi = stream_getw (s);
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002143 /* reserved byte */
2144 stream_getc (s);
paul718e3742002-12-13 20:15:29 +00002145 safi = stream_getc (s);
2146
2147 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002148 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00002149 peer->host, afi, safi);
2150
2151 /* Check AFI and SAFI. */
2152 if ((afi != AFI_IP && afi != AFI_IP6)
2153 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
Denis Ovsienko42e6d742011-07-14 12:36:19 +04002154 && safi != SAFI_MPLS_LABELED_VPN))
paul718e3742002-12-13 20:15:29 +00002155 {
2156 if (BGP_DEBUG (normal, NORMAL))
2157 {
ajs6b514742004-12-08 21:03:23 +00002158 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00002159 peer->host, afi, safi);
2160 }
2161 return;
2162 }
2163
2164 /* Adjust safi code. */
Denis Ovsienko42e6d742011-07-14 12:36:19 +04002165 if (safi == SAFI_MPLS_LABELED_VPN)
paul718e3742002-12-13 20:15:29 +00002166 safi = SAFI_MPLS_VPN;
2167
2168 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
2169 {
2170 u_char *end;
2171 u_char when_to_refresh;
2172 u_char orf_type;
2173 u_int16_t orf_len;
2174
2175 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
2176 {
2177 zlog_info ("%s ORF route refresh length error", peer->host);
2178 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2179 return;
2180 }
2181
2182 when_to_refresh = stream_getc (s);
2183 end = stream_pnt (s) + (size - 5);
2184
Paul Jakma370b64a2007-12-22 16:49:52 +00002185 while ((stream_pnt (s) + 2) < end)
paul718e3742002-12-13 20:15:29 +00002186 {
2187 orf_type = stream_getc (s);
2188 orf_len = stream_getw (s);
Paul Jakma370b64a2007-12-22 16:49:52 +00002189
2190 /* orf_len in bounds? */
2191 if ((stream_pnt (s) + orf_len) > end)
2192 break; /* XXX: Notify instead?? */
paul718e3742002-12-13 20:15:29 +00002193 if (orf_type == ORF_TYPE_PREFIX
2194 || orf_type == ORF_TYPE_PREFIX_OLD)
2195 {
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002196 uint8_t *p_pnt = stream_pnt (s);
2197 uint8_t *p_end = stream_pnt (s) + orf_len;
paul718e3742002-12-13 20:15:29 +00002198 struct orf_prefix orfp;
2199 u_char common = 0;
2200 u_int32_t seq;
2201 int psize;
2202 char name[BUFSIZ];
paul718e3742002-12-13 20:15:29 +00002203 int ret;
2204
2205 if (BGP_DEBUG (normal, NORMAL))
2206 {
ajs6b514742004-12-08 21:03:23 +00002207 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00002208 peer->host, orf_type, orf_len);
2209 }
2210
Paul Jakma370b64a2007-12-22 16:49:52 +00002211 /* we're going to read at least 1 byte of common ORF header,
2212 * and 7 bytes of ORF Address-filter entry from the stream
2213 */
2214 if (orf_len < 7)
2215 break;
2216
paul718e3742002-12-13 20:15:29 +00002217 /* ORF prefix-list name */
2218 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
2219
2220 while (p_pnt < p_end)
2221 {
Chris Halld64379e2010-05-14 16:38:39 +04002222 /* If the ORF entry is malformed, want to read as much of it
2223 * as possible without going beyond the bounds of the entry,
2224 * to maximise debug information.
2225 */
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002226 int ok;
paul718e3742002-12-13 20:15:29 +00002227 memset (&orfp, 0, sizeof (struct orf_prefix));
2228 common = *p_pnt++;
Chris Halld64379e2010-05-14 16:38:39 +04002229 /* after ++: p_pnt <= p_end */
paul718e3742002-12-13 20:15:29 +00002230 if (common & ORF_COMMON_PART_REMOVE_ALL)
2231 {
2232 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002233 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
David Lamparterc9c06d02015-04-13 10:21:35 +02002234 prefix_bgp_orf_remove_all (afi, name);
paul718e3742002-12-13 20:15:29 +00002235 break;
2236 }
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002237 ok = ((size_t)(p_end - p_pnt) >= sizeof(u_int32_t)) ;
Denis Ovsienkobb915f52011-12-13 21:11:39 +04002238 if (ok)
Chris Halld64379e2010-05-14 16:38:39 +04002239 {
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002240 memcpy (&seq, p_pnt, sizeof (u_int32_t));
2241 p_pnt += sizeof (u_int32_t);
2242 orfp.seq = ntohl (seq);
Chris Halld64379e2010-05-14 16:38:39 +04002243 }
2244 else
2245 p_pnt = p_end ;
2246
2247 if ((ok = (p_pnt < p_end)))
2248 orfp.ge = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2249 if ((ok = (p_pnt < p_end)))
2250 orfp.le = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2251 if ((ok = (p_pnt < p_end)))
2252 orfp.p.prefixlen = *p_pnt++ ;
2253 orfp.p.family = afi2family (afi); /* afi checked already */
2254
2255 psize = PSIZE (orfp.p.prefixlen); /* 0 if not ok */
2256 if (psize > prefix_blen(&orfp.p)) /* valid for family ? */
2257 {
2258 ok = 0 ;
2259 psize = prefix_blen(&orfp.p) ;
2260 }
2261 if (psize > (p_end - p_pnt)) /* valid for packet ? */
2262 {
2263 ok = 0 ;
2264 psize = p_end - p_pnt ;
2265 }
2266
2267 if (psize > 0)
2268 memcpy (&orfp.p.u.prefix, p_pnt, psize);
paul718e3742002-12-13 20:15:29 +00002269 p_pnt += psize;
2270
2271 if (BGP_DEBUG (normal, NORMAL))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +00002272 {
2273 char buf[INET6_BUFSIZ];
2274
2275 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
2276 peer->host,
2277 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
2278 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
2279 orfp.seq,
2280 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, INET6_BUFSIZ),
2281 orfp.p.prefixlen, orfp.ge, orfp.le,
2282 ok ? "" : " MALFORMED");
2283 }
2284
Chris Halld64379e2010-05-14 16:38:39 +04002285 if (ok)
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002286 ret = prefix_bgp_orf_set (name, afi, &orfp,
2287 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
2288 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002289
2290 if (!ok || (ok && ret != CMD_SUCCESS))
paul718e3742002-12-13 20:15:29 +00002291 {
2292 if (BGP_DEBUG (normal, NORMAL))
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002293 zlog_debug ("%s Received misformatted prefixlist ORF."
2294 " Remove All pfxlist", peer->host);
David Lamparterc9c06d02015-04-13 10:21:35 +02002295 prefix_bgp_orf_remove_all (afi, name);
paul718e3742002-12-13 20:15:29 +00002296 break;
2297 }
2298 }
2299 peer->orf_plist[afi][safi] =
David Lamparterc9c06d02015-04-13 10:21:35 +02002300 prefix_bgp_orf_lookup (afi, name);
paul718e3742002-12-13 20:15:29 +00002301 }
paul9985f832005-02-09 15:51:56 +00002302 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00002303 }
2304 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002305 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00002306 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
2307 if (when_to_refresh == REFRESH_DEFER)
2308 return;
2309 }
2310
2311 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2312 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
2313 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
2314
2315 /* Perform route refreshment to the peer */
2316 bgp_announce_route (peer, afi, safi);
2317}
2318
paul94f2b392005-06-28 12:44:16 +00002319static int
paul718e3742002-12-13 20:15:29 +00002320bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
2321{
2322 u_char *end;
Paul Jakma6d582722007-08-06 15:21:45 +00002323 struct capability_mp_data mpc;
2324 struct capability_header *hdr;
paul718e3742002-12-13 20:15:29 +00002325 u_char action;
paul718e3742002-12-13 20:15:29 +00002326 afi_t afi;
2327 safi_t safi;
2328
paul718e3742002-12-13 20:15:29 +00002329 end = pnt + length;
2330
2331 while (pnt < end)
Paul Jakma6d582722007-08-06 15:21:45 +00002332 {
paul718e3742002-12-13 20:15:29 +00002333 /* We need at least action, capability code and capability length. */
2334 if (pnt + 3 > end)
2335 {
2336 zlog_info ("%s Capability length error", peer->host);
2337 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2338 return -1;
2339 }
paul718e3742002-12-13 20:15:29 +00002340 action = *pnt;
Paul Jakma6d582722007-08-06 15:21:45 +00002341 hdr = (struct capability_header *)(pnt + 1);
2342
paul718e3742002-12-13 20:15:29 +00002343 /* Action value check. */
2344 if (action != CAPABILITY_ACTION_SET
2345 && action != CAPABILITY_ACTION_UNSET)
2346 {
2347 zlog_info ("%s Capability Action Value error %d",
2348 peer->host, action);
2349 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2350 return -1;
2351 }
2352
2353 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002354 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
Paul Jakma6d582722007-08-06 15:21:45 +00002355 peer->host, action, hdr->code, hdr->length);
paul718e3742002-12-13 20:15:29 +00002356
2357 /* Capability length check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002358 if ((pnt + hdr->length + 3) > end)
paul718e3742002-12-13 20:15:29 +00002359 {
2360 zlog_info ("%s Capability length error", peer->host);
2361 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2362 return -1;
2363 }
2364
Paul Jakma6d582722007-08-06 15:21:45 +00002365 /* Fetch structure to the byte stream. */
2366 memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
2367
paul718e3742002-12-13 20:15:29 +00002368 /* We know MP Capability Code. */
Paul Jakma6d582722007-08-06 15:21:45 +00002369 if (hdr->code == CAPABILITY_CODE_MP)
paul718e3742002-12-13 20:15:29 +00002370 {
Paul Jakma6d582722007-08-06 15:21:45 +00002371 afi = ntohs (mpc.afi);
2372 safi = mpc.safi;
paul718e3742002-12-13 20:15:29 +00002373
2374 /* Ignore capability when override-capability is set. */
2375 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2376 continue;
Paul Jakma6d582722007-08-06 15:21:45 +00002377
2378 if (!bgp_afi_safi_valid_indices (afi, &safi))
2379 {
2380 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002381 zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
2382 "(%u/%u)", peer->host, afi, safi);
Paul Jakma6d582722007-08-06 15:21:45 +00002383 continue;
2384 }
2385
paul718e3742002-12-13 20:15:29 +00002386 /* Address family check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002387 if (BGP_DEBUG (normal, NORMAL))
2388 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2389 peer->host,
2390 action == CAPABILITY_ACTION_SET
2391 ? "Advertising" : "Removing",
2392 ntohs(mpc.afi) , mpc.safi);
2393
2394 if (action == CAPABILITY_ACTION_SET)
2395 {
2396 peer->afc_recv[afi][safi] = 1;
2397 if (peer->afc[afi][safi])
2398 {
2399 peer->afc_nego[afi][safi] = 1;
2400 bgp_announce_route (peer, afi, safi);
2401 }
2402 }
2403 else
2404 {
2405 peer->afc_recv[afi][safi] = 0;
2406 peer->afc_nego[afi][safi] = 0;
paul718e3742002-12-13 20:15:29 +00002407
Paul Jakma6d582722007-08-06 15:21:45 +00002408 if (peer_active_nego (peer))
Chris Caputo228da422009-07-18 05:44:03 +00002409 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
Paul Jakma6d582722007-08-06 15:21:45 +00002410 else
2411 BGP_EVENT_ADD (peer, BGP_Stop);
2412 }
paul718e3742002-12-13 20:15:29 +00002413 }
paul718e3742002-12-13 20:15:29 +00002414 else
2415 {
2416 zlog_warn ("%s unrecognized capability code: %d - ignored",
Paul Jakma6d582722007-08-06 15:21:45 +00002417 peer->host, hdr->code);
paul718e3742002-12-13 20:15:29 +00002418 }
Paul Jakma6d582722007-08-06 15:21:45 +00002419 pnt += hdr->length + 3;
paul718e3742002-12-13 20:15:29 +00002420 }
2421 return 0;
2422}
2423
Paul Jakma01b7ce22009-06-18 12:34:43 +01002424/* Dynamic Capability is received.
2425 *
2426 * This is exported for unit-test purposes
2427 */
Paul Jakma6d582722007-08-06 15:21:45 +00002428int
paul718e3742002-12-13 20:15:29 +00002429bgp_capability_receive (struct peer *peer, bgp_size_t size)
2430{
2431 u_char *pnt;
paul718e3742002-12-13 20:15:29 +00002432
2433 /* Fetch pointer. */
2434 pnt = stream_pnt (peer->ibuf);
2435
2436 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002437 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002438
2439 /* If peer does not have the capability, send notification. */
2440 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2441 {
2442 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2443 peer->host);
2444 bgp_notify_send (peer,
2445 BGP_NOTIFY_HEADER_ERR,
2446 BGP_NOTIFY_HEADER_BAD_MESTYPE);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002447 return -1;
paul718e3742002-12-13 20:15:29 +00002448 }
2449
2450 /* Status must be Established. */
2451 if (peer->status != Established)
2452 {
2453 plog_err (peer->log,
2454 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2455 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002456 return -1;
paul718e3742002-12-13 20:15:29 +00002457 }
2458
2459 /* Parse packet. */
Paul Jakma6d582722007-08-06 15:21:45 +00002460 return bgp_capability_msg_parse (peer, pnt, size);
paul718e3742002-12-13 20:15:29 +00002461}
David Lamparter6b0655a2014-06-04 06:53:35 +02002462
paul718e3742002-12-13 20:15:29 +00002463/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002464static int
paul718e3742002-12-13 20:15:29 +00002465bgp_read_packet (struct peer *peer)
2466{
2467 int nbytes;
2468 int readsize;
2469
paul9985f832005-02-09 15:51:56 +00002470 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002471
2472 /* If size is zero then return. */
2473 if (! readsize)
2474 return 0;
2475
2476 /* Read packet from fd. */
Stephen Hemminger35398582010-08-05 10:26:23 -07002477 nbytes = stream_read_try (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002478
2479 /* If read byte is smaller than zero then error occured. */
2480 if (nbytes < 0)
2481 {
Stephen Hemminger35398582010-08-05 10:26:23 -07002482 /* Transient error should retry */
2483 if (nbytes == -2)
paul718e3742002-12-13 20:15:29 +00002484 return -1;
2485
2486 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002487 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002488
2489 if (peer->status == Established)
2490 {
2491 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2492 {
2493 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2494 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2495 }
2496 else
2497 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2498 }
2499
paul718e3742002-12-13 20:15:29 +00002500 BGP_EVENT_ADD (peer, TCP_fatal_error);
2501 return -1;
2502 }
2503
2504 /* When read byte is zero : clear bgp peer and return */
2505 if (nbytes == 0)
2506 {
2507 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002508 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002509 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002510
2511 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002512 {
2513 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2514 {
2515 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2516 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2517 }
2518 else
2519 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2520 }
hassoe0701b72004-05-20 09:19:34 +00002521
paul718e3742002-12-13 20:15:29 +00002522 BGP_EVENT_ADD (peer, TCP_connection_closed);
2523 return -1;
2524 }
2525
2526 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002527 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002528 return -1;
2529
2530 return 0;
2531}
2532
2533/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002534static int
paul718e3742002-12-13 20:15:29 +00002535bgp_marker_all_one (struct stream *s, int length)
2536{
2537 int i;
2538
2539 for (i = 0; i < length; i++)
2540 if (s->data[i] != 0xff)
2541 return 0;
2542
2543 return 1;
2544}
2545
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002546/* Recent thread time.
2547 On same clock base as bgp_clock (MONOTONIC)
2548 but can be time of last context switch to bgp_read thread. */
2549static time_t
2550bgp_recent_clock (void)
2551{
2552 return recent_relative_time().tv_sec;
2553}
2554
paul718e3742002-12-13 20:15:29 +00002555/* Starting point of packet process function. */
2556int
2557bgp_read (struct thread *thread)
2558{
2559 int ret;
2560 u_char type = 0;
2561 struct peer *peer;
2562 bgp_size_t size;
2563 char notify_data_length[2];
2564
2565 /* Yes first of all get peer pointer. */
2566 peer = THREAD_ARG (thread);
2567 peer->t_read = NULL;
2568
2569 /* For non-blocking IO check. */
2570 if (peer->status == Connect)
2571 {
Paul Jakma743dd422016-09-30 13:55:47 +01002572 bgp_connect_check (peer);
paul718e3742002-12-13 20:15:29 +00002573 goto done;
2574 }
2575 else
2576 {
pauleb821182004-05-01 08:44:08 +00002577 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002578 {
pauleb821182004-05-01 08:44:08 +00002579 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002580 return -1;
2581 }
pauleb821182004-05-01 08:44:08 +00002582 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002583 }
2584
2585 /* Read packet header to determine type of the packet */
2586 if (peer->packet_size == 0)
2587 peer->packet_size = BGP_HEADER_SIZE;
2588
paul9985f832005-02-09 15:51:56 +00002589 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002590 {
2591 ret = bgp_read_packet (peer);
2592
2593 /* Header read error or partial read packet. */
2594 if (ret < 0)
2595 goto done;
2596
2597 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002598 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002599 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2600 size = stream_getw (peer->ibuf);
2601 type = stream_getc (peer->ibuf);
2602
2603 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002604 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002605 peer->host, type, size - BGP_HEADER_SIZE);
2606
2607 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002608 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002609 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2610 {
2611 bgp_notify_send (peer,
2612 BGP_NOTIFY_HEADER_ERR,
2613 BGP_NOTIFY_HEADER_NOT_SYNC);
2614 goto done;
2615 }
2616
2617 /* BGP type check. */
2618 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2619 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2620 && type != BGP_MSG_ROUTE_REFRESH_NEW
2621 && type != BGP_MSG_ROUTE_REFRESH_OLD
2622 && type != BGP_MSG_CAPABILITY)
2623 {
2624 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002625 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002626 "%s unknown message type 0x%02x",
2627 peer->host, type);
2628 bgp_notify_send_with_data (peer,
2629 BGP_NOTIFY_HEADER_ERR,
2630 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2631 &type, 1);
2632 goto done;
2633 }
2634 /* Mimimum packet length check. */
2635 if ((size < BGP_HEADER_SIZE)
2636 || (size > BGP_MAX_PACKET_SIZE)
2637 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2638 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2639 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2640 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2641 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2642 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2643 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2644 {
2645 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002646 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002647 "%s bad message length - %d for %s",
2648 peer->host, size,
2649 type == 128 ? "ROUTE-REFRESH" :
2650 bgp_type_str[(int) type]);
2651 bgp_notify_send_with_data (peer,
2652 BGP_NOTIFY_HEADER_ERR,
2653 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002654 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002655 goto done;
2656 }
2657
2658 /* Adjust size to message length. */
2659 peer->packet_size = size;
2660 }
2661
2662 ret = bgp_read_packet (peer);
2663 if (ret < 0)
2664 goto done;
2665
2666 /* Get size and type again. */
2667 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2668 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2669
2670 /* BGP packet dump function. */
2671 bgp_dump_packet (peer, type, peer->ibuf);
2672
2673 size = (peer->packet_size - BGP_HEADER_SIZE);
2674
2675 /* Read rest of the packet and call each sort of packet routine */
2676 switch (type)
2677 {
2678 case BGP_MSG_OPEN:
2679 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002680 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002681 break;
2682 case BGP_MSG_UPDATE:
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002683 peer->readtime = bgp_recent_clock ();
paul718e3742002-12-13 20:15:29 +00002684 bgp_update_receive (peer, size);
2685 break;
2686 case BGP_MSG_NOTIFY:
2687 bgp_notify_receive (peer, size);
2688 break;
2689 case BGP_MSG_KEEPALIVE:
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002690 peer->readtime = bgp_recent_clock ();
paul718e3742002-12-13 20:15:29 +00002691 bgp_keepalive_receive (peer, size);
2692 break;
2693 case BGP_MSG_ROUTE_REFRESH_NEW:
2694 case BGP_MSG_ROUTE_REFRESH_OLD:
2695 peer->refresh_in++;
2696 bgp_route_refresh_receive (peer, size);
2697 break;
2698 case BGP_MSG_CAPABILITY:
2699 peer->dynamic_cap_in++;
2700 bgp_capability_receive (peer, size);
2701 break;
2702 }
2703
2704 /* Clear input buffer. */
2705 peer->packet_size = 0;
2706 if (peer->ibuf)
2707 stream_reset (peer->ibuf);
2708
2709 done:
2710 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2711 {
2712 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002713 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002714 peer_delete (peer);
paul718e3742002-12-13 20:15:29 +00002715 }
2716 return 0;
2717}