blob: f42e544b4b8bdc8b598bd31822977c4119dadf0c [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++;
769 /* Double start timer. */
770 peer->v_start *= 2;
771
772 /* Overflow check. */
773 if (peer->v_start >= (60 * 2))
774 peer->v_start = (60 * 2);
775
Paul Jakmaca058a32006-09-14 02:58:49 +0000776 /* Flush any existing events */
Paul Jakmadcdf3992006-10-15 23:39:59 +0000777 BGP_EVENT_ADD (peer, BGP_Stop);
Stephen Hemminger3a69f742013-01-11 18:27:23 +0000778 goto done;
779
paul718e3742002-12-13 20:15:29 +0000780 case BGP_MSG_KEEPALIVE:
781 peer->keepalive_out++;
782 break;
783 case BGP_MSG_ROUTE_REFRESH_NEW:
784 case BGP_MSG_ROUTE_REFRESH_OLD:
785 peer->refresh_out++;
786 break;
787 case BGP_MSG_CAPABILITY:
788 peer->dynamic_cap_out++;
789 break;
790 }
791
792 /* OK we send packet so delete it. */
793 bgp_packet_delete (peer);
paul718e3742002-12-13 20:15:29 +0000794 }
Stephen Hemmingereac57022010-08-05 10:26:25 -0700795 while (++count < BGP_WRITE_PACKET_MAX &&
796 (s = bgp_write_packet (peer)) != NULL);
paul718e3742002-12-13 20:15:29 +0000797
798 if (bgp_write_proceed (peer))
pauleb821182004-05-01 08:44:08 +0000799 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
Stephen Hemminger3a69f742013-01-11 18:27:23 +0000800
801 done:
802 sockopt_cork (peer->fd, 0);
paul718e3742002-12-13 20:15:29 +0000803 return 0;
804}
805
806/* This is only for sending NOTIFICATION message to neighbor. */
paul94f2b392005-06-28 12:44:16 +0000807static int
paul718e3742002-12-13 20:15:29 +0000808bgp_write_notify (struct peer *peer)
809{
Stephen Hemminger35398582010-08-05 10:26:23 -0700810 int ret, val;
paul718e3742002-12-13 20:15:29 +0000811 u_char type;
812 struct stream *s;
813
814 /* There should be at least one packet. */
815 s = stream_fifo_head (peer->obuf);
816 if (!s)
817 return 0;
818 assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
819
Leonid Rosenboim86998bc2012-12-14 19:12:17 +0000820 /* Stop collecting data within the socket */
821 sockopt_cork (peer->fd, 0);
822
David Lamparter8ff202e2013-07-31 14:39:41 +0200823 /* socket is in nonblocking mode, if we can't deliver the NOTIFY, well,
824 * we only care about getting a clean shutdown at this point. */
Leonid Rosenboim86998bc2012-12-14 19:12:17 +0000825 ret = write (peer->fd, STREAM_DATA (s), stream_get_endp (s));
David Lamparter8ff202e2013-07-31 14:39:41 +0200826
827 /* only connection reset/close gets counted as TCP_fatal_error, failure
828 * to write the entire NOTIFY doesn't get different FSM treatment */
paul718e3742002-12-13 20:15:29 +0000829 if (ret <= 0)
830 {
Paul Jakmadcdf3992006-10-15 23:39:59 +0000831 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000832 return 0;
833 }
834
Leonid Rosenboim86998bc2012-12-14 19:12:17 +0000835 /* Disable Nagle, make NOTIFY packet go out right away */
836 val = 1;
837 (void) setsockopt (peer->fd, IPPROTO_TCP, TCP_NODELAY,
838 (char *) &val, sizeof (val));
839
paul718e3742002-12-13 20:15:29 +0000840 /* Retrieve BGP packet type. */
841 stream_set_getp (s, BGP_MARKER_SIZE + 2);
842 type = stream_getc (s);
843
844 assert (type == BGP_MSG_NOTIFY);
845
846 /* Type should be notify. */
847 peer->notify_out++;
848
849 /* Double start timer. */
850 peer->v_start *= 2;
851
852 /* Overflow check. */
853 if (peer->v_start >= (60 * 2))
854 peer->v_start = (60 * 2);
855
Paul Jakmadcdf3992006-10-15 23:39:59 +0000856 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000857
858 return 0;
859}
860
861/* Make keepalive packet and send it to the peer. */
862void
863bgp_keepalive_send (struct peer *peer)
864{
865 struct stream *s;
866 int length;
867
868 s = stream_new (BGP_MAX_PACKET_SIZE);
869
870 /* Make keepalive packet. */
871 bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
872
873 /* Set packet size. */
874 length = bgp_packet_set_size (s);
875
876 /* Dump packet if debug option is set. */
877 /* bgp_packet_dump (s); */
878
879 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +0000880 zlog_debug ("%s sending KEEPALIVE", peer->host);
paul718e3742002-12-13 20:15:29 +0000881 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000882 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000883 peer->host, BGP_MSG_KEEPALIVE, length);
884
885 /* Add packet to the peer. */
886 bgp_packet_add (peer, s);
887
pauleb821182004-05-01 08:44:08 +0000888 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000889}
890
891/* Make open packet and send it to the peer. */
892void
893bgp_open_send (struct peer *peer)
894{
895 struct stream *s;
896 int length;
897 u_int16_t send_holdtime;
898 as_t local_as;
899
900 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
901 send_holdtime = peer->holdtime;
902 else
903 send_holdtime = peer->bgp->default_holdtime;
904
905 /* local-as Change */
906 if (peer->change_local_as)
907 local_as = peer->change_local_as;
908 else
909 local_as = peer->local_as;
910
911 s = stream_new (BGP_MAX_PACKET_SIZE);
912
913 /* Make open packet. */
914 bgp_packet_set_marker (s, BGP_MSG_OPEN);
915
916 /* Set open packet values. */
917 stream_putc (s, BGP_VERSION_4); /* BGP version */
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000918 stream_putw (s, (local_as <= BGP_AS_MAX) ? (u_int16_t) local_as
919 : BGP_AS_TRANS);
paul718e3742002-12-13 20:15:29 +0000920 stream_putw (s, send_holdtime); /* Hold Time */
921 stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
922
923 /* Set capability code. */
924 bgp_open_capability (s, peer);
925
926 /* Set BGP packet length. */
927 length = bgp_packet_set_size (s);
928
929 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400930 zlog_debug ("%s sending OPEN, version %d, my as %u, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +0000931 peer->host, BGP_VERSION_4, local_as,
932 send_holdtime, inet_ntoa (peer->local_id));
933
934 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000935 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000936 peer->host, BGP_MSG_OPEN, length);
937
938 /* Dump packet if debug option is set. */
939 /* bgp_packet_dump (s); */
940
941 /* Add packet to the peer. */
942 bgp_packet_add (peer, s);
943
pauleb821182004-05-01 08:44:08 +0000944 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000945}
946
947/* Send BGP notify packet with data potion. */
948void
949bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
950 u_char *data, size_t datalen)
951{
952 struct stream *s;
953 int length;
954
955 /* Allocate new stream. */
956 s = stream_new (BGP_MAX_PACKET_SIZE);
957
958 /* Make nitify packet. */
959 bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
960
961 /* Set notify packet values. */
962 stream_putc (s, code); /* BGP notify code */
963 stream_putc (s, sub_code); /* BGP notify sub_code */
964
965 /* If notify data is present. */
966 if (data)
967 stream_write (s, data, datalen);
968
969 /* Set BGP packet length. */
970 length = bgp_packet_set_size (s);
971
972 /* Add packet to the peer. */
973 stream_fifo_clean (peer->obuf);
974 bgp_packet_add (peer, s);
975
976 /* For debug */
977 {
978 struct bgp_notify bgp_notify;
979 int first = 0;
980 int i;
981 char c[4];
982
983 bgp_notify.code = code;
984 bgp_notify.subcode = sub_code;
985 bgp_notify.data = NULL;
986 bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
987
988 if (bgp_notify.length)
989 {
990 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
991 for (i = 0; i < bgp_notify.length; i++)
992 if (first)
993 {
994 sprintf (c, " %02x", data[i]);
995 strcat (bgp_notify.data, c);
996 }
997 else
998 {
999 first = 1;
1000 sprintf (c, "%02x", data[i]);
1001 strcpy (bgp_notify.data, c);
1002 }
1003 }
1004 bgp_notify_print (peer, &bgp_notify, "sending");
Daniel Walton363c9032015-10-21 06:42:54 -07001005
paul718e3742002-12-13 20:15:29 +00001006 if (bgp_notify.data)
Daniel Walton363c9032015-10-21 06:42:54 -07001007 {
1008 XFREE (MTYPE_TMP, bgp_notify.data);
1009 bgp_notify.data = NULL;
1010 bgp_notify.length = 0;
1011 }
paul718e3742002-12-13 20:15:29 +00001012 }
1013
1014 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001015 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001016 peer->host, BGP_MSG_NOTIFY, length);
1017
hassoe0701b72004-05-20 09:19:34 +00001018 /* peer reset cause */
1019 if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
1020 {
1021 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
heasley1212dc12011-09-12 13:27:52 +04001022 {
1023 peer->last_reset = PEER_DOWN_USER_RESET;
1024 zlog_info ("Notification sent to neighbor %s: User reset", peer->host);
1025 }
hassoe0701b72004-05-20 09:19:34 +00001026 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
heasley1212dc12011-09-12 13:27:52 +04001027 {
1028 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
1029 zlog_info ("Notification sent to neighbor %s: shutdown", peer->host);
1030 }
hassoe0701b72004-05-20 09:19:34 +00001031 else
heasley1212dc12011-09-12 13:27:52 +04001032 {
1033 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
1034 zlog_info ("Notification sent to neighbor %s: type %u/%u",
1035 peer->host, code, sub_code);
1036 }
hassoe0701b72004-05-20 09:19:34 +00001037 }
heasley1212dc12011-09-12 13:27:52 +04001038 else
1039 zlog_info ("Notification sent to neighbor %s: configuration change",
1040 peer->host);
hassoe0701b72004-05-20 09:19:34 +00001041
Denis Ovsienko7ccf5e52011-09-10 16:53:30 +04001042 /* Call immediately. */
paul718e3742002-12-13 20:15:29 +00001043 BGP_WRITE_OFF (peer->t_write);
1044
1045 bgp_write_notify (peer);
1046}
1047
1048/* Send BGP notify packet. */
1049void
1050bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
1051{
1052 bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
1053}
1054
paul718e3742002-12-13 20:15:29 +00001055/* Send route refresh message to the peer. */
1056void
1057bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
1058 u_char orf_type, u_char when_to_refresh, int remove)
1059{
1060 struct stream *s;
paul718e3742002-12-13 20:15:29 +00001061 int length;
1062 struct bgp_filter *filter;
1063 int orf_refresh = 0;
1064
Paul Jakma750e8142008-07-22 21:11:48 +00001065 if (DISABLE_BGP_ANNOUNCE)
1066 return;
paul718e3742002-12-13 20:15:29 +00001067
1068 filter = &peer->filter[afi][safi];
1069
1070 /* Adjust safi code. */
1071 if (safi == SAFI_MPLS_VPN)
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001072 safi = SAFI_MPLS_LABELED_VPN;
paul718e3742002-12-13 20:15:29 +00001073
1074 s = stream_new (BGP_MAX_PACKET_SIZE);
1075
1076 /* Make BGP update packet. */
1077 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
1078 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
1079 else
1080 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
1081
1082 /* Encode Route Refresh message. */
1083 stream_putw (s, afi);
1084 stream_putc (s, 0);
1085 stream_putc (s, safi);
1086
1087 if (orf_type == ORF_TYPE_PREFIX
1088 || orf_type == ORF_TYPE_PREFIX_OLD)
1089 if (remove || filter->plist[FILTER_IN].plist)
1090 {
1091 u_int16_t orf_len;
1092 unsigned long orfp;
1093
1094 orf_refresh = 1;
1095 stream_putc (s, when_to_refresh);
1096 stream_putc (s, orf_type);
paul9985f832005-02-09 15:51:56 +00001097 orfp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00001098 stream_putw (s, 0);
1099
1100 if (remove)
1101 {
1102 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1103 stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
1104 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001105 zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001106 peer->host, orf_type,
1107 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1108 afi, safi);
1109 }
1110 else
1111 {
1112 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1113 prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
1114 ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
1115 ORF_COMMON_PART_DENY);
1116 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001117 zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001118 peer->host, orf_type,
1119 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1120 afi, safi);
1121 }
1122
1123 /* Total ORF Entry Len. */
paul9985f832005-02-09 15:51:56 +00001124 orf_len = stream_get_endp (s) - orfp - 2;
paul718e3742002-12-13 20:15:29 +00001125 stream_putw_at (s, orfp, orf_len);
1126 }
1127
1128 /* Set packet size. */
1129 length = bgp_packet_set_size (s);
1130
1131 if (BGP_DEBUG (normal, NORMAL))
1132 {
1133 if (! orf_refresh)
ajs6b514742004-12-08 21:03:23 +00001134 zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001135 peer->host, afi, safi);
ajs6b514742004-12-08 21:03:23 +00001136 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001137 peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
1138 BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
1139 }
1140
paul718e3742002-12-13 20:15:29 +00001141 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -04001142 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +00001143
pauleb821182004-05-01 08:44:08 +00001144 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001145}
1146
1147/* Send capability message to the peer. */
1148void
1149bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
1150 int capability_code, int action)
1151{
1152 struct stream *s;
paul718e3742002-12-13 20:15:29 +00001153 int length;
1154
1155 /* Adjust safi code. */
1156 if (safi == SAFI_MPLS_VPN)
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001157 safi = SAFI_MPLS_LABELED_VPN;
paul718e3742002-12-13 20:15:29 +00001158
1159 s = stream_new (BGP_MAX_PACKET_SIZE);
1160
1161 /* Make BGP update packet. */
1162 bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
1163
1164 /* Encode MP_EXT capability. */
1165 if (capability_code == CAPABILITY_CODE_MP)
1166 {
1167 stream_putc (s, action);
1168 stream_putc (s, CAPABILITY_CODE_MP);
1169 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1170 stream_putw (s, afi);
1171 stream_putc (s, 0);
1172 stream_putc (s, safi);
1173
1174 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001175 zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001176 peer->host, action == CAPABILITY_ACTION_SET ?
1177 "Advertising" : "Removing", afi, safi);
1178 }
1179
paul718e3742002-12-13 20:15:29 +00001180 /* Set packet size. */
1181 length = bgp_packet_set_size (s);
1182
paul718e3742002-12-13 20:15:29 +00001183
1184 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -04001185 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +00001186
1187 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001188 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001189 peer->host, BGP_MSG_CAPABILITY, length);
1190
pauleb821182004-05-01 08:44:08 +00001191 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001192}
David Lamparter6b0655a2014-06-04 06:53:35 +02001193
paul718e3742002-12-13 20:15:29 +00001194/* RFC1771 6.8 Connection collision detection. */
paul94f2b392005-06-28 12:44:16 +00001195static int
pauleb821182004-05-01 08:44:08 +00001196bgp_collision_detect (struct peer *new, struct in_addr remote_id)
paul718e3742002-12-13 20:15:29 +00001197{
pauleb821182004-05-01 08:44:08 +00001198 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +00001199 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001200 struct bgp *bgp;
1201
1202 bgp = bgp_get_default ();
1203 if (! bgp)
1204 return 0;
1205
1206 /* Upon receipt of an OPEN message, the local system must examine
1207 all of its connections that are in the OpenConfirm state. A BGP
1208 speaker may also examine connections in an OpenSent state if it
1209 knows the BGP Identifier of the peer by means outside of the
1210 protocol. If among these connections there is a connection to a
1211 remote BGP speaker whose BGP Identifier equals the one in the
1212 OPEN message, then the local system performs the following
1213 collision resolution procedure: */
1214
paul1eb8ef22005-04-07 07:30:20 +00001215 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00001216 {
1217 /* Under OpenConfirm status, local peer structure already hold
1218 remote router ID. */
pauleb821182004-05-01 08:44:08 +00001219
1220 if (peer != new
1221 && (peer->status == OpenConfirm || peer->status == OpenSent)
1222 && sockunion_same (&peer->su, &new->su))
1223 {
paul718e3742002-12-13 20:15:29 +00001224 /* 1. The BGP Identifier of the local system is compared to
1225 the BGP Identifier of the remote system (as specified in
1226 the OPEN message). */
1227
1228 if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
1229 {
1230 /* 2. If the value of the local BGP Identifier is less
1231 than the remote one, the local system closes BGP
1232 connection that already exists (the one that is
1233 already in the OpenConfirm state), and accepts BGP
1234 connection initiated by the remote system. */
1235
pauleb821182004-05-01 08:44:08 +00001236 if (peer->fd >= 0)
hassoe0701b72004-05-20 09:19:34 +00001237 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001238 return 1;
1239 }
1240 else
1241 {
1242 /* 3. Otherwise, the local system closes newly created
1243 BGP connection (the one associated with the newly
1244 received OPEN message), and continues to use the
1245 existing one (the one that is already in the
1246 OpenConfirm state). */
1247
pauleb821182004-05-01 08:44:08 +00001248 if (new->fd >= 0)
paulf5ba3872004-07-09 12:11:31 +00001249 bgp_notify_send (new, BGP_NOTIFY_CEASE,
1250 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001251 return -1;
1252 }
pauleb821182004-05-01 08:44:08 +00001253 }
1254 }
paul718e3742002-12-13 20:15:29 +00001255 return 0;
1256}
1257
paul94f2b392005-06-28 12:44:16 +00001258static int
paul718e3742002-12-13 20:15:29 +00001259bgp_open_receive (struct peer *peer, bgp_size_t size)
1260{
1261 int ret;
1262 u_char version;
1263 u_char optlen;
1264 u_int16_t holdtime;
1265 u_int16_t send_holdtime;
1266 as_t remote_as;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001267 as_t as4 = 0;
paul718e3742002-12-13 20:15:29 +00001268 struct peer *realpeer;
1269 struct in_addr remote_id;
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001270 int mp_capability;
paul5228ad22004-06-04 17:58:18 +00001271 u_int8_t notify_data_remote_as[2];
1272 u_int8_t notify_data_remote_id[4];
Daniel Waltonc6969872015-05-19 18:03:43 -07001273 u_int16_t *holdtime_ptr;
paul718e3742002-12-13 20:15:29 +00001274
1275 realpeer = NULL;
1276
1277 /* Parse open packet. */
1278 version = stream_getc (peer->ibuf);
1279 memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1280 remote_as = stream_getw (peer->ibuf);
Daniel Waltonc6969872015-05-19 18:03:43 -07001281 holdtime_ptr = (u_int16_t *)stream_pnt (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00001282 holdtime = stream_getw (peer->ibuf);
1283 memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1284 remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1285
1286 /* Receive OPEN message log */
1287 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001288 zlog_debug ("%s rcv OPEN, version %d, remote-as (in open) %u,"
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001289 " holdtime %d, id %s",
1290 peer->host, version, remote_as, holdtime,
1291 inet_ntoa (remote_id));
1292
1293 /* BEGIN to read the capability here, but dont do it yet */
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001294 mp_capability = 0;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001295 optlen = stream_getc (peer->ibuf);
1296
1297 if (optlen != 0)
1298 {
1299 /* We need the as4 capability value *right now* because
1300 * if it is there, we have not got the remote_as yet, and without
1301 * that we do not know which peer is connecting to us now.
1302 */
1303 as4 = peek_for_as4_capability (peer, optlen);
1304 }
1305
1306 /* Just in case we have a silly peer who sends AS4 capability set to 0 */
1307 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) && !as4)
1308 {
1309 zlog_err ("%s bad OPEN, got AS4 capability, but AS4 set to 0",
1310 peer->host);
1311 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1312 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1313 return -1;
1314 }
1315
1316 if (remote_as == BGP_AS_TRANS)
1317 {
1318 /* Take the AS4 from the capability. We must have received the
1319 * capability now! Otherwise we have a asn16 peer who uses
1320 * BGP_AS_TRANS, for some unknown reason.
1321 */
1322 if (as4 == BGP_AS_TRANS)
1323 {
1324 zlog_err ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
1325 peer->host);
1326 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1327 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1328 return -1;
1329 }
1330
1331 if (!as4 && BGP_DEBUG (as4, AS4))
1332 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
1333 " Odd, but proceeding.", peer->host);
1334 else if (as4 < BGP_AS_MAX && BGP_DEBUG (as4, AS4))
Paul Jakma0df7c912008-07-21 21:02:49 +00001335 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits "
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001336 "in 2-bytes, very odd peer.", peer->host, as4);
1337 if (as4)
1338 remote_as = as4;
1339 }
1340 else
1341 {
1342 /* We may have a partner with AS4 who has an asno < BGP_AS_MAX */
1343 /* If we have got the capability, peer->as4cap must match remote_as */
1344 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)
1345 && as4 != remote_as)
1346 {
1347 /* raise error, log this, close session */
1348 zlog_err ("%s bad OPEN, got AS4 capability, but remote_as %u"
1349 " mismatch with 16bit 'myasn' %u in open",
1350 peer->host, as4, remote_as);
1351 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1352 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1353 return -1;
1354 }
1355 }
1356
paul718e3742002-12-13 20:15:29 +00001357 /* Lookup peer from Open packet. */
1358 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1359 {
1360 int as = 0;
1361
1362 realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1363
1364 if (! realpeer)
1365 {
1366 /* Peer's source IP address is check in bgp_accept(), so this
1367 must be AS number mismatch or remote-id configuration
1368 mismatch. */
1369 if (as)
1370 {
1371 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001372 zlog_debug ("%s bad OPEN, wrong router identifier %s",
1373 peer->host, inet_ntoa (remote_id));
1374 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1375 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1376 notify_data_remote_id, 4);
paul718e3742002-12-13 20:15:29 +00001377 }
1378 else
1379 {
1380 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001381 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
ajs6b514742004-12-08 21:03:23 +00001382 peer->host, remote_as, peer->as);
1383 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1384 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1385 notify_data_remote_as, 2);
paul718e3742002-12-13 20:15:29 +00001386 }
1387 return -1;
1388 }
1389 }
1390
1391 /* When collision is detected and this peer is closed. Retrun
1392 immidiately. */
1393 ret = bgp_collision_detect (peer, remote_id);
1394 if (ret < 0)
1395 return ret;
1396
pauleb821182004-05-01 08:44:08 +00001397 /* Hack part. */
1398 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1399 {
hasso93406d82005-02-02 14:40:33 +00001400 if (realpeer->status == Established
1401 && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1402 {
1403 realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1404 SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1405 }
1406 else if (ret == 0 && realpeer->status != Active
1407 && realpeer->status != OpenSent
Paul Jakma6e199262008-09-09 17:14:33 +01001408 && realpeer->status != OpenConfirm
1409 && realpeer->status != Connect)
pauleb821182004-05-01 08:44:08 +00001410 {
Paul Jakma2b2fc562008-09-06 13:09:35 +01001411 /* XXX: This is an awful problem..
1412 *
1413 * According to the RFC we should just let this connection (of the
1414 * accepted 'peer') continue on to Established if the other
1415 * connection (the 'realpeer' one) is in state Connect, and deal
1416 * with the more larval FSM as/when it gets far enough to receive
1417 * an Open. We don't do that though, we instead close the (more
1418 * developed) accepted connection.
1419 *
1420 * This means there's a race, which if hit, can loop:
1421 *
1422 * FSM for A FSM for B
1423 * realpeer accept-peer realpeer accept-peer
1424 *
1425 * Connect Connect
1426 * Active
1427 * OpenSent OpenSent
1428 * <arrive here,
1429 * Notify, delete>
1430 * Idle Active
1431 * OpenSent OpenSent
1432 * <arrive here,
1433 * Notify, delete>
1434 * Idle
1435 * <wait> <wait>
1436 * Connect Connect
1437 *
1438 *
1439 * If both sides are Quagga, they're almost certain to wait for
1440 * the same amount of time of course (which doesn't preclude other
1441 * implementations also waiting for same time). The race is
1442 * exacerbated by high-latency (in bgpd and/or the network).
1443 *
1444 * The reason we do this is because our FSM is tied to our peer
1445 * structure, which carries our configuration information, etc.
1446 * I.e. we can't let the accepted-peer FSM continue on as it is,
1447 * cause it's not associated with any actual peer configuration -
1448 * it's just a dummy.
1449 *
1450 * It's possible we could hack-fix this by just bgp_stop'ing the
1451 * realpeer and continueing on with the 'transfer FSM' below.
1452 * Ideally, we need to seperate FSMs from struct peer.
1453 *
1454 * Setting one side to passive avoids the race, as a workaround.
1455 */
pauleb821182004-05-01 08:44:08 +00001456 if (BGP_DEBUG (events, EVENTS))
hasso93406d82005-02-02 14:40:33 +00001457 zlog_debug ("%s peer status is %s close connection",
1458 realpeer->host, LOOKUP (bgp_status_msg,
1459 realpeer->status));
1460 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1461 BGP_NOTIFY_CEASE_CONNECT_REJECT);
1462
pauleb821182004-05-01 08:44:08 +00001463 return -1;
1464 }
1465
1466 if (BGP_DEBUG (events, EVENTS))
Paul Jakma6e199262008-09-09 17:14:33 +01001467 zlog_debug ("%s [Event] Transfer accept BGP peer to real (state %s)",
1468 peer->host,
1469 LOOKUP (bgp_status_msg, realpeer->status));
pauleb821182004-05-01 08:44:08 +00001470
1471 bgp_stop (realpeer);
1472
1473 /* Transfer file descriptor. */
1474 realpeer->fd = peer->fd;
1475 peer->fd = -1;
1476
1477 /* Transfer input buffer. */
1478 stream_free (realpeer->ibuf);
1479 realpeer->ibuf = peer->ibuf;
1480 realpeer->packet_size = peer->packet_size;
1481 peer->ibuf = NULL;
1482
1483 /* Transfer status. */
1484 realpeer->status = peer->status;
1485 bgp_stop (peer);
paul200df112005-06-01 11:17:05 +00001486
pauleb821182004-05-01 08:44:08 +00001487 /* peer pointer change. Open packet send to neighbor. */
1488 peer = realpeer;
1489 bgp_open_send (peer);
1490 if (peer->fd < 0)
1491 {
1492 zlog_err ("bgp_open_receive peer's fd is negative value %d",
1493 peer->fd);
1494 return -1;
1495 }
1496 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1497 }
1498
paul718e3742002-12-13 20:15:29 +00001499 /* remote router-id check. */
1500 if (remote_id.s_addr == 0
Denis Ovsienko733cd9e2011-12-17 19:39:30 +04001501 || IPV4_CLASS_DE (ntohl (remote_id.s_addr))
paul718e3742002-12-13 20:15:29 +00001502 || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1503 {
1504 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001505 zlog_debug ("%s bad OPEN, wrong router identifier %s",
paul718e3742002-12-13 20:15:29 +00001506 peer->host, inet_ntoa (remote_id));
1507 bgp_notify_send_with_data (peer,
1508 BGP_NOTIFY_OPEN_ERR,
1509 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1510 notify_data_remote_id, 4);
1511 return -1;
1512 }
1513
1514 /* Set remote router-id */
1515 peer->remote_id = remote_id;
1516
1517 /* Peer BGP version check. */
1518 if (version != BGP_VERSION_4)
1519 {
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001520 u_int16_t maxver = htons(BGP_VERSION_4);
1521 /* XXX this reply may not be correct if version < 4 XXX */
paul718e3742002-12-13 20:15:29 +00001522 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001523 zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
paul718e3742002-12-13 20:15:29 +00001524 peer->host, version, BGP_VERSION_4);
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001525 /* Data must be in network byte order here */
paul718e3742002-12-13 20:15:29 +00001526 bgp_notify_send_with_data (peer,
1527 BGP_NOTIFY_OPEN_ERR,
1528 BGP_NOTIFY_OPEN_UNSUP_VERSION,
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001529 (u_int8_t *) &maxver, 2);
paul718e3742002-12-13 20:15:29 +00001530 return -1;
1531 }
1532
1533 /* Check neighbor as number. */
1534 if (remote_as != peer->as)
1535 {
1536 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001537 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
paul718e3742002-12-13 20:15:29 +00001538 peer->host, remote_as, peer->as);
1539 bgp_notify_send_with_data (peer,
1540 BGP_NOTIFY_OPEN_ERR,
1541 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1542 notify_data_remote_as, 2);
1543 return -1;
1544 }
1545
1546 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1547 calculate the value of the Hold Timer by using the smaller of its
1548 configured Hold Time and the Hold Time received in the OPEN message.
1549 The Hold Time MUST be either zero or at least three seconds. An
1550 implementation may reject connections on the basis of the Hold Time. */
1551
1552 if (holdtime < 3 && holdtime != 0)
1553 {
Daniel Waltonc6969872015-05-19 18:03:43 -07001554 bgp_notify_send_with_data (peer,
1555 BGP_NOTIFY_OPEN_ERR,
1556 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME,
1557 (u_int8_t *)holdtime_ptr, 2);
paul718e3742002-12-13 20:15:29 +00001558 return -1;
1559 }
1560
1561 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1562 would be one third of the Hold Time interval. KEEPALIVE messages
1563 MUST NOT be sent more frequently than one per second. An
1564 implementation MAY adjust the rate at which it sends KEEPALIVE
1565 messages as a function of the Hold Time interval. */
1566
1567 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1568 send_holdtime = peer->holdtime;
1569 else
1570 send_holdtime = peer->bgp->default_holdtime;
1571
1572 if (holdtime < send_holdtime)
1573 peer->v_holdtime = holdtime;
1574 else
1575 peer->v_holdtime = send_holdtime;
1576
1577 peer->v_keepalive = peer->v_holdtime / 3;
1578
1579 /* Open option part parse. */
paul718e3742002-12-13 20:15:29 +00001580 if (optlen != 0)
1581 {
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001582 if ((ret = bgp_open_option_parse (peer, optlen, &mp_capability)) < 0)
Paul Jakma58617392012-01-09 20:59:26 +00001583 {
1584 bgp_notify_send (peer,
1585 BGP_NOTIFY_OPEN_ERR,
Paul Jakma68ec4242015-11-25 17:14:34 +00001586 BGP_NOTIFY_OPEN_UNSPECIFIC);
Paul Jakma58617392012-01-09 20:59:26 +00001587 return ret;
1588 }
paul718e3742002-12-13 20:15:29 +00001589 }
1590 else
1591 {
1592 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001593 zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
paul718e3742002-12-13 20:15:29 +00001594 peer->host);
1595 }
1596
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001597 /*
1598 * Assume that the peer supports the locally configured set of
1599 * AFI/SAFIs if the peer did not send us any Mulitiprotocol
1600 * capabilities, or if 'override-capability' is configured.
1601 */
1602 if (! mp_capability ||
1603 CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
paul718e3742002-12-13 20:15:29 +00001604 {
1605 peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1606 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1607 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1608 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1609 }
1610
1611 /* Get sockname. */
1612 bgp_getsockname (peer);
Timo Teräs0edba8b2015-10-22 11:35:17 +03001613 peer->rtt = sockopt_tcp_rtt (peer->fd);
paul718e3742002-12-13 20:15:29 +00001614
1615 BGP_EVENT_ADD (peer, Receive_OPEN_message);
1616
1617 peer->packet_size = 0;
1618 if (peer->ibuf)
1619 stream_reset (peer->ibuf);
1620
1621 return 0;
1622}
1623
Paul Jakma518a4b72016-02-04 13:27:04 +00001624/* Frontend for NLRI parsing, to fan-out to AFI/SAFI specific parsers */
1625int
1626bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
1627{
1628 switch (packet->safi)
1629 {
1630 case SAFI_UNICAST:
1631 case SAFI_MULTICAST:
1632 return bgp_nlri_parse_ip (peer, attr, packet);
1633 case SAFI_MPLS_VPN:
1634 case SAFI_MPLS_LABELED_VPN:
1635 return bgp_nlri_parse_vpn (peer, attr, packet);
1636 case SAFI_ENCAP:
1637 return bgp_nlri_parse_encap (peer, attr, packet);
1638 }
1639 return -1;
1640}
1641
paul718e3742002-12-13 20:15:29 +00001642/* Parse BGP Update packet and make attribute object. */
paul94f2b392005-06-28 12:44:16 +00001643static int
paul718e3742002-12-13 20:15:29 +00001644bgp_update_receive (struct peer *peer, bgp_size_t size)
1645{
Paul Jakma518a4b72016-02-04 13:27:04 +00001646 int ret, nlri_ret;
paul718e3742002-12-13 20:15:29 +00001647 u_char *end;
1648 struct stream *s;
1649 struct attr attr;
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001650 struct attr_extra extra;
paul718e3742002-12-13 20:15:29 +00001651 bgp_size_t attribute_len;
1652 bgp_size_t update_len;
1653 bgp_size_t withdraw_len;
Paul Jakma518a4b72016-02-04 13:27:04 +00001654 int i;
1655
1656 enum NLRI_TYPES {
1657 NLRI_UPDATE,
1658 NLRI_WITHDRAW,
1659 NLRI_MP_UPDATE,
1660 NLRI_MP_WITHDRAW,
1661 NLRI_TYPE_MAX,
1662 };
1663 struct bgp_nlri nlris[NLRI_TYPE_MAX];
paul718e3742002-12-13 20:15:29 +00001664
1665 /* Status must be Established. */
1666 if (peer->status != Established)
1667 {
1668 zlog_err ("%s [FSM] Update packet received under status %s",
1669 peer->host, LOOKUP (bgp_status_msg, peer->status));
1670 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1671 return -1;
1672 }
1673
1674 /* Set initial values. */
1675 memset (&attr, 0, sizeof (struct attr));
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001676 memset (&extra, 0, sizeof (struct attr_extra));
Paul Jakma518a4b72016-02-04 13:27:04 +00001677 memset (&nlris, 0, sizeof nlris);
Paul Jakma3b847ef2016-04-22 12:48:49 +01001678
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001679 attr.extra = &extra;
paul718e3742002-12-13 20:15:29 +00001680
1681 s = peer->ibuf;
1682 end = stream_pnt (s) + size;
1683
1684 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1685 Length is too large (i.e., if Unfeasible Routes Length + Total
1686 Attribute Length + 23 exceeds the message Length), then the Error
1687 Subcode is set to Malformed Attribute List. */
1688 if (stream_pnt (s) + 2 > end)
1689 {
1690 zlog_err ("%s [Error] Update packet error"
1691 " (packet length is short for unfeasible length)",
1692 peer->host);
1693 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1694 BGP_NOTIFY_UPDATE_MAL_ATTR);
1695 return -1;
1696 }
1697
1698 /* Unfeasible Route Length. */
1699 withdraw_len = stream_getw (s);
1700
1701 /* Unfeasible Route Length check. */
1702 if (stream_pnt (s) + withdraw_len > end)
1703 {
1704 zlog_err ("%s [Error] Update packet error"
1705 " (packet unfeasible length overflow %d)",
1706 peer->host, withdraw_len);
1707 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1708 BGP_NOTIFY_UPDATE_MAL_ATTR);
1709 return -1;
1710 }
1711
1712 /* Unfeasible Route packet format check. */
1713 if (withdraw_len > 0)
1714 {
Paul Jakma518a4b72016-02-04 13:27:04 +00001715 nlris[NLRI_WITHDRAW].afi = AFI_IP;
1716 nlris[NLRI_WITHDRAW].safi = SAFI_UNICAST;
1717 nlris[NLRI_WITHDRAW].nlri = stream_pnt (s);
1718 nlris[NLRI_WITHDRAW].length = withdraw_len;
1719
paul718e3742002-12-13 20:15:29 +00001720 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001721 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001722
paul9985f832005-02-09 15:51:56 +00001723 stream_forward_getp (s, withdraw_len);
paul718e3742002-12-13 20:15:29 +00001724 }
1725
1726 /* Attribute total length check. */
1727 if (stream_pnt (s) + 2 > end)
1728 {
1729 zlog_warn ("%s [Error] Packet Error"
1730 " (update packet is short for attribute length)",
1731 peer->host);
1732 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1733 BGP_NOTIFY_UPDATE_MAL_ATTR);
1734 return -1;
1735 }
1736
1737 /* Fetch attribute total length. */
1738 attribute_len = stream_getw (s);
1739
1740 /* Attribute length check. */
1741 if (stream_pnt (s) + attribute_len > end)
1742 {
1743 zlog_warn ("%s [Error] Packet Error"
1744 " (update packet attribute length overflow %d)",
1745 peer->host, attribute_len);
1746 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1747 BGP_NOTIFY_UPDATE_MAL_ATTR);
1748 return -1;
1749 }
Paul Jakmab881c702010-11-23 16:35:42 +00001750
1751 /* Certain attribute parsing errors should not be considered bad enough
1752 * to reset the session for, most particularly any partial/optional
1753 * attributes that have 'tunneled' over speakers that don't understand
1754 * them. Instead we withdraw only the prefix concerned.
1755 *
1756 * Complicates the flow a little though..
1757 */
1758 bgp_attr_parse_ret_t attr_parse_ret = BGP_ATTR_PARSE_PROCEED;
1759 /* This define morphs the update case into a withdraw when lower levels
1760 * have signalled an error condition where this is best.
1761 */
1762#define NLRI_ATTR_ARG (attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : NULL)
paul718e3742002-12-13 20:15:29 +00001763
1764 /* Parse attribute when it exists. */
1765 if (attribute_len)
1766 {
Paul Jakmab881c702010-11-23 16:35:42 +00001767 attr_parse_ret = bgp_attr_parse (peer, &attr, attribute_len,
Paul Jakma518a4b72016-02-04 13:27:04 +00001768 &nlris[NLRI_MP_UPDATE], &nlris[NLRI_MP_WITHDRAW]);
Paul Jakmab881c702010-11-23 16:35:42 +00001769 if (attr_parse_ret == BGP_ATTR_PARSE_ERROR)
David Lamparterf80f8382014-06-04 01:00:51 +02001770 {
1771 bgp_attr_unintern_sub (&attr);
Lou Berger050defe2016-01-12 13:41:59 -05001772 bgp_attr_flush (&attr);
David Lamparterf80f8382014-06-04 01:00:51 +02001773 return -1;
1774 }
paul718e3742002-12-13 20:15:29 +00001775 }
Paul Jakmab881c702010-11-23 16:35:42 +00001776
paul718e3742002-12-13 20:15:29 +00001777 /* Logging the attribute. */
Paul Jakmab881c702010-11-23 16:35:42 +00001778 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW
1779 || BGP_DEBUG (update, UPDATE_IN))
paul718e3742002-12-13 20:15:29 +00001780 {
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +00001781 char attrstr[BUFSIZ];
1782 attrstr[0] = '\0';
1783
paule01f9cb2004-07-09 17:48:53 +00001784 ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
Paul Jakmab881c702010-11-23 16:35:42 +00001785 int lvl = (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1786 ? LOG_ERR : LOG_DEBUG;
1787
1788 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1789 zlog (peer->log, LOG_ERR,
1790 "%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
1791 peer->host);
paule01f9cb2004-07-09 17:48:53 +00001792
1793 if (ret)
Paul Jakmab881c702010-11-23 16:35:42 +00001794 zlog (peer->log, lvl, "%s rcvd UPDATE w/ attr: %s",
paule01f9cb2004-07-09 17:48:53 +00001795 peer->host, attrstr);
paul718e3742002-12-13 20:15:29 +00001796 }
Paul Jakmab881c702010-11-23 16:35:42 +00001797
paul718e3742002-12-13 20:15:29 +00001798 /* Network Layer Reachability Information. */
1799 update_len = end - stream_pnt (s);
1800
1801 if (update_len)
1802 {
Paul Jakma18ab08b2016-01-27 16:37:33 +00001803 /* Set NLRI portion to structure. */
Paul Jakma518a4b72016-02-04 13:27:04 +00001804 nlris[NLRI_UPDATE].afi = AFI_IP;
1805 nlris[NLRI_UPDATE].safi = SAFI_UNICAST;
1806 nlris[NLRI_UPDATE].nlri = stream_pnt (s);
1807 nlris[NLRI_UPDATE].length = update_len;
Paul Jakma18ab08b2016-01-27 16:37:33 +00001808
paul9985f832005-02-09 15:51:56 +00001809 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001810 }
Paul Jakma518a4b72016-02-04 13:27:04 +00001811
1812 /* Parse any given NLRIs */
1813 for (i = NLRI_UPDATE; i < NLRI_TYPE_MAX; i++)
paul718e3742002-12-13 20:15:29 +00001814 {
Paul Jakma3b847ef2016-04-22 12:48:49 +01001815 if (!nlris[i].nlri) continue;
1816
Paul Jakma518a4b72016-02-04 13:27:04 +00001817 /* We use afi and safi as indices into tables and what not. It would
1818 * be impossible, at this time, to support unknown afi/safis. And
1819 * anyway, the peer needs to be configured to enable the afi/safi
1820 * explicitly which requires UI support.
1821 *
1822 * Ignore unknown afi/safi NLRIs.
1823 *
1824 * Note: this means nlri[x].afi/safi still can not be trusted for
1825 * indexing later in this function!
1826 *
1827 * Note2: This will also remap the wire code-point for VPN safi to the
1828 * internal safi_t point, as needs be.
1829 */
1830 if (!bgp_afi_safi_valid_indices (nlris[i].afi, &nlris[i].safi))
1831 {
1832 plog_info (peer->log,
1833 "%s [Info] UPDATE with unsupported AFI/SAFI %u/%u",
1834 peer->host, nlris[i].afi, nlris[i].safi);
1835 continue;
1836 }
1837
1838 /* NLRI is processed only when the peer is configured specific
1839 Address Family and Subsequent Address Family. */
1840 if (!peer->afc[nlris[i].afi][nlris[i].safi])
1841 {
1842 plog_info (peer->log,
1843 "%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u",
1844 peer->host, nlris[i].afi, nlris[i].safi);
1845 continue;
1846 }
1847
1848 /* EoR handled later */
1849 if (nlris[i].length == 0)
1850 continue;
1851
1852 switch (i)
1853 {
1854 case NLRI_UPDATE:
1855 case NLRI_MP_UPDATE:
1856 nlri_ret = bgp_nlri_parse (peer, NLRI_ATTR_ARG, &nlris[i]);
1857 break;
1858 case NLRI_WITHDRAW:
1859 case NLRI_MP_WITHDRAW:
1860 nlri_ret = bgp_nlri_parse (peer, NULL, &nlris[i]);
1861 }
1862
1863 if (nlri_ret < 0)
1864 {
1865 plog_err (peer->log,
1866 "%s [Error] Error parsing NLRI", peer->host);
1867 if (peer->status == Established)
1868 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1869 i <= NLRI_WITHDRAW
1870 ? BGP_NOTIFY_UPDATE_INVAL_NETWORK
1871 : BGP_NOTIFY_UPDATE_OPT_ATTR_ERR);
1872 bgp_attr_unintern_sub (&attr);
1873 return -1;
1874 }
1875 }
1876
1877 /* EoR checks.
1878 *
1879 * Non-MP IPv4/Unicast EoR is a completely empty UPDATE
1880 * and MP EoR should have only an empty MP_UNREACH
1881 */
1882 if (!update_len && !withdraw_len
1883 && nlris[NLRI_MP_UPDATE].length == 0)
1884 {
1885 afi_t afi = 0;
1886 safi_t safi;
1887
1888 /* Non-MP IPv4/Unicast is a completely empty UPDATE - already
1889 * checked update and withdraw NLRI lengths are 0.
1890 */
1891 if (!attribute_len)
1892 {
1893 afi = AFI_IP;
1894 safi = SAFI_UNICAST;
1895 }
1896 /* otherwise MP AFI/SAFI is an empty update, other than an empty
1897 * MP_UNREACH_NLRI attr (with an AFI/SAFI we recognise).
1898 */
1899 else if (attr.flag == BGP_ATTR_MP_UNREACH_NLRI
1900 && nlris[NLRI_MP_WITHDRAW].length == 0
1901 && bgp_afi_safi_valid_indices (nlris[NLRI_MP_WITHDRAW].afi,
1902 &nlris[NLRI_MP_WITHDRAW].safi))
1903 {
1904 afi = nlris[NLRI_MP_WITHDRAW].afi;
1905 safi = nlris[NLRI_MP_WITHDRAW].safi;
1906 }
1907
1908 if (afi && peer->afc[afi][safi])
1909 {
paule01f9cb2004-07-09 17:48:53 +00001910 /* End-of-RIB received */
Paul Jakma518a4b72016-02-04 13:27:04 +00001911 SET_FLAG (peer->af_sflags[afi][safi],
hasso93406d82005-02-02 14:40:33 +00001912 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001913
hasso93406d82005-02-02 14:40:33 +00001914 /* NSF delete stale route */
Paul Jakma518a4b72016-02-04 13:27:04 +00001915 if (peer->nsf[afi][safi])
1916 bgp_clear_stale_route (peer, afi, safi);
hasso93406d82005-02-02 14:40:33 +00001917
1918 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma518a4b72016-02-04 13:27:04 +00001919 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for %s from %s",
1920 peer->host, afi_safi_print (afi, safi));
1921 }
paul718e3742002-12-13 20:15:29 +00001922 }
Paul Jakma518a4b72016-02-04 13:27:04 +00001923
paul718e3742002-12-13 20:15:29 +00001924 /* Everything is done. We unintern temporary structures which
1925 interned in bgp_attr_parse(). */
Paul Jakmab881c702010-11-23 16:35:42 +00001926 bgp_attr_unintern_sub (&attr);
Lou Berger050defe2016-01-12 13:41:59 -05001927 bgp_attr_flush (&attr);
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001928
paul718e3742002-12-13 20:15:29 +00001929 /* If peering is stopped due to some reason, do not generate BGP
1930 event. */
1931 if (peer->status != Established)
1932 return 0;
1933
1934 /* Increment packet counter. */
1935 peer->update_in++;
Stephen Hemminger65957882010-01-15 16:22:10 +03001936 peer->update_time = bgp_clock ();
paul718e3742002-12-13 20:15:29 +00001937
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02001938 /* Rearm holdtime timer */
Jorge Boncompte [DTI2]6a4677b2012-05-07 16:53:07 +00001939 BGP_TIMER_OFF (peer->t_holdtime);
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02001940 bgp_timer_set (peer);
paul718e3742002-12-13 20:15:29 +00001941
1942 return 0;
1943}
1944
1945/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00001946static void
paul718e3742002-12-13 20:15:29 +00001947bgp_notify_receive (struct peer *peer, bgp_size_t size)
1948{
1949 struct bgp_notify bgp_notify;
1950
1951 if (peer->notify.data)
1952 {
1953 XFREE (MTYPE_TMP, peer->notify.data);
1954 peer->notify.data = NULL;
1955 peer->notify.length = 0;
1956 }
1957
1958 bgp_notify.code = stream_getc (peer->ibuf);
1959 bgp_notify.subcode = stream_getc (peer->ibuf);
1960 bgp_notify.length = size - 2;
1961 bgp_notify.data = NULL;
1962
1963 /* Preserv notify code and sub code. */
1964 peer->notify.code = bgp_notify.code;
1965 peer->notify.subcode = bgp_notify.subcode;
1966 /* For further diagnostic record returned Data. */
1967 if (bgp_notify.length)
1968 {
1969 peer->notify.length = size - 2;
1970 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
1971 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
1972 }
1973
1974 /* For debug */
1975 {
1976 int i;
1977 int first = 0;
1978 char c[4];
1979
1980 if (bgp_notify.length)
1981 {
1982 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
1983 for (i = 0; i < bgp_notify.length; i++)
1984 if (first)
1985 {
1986 sprintf (c, " %02x", stream_getc (peer->ibuf));
1987 strcat (bgp_notify.data, c);
1988 }
1989 else
1990 {
1991 first = 1;
1992 sprintf (c, "%02x", stream_getc (peer->ibuf));
1993 strcpy (bgp_notify.data, c);
1994 }
1995 }
1996
1997 bgp_notify_print(peer, &bgp_notify, "received");
1998 if (bgp_notify.data)
Daniel Walton363c9032015-10-21 06:42:54 -07001999 {
2000 XFREE (MTYPE_TMP, bgp_notify.data);
2001 bgp_notify.data = NULL;
2002 bgp_notify.length = 0;
2003 }
paul718e3742002-12-13 20:15:29 +00002004 }
2005
2006 /* peer count update */
2007 peer->notify_in++;
2008
hassoe0701b72004-05-20 09:19:34 +00002009 if (peer->status == Established)
2010 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
2011
paul718e3742002-12-13 20:15:29 +00002012 /* We have to check for Notify with Unsupported Optional Parameter.
2013 in that case we fallback to open without the capability option.
2014 But this done in bgp_stop. We just mark it here to avoid changing
2015 the fsm tables. */
2016 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
2017 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
2018 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
2019
paul718e3742002-12-13 20:15:29 +00002020 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
2021}
2022
2023/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00002024static void
paul718e3742002-12-13 20:15:29 +00002025bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
2026{
2027 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00002028 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00002029
2030 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
2031}
2032
2033/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00002034static void
paul718e3742002-12-13 20:15:29 +00002035bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
2036{
2037 afi_t afi;
2038 safi_t safi;
paul718e3742002-12-13 20:15:29 +00002039 struct stream *s;
2040
2041 /* If peer does not have the capability, send notification. */
2042 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
2043 {
2044 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
2045 peer->host);
2046 bgp_notify_send (peer,
2047 BGP_NOTIFY_HEADER_ERR,
2048 BGP_NOTIFY_HEADER_BAD_MESTYPE);
2049 return;
2050 }
2051
2052 /* Status must be Established. */
2053 if (peer->status != Established)
2054 {
2055 plog_err (peer->log,
2056 "%s [Error] Route refresh packet received under status %s",
2057 peer->host, LOOKUP (bgp_status_msg, peer->status));
2058 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
2059 return;
2060 }
2061
2062 s = peer->ibuf;
2063
2064 /* Parse packet. */
2065 afi = stream_getw (s);
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002066 /* reserved byte */
2067 stream_getc (s);
paul718e3742002-12-13 20:15:29 +00002068 safi = stream_getc (s);
2069
2070 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002071 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00002072 peer->host, afi, safi);
2073
2074 /* Check AFI and SAFI. */
2075 if ((afi != AFI_IP && afi != AFI_IP6)
2076 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
Denis Ovsienko42e6d742011-07-14 12:36:19 +04002077 && safi != SAFI_MPLS_LABELED_VPN))
paul718e3742002-12-13 20:15:29 +00002078 {
2079 if (BGP_DEBUG (normal, NORMAL))
2080 {
ajs6b514742004-12-08 21:03:23 +00002081 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00002082 peer->host, afi, safi);
2083 }
2084 return;
2085 }
2086
2087 /* Adjust safi code. */
Denis Ovsienko42e6d742011-07-14 12:36:19 +04002088 if (safi == SAFI_MPLS_LABELED_VPN)
paul718e3742002-12-13 20:15:29 +00002089 safi = SAFI_MPLS_VPN;
2090
2091 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
2092 {
2093 u_char *end;
2094 u_char when_to_refresh;
2095 u_char orf_type;
2096 u_int16_t orf_len;
2097
2098 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
2099 {
2100 zlog_info ("%s ORF route refresh length error", peer->host);
2101 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2102 return;
2103 }
2104
2105 when_to_refresh = stream_getc (s);
2106 end = stream_pnt (s) + (size - 5);
2107
Paul Jakma370b64a2007-12-22 16:49:52 +00002108 while ((stream_pnt (s) + 2) < end)
paul718e3742002-12-13 20:15:29 +00002109 {
2110 orf_type = stream_getc (s);
2111 orf_len = stream_getw (s);
Paul Jakma370b64a2007-12-22 16:49:52 +00002112
2113 /* orf_len in bounds? */
2114 if ((stream_pnt (s) + orf_len) > end)
2115 break; /* XXX: Notify instead?? */
paul718e3742002-12-13 20:15:29 +00002116 if (orf_type == ORF_TYPE_PREFIX
2117 || orf_type == ORF_TYPE_PREFIX_OLD)
2118 {
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002119 uint8_t *p_pnt = stream_pnt (s);
2120 uint8_t *p_end = stream_pnt (s) + orf_len;
paul718e3742002-12-13 20:15:29 +00002121 struct orf_prefix orfp;
2122 u_char common = 0;
2123 u_int32_t seq;
2124 int psize;
2125 char name[BUFSIZ];
paul718e3742002-12-13 20:15:29 +00002126 int ret;
2127
2128 if (BGP_DEBUG (normal, NORMAL))
2129 {
ajs6b514742004-12-08 21:03:23 +00002130 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00002131 peer->host, orf_type, orf_len);
2132 }
2133
Paul Jakma370b64a2007-12-22 16:49:52 +00002134 /* we're going to read at least 1 byte of common ORF header,
2135 * and 7 bytes of ORF Address-filter entry from the stream
2136 */
2137 if (orf_len < 7)
2138 break;
2139
paul718e3742002-12-13 20:15:29 +00002140 /* ORF prefix-list name */
2141 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
2142
2143 while (p_pnt < p_end)
2144 {
Chris Halld64379e2010-05-14 16:38:39 +04002145 /* If the ORF entry is malformed, want to read as much of it
2146 * as possible without going beyond the bounds of the entry,
2147 * to maximise debug information.
2148 */
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002149 int ok;
paul718e3742002-12-13 20:15:29 +00002150 memset (&orfp, 0, sizeof (struct orf_prefix));
2151 common = *p_pnt++;
Chris Halld64379e2010-05-14 16:38:39 +04002152 /* after ++: p_pnt <= p_end */
paul718e3742002-12-13 20:15:29 +00002153 if (common & ORF_COMMON_PART_REMOVE_ALL)
2154 {
2155 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002156 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
David Lamparterc9c06d02015-04-13 10:21:35 +02002157 prefix_bgp_orf_remove_all (afi, name);
paul718e3742002-12-13 20:15:29 +00002158 break;
2159 }
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002160 ok = ((size_t)(p_end - p_pnt) >= sizeof(u_int32_t)) ;
Denis Ovsienkobb915f52011-12-13 21:11:39 +04002161 if (ok)
Chris Halld64379e2010-05-14 16:38:39 +04002162 {
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002163 memcpy (&seq, p_pnt, sizeof (u_int32_t));
2164 p_pnt += sizeof (u_int32_t);
2165 orfp.seq = ntohl (seq);
Chris Halld64379e2010-05-14 16:38:39 +04002166 }
2167 else
2168 p_pnt = p_end ;
2169
2170 if ((ok = (p_pnt < p_end)))
2171 orfp.ge = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2172 if ((ok = (p_pnt < p_end)))
2173 orfp.le = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2174 if ((ok = (p_pnt < p_end)))
2175 orfp.p.prefixlen = *p_pnt++ ;
2176 orfp.p.family = afi2family (afi); /* afi checked already */
2177
2178 psize = PSIZE (orfp.p.prefixlen); /* 0 if not ok */
2179 if (psize > prefix_blen(&orfp.p)) /* valid for family ? */
2180 {
2181 ok = 0 ;
2182 psize = prefix_blen(&orfp.p) ;
2183 }
2184 if (psize > (p_end - p_pnt)) /* valid for packet ? */
2185 {
2186 ok = 0 ;
2187 psize = p_end - p_pnt ;
2188 }
2189
2190 if (psize > 0)
2191 memcpy (&orfp.p.u.prefix, p_pnt, psize);
paul718e3742002-12-13 20:15:29 +00002192 p_pnt += psize;
2193
2194 if (BGP_DEBUG (normal, NORMAL))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +00002195 {
2196 char buf[INET6_BUFSIZ];
2197
2198 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
2199 peer->host,
2200 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
2201 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
2202 orfp.seq,
2203 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, INET6_BUFSIZ),
2204 orfp.p.prefixlen, orfp.ge, orfp.le,
2205 ok ? "" : " MALFORMED");
2206 }
2207
Chris Halld64379e2010-05-14 16:38:39 +04002208 if (ok)
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002209 ret = prefix_bgp_orf_set (name, afi, &orfp,
2210 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
2211 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002212
2213 if (!ok || (ok && ret != CMD_SUCCESS))
paul718e3742002-12-13 20:15:29 +00002214 {
2215 if (BGP_DEBUG (normal, NORMAL))
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002216 zlog_debug ("%s Received misformatted prefixlist ORF."
2217 " Remove All pfxlist", peer->host);
David Lamparterc9c06d02015-04-13 10:21:35 +02002218 prefix_bgp_orf_remove_all (afi, name);
paul718e3742002-12-13 20:15:29 +00002219 break;
2220 }
2221 }
2222 peer->orf_plist[afi][safi] =
David Lamparterc9c06d02015-04-13 10:21:35 +02002223 prefix_bgp_orf_lookup (afi, name);
paul718e3742002-12-13 20:15:29 +00002224 }
paul9985f832005-02-09 15:51:56 +00002225 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00002226 }
2227 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002228 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00002229 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
2230 if (when_to_refresh == REFRESH_DEFER)
2231 return;
2232 }
2233
2234 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2235 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
2236 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
2237
2238 /* Perform route refreshment to the peer */
2239 bgp_announce_route (peer, afi, safi);
2240}
2241
paul94f2b392005-06-28 12:44:16 +00002242static int
paul718e3742002-12-13 20:15:29 +00002243bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
2244{
2245 u_char *end;
Paul Jakma6d582722007-08-06 15:21:45 +00002246 struct capability_mp_data mpc;
2247 struct capability_header *hdr;
paul718e3742002-12-13 20:15:29 +00002248 u_char action;
paul718e3742002-12-13 20:15:29 +00002249 afi_t afi;
2250 safi_t safi;
2251
paul718e3742002-12-13 20:15:29 +00002252 end = pnt + length;
2253
2254 while (pnt < end)
Paul Jakma6d582722007-08-06 15:21:45 +00002255 {
paul718e3742002-12-13 20:15:29 +00002256 /* We need at least action, capability code and capability length. */
2257 if (pnt + 3 > end)
2258 {
2259 zlog_info ("%s Capability length error", peer->host);
2260 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2261 return -1;
2262 }
paul718e3742002-12-13 20:15:29 +00002263 action = *pnt;
Paul Jakma6d582722007-08-06 15:21:45 +00002264 hdr = (struct capability_header *)(pnt + 1);
2265
paul718e3742002-12-13 20:15:29 +00002266 /* Action value check. */
2267 if (action != CAPABILITY_ACTION_SET
2268 && action != CAPABILITY_ACTION_UNSET)
2269 {
2270 zlog_info ("%s Capability Action Value error %d",
2271 peer->host, action);
2272 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2273 return -1;
2274 }
2275
2276 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002277 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
Paul Jakma6d582722007-08-06 15:21:45 +00002278 peer->host, action, hdr->code, hdr->length);
paul718e3742002-12-13 20:15:29 +00002279
2280 /* Capability length check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002281 if ((pnt + hdr->length + 3) > end)
paul718e3742002-12-13 20:15:29 +00002282 {
2283 zlog_info ("%s Capability length error", peer->host);
2284 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2285 return -1;
2286 }
2287
Paul Jakma6d582722007-08-06 15:21:45 +00002288 /* Fetch structure to the byte stream. */
2289 memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
2290
paul718e3742002-12-13 20:15:29 +00002291 /* We know MP Capability Code. */
Paul Jakma6d582722007-08-06 15:21:45 +00002292 if (hdr->code == CAPABILITY_CODE_MP)
paul718e3742002-12-13 20:15:29 +00002293 {
Paul Jakma6d582722007-08-06 15:21:45 +00002294 afi = ntohs (mpc.afi);
2295 safi = mpc.safi;
paul718e3742002-12-13 20:15:29 +00002296
2297 /* Ignore capability when override-capability is set. */
2298 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2299 continue;
Paul Jakma6d582722007-08-06 15:21:45 +00002300
2301 if (!bgp_afi_safi_valid_indices (afi, &safi))
2302 {
2303 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002304 zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
2305 "(%u/%u)", peer->host, afi, safi);
Paul Jakma6d582722007-08-06 15:21:45 +00002306 continue;
2307 }
2308
paul718e3742002-12-13 20:15:29 +00002309 /* Address family check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002310 if (BGP_DEBUG (normal, NORMAL))
2311 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2312 peer->host,
2313 action == CAPABILITY_ACTION_SET
2314 ? "Advertising" : "Removing",
2315 ntohs(mpc.afi) , mpc.safi);
2316
2317 if (action == CAPABILITY_ACTION_SET)
2318 {
2319 peer->afc_recv[afi][safi] = 1;
2320 if (peer->afc[afi][safi])
2321 {
2322 peer->afc_nego[afi][safi] = 1;
2323 bgp_announce_route (peer, afi, safi);
2324 }
2325 }
2326 else
2327 {
2328 peer->afc_recv[afi][safi] = 0;
2329 peer->afc_nego[afi][safi] = 0;
paul718e3742002-12-13 20:15:29 +00002330
Paul Jakma6d582722007-08-06 15:21:45 +00002331 if (peer_active_nego (peer))
Chris Caputo228da422009-07-18 05:44:03 +00002332 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
Paul Jakma6d582722007-08-06 15:21:45 +00002333 else
2334 BGP_EVENT_ADD (peer, BGP_Stop);
2335 }
paul718e3742002-12-13 20:15:29 +00002336 }
paul718e3742002-12-13 20:15:29 +00002337 else
2338 {
2339 zlog_warn ("%s unrecognized capability code: %d - ignored",
Paul Jakma6d582722007-08-06 15:21:45 +00002340 peer->host, hdr->code);
paul718e3742002-12-13 20:15:29 +00002341 }
Paul Jakma6d582722007-08-06 15:21:45 +00002342 pnt += hdr->length + 3;
paul718e3742002-12-13 20:15:29 +00002343 }
2344 return 0;
2345}
2346
Paul Jakma01b7ce22009-06-18 12:34:43 +01002347/* Dynamic Capability is received.
2348 *
2349 * This is exported for unit-test purposes
2350 */
Paul Jakma6d582722007-08-06 15:21:45 +00002351int
paul718e3742002-12-13 20:15:29 +00002352bgp_capability_receive (struct peer *peer, bgp_size_t size)
2353{
2354 u_char *pnt;
paul718e3742002-12-13 20:15:29 +00002355
2356 /* Fetch pointer. */
2357 pnt = stream_pnt (peer->ibuf);
2358
2359 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002360 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002361
2362 /* If peer does not have the capability, send notification. */
2363 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2364 {
2365 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2366 peer->host);
2367 bgp_notify_send (peer,
2368 BGP_NOTIFY_HEADER_ERR,
2369 BGP_NOTIFY_HEADER_BAD_MESTYPE);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002370 return -1;
paul718e3742002-12-13 20:15:29 +00002371 }
2372
2373 /* Status must be Established. */
2374 if (peer->status != Established)
2375 {
2376 plog_err (peer->log,
2377 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2378 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002379 return -1;
paul718e3742002-12-13 20:15:29 +00002380 }
2381
2382 /* Parse packet. */
Paul Jakma6d582722007-08-06 15:21:45 +00002383 return bgp_capability_msg_parse (peer, pnt, size);
paul718e3742002-12-13 20:15:29 +00002384}
David Lamparter6b0655a2014-06-04 06:53:35 +02002385
paul718e3742002-12-13 20:15:29 +00002386/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002387static int
paul718e3742002-12-13 20:15:29 +00002388bgp_read_packet (struct peer *peer)
2389{
2390 int nbytes;
2391 int readsize;
2392
paul9985f832005-02-09 15:51:56 +00002393 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002394
2395 /* If size is zero then return. */
2396 if (! readsize)
2397 return 0;
2398
2399 /* Read packet from fd. */
Stephen Hemminger35398582010-08-05 10:26:23 -07002400 nbytes = stream_read_try (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002401
2402 /* If read byte is smaller than zero then error occured. */
2403 if (nbytes < 0)
2404 {
Stephen Hemminger35398582010-08-05 10:26:23 -07002405 /* Transient error should retry */
2406 if (nbytes == -2)
paul718e3742002-12-13 20:15:29 +00002407 return -1;
2408
2409 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002410 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002411
2412 if (peer->status == Established)
2413 {
2414 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2415 {
2416 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2417 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2418 }
2419 else
2420 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2421 }
2422
paul718e3742002-12-13 20:15:29 +00002423 BGP_EVENT_ADD (peer, TCP_fatal_error);
2424 return -1;
2425 }
2426
2427 /* When read byte is zero : clear bgp peer and return */
2428 if (nbytes == 0)
2429 {
2430 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002431 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002432 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002433
2434 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002435 {
2436 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2437 {
2438 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2439 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2440 }
2441 else
2442 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2443 }
hassoe0701b72004-05-20 09:19:34 +00002444
paul718e3742002-12-13 20:15:29 +00002445 BGP_EVENT_ADD (peer, TCP_connection_closed);
2446 return -1;
2447 }
2448
2449 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002450 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002451 return -1;
2452
2453 return 0;
2454}
2455
2456/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002457static int
paul718e3742002-12-13 20:15:29 +00002458bgp_marker_all_one (struct stream *s, int length)
2459{
2460 int i;
2461
2462 for (i = 0; i < length; i++)
2463 if (s->data[i] != 0xff)
2464 return 0;
2465
2466 return 1;
2467}
2468
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002469/* Recent thread time.
2470 On same clock base as bgp_clock (MONOTONIC)
2471 but can be time of last context switch to bgp_read thread. */
2472static time_t
2473bgp_recent_clock (void)
2474{
2475 return recent_relative_time().tv_sec;
2476}
2477
paul718e3742002-12-13 20:15:29 +00002478/* Starting point of packet process function. */
2479int
2480bgp_read (struct thread *thread)
2481{
2482 int ret;
2483 u_char type = 0;
2484 struct peer *peer;
2485 bgp_size_t size;
2486 char notify_data_length[2];
2487
2488 /* Yes first of all get peer pointer. */
2489 peer = THREAD_ARG (thread);
2490 peer->t_read = NULL;
2491
2492 /* For non-blocking IO check. */
2493 if (peer->status == Connect)
2494 {
Paul Jakma743dd422016-09-30 13:55:47 +01002495 bgp_connect_check (peer);
paul718e3742002-12-13 20:15:29 +00002496 goto done;
2497 }
2498 else
2499 {
pauleb821182004-05-01 08:44:08 +00002500 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002501 {
pauleb821182004-05-01 08:44:08 +00002502 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002503 return -1;
2504 }
pauleb821182004-05-01 08:44:08 +00002505 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002506 }
2507
2508 /* Read packet header to determine type of the packet */
2509 if (peer->packet_size == 0)
2510 peer->packet_size = BGP_HEADER_SIZE;
2511
paul9985f832005-02-09 15:51:56 +00002512 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002513 {
2514 ret = bgp_read_packet (peer);
2515
2516 /* Header read error or partial read packet. */
2517 if (ret < 0)
2518 goto done;
2519
2520 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002521 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002522 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2523 size = stream_getw (peer->ibuf);
2524 type = stream_getc (peer->ibuf);
2525
2526 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002527 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002528 peer->host, type, size - BGP_HEADER_SIZE);
2529
2530 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002531 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002532 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2533 {
2534 bgp_notify_send (peer,
2535 BGP_NOTIFY_HEADER_ERR,
2536 BGP_NOTIFY_HEADER_NOT_SYNC);
2537 goto done;
2538 }
2539
2540 /* BGP type check. */
2541 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2542 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2543 && type != BGP_MSG_ROUTE_REFRESH_NEW
2544 && type != BGP_MSG_ROUTE_REFRESH_OLD
2545 && type != BGP_MSG_CAPABILITY)
2546 {
2547 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002548 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002549 "%s unknown message type 0x%02x",
2550 peer->host, type);
2551 bgp_notify_send_with_data (peer,
2552 BGP_NOTIFY_HEADER_ERR,
2553 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2554 &type, 1);
2555 goto done;
2556 }
2557 /* Mimimum packet length check. */
2558 if ((size < BGP_HEADER_SIZE)
2559 || (size > BGP_MAX_PACKET_SIZE)
2560 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2561 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2562 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2563 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2564 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2565 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2566 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2567 {
2568 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002569 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002570 "%s bad message length - %d for %s",
2571 peer->host, size,
2572 type == 128 ? "ROUTE-REFRESH" :
2573 bgp_type_str[(int) type]);
2574 bgp_notify_send_with_data (peer,
2575 BGP_NOTIFY_HEADER_ERR,
2576 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002577 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002578 goto done;
2579 }
2580
2581 /* Adjust size to message length. */
2582 peer->packet_size = size;
2583 }
2584
2585 ret = bgp_read_packet (peer);
2586 if (ret < 0)
2587 goto done;
2588
2589 /* Get size and type again. */
2590 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2591 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2592
2593 /* BGP packet dump function. */
2594 bgp_dump_packet (peer, type, peer->ibuf);
2595
2596 size = (peer->packet_size - BGP_HEADER_SIZE);
2597
2598 /* Read rest of the packet and call each sort of packet routine */
2599 switch (type)
2600 {
2601 case BGP_MSG_OPEN:
2602 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002603 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002604 break;
2605 case BGP_MSG_UPDATE:
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002606 peer->readtime = bgp_recent_clock ();
paul718e3742002-12-13 20:15:29 +00002607 bgp_update_receive (peer, size);
2608 break;
2609 case BGP_MSG_NOTIFY:
2610 bgp_notify_receive (peer, size);
2611 break;
2612 case BGP_MSG_KEEPALIVE:
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002613 peer->readtime = bgp_recent_clock ();
paul718e3742002-12-13 20:15:29 +00002614 bgp_keepalive_receive (peer, size);
2615 break;
2616 case BGP_MSG_ROUTE_REFRESH_NEW:
2617 case BGP_MSG_ROUTE_REFRESH_OLD:
2618 peer->refresh_in++;
2619 bgp_route_refresh_receive (peer, size);
2620 break;
2621 case BGP_MSG_CAPABILITY:
2622 peer->dynamic_cap_in++;
2623 bgp_capability_receive (peer, size);
2624 break;
2625 }
2626
2627 /* Clear input buffer. */
2628 peer->packet_size = 0;
2629 if (peer->ibuf)
2630 stream_reset (peer->ibuf);
2631
2632 done:
2633 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2634 {
2635 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002636 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002637 peer_delete (peer);
paul718e3742002-12-13 20:15:29 +00002638 }
2639 return 0;
2640}