blob: d3acbd23593ee50209bcd998a881dc60a9e2f59f [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;
1011 zlog_info ("Notification sent to neighbor %s: User reset", peer->host);
1012 }
hassoe0701b72004-05-20 09:19:34 +00001013 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
heasley1212dc12011-09-12 13:27:52 +04001014 {
1015 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
1016 zlog_info ("Notification sent to neighbor %s: shutdown", peer->host);
1017 }
hassoe0701b72004-05-20 09:19:34 +00001018 else
heasley1212dc12011-09-12 13:27:52 +04001019 {
1020 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
1021 zlog_info ("Notification sent to neighbor %s: type %u/%u",
1022 peer->host, code, sub_code);
1023 }
hassoe0701b72004-05-20 09:19:34 +00001024 }
heasley1212dc12011-09-12 13:27:52 +04001025 else
1026 zlog_info ("Notification sent to neighbor %s: configuration change",
1027 peer->host);
hassoe0701b72004-05-20 09:19:34 +00001028
Denis Ovsienko7ccf5e52011-09-10 16:53:30 +04001029 /* Call immediately. */
paul718e3742002-12-13 20:15:29 +00001030 BGP_WRITE_OFF (peer->t_write);
1031
1032 bgp_write_notify (peer);
1033}
1034
1035/* Send BGP notify packet. */
1036void
1037bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
1038{
1039 bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
1040}
1041
paul718e3742002-12-13 20:15:29 +00001042/* Send route refresh message to the peer. */
1043void
1044bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
1045 u_char orf_type, u_char when_to_refresh, int remove)
1046{
1047 struct stream *s;
paul718e3742002-12-13 20:15:29 +00001048 int length;
1049 struct bgp_filter *filter;
1050 int orf_refresh = 0;
1051
Paul Jakma750e8142008-07-22 21:11:48 +00001052 if (DISABLE_BGP_ANNOUNCE)
1053 return;
paul718e3742002-12-13 20:15:29 +00001054
1055 filter = &peer->filter[afi][safi];
1056
1057 /* Adjust safi code. */
1058 if (safi == SAFI_MPLS_VPN)
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001059 safi = SAFI_MPLS_LABELED_VPN;
paul718e3742002-12-13 20:15:29 +00001060
1061 s = stream_new (BGP_MAX_PACKET_SIZE);
1062
1063 /* Make BGP update packet. */
1064 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
1065 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
1066 else
1067 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
1068
1069 /* Encode Route Refresh message. */
1070 stream_putw (s, afi);
1071 stream_putc (s, 0);
1072 stream_putc (s, safi);
1073
1074 if (orf_type == ORF_TYPE_PREFIX
1075 || orf_type == ORF_TYPE_PREFIX_OLD)
1076 if (remove || filter->plist[FILTER_IN].plist)
1077 {
1078 u_int16_t orf_len;
1079 unsigned long orfp;
1080
1081 orf_refresh = 1;
1082 stream_putc (s, when_to_refresh);
1083 stream_putc (s, orf_type);
paul9985f832005-02-09 15:51:56 +00001084 orfp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00001085 stream_putw (s, 0);
1086
1087 if (remove)
1088 {
1089 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1090 stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
1091 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001092 zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001093 peer->host, orf_type,
1094 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1095 afi, safi);
1096 }
1097 else
1098 {
1099 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1100 prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
1101 ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
1102 ORF_COMMON_PART_DENY);
1103 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001104 zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001105 peer->host, orf_type,
1106 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1107 afi, safi);
1108 }
1109
1110 /* Total ORF Entry Len. */
paul9985f832005-02-09 15:51:56 +00001111 orf_len = stream_get_endp (s) - orfp - 2;
paul718e3742002-12-13 20:15:29 +00001112 stream_putw_at (s, orfp, orf_len);
1113 }
1114
1115 /* Set packet size. */
1116 length = bgp_packet_set_size (s);
1117
1118 if (BGP_DEBUG (normal, NORMAL))
1119 {
1120 if (! orf_refresh)
ajs6b514742004-12-08 21:03:23 +00001121 zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001122 peer->host, afi, safi);
ajs6b514742004-12-08 21:03:23 +00001123 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001124 peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
1125 BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
1126 }
1127
paul718e3742002-12-13 20:15:29 +00001128 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -04001129 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +00001130
pauleb821182004-05-01 08:44:08 +00001131 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001132}
1133
1134/* Send capability message to the peer. */
1135void
1136bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
1137 int capability_code, int action)
1138{
1139 struct stream *s;
paul718e3742002-12-13 20:15:29 +00001140 int length;
1141
1142 /* Adjust safi code. */
1143 if (safi == SAFI_MPLS_VPN)
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001144 safi = SAFI_MPLS_LABELED_VPN;
paul718e3742002-12-13 20:15:29 +00001145
1146 s = stream_new (BGP_MAX_PACKET_SIZE);
1147
1148 /* Make BGP update packet. */
1149 bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
1150
1151 /* Encode MP_EXT capability. */
1152 if (capability_code == CAPABILITY_CODE_MP)
1153 {
1154 stream_putc (s, action);
1155 stream_putc (s, CAPABILITY_CODE_MP);
1156 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1157 stream_putw (s, afi);
1158 stream_putc (s, 0);
1159 stream_putc (s, safi);
1160
1161 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001162 zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001163 peer->host, action == CAPABILITY_ACTION_SET ?
1164 "Advertising" : "Removing", afi, safi);
1165 }
1166
paul718e3742002-12-13 20:15:29 +00001167 /* Set packet size. */
1168 length = bgp_packet_set_size (s);
1169
paul718e3742002-12-13 20:15:29 +00001170
1171 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -04001172 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +00001173
1174 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001175 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001176 peer->host, BGP_MSG_CAPABILITY, length);
1177
pauleb821182004-05-01 08:44:08 +00001178 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001179}
David Lamparter6b0655a2014-06-04 06:53:35 +02001180
paul718e3742002-12-13 20:15:29 +00001181/* RFC1771 6.8 Connection collision detection. */
paul94f2b392005-06-28 12:44:16 +00001182static int
pauleb821182004-05-01 08:44:08 +00001183bgp_collision_detect (struct peer *new, struct in_addr remote_id)
paul718e3742002-12-13 20:15:29 +00001184{
pauleb821182004-05-01 08:44:08 +00001185 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +00001186 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001187 struct bgp *bgp;
1188
1189 bgp = bgp_get_default ();
1190 if (! bgp)
1191 return 0;
1192
1193 /* Upon receipt of an OPEN message, the local system must examine
1194 all of its connections that are in the OpenConfirm state. A BGP
1195 speaker may also examine connections in an OpenSent state if it
1196 knows the BGP Identifier of the peer by means outside of the
1197 protocol. If among these connections there is a connection to a
1198 remote BGP speaker whose BGP Identifier equals the one in the
1199 OPEN message, then the local system performs the following
1200 collision resolution procedure: */
1201
paul1eb8ef22005-04-07 07:30:20 +00001202 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00001203 {
1204 /* Under OpenConfirm status, local peer structure already hold
1205 remote router ID. */
pauleb821182004-05-01 08:44:08 +00001206
1207 if (peer != new
1208 && (peer->status == OpenConfirm || peer->status == OpenSent)
1209 && sockunion_same (&peer->su, &new->su))
1210 {
paul718e3742002-12-13 20:15:29 +00001211 /* 1. The BGP Identifier of the local system is compared to
1212 the BGP Identifier of the remote system (as specified in
1213 the OPEN message). */
1214
1215 if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
1216 {
1217 /* 2. If the value of the local BGP Identifier is less
1218 than the remote one, the local system closes BGP
1219 connection that already exists (the one that is
1220 already in the OpenConfirm state), and accepts BGP
1221 connection initiated by the remote system. */
1222
pauleb821182004-05-01 08:44:08 +00001223 if (peer->fd >= 0)
hassoe0701b72004-05-20 09:19:34 +00001224 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001225 return 1;
1226 }
1227 else
1228 {
1229 /* 3. Otherwise, the local system closes newly created
1230 BGP connection (the one associated with the newly
1231 received OPEN message), and continues to use the
1232 existing one (the one that is already in the
1233 OpenConfirm state). */
1234
pauleb821182004-05-01 08:44:08 +00001235 if (new->fd >= 0)
paulf5ba3872004-07-09 12:11:31 +00001236 bgp_notify_send (new, BGP_NOTIFY_CEASE,
1237 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001238 return -1;
1239 }
pauleb821182004-05-01 08:44:08 +00001240 }
1241 }
paul718e3742002-12-13 20:15:29 +00001242 return 0;
1243}
1244
paul94f2b392005-06-28 12:44:16 +00001245static int
paul718e3742002-12-13 20:15:29 +00001246bgp_open_receive (struct peer *peer, bgp_size_t size)
1247{
1248 int ret;
1249 u_char version;
1250 u_char optlen;
1251 u_int16_t holdtime;
1252 u_int16_t send_holdtime;
1253 as_t remote_as;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001254 as_t as4 = 0;
paul718e3742002-12-13 20:15:29 +00001255 struct peer *realpeer;
1256 struct in_addr remote_id;
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001257 int mp_capability;
paul5228ad22004-06-04 17:58:18 +00001258 u_int8_t notify_data_remote_as[2];
1259 u_int8_t notify_data_remote_id[4];
Daniel Waltonc6969872015-05-19 18:03:43 -07001260 u_int16_t *holdtime_ptr;
paul718e3742002-12-13 20:15:29 +00001261
1262 realpeer = NULL;
1263
1264 /* Parse open packet. */
1265 version = stream_getc (peer->ibuf);
1266 memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1267 remote_as = stream_getw (peer->ibuf);
Daniel Waltonc6969872015-05-19 18:03:43 -07001268 holdtime_ptr = (u_int16_t *)stream_pnt (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00001269 holdtime = stream_getw (peer->ibuf);
1270 memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1271 remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1272
1273 /* Receive OPEN message log */
1274 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001275 zlog_debug ("%s rcv OPEN, version %d, remote-as (in open) %u,"
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001276 " holdtime %d, id %s",
1277 peer->host, version, remote_as, holdtime,
1278 inet_ntoa (remote_id));
1279
1280 /* BEGIN to read the capability here, but dont do it yet */
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001281 mp_capability = 0;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001282 optlen = stream_getc (peer->ibuf);
1283
1284 if (optlen != 0)
1285 {
1286 /* We need the as4 capability value *right now* because
1287 * if it is there, we have not got the remote_as yet, and without
1288 * that we do not know which peer is connecting to us now.
1289 */
1290 as4 = peek_for_as4_capability (peer, optlen);
1291 }
1292
1293 /* Just in case we have a silly peer who sends AS4 capability set to 0 */
1294 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) && !as4)
1295 {
1296 zlog_err ("%s bad OPEN, got AS4 capability, but AS4 set to 0",
1297 peer->host);
1298 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1299 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1300 return -1;
1301 }
1302
1303 if (remote_as == BGP_AS_TRANS)
1304 {
1305 /* Take the AS4 from the capability. We must have received the
1306 * capability now! Otherwise we have a asn16 peer who uses
1307 * BGP_AS_TRANS, for some unknown reason.
1308 */
1309 if (as4 == BGP_AS_TRANS)
1310 {
1311 zlog_err ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
1312 peer->host);
1313 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1314 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1315 return -1;
1316 }
1317
1318 if (!as4 && BGP_DEBUG (as4, AS4))
1319 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
1320 " Odd, but proceeding.", peer->host);
1321 else if (as4 < BGP_AS_MAX && BGP_DEBUG (as4, AS4))
Paul Jakma0df7c912008-07-21 21:02:49 +00001322 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits "
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001323 "in 2-bytes, very odd peer.", peer->host, as4);
1324 if (as4)
1325 remote_as = as4;
1326 }
1327 else
1328 {
1329 /* We may have a partner with AS4 who has an asno < BGP_AS_MAX */
1330 /* If we have got the capability, peer->as4cap must match remote_as */
1331 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)
1332 && as4 != remote_as)
1333 {
1334 /* raise error, log this, close session */
1335 zlog_err ("%s bad OPEN, got AS4 capability, but remote_as %u"
1336 " mismatch with 16bit 'myasn' %u in open",
1337 peer->host, as4, remote_as);
1338 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1339 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1340 return -1;
1341 }
1342 }
1343
paul718e3742002-12-13 20:15:29 +00001344 /* Lookup peer from Open packet. */
1345 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1346 {
1347 int as = 0;
1348
1349 realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1350
1351 if (! realpeer)
1352 {
1353 /* Peer's source IP address is check in bgp_accept(), so this
1354 must be AS number mismatch or remote-id configuration
1355 mismatch. */
1356 if (as)
1357 {
1358 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001359 zlog_debug ("%s bad OPEN, wrong router identifier %s",
1360 peer->host, inet_ntoa (remote_id));
1361 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1362 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1363 notify_data_remote_id, 4);
paul718e3742002-12-13 20:15:29 +00001364 }
1365 else
1366 {
1367 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001368 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
ajs6b514742004-12-08 21:03:23 +00001369 peer->host, remote_as, peer->as);
1370 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1371 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1372 notify_data_remote_as, 2);
paul718e3742002-12-13 20:15:29 +00001373 }
1374 return -1;
1375 }
1376 }
1377
1378 /* When collision is detected and this peer is closed. Retrun
1379 immidiately. */
1380 ret = bgp_collision_detect (peer, remote_id);
1381 if (ret < 0)
1382 return ret;
1383
pauleb821182004-05-01 08:44:08 +00001384 /* Hack part. */
1385 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1386 {
hasso93406d82005-02-02 14:40:33 +00001387 if (realpeer->status == Established
1388 && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1389 {
1390 realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1391 SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1392 }
1393 else if (ret == 0 && realpeer->status != Active
1394 && realpeer->status != OpenSent
Paul Jakma6e199262008-09-09 17:14:33 +01001395 && realpeer->status != OpenConfirm
1396 && realpeer->status != Connect)
pauleb821182004-05-01 08:44:08 +00001397 {
Paul Jakma2b2fc562008-09-06 13:09:35 +01001398 /* XXX: This is an awful problem..
1399 *
1400 * According to the RFC we should just let this connection (of the
1401 * accepted 'peer') continue on to Established if the other
1402 * connection (the 'realpeer' one) is in state Connect, and deal
1403 * with the more larval FSM as/when it gets far enough to receive
1404 * an Open. We don't do that though, we instead close the (more
1405 * developed) accepted connection.
1406 *
1407 * This means there's a race, which if hit, can loop:
1408 *
1409 * FSM for A FSM for B
1410 * realpeer accept-peer realpeer accept-peer
1411 *
1412 * Connect Connect
1413 * Active
1414 * OpenSent OpenSent
1415 * <arrive here,
1416 * Notify, delete>
1417 * Idle Active
1418 * OpenSent OpenSent
1419 * <arrive here,
1420 * Notify, delete>
1421 * Idle
1422 * <wait> <wait>
1423 * Connect Connect
1424 *
1425 *
Paul Jakma2d81a7a2016-04-20 14:05:20 +01001426 * Note that Active->OpenSent historically in Quagga did not send
1427 * OPEN on the accept-peer connection.
1428 *
Paul Jakma2b2fc562008-09-06 13:09:35 +01001429 * If both sides are Quagga, they're almost certain to wait for
1430 * the same amount of time of course (which doesn't preclude other
1431 * implementations also waiting for same time). The race is
1432 * exacerbated by high-latency (in bgpd and/or the network).
1433 *
1434 * The reason we do this is because our FSM is tied to our peer
1435 * structure, which carries our configuration information, etc.
1436 * I.e. we can't let the accepted-peer FSM continue on as it is,
1437 * cause it's not associated with any actual peer configuration -
1438 * it's just a dummy.
1439 *
1440 * It's possible we could hack-fix this by just bgp_stop'ing the
1441 * realpeer and continueing on with the 'transfer FSM' below.
1442 * Ideally, we need to seperate FSMs from struct peer.
1443 *
1444 * Setting one side to passive avoids the race, as a workaround.
1445 */
pauleb821182004-05-01 08:44:08 +00001446 if (BGP_DEBUG (events, EVENTS))
hasso93406d82005-02-02 14:40:33 +00001447 zlog_debug ("%s peer status is %s close connection",
1448 realpeer->host, LOOKUP (bgp_status_msg,
1449 realpeer->status));
1450 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1451 BGP_NOTIFY_CEASE_CONNECT_REJECT);
1452
pauleb821182004-05-01 08:44:08 +00001453 return -1;
1454 }
1455
1456 if (BGP_DEBUG (events, EVENTS))
Paul Jakma6e199262008-09-09 17:14:33 +01001457 zlog_debug ("%s [Event] Transfer accept BGP peer to real (state %s)",
1458 peer->host,
1459 LOOKUP (bgp_status_msg, realpeer->status));
pauleb821182004-05-01 08:44:08 +00001460
1461 bgp_stop (realpeer);
1462
1463 /* Transfer file descriptor. */
1464 realpeer->fd = peer->fd;
1465 peer->fd = -1;
1466
1467 /* Transfer input buffer. */
1468 stream_free (realpeer->ibuf);
1469 realpeer->ibuf = peer->ibuf;
1470 realpeer->packet_size = peer->packet_size;
1471 peer->ibuf = NULL;
Paul Jakma2d81a7a2016-04-20 14:05:20 +01001472
1473 /* Transfer output buffer, there may be an OPEN queued to send */
1474 stream_fifo_free (realpeer->obuf);
1475 realpeer->obuf = peer->obuf;
1476 peer->obuf = NULL;
pauleb821182004-05-01 08:44:08 +00001477
1478 /* Transfer status. */
1479 realpeer->status = peer->status;
1480 bgp_stop (peer);
paul200df112005-06-01 11:17:05 +00001481
pauleb821182004-05-01 08:44:08 +00001482 /* peer pointer change. Open packet send to neighbor. */
1483 peer = realpeer;
pauleb821182004-05-01 08:44:08 +00001484 if (peer->fd < 0)
1485 {
1486 zlog_err ("bgp_open_receive peer's fd is negative value %d",
1487 peer->fd);
1488 return -1;
1489 }
1490 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
Paul Jakma2d81a7a2016-04-20 14:05:20 +01001491 if (stream_fifo_head (peer->obuf))
1492 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
pauleb821182004-05-01 08:44:08 +00001493 }
1494
paul718e3742002-12-13 20:15:29 +00001495 /* remote router-id check. */
1496 if (remote_id.s_addr == 0
Denis Ovsienko733cd9e2011-12-17 19:39:30 +04001497 || IPV4_CLASS_DE (ntohl (remote_id.s_addr))
paul718e3742002-12-13 20:15:29 +00001498 || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1499 {
1500 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001501 zlog_debug ("%s bad OPEN, wrong router identifier %s",
paul718e3742002-12-13 20:15:29 +00001502 peer->host, inet_ntoa (remote_id));
1503 bgp_notify_send_with_data (peer,
1504 BGP_NOTIFY_OPEN_ERR,
1505 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1506 notify_data_remote_id, 4);
1507 return -1;
1508 }
1509
1510 /* Set remote router-id */
1511 peer->remote_id = remote_id;
1512
1513 /* Peer BGP version check. */
1514 if (version != BGP_VERSION_4)
1515 {
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001516 u_int16_t maxver = htons(BGP_VERSION_4);
1517 /* XXX this reply may not be correct if version < 4 XXX */
paul718e3742002-12-13 20:15:29 +00001518 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001519 zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
paul718e3742002-12-13 20:15:29 +00001520 peer->host, version, BGP_VERSION_4);
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001521 /* Data must be in network byte order here */
paul718e3742002-12-13 20:15:29 +00001522 bgp_notify_send_with_data (peer,
1523 BGP_NOTIFY_OPEN_ERR,
1524 BGP_NOTIFY_OPEN_UNSUP_VERSION,
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001525 (u_int8_t *) &maxver, 2);
paul718e3742002-12-13 20:15:29 +00001526 return -1;
1527 }
1528
1529 /* Check neighbor as number. */
1530 if (remote_as != peer->as)
1531 {
1532 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001533 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
paul718e3742002-12-13 20:15:29 +00001534 peer->host, remote_as, peer->as);
1535 bgp_notify_send_with_data (peer,
1536 BGP_NOTIFY_OPEN_ERR,
1537 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1538 notify_data_remote_as, 2);
1539 return -1;
1540 }
1541
1542 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1543 calculate the value of the Hold Timer by using the smaller of its
1544 configured Hold Time and the Hold Time received in the OPEN message.
1545 The Hold Time MUST be either zero or at least three seconds. An
1546 implementation may reject connections on the basis of the Hold Time. */
1547
1548 if (holdtime < 3 && holdtime != 0)
1549 {
Daniel Waltonc6969872015-05-19 18:03:43 -07001550 bgp_notify_send_with_data (peer,
1551 BGP_NOTIFY_OPEN_ERR,
1552 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME,
1553 (u_int8_t *)holdtime_ptr, 2);
paul718e3742002-12-13 20:15:29 +00001554 return -1;
1555 }
1556
1557 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1558 would be one third of the Hold Time interval. KEEPALIVE messages
1559 MUST NOT be sent more frequently than one per second. An
1560 implementation MAY adjust the rate at which it sends KEEPALIVE
1561 messages as a function of the Hold Time interval. */
1562
1563 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1564 send_holdtime = peer->holdtime;
1565 else
1566 send_holdtime = peer->bgp->default_holdtime;
1567
1568 if (holdtime < send_holdtime)
1569 peer->v_holdtime = holdtime;
1570 else
1571 peer->v_holdtime = send_holdtime;
1572
1573 peer->v_keepalive = peer->v_holdtime / 3;
1574
1575 /* Open option part parse. */
paul718e3742002-12-13 20:15:29 +00001576 if (optlen != 0)
1577 {
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001578 if ((ret = bgp_open_option_parse (peer, optlen, &mp_capability)) < 0)
Paul Jakma58617392012-01-09 20:59:26 +00001579 {
1580 bgp_notify_send (peer,
1581 BGP_NOTIFY_OPEN_ERR,
Paul Jakma68ec4242015-11-25 17:14:34 +00001582 BGP_NOTIFY_OPEN_UNSPECIFIC);
Paul Jakma58617392012-01-09 20:59:26 +00001583 return ret;
1584 }
paul718e3742002-12-13 20:15:29 +00001585 }
1586 else
1587 {
1588 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001589 zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
paul718e3742002-12-13 20:15:29 +00001590 peer->host);
1591 }
1592
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001593 /*
1594 * Assume that the peer supports the locally configured set of
1595 * AFI/SAFIs if the peer did not send us any Mulitiprotocol
1596 * capabilities, or if 'override-capability' is configured.
1597 */
1598 if (! mp_capability ||
1599 CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
paul718e3742002-12-13 20:15:29 +00001600 {
1601 peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1602 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1603 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1604 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1605 }
1606
1607 /* Get sockname. */
1608 bgp_getsockname (peer);
Timo Teräs0edba8b2015-10-22 11:35:17 +03001609 peer->rtt = sockopt_tcp_rtt (peer->fd);
paul718e3742002-12-13 20:15:29 +00001610
1611 BGP_EVENT_ADD (peer, Receive_OPEN_message);
1612
1613 peer->packet_size = 0;
1614 if (peer->ibuf)
1615 stream_reset (peer->ibuf);
1616
1617 return 0;
1618}
1619
Paul Jakma518a4b72016-02-04 13:27:04 +00001620/* Frontend for NLRI parsing, to fan-out to AFI/SAFI specific parsers */
1621int
1622bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
1623{
1624 switch (packet->safi)
1625 {
1626 case SAFI_UNICAST:
1627 case SAFI_MULTICAST:
1628 return bgp_nlri_parse_ip (peer, attr, packet);
1629 case SAFI_MPLS_VPN:
1630 case SAFI_MPLS_LABELED_VPN:
1631 return bgp_nlri_parse_vpn (peer, attr, packet);
1632 case SAFI_ENCAP:
1633 return bgp_nlri_parse_encap (peer, attr, packet);
1634 }
1635 return -1;
1636}
1637
paul718e3742002-12-13 20:15:29 +00001638/* Parse BGP Update packet and make attribute object. */
paul94f2b392005-06-28 12:44:16 +00001639static int
paul718e3742002-12-13 20:15:29 +00001640bgp_update_receive (struct peer *peer, bgp_size_t size)
1641{
Paul Jakma518a4b72016-02-04 13:27:04 +00001642 int ret, nlri_ret;
paul718e3742002-12-13 20:15:29 +00001643 u_char *end;
1644 struct stream *s;
1645 struct attr attr;
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001646 struct attr_extra extra;
paul718e3742002-12-13 20:15:29 +00001647 bgp_size_t attribute_len;
1648 bgp_size_t update_len;
1649 bgp_size_t withdraw_len;
Paul Jakma518a4b72016-02-04 13:27:04 +00001650 int i;
1651
1652 enum NLRI_TYPES {
1653 NLRI_UPDATE,
1654 NLRI_WITHDRAW,
1655 NLRI_MP_UPDATE,
1656 NLRI_MP_WITHDRAW,
1657 NLRI_TYPE_MAX,
1658 };
1659 struct bgp_nlri nlris[NLRI_TYPE_MAX];
paul718e3742002-12-13 20:15:29 +00001660
1661 /* Status must be Established. */
1662 if (peer->status != Established)
1663 {
1664 zlog_err ("%s [FSM] Update packet received under status %s",
1665 peer->host, LOOKUP (bgp_status_msg, peer->status));
1666 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1667 return -1;
1668 }
1669
1670 /* Set initial values. */
1671 memset (&attr, 0, sizeof (struct attr));
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001672 memset (&extra, 0, sizeof (struct attr_extra));
Paul Jakma518a4b72016-02-04 13:27:04 +00001673 memset (&nlris, 0, sizeof nlris);
Paul Jakma3b847ef2016-04-22 12:48:49 +01001674
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001675 attr.extra = &extra;
paul718e3742002-12-13 20:15:29 +00001676
1677 s = peer->ibuf;
1678 end = stream_pnt (s) + size;
1679
1680 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1681 Length is too large (i.e., if Unfeasible Routes Length + Total
1682 Attribute Length + 23 exceeds the message Length), then the Error
1683 Subcode is set to Malformed Attribute List. */
1684 if (stream_pnt (s) + 2 > end)
1685 {
1686 zlog_err ("%s [Error] Update packet error"
1687 " (packet length is short for unfeasible length)",
1688 peer->host);
1689 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1690 BGP_NOTIFY_UPDATE_MAL_ATTR);
1691 return -1;
1692 }
1693
1694 /* Unfeasible Route Length. */
1695 withdraw_len = stream_getw (s);
1696
1697 /* Unfeasible Route Length check. */
1698 if (stream_pnt (s) + withdraw_len > end)
1699 {
1700 zlog_err ("%s [Error] Update packet error"
1701 " (packet unfeasible length overflow %d)",
1702 peer->host, withdraw_len);
1703 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1704 BGP_NOTIFY_UPDATE_MAL_ATTR);
1705 return -1;
1706 }
1707
1708 /* Unfeasible Route packet format check. */
1709 if (withdraw_len > 0)
1710 {
Paul Jakma518a4b72016-02-04 13:27:04 +00001711 nlris[NLRI_WITHDRAW].afi = AFI_IP;
1712 nlris[NLRI_WITHDRAW].safi = SAFI_UNICAST;
1713 nlris[NLRI_WITHDRAW].nlri = stream_pnt (s);
1714 nlris[NLRI_WITHDRAW].length = withdraw_len;
1715
paul718e3742002-12-13 20:15:29 +00001716 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001717 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001718
paul9985f832005-02-09 15:51:56 +00001719 stream_forward_getp (s, withdraw_len);
paul718e3742002-12-13 20:15:29 +00001720 }
1721
1722 /* Attribute total length check. */
1723 if (stream_pnt (s) + 2 > end)
1724 {
1725 zlog_warn ("%s [Error] Packet Error"
1726 " (update packet is short for attribute length)",
1727 peer->host);
1728 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1729 BGP_NOTIFY_UPDATE_MAL_ATTR);
1730 return -1;
1731 }
1732
1733 /* Fetch attribute total length. */
1734 attribute_len = stream_getw (s);
1735
1736 /* Attribute length check. */
1737 if (stream_pnt (s) + attribute_len > end)
1738 {
1739 zlog_warn ("%s [Error] Packet Error"
1740 " (update packet attribute length overflow %d)",
1741 peer->host, attribute_len);
1742 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1743 BGP_NOTIFY_UPDATE_MAL_ATTR);
1744 return -1;
1745 }
Paul Jakmab881c702010-11-23 16:35:42 +00001746
1747 /* Certain attribute parsing errors should not be considered bad enough
1748 * to reset the session for, most particularly any partial/optional
1749 * attributes that have 'tunneled' over speakers that don't understand
1750 * them. Instead we withdraw only the prefix concerned.
1751 *
1752 * Complicates the flow a little though..
1753 */
1754 bgp_attr_parse_ret_t attr_parse_ret = BGP_ATTR_PARSE_PROCEED;
1755 /* This define morphs the update case into a withdraw when lower levels
1756 * have signalled an error condition where this is best.
1757 */
1758#define NLRI_ATTR_ARG (attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : NULL)
paul718e3742002-12-13 20:15:29 +00001759
1760 /* Parse attribute when it exists. */
1761 if (attribute_len)
1762 {
Paul Jakmab881c702010-11-23 16:35:42 +00001763 attr_parse_ret = bgp_attr_parse (peer, &attr, attribute_len,
Paul Jakma518a4b72016-02-04 13:27:04 +00001764 &nlris[NLRI_MP_UPDATE], &nlris[NLRI_MP_WITHDRAW]);
Paul Jakmab881c702010-11-23 16:35:42 +00001765 if (attr_parse_ret == BGP_ATTR_PARSE_ERROR)
David Lamparterf80f8382014-06-04 01:00:51 +02001766 {
1767 bgp_attr_unintern_sub (&attr);
Lou Berger050defe2016-01-12 13:41:59 -05001768 bgp_attr_flush (&attr);
David Lamparterf80f8382014-06-04 01:00:51 +02001769 return -1;
1770 }
paul718e3742002-12-13 20:15:29 +00001771 }
Paul Jakmab881c702010-11-23 16:35:42 +00001772
paul718e3742002-12-13 20:15:29 +00001773 /* Logging the attribute. */
Paul Jakmab881c702010-11-23 16:35:42 +00001774 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW
1775 || BGP_DEBUG (update, UPDATE_IN))
paul718e3742002-12-13 20:15:29 +00001776 {
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +00001777 char attrstr[BUFSIZ];
1778 attrstr[0] = '\0';
1779
paule01f9cb2004-07-09 17:48:53 +00001780 ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
Paul Jakmab881c702010-11-23 16:35:42 +00001781 int lvl = (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1782 ? LOG_ERR : LOG_DEBUG;
1783
1784 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1785 zlog (peer->log, LOG_ERR,
1786 "%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
1787 peer->host);
paule01f9cb2004-07-09 17:48:53 +00001788
1789 if (ret)
Paul Jakmab881c702010-11-23 16:35:42 +00001790 zlog (peer->log, lvl, "%s rcvd UPDATE w/ attr: %s",
paule01f9cb2004-07-09 17:48:53 +00001791 peer->host, attrstr);
paul718e3742002-12-13 20:15:29 +00001792 }
Paul Jakmab881c702010-11-23 16:35:42 +00001793
paul718e3742002-12-13 20:15:29 +00001794 /* Network Layer Reachability Information. */
1795 update_len = end - stream_pnt (s);
1796
1797 if (update_len)
1798 {
Paul Jakma18ab08b2016-01-27 16:37:33 +00001799 /* Set NLRI portion to structure. */
Paul Jakma518a4b72016-02-04 13:27:04 +00001800 nlris[NLRI_UPDATE].afi = AFI_IP;
1801 nlris[NLRI_UPDATE].safi = SAFI_UNICAST;
1802 nlris[NLRI_UPDATE].nlri = stream_pnt (s);
1803 nlris[NLRI_UPDATE].length = update_len;
Paul Jakma18ab08b2016-01-27 16:37:33 +00001804
paul9985f832005-02-09 15:51:56 +00001805 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001806 }
Paul Jakma518a4b72016-02-04 13:27:04 +00001807
1808 /* Parse any given NLRIs */
1809 for (i = NLRI_UPDATE; i < NLRI_TYPE_MAX; i++)
paul718e3742002-12-13 20:15:29 +00001810 {
Paul Jakma3b847ef2016-04-22 12:48:49 +01001811 if (!nlris[i].nlri) continue;
1812
Paul Jakma518a4b72016-02-04 13:27:04 +00001813 /* We use afi and safi as indices into tables and what not. It would
1814 * be impossible, at this time, to support unknown afi/safis. And
1815 * anyway, the peer needs to be configured to enable the afi/safi
1816 * explicitly which requires UI support.
1817 *
1818 * Ignore unknown afi/safi NLRIs.
1819 *
1820 * Note: this means nlri[x].afi/safi still can not be trusted for
1821 * indexing later in this function!
1822 *
1823 * Note2: This will also remap the wire code-point for VPN safi to the
1824 * internal safi_t point, as needs be.
1825 */
1826 if (!bgp_afi_safi_valid_indices (nlris[i].afi, &nlris[i].safi))
1827 {
1828 plog_info (peer->log,
1829 "%s [Info] UPDATE with unsupported AFI/SAFI %u/%u",
1830 peer->host, nlris[i].afi, nlris[i].safi);
1831 continue;
1832 }
1833
1834 /* NLRI is processed only when the peer is configured specific
1835 Address Family and Subsequent Address Family. */
1836 if (!peer->afc[nlris[i].afi][nlris[i].safi])
1837 {
1838 plog_info (peer->log,
1839 "%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u",
1840 peer->host, nlris[i].afi, nlris[i].safi);
1841 continue;
1842 }
1843
1844 /* EoR handled later */
1845 if (nlris[i].length == 0)
1846 continue;
1847
1848 switch (i)
1849 {
1850 case NLRI_UPDATE:
1851 case NLRI_MP_UPDATE:
1852 nlri_ret = bgp_nlri_parse (peer, NLRI_ATTR_ARG, &nlris[i]);
1853 break;
1854 case NLRI_WITHDRAW:
1855 case NLRI_MP_WITHDRAW:
1856 nlri_ret = bgp_nlri_parse (peer, NULL, &nlris[i]);
1857 }
1858
1859 if (nlri_ret < 0)
1860 {
1861 plog_err (peer->log,
1862 "%s [Error] Error parsing NLRI", peer->host);
1863 if (peer->status == Established)
1864 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1865 i <= NLRI_WITHDRAW
1866 ? BGP_NOTIFY_UPDATE_INVAL_NETWORK
1867 : BGP_NOTIFY_UPDATE_OPT_ATTR_ERR);
1868 bgp_attr_unintern_sub (&attr);
1869 return -1;
1870 }
1871 }
1872
1873 /* EoR checks.
1874 *
1875 * Non-MP IPv4/Unicast EoR is a completely empty UPDATE
1876 * and MP EoR should have only an empty MP_UNREACH
1877 */
1878 if (!update_len && !withdraw_len
1879 && nlris[NLRI_MP_UPDATE].length == 0)
1880 {
1881 afi_t afi = 0;
1882 safi_t safi;
1883
1884 /* Non-MP IPv4/Unicast is a completely empty UPDATE - already
1885 * checked update and withdraw NLRI lengths are 0.
1886 */
1887 if (!attribute_len)
1888 {
1889 afi = AFI_IP;
1890 safi = SAFI_UNICAST;
1891 }
1892 /* otherwise MP AFI/SAFI is an empty update, other than an empty
1893 * MP_UNREACH_NLRI attr (with an AFI/SAFI we recognise).
1894 */
1895 else if (attr.flag == BGP_ATTR_MP_UNREACH_NLRI
1896 && nlris[NLRI_MP_WITHDRAW].length == 0
1897 && bgp_afi_safi_valid_indices (nlris[NLRI_MP_WITHDRAW].afi,
1898 &nlris[NLRI_MP_WITHDRAW].safi))
1899 {
1900 afi = nlris[NLRI_MP_WITHDRAW].afi;
1901 safi = nlris[NLRI_MP_WITHDRAW].safi;
1902 }
1903
1904 if (afi && peer->afc[afi][safi])
1905 {
paule01f9cb2004-07-09 17:48:53 +00001906 /* End-of-RIB received */
Paul Jakma518a4b72016-02-04 13:27:04 +00001907 SET_FLAG (peer->af_sflags[afi][safi],
hasso93406d82005-02-02 14:40:33 +00001908 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001909
hasso93406d82005-02-02 14:40:33 +00001910 /* NSF delete stale route */
Paul Jakma518a4b72016-02-04 13:27:04 +00001911 if (peer->nsf[afi][safi])
1912 bgp_clear_stale_route (peer, afi, safi);
hasso93406d82005-02-02 14:40:33 +00001913
1914 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma518a4b72016-02-04 13:27:04 +00001915 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for %s from %s",
1916 peer->host, afi_safi_print (afi, safi));
1917 }
paul718e3742002-12-13 20:15:29 +00001918 }
Paul Jakma518a4b72016-02-04 13:27:04 +00001919
paul718e3742002-12-13 20:15:29 +00001920 /* Everything is done. We unintern temporary structures which
1921 interned in bgp_attr_parse(). */
Paul Jakmab881c702010-11-23 16:35:42 +00001922 bgp_attr_unintern_sub (&attr);
Lou Berger050defe2016-01-12 13:41:59 -05001923 bgp_attr_flush (&attr);
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001924
paul718e3742002-12-13 20:15:29 +00001925 /* If peering is stopped due to some reason, do not generate BGP
1926 event. */
1927 if (peer->status != Established)
1928 return 0;
1929
1930 /* Increment packet counter. */
1931 peer->update_in++;
Stephen Hemminger65957882010-01-15 16:22:10 +03001932 peer->update_time = bgp_clock ();
paul718e3742002-12-13 20:15:29 +00001933
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02001934 /* Rearm holdtime timer */
Jorge Boncompte [DTI2]6a4677b2012-05-07 16:53:07 +00001935 BGP_TIMER_OFF (peer->t_holdtime);
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02001936 bgp_timer_set (peer);
paul718e3742002-12-13 20:15:29 +00001937
1938 return 0;
1939}
1940
1941/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00001942static void
paul718e3742002-12-13 20:15:29 +00001943bgp_notify_receive (struct peer *peer, bgp_size_t size)
1944{
1945 struct bgp_notify bgp_notify;
1946
1947 if (peer->notify.data)
1948 {
1949 XFREE (MTYPE_TMP, peer->notify.data);
1950 peer->notify.data = NULL;
1951 peer->notify.length = 0;
1952 }
1953
1954 bgp_notify.code = stream_getc (peer->ibuf);
1955 bgp_notify.subcode = stream_getc (peer->ibuf);
1956 bgp_notify.length = size - 2;
1957 bgp_notify.data = NULL;
1958
1959 /* Preserv notify code and sub code. */
1960 peer->notify.code = bgp_notify.code;
1961 peer->notify.subcode = bgp_notify.subcode;
1962 /* For further diagnostic record returned Data. */
1963 if (bgp_notify.length)
1964 {
1965 peer->notify.length = size - 2;
1966 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
1967 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
1968 }
1969
1970 /* For debug */
1971 {
1972 int i;
1973 int first = 0;
1974 char c[4];
1975
1976 if (bgp_notify.length)
1977 {
1978 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
1979 for (i = 0; i < bgp_notify.length; i++)
1980 if (first)
1981 {
1982 sprintf (c, " %02x", stream_getc (peer->ibuf));
1983 strcat (bgp_notify.data, c);
1984 }
1985 else
1986 {
1987 first = 1;
1988 sprintf (c, "%02x", stream_getc (peer->ibuf));
1989 strcpy (bgp_notify.data, c);
1990 }
1991 }
1992
1993 bgp_notify_print(peer, &bgp_notify, "received");
1994 if (bgp_notify.data)
Daniel Walton363c9032015-10-21 06:42:54 -07001995 {
1996 XFREE (MTYPE_TMP, bgp_notify.data);
1997 bgp_notify.data = NULL;
1998 bgp_notify.length = 0;
1999 }
paul718e3742002-12-13 20:15:29 +00002000 }
2001
2002 /* peer count update */
2003 peer->notify_in++;
2004
hassoe0701b72004-05-20 09:19:34 +00002005 if (peer->status == Established)
2006 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
2007
paul718e3742002-12-13 20:15:29 +00002008 /* We have to check for Notify with Unsupported Optional Parameter.
2009 in that case we fallback to open without the capability option.
2010 But this done in bgp_stop. We just mark it here to avoid changing
2011 the fsm tables. */
2012 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
2013 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
2014 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
2015
paul718e3742002-12-13 20:15:29 +00002016 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
2017}
2018
2019/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00002020static void
paul718e3742002-12-13 20:15:29 +00002021bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
2022{
2023 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00002024 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00002025
2026 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
2027}
2028
2029/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00002030static void
paul718e3742002-12-13 20:15:29 +00002031bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
2032{
2033 afi_t afi;
2034 safi_t safi;
paul718e3742002-12-13 20:15:29 +00002035 struct stream *s;
2036
2037 /* If peer does not have the capability, send notification. */
2038 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
2039 {
2040 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
2041 peer->host);
2042 bgp_notify_send (peer,
2043 BGP_NOTIFY_HEADER_ERR,
2044 BGP_NOTIFY_HEADER_BAD_MESTYPE);
2045 return;
2046 }
2047
2048 /* Status must be Established. */
2049 if (peer->status != Established)
2050 {
2051 plog_err (peer->log,
2052 "%s [Error] Route refresh packet received under status %s",
2053 peer->host, LOOKUP (bgp_status_msg, peer->status));
2054 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
2055 return;
2056 }
2057
2058 s = peer->ibuf;
2059
2060 /* Parse packet. */
2061 afi = stream_getw (s);
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002062 /* reserved byte */
2063 stream_getc (s);
paul718e3742002-12-13 20:15:29 +00002064 safi = stream_getc (s);
2065
2066 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002067 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00002068 peer->host, afi, safi);
2069
2070 /* Check AFI and SAFI. */
2071 if ((afi != AFI_IP && afi != AFI_IP6)
2072 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
Denis Ovsienko42e6d742011-07-14 12:36:19 +04002073 && safi != SAFI_MPLS_LABELED_VPN))
paul718e3742002-12-13 20:15:29 +00002074 {
2075 if (BGP_DEBUG (normal, NORMAL))
2076 {
ajs6b514742004-12-08 21:03:23 +00002077 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00002078 peer->host, afi, safi);
2079 }
2080 return;
2081 }
2082
2083 /* Adjust safi code. */
Denis Ovsienko42e6d742011-07-14 12:36:19 +04002084 if (safi == SAFI_MPLS_LABELED_VPN)
paul718e3742002-12-13 20:15:29 +00002085 safi = SAFI_MPLS_VPN;
2086
2087 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
2088 {
2089 u_char *end;
2090 u_char when_to_refresh;
2091 u_char orf_type;
2092 u_int16_t orf_len;
2093
2094 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
2095 {
2096 zlog_info ("%s ORF route refresh length error", peer->host);
2097 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2098 return;
2099 }
2100
2101 when_to_refresh = stream_getc (s);
2102 end = stream_pnt (s) + (size - 5);
2103
Paul Jakma370b64a2007-12-22 16:49:52 +00002104 while ((stream_pnt (s) + 2) < end)
paul718e3742002-12-13 20:15:29 +00002105 {
2106 orf_type = stream_getc (s);
2107 orf_len = stream_getw (s);
Paul Jakma370b64a2007-12-22 16:49:52 +00002108
2109 /* orf_len in bounds? */
2110 if ((stream_pnt (s) + orf_len) > end)
2111 break; /* XXX: Notify instead?? */
paul718e3742002-12-13 20:15:29 +00002112 if (orf_type == ORF_TYPE_PREFIX
2113 || orf_type == ORF_TYPE_PREFIX_OLD)
2114 {
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002115 uint8_t *p_pnt = stream_pnt (s);
2116 uint8_t *p_end = stream_pnt (s) + orf_len;
paul718e3742002-12-13 20:15:29 +00002117 struct orf_prefix orfp;
2118 u_char common = 0;
2119 u_int32_t seq;
2120 int psize;
2121 char name[BUFSIZ];
paul718e3742002-12-13 20:15:29 +00002122 int ret;
2123
2124 if (BGP_DEBUG (normal, NORMAL))
2125 {
ajs6b514742004-12-08 21:03:23 +00002126 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00002127 peer->host, orf_type, orf_len);
2128 }
2129
Paul Jakma370b64a2007-12-22 16:49:52 +00002130 /* we're going to read at least 1 byte of common ORF header,
2131 * and 7 bytes of ORF Address-filter entry from the stream
2132 */
2133 if (orf_len < 7)
2134 break;
2135
paul718e3742002-12-13 20:15:29 +00002136 /* ORF prefix-list name */
2137 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
2138
2139 while (p_pnt < p_end)
2140 {
Chris Halld64379e2010-05-14 16:38:39 +04002141 /* If the ORF entry is malformed, want to read as much of it
2142 * as possible without going beyond the bounds of the entry,
2143 * to maximise debug information.
2144 */
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002145 int ok;
paul718e3742002-12-13 20:15:29 +00002146 memset (&orfp, 0, sizeof (struct orf_prefix));
2147 common = *p_pnt++;
Chris Halld64379e2010-05-14 16:38:39 +04002148 /* after ++: p_pnt <= p_end */
paul718e3742002-12-13 20:15:29 +00002149 if (common & ORF_COMMON_PART_REMOVE_ALL)
2150 {
2151 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002152 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
David Lamparterc9c06d02015-04-13 10:21:35 +02002153 prefix_bgp_orf_remove_all (afi, name);
paul718e3742002-12-13 20:15:29 +00002154 break;
2155 }
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002156 ok = ((size_t)(p_end - p_pnt) >= sizeof(u_int32_t)) ;
Denis Ovsienkobb915f52011-12-13 21:11:39 +04002157 if (ok)
Chris Halld64379e2010-05-14 16:38:39 +04002158 {
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002159 memcpy (&seq, p_pnt, sizeof (u_int32_t));
2160 p_pnt += sizeof (u_int32_t);
2161 orfp.seq = ntohl (seq);
Chris Halld64379e2010-05-14 16:38:39 +04002162 }
2163 else
2164 p_pnt = p_end ;
2165
2166 if ((ok = (p_pnt < p_end)))
2167 orfp.ge = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2168 if ((ok = (p_pnt < p_end)))
2169 orfp.le = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2170 if ((ok = (p_pnt < p_end)))
2171 orfp.p.prefixlen = *p_pnt++ ;
2172 orfp.p.family = afi2family (afi); /* afi checked already */
2173
2174 psize = PSIZE (orfp.p.prefixlen); /* 0 if not ok */
2175 if (psize > prefix_blen(&orfp.p)) /* valid for family ? */
2176 {
2177 ok = 0 ;
2178 psize = prefix_blen(&orfp.p) ;
2179 }
2180 if (psize > (p_end - p_pnt)) /* valid for packet ? */
2181 {
2182 ok = 0 ;
2183 psize = p_end - p_pnt ;
2184 }
2185
2186 if (psize > 0)
2187 memcpy (&orfp.p.u.prefix, p_pnt, psize);
paul718e3742002-12-13 20:15:29 +00002188 p_pnt += psize;
2189
2190 if (BGP_DEBUG (normal, NORMAL))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +00002191 {
2192 char buf[INET6_BUFSIZ];
2193
2194 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
2195 peer->host,
2196 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
2197 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
2198 orfp.seq,
2199 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, INET6_BUFSIZ),
2200 orfp.p.prefixlen, orfp.ge, orfp.le,
2201 ok ? "" : " MALFORMED");
2202 }
2203
Chris Halld64379e2010-05-14 16:38:39 +04002204 if (ok)
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002205 ret = prefix_bgp_orf_set (name, afi, &orfp,
2206 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
2207 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002208
2209 if (!ok || (ok && ret != CMD_SUCCESS))
paul718e3742002-12-13 20:15:29 +00002210 {
2211 if (BGP_DEBUG (normal, NORMAL))
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002212 zlog_debug ("%s Received misformatted prefixlist ORF."
2213 " Remove All pfxlist", peer->host);
David Lamparterc9c06d02015-04-13 10:21:35 +02002214 prefix_bgp_orf_remove_all (afi, name);
paul718e3742002-12-13 20:15:29 +00002215 break;
2216 }
2217 }
2218 peer->orf_plist[afi][safi] =
David Lamparterc9c06d02015-04-13 10:21:35 +02002219 prefix_bgp_orf_lookup (afi, name);
paul718e3742002-12-13 20:15:29 +00002220 }
paul9985f832005-02-09 15:51:56 +00002221 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00002222 }
2223 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002224 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00002225 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
2226 if (when_to_refresh == REFRESH_DEFER)
2227 return;
2228 }
2229
2230 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2231 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
2232 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
2233
2234 /* Perform route refreshment to the peer */
2235 bgp_announce_route (peer, afi, safi);
2236}
2237
paul94f2b392005-06-28 12:44:16 +00002238static int
paul718e3742002-12-13 20:15:29 +00002239bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
2240{
2241 u_char *end;
Paul Jakma6d582722007-08-06 15:21:45 +00002242 struct capability_mp_data mpc;
2243 struct capability_header *hdr;
paul718e3742002-12-13 20:15:29 +00002244 u_char action;
paul718e3742002-12-13 20:15:29 +00002245 afi_t afi;
2246 safi_t safi;
2247
paul718e3742002-12-13 20:15:29 +00002248 end = pnt + length;
2249
2250 while (pnt < end)
Paul Jakma6d582722007-08-06 15:21:45 +00002251 {
paul718e3742002-12-13 20:15:29 +00002252 /* We need at least action, capability code and capability length. */
2253 if (pnt + 3 > end)
2254 {
2255 zlog_info ("%s Capability length error", peer->host);
2256 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2257 return -1;
2258 }
paul718e3742002-12-13 20:15:29 +00002259 action = *pnt;
Paul Jakma6d582722007-08-06 15:21:45 +00002260 hdr = (struct capability_header *)(pnt + 1);
2261
paul718e3742002-12-13 20:15:29 +00002262 /* Action value check. */
2263 if (action != CAPABILITY_ACTION_SET
2264 && action != CAPABILITY_ACTION_UNSET)
2265 {
2266 zlog_info ("%s Capability Action Value error %d",
2267 peer->host, action);
2268 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2269 return -1;
2270 }
2271
2272 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002273 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
Paul Jakma6d582722007-08-06 15:21:45 +00002274 peer->host, action, hdr->code, hdr->length);
paul718e3742002-12-13 20:15:29 +00002275
2276 /* Capability length check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002277 if ((pnt + hdr->length + 3) > end)
paul718e3742002-12-13 20:15:29 +00002278 {
2279 zlog_info ("%s Capability length error", peer->host);
2280 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2281 return -1;
2282 }
2283
Paul Jakma6d582722007-08-06 15:21:45 +00002284 /* Fetch structure to the byte stream. */
2285 memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
2286
paul718e3742002-12-13 20:15:29 +00002287 /* We know MP Capability Code. */
Paul Jakma6d582722007-08-06 15:21:45 +00002288 if (hdr->code == CAPABILITY_CODE_MP)
paul718e3742002-12-13 20:15:29 +00002289 {
Paul Jakma6d582722007-08-06 15:21:45 +00002290 afi = ntohs (mpc.afi);
2291 safi = mpc.safi;
paul718e3742002-12-13 20:15:29 +00002292
2293 /* Ignore capability when override-capability is set. */
2294 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2295 continue;
Paul Jakma6d582722007-08-06 15:21:45 +00002296
2297 if (!bgp_afi_safi_valid_indices (afi, &safi))
2298 {
2299 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002300 zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
2301 "(%u/%u)", peer->host, afi, safi);
Paul Jakma6d582722007-08-06 15:21:45 +00002302 continue;
2303 }
2304
paul718e3742002-12-13 20:15:29 +00002305 /* Address family check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002306 if (BGP_DEBUG (normal, NORMAL))
2307 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2308 peer->host,
2309 action == CAPABILITY_ACTION_SET
2310 ? "Advertising" : "Removing",
2311 ntohs(mpc.afi) , mpc.safi);
2312
2313 if (action == CAPABILITY_ACTION_SET)
2314 {
2315 peer->afc_recv[afi][safi] = 1;
2316 if (peer->afc[afi][safi])
2317 {
2318 peer->afc_nego[afi][safi] = 1;
2319 bgp_announce_route (peer, afi, safi);
2320 }
2321 }
2322 else
2323 {
2324 peer->afc_recv[afi][safi] = 0;
2325 peer->afc_nego[afi][safi] = 0;
paul718e3742002-12-13 20:15:29 +00002326
Paul Jakma6d582722007-08-06 15:21:45 +00002327 if (peer_active_nego (peer))
Chris Caputo228da422009-07-18 05:44:03 +00002328 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
Paul Jakma6d582722007-08-06 15:21:45 +00002329 else
2330 BGP_EVENT_ADD (peer, BGP_Stop);
2331 }
paul718e3742002-12-13 20:15:29 +00002332 }
paul718e3742002-12-13 20:15:29 +00002333 else
2334 {
2335 zlog_warn ("%s unrecognized capability code: %d - ignored",
Paul Jakma6d582722007-08-06 15:21:45 +00002336 peer->host, hdr->code);
paul718e3742002-12-13 20:15:29 +00002337 }
Paul Jakma6d582722007-08-06 15:21:45 +00002338 pnt += hdr->length + 3;
paul718e3742002-12-13 20:15:29 +00002339 }
2340 return 0;
2341}
2342
Paul Jakma01b7ce22009-06-18 12:34:43 +01002343/* Dynamic Capability is received.
2344 *
2345 * This is exported for unit-test purposes
2346 */
Paul Jakma6d582722007-08-06 15:21:45 +00002347int
paul718e3742002-12-13 20:15:29 +00002348bgp_capability_receive (struct peer *peer, bgp_size_t size)
2349{
2350 u_char *pnt;
paul718e3742002-12-13 20:15:29 +00002351
2352 /* Fetch pointer. */
2353 pnt = stream_pnt (peer->ibuf);
2354
2355 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002356 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002357
2358 /* If peer does not have the capability, send notification. */
2359 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2360 {
2361 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2362 peer->host);
2363 bgp_notify_send (peer,
2364 BGP_NOTIFY_HEADER_ERR,
2365 BGP_NOTIFY_HEADER_BAD_MESTYPE);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002366 return -1;
paul718e3742002-12-13 20:15:29 +00002367 }
2368
2369 /* Status must be Established. */
2370 if (peer->status != Established)
2371 {
2372 plog_err (peer->log,
2373 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2374 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002375 return -1;
paul718e3742002-12-13 20:15:29 +00002376 }
2377
2378 /* Parse packet. */
Paul Jakma6d582722007-08-06 15:21:45 +00002379 return bgp_capability_msg_parse (peer, pnt, size);
paul718e3742002-12-13 20:15:29 +00002380}
David Lamparter6b0655a2014-06-04 06:53:35 +02002381
paul718e3742002-12-13 20:15:29 +00002382/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002383static int
paul718e3742002-12-13 20:15:29 +00002384bgp_read_packet (struct peer *peer)
2385{
2386 int nbytes;
2387 int readsize;
2388
paul9985f832005-02-09 15:51:56 +00002389 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002390
2391 /* If size is zero then return. */
2392 if (! readsize)
2393 return 0;
2394
2395 /* Read packet from fd. */
Stephen Hemminger35398582010-08-05 10:26:23 -07002396 nbytes = stream_read_try (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002397
2398 /* If read byte is smaller than zero then error occured. */
2399 if (nbytes < 0)
2400 {
Stephen Hemminger35398582010-08-05 10:26:23 -07002401 /* Transient error should retry */
2402 if (nbytes == -2)
paul718e3742002-12-13 20:15:29 +00002403 return -1;
2404
2405 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002406 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002407
2408 if (peer->status == Established)
2409 {
2410 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2411 {
2412 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2413 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2414 }
2415 else
2416 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2417 }
2418
paul718e3742002-12-13 20:15:29 +00002419 BGP_EVENT_ADD (peer, TCP_fatal_error);
2420 return -1;
2421 }
2422
2423 /* When read byte is zero : clear bgp peer and return */
2424 if (nbytes == 0)
2425 {
2426 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002427 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002428 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002429
2430 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002431 {
2432 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2433 {
2434 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2435 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2436 }
2437 else
2438 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2439 }
hassoe0701b72004-05-20 09:19:34 +00002440
paul718e3742002-12-13 20:15:29 +00002441 BGP_EVENT_ADD (peer, TCP_connection_closed);
2442 return -1;
2443 }
2444
2445 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002446 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002447 return -1;
2448
2449 return 0;
2450}
2451
2452/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002453static int
paul718e3742002-12-13 20:15:29 +00002454bgp_marker_all_one (struct stream *s, int length)
2455{
2456 int i;
2457
2458 for (i = 0; i < length; i++)
2459 if (s->data[i] != 0xff)
2460 return 0;
2461
2462 return 1;
2463}
2464
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002465/* Recent thread time.
2466 On same clock base as bgp_clock (MONOTONIC)
2467 but can be time of last context switch to bgp_read thread. */
2468static time_t
2469bgp_recent_clock (void)
2470{
2471 return recent_relative_time().tv_sec;
2472}
2473
paul718e3742002-12-13 20:15:29 +00002474/* Starting point of packet process function. */
2475int
2476bgp_read (struct thread *thread)
2477{
2478 int ret;
2479 u_char type = 0;
2480 struct peer *peer;
2481 bgp_size_t size;
2482 char notify_data_length[2];
2483
2484 /* Yes first of all get peer pointer. */
2485 peer = THREAD_ARG (thread);
2486 peer->t_read = NULL;
2487
2488 /* For non-blocking IO check. */
2489 if (peer->status == Connect)
2490 {
Paul Jakma743dd422016-09-30 13:55:47 +01002491 bgp_connect_check (peer);
paul718e3742002-12-13 20:15:29 +00002492 goto done;
2493 }
2494 else
2495 {
pauleb821182004-05-01 08:44:08 +00002496 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002497 {
pauleb821182004-05-01 08:44:08 +00002498 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002499 return -1;
2500 }
pauleb821182004-05-01 08:44:08 +00002501 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002502 }
2503
2504 /* Read packet header to determine type of the packet */
2505 if (peer->packet_size == 0)
2506 peer->packet_size = BGP_HEADER_SIZE;
2507
paul9985f832005-02-09 15:51:56 +00002508 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002509 {
2510 ret = bgp_read_packet (peer);
2511
2512 /* Header read error or partial read packet. */
2513 if (ret < 0)
2514 goto done;
2515
2516 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002517 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002518 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2519 size = stream_getw (peer->ibuf);
2520 type = stream_getc (peer->ibuf);
2521
2522 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002523 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002524 peer->host, type, size - BGP_HEADER_SIZE);
2525
2526 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002527 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002528 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2529 {
2530 bgp_notify_send (peer,
2531 BGP_NOTIFY_HEADER_ERR,
2532 BGP_NOTIFY_HEADER_NOT_SYNC);
2533 goto done;
2534 }
2535
2536 /* BGP type check. */
2537 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2538 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2539 && type != BGP_MSG_ROUTE_REFRESH_NEW
2540 && type != BGP_MSG_ROUTE_REFRESH_OLD
2541 && type != BGP_MSG_CAPABILITY)
2542 {
2543 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002544 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002545 "%s unknown message type 0x%02x",
2546 peer->host, type);
2547 bgp_notify_send_with_data (peer,
2548 BGP_NOTIFY_HEADER_ERR,
2549 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2550 &type, 1);
2551 goto done;
2552 }
2553 /* Mimimum packet length check. */
2554 if ((size < BGP_HEADER_SIZE)
2555 || (size > BGP_MAX_PACKET_SIZE)
2556 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2557 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2558 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2559 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2560 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2561 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2562 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2563 {
2564 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002565 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002566 "%s bad message length - %d for %s",
2567 peer->host, size,
2568 type == 128 ? "ROUTE-REFRESH" :
2569 bgp_type_str[(int) type]);
2570 bgp_notify_send_with_data (peer,
2571 BGP_NOTIFY_HEADER_ERR,
2572 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002573 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002574 goto done;
2575 }
2576
2577 /* Adjust size to message length. */
2578 peer->packet_size = size;
2579 }
2580
2581 ret = bgp_read_packet (peer);
2582 if (ret < 0)
2583 goto done;
2584
2585 /* Get size and type again. */
2586 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2587 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2588
2589 /* BGP packet dump function. */
2590 bgp_dump_packet (peer, type, peer->ibuf);
2591
2592 size = (peer->packet_size - BGP_HEADER_SIZE);
2593
2594 /* Read rest of the packet and call each sort of packet routine */
2595 switch (type)
2596 {
2597 case BGP_MSG_OPEN:
2598 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002599 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002600 break;
2601 case BGP_MSG_UPDATE:
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002602 peer->readtime = bgp_recent_clock ();
paul718e3742002-12-13 20:15:29 +00002603 bgp_update_receive (peer, size);
2604 break;
2605 case BGP_MSG_NOTIFY:
2606 bgp_notify_receive (peer, size);
2607 break;
2608 case BGP_MSG_KEEPALIVE:
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002609 peer->readtime = bgp_recent_clock ();
paul718e3742002-12-13 20:15:29 +00002610 bgp_keepalive_receive (peer, size);
2611 break;
2612 case BGP_MSG_ROUTE_REFRESH_NEW:
2613 case BGP_MSG_ROUTE_REFRESH_OLD:
2614 peer->refresh_in++;
2615 bgp_route_refresh_receive (peer, size);
2616 break;
2617 case BGP_MSG_CAPABILITY:
2618 peer->dynamic_cap_in++;
2619 bgp_capability_receive (peer, size);
2620 break;
2621 }
2622
2623 /* Clear input buffer. */
2624 peer->packet_size = 0;
2625 if (peer->ibuf)
2626 stream_reset (peer->ibuf);
2627
2628 done:
2629 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2630 {
2631 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002632 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002633 peer_delete (peer);
paul718e3742002-12-13 20:15:29 +00002634 }
2635 return 0;
2636}