blob: 16e1435a02187911039d5aed3eead513bf37afb0 [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"
50#include "bgpd/bgp_advertise.h"
hasso93406d82005-02-02 14:40:33 +000051#include "bgpd/bgp_vty.h"
paul718e3742002-12-13 20:15:29 +000052
53int stream_put_prefix (struct stream *, struct prefix *);
David Lamparter6b0655a2014-06-04 06:53:35 +020054
paul718e3742002-12-13 20:15:29 +000055/* Set up BGP packet marker and packet type. */
56static int
57bgp_packet_set_marker (struct stream *s, u_char type)
58{
59 int i;
60
61 /* Fill in marker. */
62 for (i = 0; i < BGP_MARKER_SIZE; i++)
63 stream_putc (s, 0xff);
64
65 /* Dummy total length. This field is should be filled in later on. */
66 stream_putw (s, 0);
67
68 /* BGP packet type. */
69 stream_putc (s, type);
70
71 /* Return current stream size. */
paul9985f832005-02-09 15:51:56 +000072 return stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +000073}
74
75/* Set BGP packet header size entry. If size is zero then use current
76 stream size. */
77static int
78bgp_packet_set_size (struct stream *s)
79{
80 int cp;
81
82 /* Preserve current pointer. */
paul9985f832005-02-09 15:51:56 +000083 cp = stream_get_endp (s);
84 stream_putw_at (s, BGP_MARKER_SIZE, cp);
paul718e3742002-12-13 20:15:29 +000085
86 return cp;
87}
88
89/* Add new packet to the peer. */
paul94f2b392005-06-28 12:44:16 +000090static void
paul718e3742002-12-13 20:15:29 +000091bgp_packet_add (struct peer *peer, struct stream *s)
92{
93 /* Add packet to the end of list. */
94 stream_fifo_push (peer->obuf, s);
95}
96
97/* Free first packet. */
paul94f2b392005-06-28 12:44:16 +000098static void
paul718e3742002-12-13 20:15:29 +000099bgp_packet_delete (struct peer *peer)
100{
101 stream_free (stream_fifo_pop (peer->obuf));
102}
103
paul718e3742002-12-13 20:15:29 +0000104/* Check file descriptor whether connect is established. */
105static void
106bgp_connect_check (struct peer *peer)
107{
108 int status;
paul5228ad22004-06-04 17:58:18 +0000109 socklen_t slen;
paul718e3742002-12-13 20:15:29 +0000110 int ret;
111
112 /* Anyway I have to reset read and write thread. */
113 BGP_READ_OFF (peer->t_read);
114 BGP_WRITE_OFF (peer->t_write);
115
116 /* Check file descriptor. */
117 slen = sizeof (status);
pauleb821182004-05-01 08:44:08 +0000118 ret = getsockopt(peer->fd, SOL_SOCKET, SO_ERROR, (void *) &status, &slen);
paul718e3742002-12-13 20:15:29 +0000119
120 /* If getsockopt is fail, this is fatal error. */
121 if (ret < 0)
122 {
123 zlog (peer->log, LOG_INFO, "can't get sockopt for nonblocking connect");
124 BGP_EVENT_ADD (peer, TCP_fatal_error);
125 return;
126 }
127
128 /* When status is 0 then TCP connection is established. */
129 if (status == 0)
130 {
131 BGP_EVENT_ADD (peer, TCP_connection_open);
132 }
133 else
134 {
135 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +0000136 plog_debug (peer->log, "%s [Event] Connect failed (%s)",
ajs6099b3b2004-11-20 02:06:59 +0000137 peer->host, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000138 BGP_EVENT_ADD (peer, TCP_connection_open_failed);
139 }
140}
141
142/* Make BGP update packet. */
paul94f2b392005-06-28 12:44:16 +0000143static struct stream *
paul718e3742002-12-13 20:15:29 +0000144bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi)
145{
146 struct stream *s;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000147 struct stream *snlri;
paul718e3742002-12-13 20:15:29 +0000148 struct bgp_adj_out *adj;
149 struct bgp_advertise *adv;
150 struct stream *packet;
151 struct bgp_node *rn = NULL;
152 struct bgp_info *binfo = NULL;
153 bgp_size_t total_attr_len = 0;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000154 unsigned long attrlen_pos = 0;
155 size_t mpattrlen_pos = 0;
156 size_t mpattr_pos = 0;
paul718e3742002-12-13 20:15:29 +0000157
158 s = peer->work;
159 stream_reset (s);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000160 snlri = peer->scratch;
161 stream_reset (snlri);
paul718e3742002-12-13 20:15:29 +0000162
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100163 adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update);
paul718e3742002-12-13 20:15:29 +0000164
165 while (adv)
166 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000167 assert (adv->rn);
168 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000169 adj = adv->adj;
170 if (adv->binfo)
171 binfo = adv->binfo;
paul718e3742002-12-13 20:15:29 +0000172
173 /* When remaining space can't include NLRI and it's length. */
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000174 if (STREAM_CONCAT_REMAIN (s, snlri, STREAM_SIZE(s)) <=
175 (BGP_NLRI_LENGTH + PSIZE (rn->p.prefixlen)))
paul718e3742002-12-13 20:15:29 +0000176 break;
177
178 /* If packet is empty, set attribute. */
179 if (stream_empty (s))
180 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000181 struct peer *from = NULL;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000182
Greg Troxeld3ddb222010-09-17 10:47:49 -0400183 if (binfo)
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000184 from = binfo->peer;
185
186 /* 1: Write the BGP message header - 16 bytes marker, 2 bytes length,
187 * one byte message type.
188 */
paul718e3742002-12-13 20:15:29 +0000189 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000190
191 /* 2: withdrawn routes length */
paul718e3742002-12-13 20:15:29 +0000192 stream_putw (s, 0);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000193
194 /* 3: total attributes length - attrlen_pos stores the position */
195 attrlen_pos = stream_get_endp (s);
196 stream_putw (s, 0);
197
198 /* 4: if there is MP_REACH_NLRI attribute, that should be the first
199 * attribute, according to draft-ietf-idr-error-handling. Save the
200 * position.
201 */
202 mpattr_pos = stream_get_endp(s);
203
204 /* 5: Encode all the attributes, except MP_REACH_NLRI attr. */
205 total_attr_len = bgp_packet_attribute (NULL, peer, s,
paul5228ad22004-06-04 17:58:18 +0000206 adv->baa->attr,
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000207 NULL, afi, safi,
208 from, NULL, NULL);
paul718e3742002-12-13 20:15:29 +0000209 }
210
211 if (afi == AFI_IP && safi == SAFI_UNICAST)
212 stream_put_prefix (s, &rn->p);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000213 else
214 {
215 /* Encode the prefix in MP_REACH_NLRI attribute */
216 struct prefix_rd *prd = NULL;
217 u_char *tag = NULL;
218
219 if (rn->prn)
220 prd = (struct prefix_rd *) &rn->prn->p;
221 if (binfo && binfo->extra)
222 tag = binfo->extra->tag;
223
224 if (stream_empty(snlri))
225 mpattrlen_pos = bgp_packet_mpattr_start(snlri, afi, safi,
226 adv->baa->attr);
227 bgp_packet_mpattr_prefix(snlri, afi, safi, &rn->p, prd, tag);
228 }
paul718e3742002-12-13 20:15:29 +0000229 if (BGP_DEBUG (update, UPDATE_OUT))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000230 {
231 char buf[INET6_BUFSIZ];
232
233 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d",
234 peer->host,
235 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, INET6_BUFSIZ),
236 rn->p.prefixlen);
237 }
paul718e3742002-12-13 20:15:29 +0000238
239 /* Synchnorize attribute. */
240 if (adj->attr)
Paul Jakmaf6f434b2010-11-23 21:28:03 +0000241 bgp_attr_unintern (&adj->attr);
paul718e3742002-12-13 20:15:29 +0000242 else
243 peer->scount[afi][safi]++;
244
245 adj->attr = bgp_attr_intern (adv->baa->attr);
246
247 adv = bgp_advertise_clean (peer, adj, afi, safi);
paul718e3742002-12-13 20:15:29 +0000248 }
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000249
paul718e3742002-12-13 20:15:29 +0000250 if (! stream_empty (s))
251 {
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000252 if (!stream_empty(snlri))
253 {
254 bgp_packet_mpattr_end(snlri, mpattrlen_pos);
255 total_attr_len += stream_get_endp(snlri);
256 }
257
258 /* set the total attribute length correctly */
259 stream_putw_at (s, attrlen_pos, total_attr_len);
260
261 if (!stream_empty(snlri))
262 packet = stream_dupcat(s, snlri, mpattr_pos);
263 else
264 packet = stream_dup (s);
265 bgp_packet_set_size (packet);
paul718e3742002-12-13 20:15:29 +0000266 bgp_packet_add (peer, packet);
pauleb821182004-05-01 08:44:08 +0000267 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000268 stream_reset (s);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000269 stream_reset (snlri);
paul718e3742002-12-13 20:15:29 +0000270 return packet;
271 }
272 return NULL;
hasso93406d82005-02-02 14:40:33 +0000273}
paul718e3742002-12-13 20:15:29 +0000274
paul94f2b392005-06-28 12:44:16 +0000275static struct stream *
hasso93406d82005-02-02 14:40:33 +0000276bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
277{
278 struct stream *s;
hasso93406d82005-02-02 14:40:33 +0000279
Paul Jakma750e8142008-07-22 21:11:48 +0000280 if (DISABLE_BGP_ANNOUNCE)
281 return NULL;
hasso93406d82005-02-02 14:40:33 +0000282
283 if (BGP_DEBUG (normal, NORMAL))
284 zlog_debug ("send End-of-RIB for %s to %s", afi_safi_print (afi, safi), peer->host);
285
286 s = stream_new (BGP_MAX_PACKET_SIZE);
287
288 /* Make BGP update packet. */
289 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
290
291 /* Unfeasible Routes Length */
292 stream_putw (s, 0);
293
294 if (afi == AFI_IP && safi == SAFI_UNICAST)
295 {
296 /* Total Path Attribute Length */
297 stream_putw (s, 0);
298 }
299 else
300 {
301 /* Total Path Attribute Length */
302 stream_putw (s, 6);
303 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
304 stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
305 stream_putc (s, 3);
306 stream_putw (s, afi);
307 stream_putc (s, safi);
308 }
309
310 bgp_packet_set_size (s);
Donald Sharpa752c3b2015-08-18 08:48:53 -0400311 bgp_packet_add (peer, s);
312 return s;
paul718e3742002-12-13 20:15:29 +0000313}
314
315/* Make BGP withdraw packet. */
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000316/* For ipv4 unicast:
317 16-octet marker | 2-octet length | 1-octet type |
318 2-octet withdrawn route length | withdrawn prefixes | 2-octet attrlen (=0)
319*/
320/* For other afi/safis:
321 16-octet marker | 2-octet length | 1-octet type |
322 2-octet withdrawn route length (=0) | 2-octet attrlen |
323 mp_unreach attr type | attr len | afi | safi | withdrawn prefixes
324*/
paul94f2b392005-06-28 12:44:16 +0000325static struct stream *
paul718e3742002-12-13 20:15:29 +0000326bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi)
327{
328 struct stream *s;
329 struct stream *packet;
330 struct bgp_adj_out *adj;
331 struct bgp_advertise *adv;
332 struct bgp_node *rn;
paul718e3742002-12-13 20:15:29 +0000333 bgp_size_t unfeasible_len;
334 bgp_size_t total_attr_len;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000335 size_t mp_start = 0;
336 size_t attrlen_pos = 0;
337 size_t mplen_pos = 0;
338 u_char first_time = 1;
paul718e3742002-12-13 20:15:29 +0000339
340 s = peer->work;
341 stream_reset (s);
342
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100343 while ((adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL)
paul718e3742002-12-13 20:15:29 +0000344 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000345 assert (adv->rn);
paul718e3742002-12-13 20:15:29 +0000346 adj = adv->adj;
347 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000348
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000349 if (STREAM_REMAIN (s)
hasso4372df72004-05-20 10:20:02 +0000350 < (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN + PSIZE (rn->p.prefixlen)))
paul718e3742002-12-13 20:15:29 +0000351 break;
352
353 if (stream_empty (s))
354 {
355 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000356 stream_putw (s, 0); /* unfeasible routes length */
paul718e3742002-12-13 20:15:29 +0000357 }
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000358 else
359 first_time = 0;
paul718e3742002-12-13 20:15:29 +0000360
361 if (afi == AFI_IP && safi == SAFI_UNICAST)
362 stream_put_prefix (s, &rn->p);
363 else
364 {
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000365 struct prefix_rd *prd = NULL;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000366
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000367 if (rn->prn)
368 prd = (struct prefix_rd *) &rn->prn->p;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000369
370 /* If first time, format the MP_UNREACH header */
371 if (first_time)
372 {
373 attrlen_pos = stream_get_endp (s);
374 /* total attr length = 0 for now. reevaluate later */
375 stream_putw (s, 0);
376 mp_start = stream_get_endp (s);
377 mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
378 }
379
380 bgp_packet_mpunreach_prefix(s, &rn->p, afi, safi, prd, NULL);
paul718e3742002-12-13 20:15:29 +0000381 }
382
383 if (BGP_DEBUG (update, UPDATE_OUT))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000384 {
385 char buf[INET6_BUFSIZ];
386
387 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
388 peer->host,
389 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, INET6_BUFSIZ),
390 rn->p.prefixlen);
391 }
paul718e3742002-12-13 20:15:29 +0000392
393 peer->scount[afi][safi]--;
394
395 bgp_adj_out_remove (rn, adj, peer, afi, safi);
396 bgp_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +0000397 }
398
399 if (! stream_empty (s))
400 {
401 if (afi == AFI_IP && safi == SAFI_UNICAST)
402 {
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000403 unfeasible_len
paul9985f832005-02-09 15:51:56 +0000404 = stream_get_endp (s) - BGP_HEADER_SIZE - BGP_UNFEASIBLE_LEN;
paul718e3742002-12-13 20:15:29 +0000405 stream_putw_at (s, BGP_HEADER_SIZE, unfeasible_len);
406 stream_putw (s, 0);
407 }
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000408 else
409 {
410 /* Set the mp_unreach attr's length */
411 bgp_packet_mpunreach_end(s, mplen_pos);
412
413 /* Set total path attribute length. */
414 total_attr_len = stream_get_endp(s) - mp_start;
415 stream_putw_at (s, attrlen_pos, total_attr_len);
416 }
paul718e3742002-12-13 20:15:29 +0000417 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000418 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000419 bgp_packet_add (peer, packet);
420 stream_reset (s);
421 return packet;
422 }
423
424 return NULL;
425}
426
427void
428bgp_default_update_send (struct peer *peer, struct attr *attr,
429 afi_t afi, safi_t safi, struct peer *from)
430{
431 struct stream *s;
paul718e3742002-12-13 20:15:29 +0000432 struct prefix p;
433 unsigned long pos;
434 bgp_size_t total_attr_len;
paul718e3742002-12-13 20:15:29 +0000435
Paul Jakma750e8142008-07-22 21:11:48 +0000436 if (DISABLE_BGP_ANNOUNCE)
437 return;
paul718e3742002-12-13 20:15:29 +0000438
439 if (afi == AFI_IP)
440 str2prefix ("0.0.0.0/0", &p);
441#ifdef HAVE_IPV6
442 else
443 str2prefix ("::/0", &p);
444#endif /* HAVE_IPV6 */
445
446 /* Logging the attribute. */
447 if (BGP_DEBUG (update, UPDATE_OUT))
448 {
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000449 char attrstr[BUFSIZ];
450 char buf[INET6_BUFSIZ];
451 attrstr[0] = '\0';
452
paul718e3742002-12-13 20:15:29 +0000453 bgp_dump_attr (peer, attr, attrstr, BUFSIZ);
ajs6b514742004-12-08 21:03:23 +0000454 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d %s",
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000455 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, INET6_BUFSIZ),
paul718e3742002-12-13 20:15:29 +0000456 p.prefixlen, attrstr);
457 }
458
459 s = stream_new (BGP_MAX_PACKET_SIZE);
460
461 /* Make BGP update packet. */
462 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
463
464 /* Unfeasible Routes Length. */
465 stream_putw (s, 0);
466
467 /* Make place for total attribute length. */
paul9985f832005-02-09 15:51:56 +0000468 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000469 stream_putw (s, 0);
470 total_attr_len = bgp_packet_attribute (NULL, peer, s, attr, &p, afi, safi, from, NULL, NULL);
471
472 /* Set Total Path Attribute Length. */
473 stream_putw_at (s, pos, total_attr_len);
474
475 /* NLRI set. */
476 if (p.family == AF_INET && safi == SAFI_UNICAST)
477 stream_put_prefix (s, &p);
478
479 /* Set size. */
480 bgp_packet_set_size (s);
481
paul718e3742002-12-13 20:15:29 +0000482 /* Dump packet if debug option is set. */
483#ifdef DEBUG
jardin2d74db52005-10-01 00:07:50 +0000484 /* bgp_packet_dump (packet); */
paul718e3742002-12-13 20:15:29 +0000485#endif /* DEBUG */
486
487 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -0400488 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +0000489
pauleb821182004-05-01 08:44:08 +0000490 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000491}
492
493void
494bgp_default_withdraw_send (struct peer *peer, afi_t afi, safi_t safi)
495{
496 struct stream *s;
paul718e3742002-12-13 20:15:29 +0000497 struct prefix p;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000498 unsigned long attrlen_pos = 0;
paul718e3742002-12-13 20:15:29 +0000499 unsigned long cp;
500 bgp_size_t unfeasible_len;
501 bgp_size_t total_attr_len;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000502 size_t mp_start = 0;
503 size_t mplen_pos = 0;
paul718e3742002-12-13 20:15:29 +0000504
Paul Jakma750e8142008-07-22 21:11:48 +0000505 if (DISABLE_BGP_ANNOUNCE)
506 return;
paul718e3742002-12-13 20:15:29 +0000507
508 if (afi == AFI_IP)
509 str2prefix ("0.0.0.0/0", &p);
510#ifdef HAVE_IPV6
511 else
512 str2prefix ("::/0", &p);
513#endif /* HAVE_IPV6 */
514
515 total_attr_len = 0;
paul718e3742002-12-13 20:15:29 +0000516
517 if (BGP_DEBUG (update, UPDATE_OUT))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000518 {
519 char buf[INET6_BUFSIZ];
520
521 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
522 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, INET6_BUFSIZ),
523 p.prefixlen);
524 }
paul718e3742002-12-13 20:15:29 +0000525
526 s = stream_new (BGP_MAX_PACKET_SIZE);
527
528 /* Make BGP update packet. */
529 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
530
531 /* Unfeasible Routes Length. */;
paul9985f832005-02-09 15:51:56 +0000532 cp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000533 stream_putw (s, 0);
534
535 /* Withdrawn Routes. */
536 if (p.family == AF_INET && safi == SAFI_UNICAST)
537 {
538 stream_put_prefix (s, &p);
539
paul9985f832005-02-09 15:51:56 +0000540 unfeasible_len = stream_get_endp (s) - cp - 2;
paul718e3742002-12-13 20:15:29 +0000541
542 /* Set unfeasible len. */
543 stream_putw_at (s, cp, unfeasible_len);
544
545 /* Set total path attribute length. */
546 stream_putw (s, 0);
547 }
548 else
549 {
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000550 attrlen_pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000551 stream_putw (s, 0);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000552 mp_start = stream_get_endp (s);
553 mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
554 bgp_packet_mpunreach_prefix(s, &p, afi, safi, NULL, NULL);
555
556 /* Set the mp_unreach attr's length */
557 bgp_packet_mpunreach_end(s, mplen_pos);
paul718e3742002-12-13 20:15:29 +0000558
559 /* Set total path attribute length. */
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000560 total_attr_len = stream_get_endp(s) - mp_start;
561 stream_putw_at (s, attrlen_pos, total_attr_len);
paul718e3742002-12-13 20:15:29 +0000562 }
563
564 bgp_packet_set_size (s);
565
paul718e3742002-12-13 20:15:29 +0000566 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -0400567 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +0000568
pauleb821182004-05-01 08:44:08 +0000569 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000570}
571
572/* Get next packet to be written. */
paul94f2b392005-06-28 12:44:16 +0000573static struct stream *
paul718e3742002-12-13 20:15:29 +0000574bgp_write_packet (struct peer *peer)
575{
576 afi_t afi;
577 safi_t safi;
578 struct stream *s = NULL;
579 struct bgp_advertise *adv;
580
581 s = stream_fifo_head (peer->obuf);
582 if (s)
583 return s;
584
585 for (afi = AFI_IP; afi < AFI_MAX; afi++)
586 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
587 {
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100588 adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->withdraw);
paul718e3742002-12-13 20:15:29 +0000589 if (adv)
590 {
591 s = bgp_withdraw_packet (peer, afi, safi);
592 if (s)
593 return s;
594 }
595 }
596
597 for (afi = AFI_IP; afi < AFI_MAX; afi++)
598 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
599 {
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100600 adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update);
paul718e3742002-12-13 20:15:29 +0000601 if (adv)
602 {
603 if (adv->binfo && adv->binfo->uptime < peer->synctime)
hasso93406d82005-02-02 14:40:33 +0000604 {
605 if (CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_RCV)
606 && CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_ADV)
Vipin Kumardd49eb12014-09-30 14:36:38 -0700607 && ! (CHECK_FLAG (adv->binfo->peer->cap,
608 PEER_CAP_RESTART_BIT_RCV) &&
609 CHECK_FLAG (adv->binfo->peer->cap,
610 PEER_CAP_RESTART_BIT_ADV))
hasso93406d82005-02-02 14:40:33 +0000611 && ! CHECK_FLAG (adv->binfo->flags, BGP_INFO_STALE)
612 && safi != SAFI_MPLS_VPN)
613 {
614 if (CHECK_FLAG (adv->binfo->peer->af_sflags[afi][safi],
615 PEER_STATUS_EOR_RECEIVED))
616 s = bgp_update_packet (peer, afi, safi);
617 }
618 else
619 s = bgp_update_packet (peer, afi, safi);
620 }
paul718e3742002-12-13 20:15:29 +0000621
622 if (s)
623 return s;
624 }
hasso93406d82005-02-02 14:40:33 +0000625
626 if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV))
627 {
628 if (peer->afc_nego[afi][safi] && peer->synctime
629 && ! CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND)
630 && safi != SAFI_MPLS_VPN)
631 {
632 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND);
633 return bgp_update_packet_eor (peer, afi, safi);
634 }
635 }
paul718e3742002-12-13 20:15:29 +0000636 }
637
638 return NULL;
639}
640
641/* Is there partially written packet or updates we can send right
642 now. */
paul94f2b392005-06-28 12:44:16 +0000643static int
paul718e3742002-12-13 20:15:29 +0000644bgp_write_proceed (struct peer *peer)
645{
646 afi_t afi;
647 safi_t safi;
648 struct bgp_advertise *adv;
649
650 if (stream_fifo_head (peer->obuf))
651 return 1;
652
653 for (afi = AFI_IP; afi < AFI_MAX; afi++)
654 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
655 if (FIFO_HEAD (&peer->sync[afi][safi]->withdraw))
656 return 1;
657
658 for (afi = AFI_IP; afi < AFI_MAX; afi++)
659 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100660 if ((adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update)) != NULL)
paul718e3742002-12-13 20:15:29 +0000661 if (adv->binfo->uptime < peer->synctime)
662 return 1;
663
664 return 0;
665}
666
667/* Write packet to the peer. */
668int
669bgp_write (struct thread *thread)
670{
671 struct peer *peer;
672 u_char type;
673 struct stream *s;
674 int num;
paulfd79ac92004-10-13 05:06:08 +0000675 unsigned int count = 0;
paul718e3742002-12-13 20:15:29 +0000676
677 /* Yes first of all get peer pointer. */
678 peer = THREAD_ARG (thread);
679 peer->t_write = NULL;
680
681 /* For non-blocking IO check. */
682 if (peer->status == Connect)
683 {
684 bgp_connect_check (peer);
685 return 0;
686 }
687
Stephen Hemmingereac57022010-08-05 10:26:25 -0700688 s = bgp_write_packet (peer);
689 if (!s)
690 return 0; /* nothing to send */
691
692 sockopt_cork (peer->fd, 1);
693
694 /* Nonblocking write until TCP output buffer is full. */
695 do
paul718e3742002-12-13 20:15:29 +0000696 {
697 int writenum;
paul718e3742002-12-13 20:15:29 +0000698
699 /* Number of bytes to be sent. */
700 writenum = stream_get_endp (s) - stream_get_getp (s);
701
702 /* Call write() system call. */
pauleb821182004-05-01 08:44:08 +0000703 num = write (peer->fd, STREAM_PNT (s), writenum);
Stephen Hemminger35398582010-08-05 10:26:23 -0700704 if (num < 0)
paul718e3742002-12-13 20:15:29 +0000705 {
Stephen Hemmingereac57022010-08-05 10:26:25 -0700706 /* write failed either retry needed or error */
707 if (ERRNO_IO_RETRY(errno))
708 break;
709
710 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000711 return 0;
712 }
Stephen Hemminger35398582010-08-05 10:26:23 -0700713
paul718e3742002-12-13 20:15:29 +0000714 if (num != writenum)
715 {
Stephen Hemminger35398582010-08-05 10:26:23 -0700716 /* Partial write */
paul9985f832005-02-09 15:51:56 +0000717 stream_forward_getp (s, num);
Stephen Hemmingereac57022010-08-05 10:26:25 -0700718 break;
paul718e3742002-12-13 20:15:29 +0000719 }
720
721 /* Retrieve BGP packet type. */
722 stream_set_getp (s, BGP_MARKER_SIZE + 2);
723 type = stream_getc (s);
724
725 switch (type)
726 {
727 case BGP_MSG_OPEN:
728 peer->open_out++;
729 break;
730 case BGP_MSG_UPDATE:
731 peer->update_out++;
732 break;
733 case BGP_MSG_NOTIFY:
734 peer->notify_out++;
735 /* Double start timer. */
736 peer->v_start *= 2;
737
738 /* Overflow check. */
739 if (peer->v_start >= (60 * 2))
740 peer->v_start = (60 * 2);
741
Paul Jakmaca058a32006-09-14 02:58:49 +0000742 /* Flush any existing events */
Paul Jakmadcdf3992006-10-15 23:39:59 +0000743 BGP_EVENT_ADD (peer, BGP_Stop);
Stephen Hemminger3a69f742013-01-11 18:27:23 +0000744 goto done;
745
paul718e3742002-12-13 20:15:29 +0000746 case BGP_MSG_KEEPALIVE:
747 peer->keepalive_out++;
748 break;
749 case BGP_MSG_ROUTE_REFRESH_NEW:
750 case BGP_MSG_ROUTE_REFRESH_OLD:
751 peer->refresh_out++;
752 break;
753 case BGP_MSG_CAPABILITY:
754 peer->dynamic_cap_out++;
755 break;
756 }
757
758 /* OK we send packet so delete it. */
759 bgp_packet_delete (peer);
paul718e3742002-12-13 20:15:29 +0000760 }
Stephen Hemmingereac57022010-08-05 10:26:25 -0700761 while (++count < BGP_WRITE_PACKET_MAX &&
762 (s = bgp_write_packet (peer)) != NULL);
paul718e3742002-12-13 20:15:29 +0000763
764 if (bgp_write_proceed (peer))
pauleb821182004-05-01 08:44:08 +0000765 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
Stephen Hemminger3a69f742013-01-11 18:27:23 +0000766
767 done:
768 sockopt_cork (peer->fd, 0);
paul718e3742002-12-13 20:15:29 +0000769 return 0;
770}
771
772/* This is only for sending NOTIFICATION message to neighbor. */
paul94f2b392005-06-28 12:44:16 +0000773static int
paul718e3742002-12-13 20:15:29 +0000774bgp_write_notify (struct peer *peer)
775{
Stephen Hemminger35398582010-08-05 10:26:23 -0700776 int ret, val;
paul718e3742002-12-13 20:15:29 +0000777 u_char type;
778 struct stream *s;
779
780 /* There should be at least one packet. */
781 s = stream_fifo_head (peer->obuf);
782 if (!s)
783 return 0;
784 assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
785
Leonid Rosenboim86998bc2012-12-14 19:12:17 +0000786 /* Stop collecting data within the socket */
787 sockopt_cork (peer->fd, 0);
788
David Lamparter8ff202e2013-07-31 14:39:41 +0200789 /* socket is in nonblocking mode, if we can't deliver the NOTIFY, well,
790 * we only care about getting a clean shutdown at this point. */
Leonid Rosenboim86998bc2012-12-14 19:12:17 +0000791 ret = write (peer->fd, STREAM_DATA (s), stream_get_endp (s));
David Lamparter8ff202e2013-07-31 14:39:41 +0200792
793 /* only connection reset/close gets counted as TCP_fatal_error, failure
794 * to write the entire NOTIFY doesn't get different FSM treatment */
paul718e3742002-12-13 20:15:29 +0000795 if (ret <= 0)
796 {
Paul Jakmadcdf3992006-10-15 23:39:59 +0000797 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000798 return 0;
799 }
800
Leonid Rosenboim86998bc2012-12-14 19:12:17 +0000801 /* Disable Nagle, make NOTIFY packet go out right away */
802 val = 1;
803 (void) setsockopt (peer->fd, IPPROTO_TCP, TCP_NODELAY,
804 (char *) &val, sizeof (val));
805
paul718e3742002-12-13 20:15:29 +0000806 /* Retrieve BGP packet type. */
807 stream_set_getp (s, BGP_MARKER_SIZE + 2);
808 type = stream_getc (s);
809
810 assert (type == BGP_MSG_NOTIFY);
811
812 /* Type should be notify. */
813 peer->notify_out++;
814
815 /* Double start timer. */
816 peer->v_start *= 2;
817
818 /* Overflow check. */
819 if (peer->v_start >= (60 * 2))
820 peer->v_start = (60 * 2);
821
Paul Jakmadcdf3992006-10-15 23:39:59 +0000822 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000823
824 return 0;
825}
826
827/* Make keepalive packet and send it to the peer. */
828void
829bgp_keepalive_send (struct peer *peer)
830{
831 struct stream *s;
832 int length;
833
834 s = stream_new (BGP_MAX_PACKET_SIZE);
835
836 /* Make keepalive packet. */
837 bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
838
839 /* Set packet size. */
840 length = bgp_packet_set_size (s);
841
842 /* Dump packet if debug option is set. */
843 /* bgp_packet_dump (s); */
844
845 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +0000846 zlog_debug ("%s sending KEEPALIVE", peer->host);
paul718e3742002-12-13 20:15:29 +0000847 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000848 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000849 peer->host, BGP_MSG_KEEPALIVE, length);
850
851 /* Add packet to the peer. */
852 bgp_packet_add (peer, s);
853
pauleb821182004-05-01 08:44:08 +0000854 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000855}
856
857/* Make open packet and send it to the peer. */
858void
859bgp_open_send (struct peer *peer)
860{
861 struct stream *s;
862 int length;
863 u_int16_t send_holdtime;
864 as_t local_as;
865
866 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
867 send_holdtime = peer->holdtime;
868 else
869 send_holdtime = peer->bgp->default_holdtime;
870
871 /* local-as Change */
872 if (peer->change_local_as)
873 local_as = peer->change_local_as;
874 else
875 local_as = peer->local_as;
876
877 s = stream_new (BGP_MAX_PACKET_SIZE);
878
879 /* Make open packet. */
880 bgp_packet_set_marker (s, BGP_MSG_OPEN);
881
882 /* Set open packet values. */
883 stream_putc (s, BGP_VERSION_4); /* BGP version */
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000884 stream_putw (s, (local_as <= BGP_AS_MAX) ? (u_int16_t) local_as
885 : BGP_AS_TRANS);
paul718e3742002-12-13 20:15:29 +0000886 stream_putw (s, send_holdtime); /* Hold Time */
887 stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
888
889 /* Set capability code. */
890 bgp_open_capability (s, peer);
891
892 /* Set BGP packet length. */
893 length = bgp_packet_set_size (s);
894
895 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400896 zlog_debug ("%s sending OPEN, version %d, my as %u, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +0000897 peer->host, BGP_VERSION_4, local_as,
898 send_holdtime, inet_ntoa (peer->local_id));
899
900 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000901 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000902 peer->host, BGP_MSG_OPEN, length);
903
904 /* Dump packet if debug option is set. */
905 /* bgp_packet_dump (s); */
906
907 /* Add packet to the peer. */
908 bgp_packet_add (peer, s);
909
pauleb821182004-05-01 08:44:08 +0000910 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000911}
912
913/* Send BGP notify packet with data potion. */
914void
915bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
916 u_char *data, size_t datalen)
917{
918 struct stream *s;
919 int length;
920
921 /* Allocate new stream. */
922 s = stream_new (BGP_MAX_PACKET_SIZE);
923
924 /* Make nitify packet. */
925 bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
926
927 /* Set notify packet values. */
928 stream_putc (s, code); /* BGP notify code */
929 stream_putc (s, sub_code); /* BGP notify sub_code */
930
931 /* If notify data is present. */
932 if (data)
933 stream_write (s, data, datalen);
934
935 /* Set BGP packet length. */
936 length = bgp_packet_set_size (s);
937
938 /* Add packet to the peer. */
939 stream_fifo_clean (peer->obuf);
940 bgp_packet_add (peer, s);
941
942 /* For debug */
943 {
944 struct bgp_notify bgp_notify;
945 int first = 0;
946 int i;
947 char c[4];
948
949 bgp_notify.code = code;
950 bgp_notify.subcode = sub_code;
951 bgp_notify.data = NULL;
952 bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
953
954 if (bgp_notify.length)
955 {
956 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
957 for (i = 0; i < bgp_notify.length; i++)
958 if (first)
959 {
960 sprintf (c, " %02x", data[i]);
961 strcat (bgp_notify.data, c);
962 }
963 else
964 {
965 first = 1;
966 sprintf (c, "%02x", data[i]);
967 strcpy (bgp_notify.data, c);
968 }
969 }
970 bgp_notify_print (peer, &bgp_notify, "sending");
Daniel Walton363c9032015-10-21 06:42:54 -0700971
paul718e3742002-12-13 20:15:29 +0000972 if (bgp_notify.data)
Daniel Walton363c9032015-10-21 06:42:54 -0700973 {
974 XFREE (MTYPE_TMP, bgp_notify.data);
975 bgp_notify.data = NULL;
976 bgp_notify.length = 0;
977 }
paul718e3742002-12-13 20:15:29 +0000978 }
979
980 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000981 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000982 peer->host, BGP_MSG_NOTIFY, length);
983
hassoe0701b72004-05-20 09:19:34 +0000984 /* peer reset cause */
985 if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
986 {
987 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
heasley1212dc12011-09-12 13:27:52 +0400988 {
989 peer->last_reset = PEER_DOWN_USER_RESET;
990 zlog_info ("Notification sent to neighbor %s: User reset", peer->host);
991 }
hassoe0701b72004-05-20 09:19:34 +0000992 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
heasley1212dc12011-09-12 13:27:52 +0400993 {
994 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
995 zlog_info ("Notification sent to neighbor %s: shutdown", peer->host);
996 }
hassoe0701b72004-05-20 09:19:34 +0000997 else
heasley1212dc12011-09-12 13:27:52 +0400998 {
999 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
1000 zlog_info ("Notification sent to neighbor %s: type %u/%u",
1001 peer->host, code, sub_code);
1002 }
hassoe0701b72004-05-20 09:19:34 +00001003 }
heasley1212dc12011-09-12 13:27:52 +04001004 else
1005 zlog_info ("Notification sent to neighbor %s: configuration change",
1006 peer->host);
hassoe0701b72004-05-20 09:19:34 +00001007
Denis Ovsienko7ccf5e52011-09-10 16:53:30 +04001008 /* Call immediately. */
paul718e3742002-12-13 20:15:29 +00001009 BGP_WRITE_OFF (peer->t_write);
1010
1011 bgp_write_notify (peer);
1012}
1013
1014/* Send BGP notify packet. */
1015void
1016bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
1017{
1018 bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
1019}
1020
paul718e3742002-12-13 20:15:29 +00001021/* Send route refresh message to the peer. */
1022void
1023bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
1024 u_char orf_type, u_char when_to_refresh, int remove)
1025{
1026 struct stream *s;
paul718e3742002-12-13 20:15:29 +00001027 int length;
1028 struct bgp_filter *filter;
1029 int orf_refresh = 0;
1030
Paul Jakma750e8142008-07-22 21:11:48 +00001031 if (DISABLE_BGP_ANNOUNCE)
1032 return;
paul718e3742002-12-13 20:15:29 +00001033
1034 filter = &peer->filter[afi][safi];
1035
1036 /* Adjust safi code. */
1037 if (safi == SAFI_MPLS_VPN)
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001038 safi = SAFI_MPLS_LABELED_VPN;
paul718e3742002-12-13 20:15:29 +00001039
1040 s = stream_new (BGP_MAX_PACKET_SIZE);
1041
1042 /* Make BGP update packet. */
1043 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
1044 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
1045 else
1046 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
1047
1048 /* Encode Route Refresh message. */
1049 stream_putw (s, afi);
1050 stream_putc (s, 0);
1051 stream_putc (s, safi);
1052
1053 if (orf_type == ORF_TYPE_PREFIX
1054 || orf_type == ORF_TYPE_PREFIX_OLD)
1055 if (remove || filter->plist[FILTER_IN].plist)
1056 {
1057 u_int16_t orf_len;
1058 unsigned long orfp;
1059
1060 orf_refresh = 1;
1061 stream_putc (s, when_to_refresh);
1062 stream_putc (s, orf_type);
paul9985f832005-02-09 15:51:56 +00001063 orfp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00001064 stream_putw (s, 0);
1065
1066 if (remove)
1067 {
1068 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1069 stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
1070 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001071 zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001072 peer->host, orf_type,
1073 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1074 afi, safi);
1075 }
1076 else
1077 {
1078 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1079 prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
1080 ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
1081 ORF_COMMON_PART_DENY);
1082 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001083 zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001084 peer->host, orf_type,
1085 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1086 afi, safi);
1087 }
1088
1089 /* Total ORF Entry Len. */
paul9985f832005-02-09 15:51:56 +00001090 orf_len = stream_get_endp (s) - orfp - 2;
paul718e3742002-12-13 20:15:29 +00001091 stream_putw_at (s, orfp, orf_len);
1092 }
1093
1094 /* Set packet size. */
1095 length = bgp_packet_set_size (s);
1096
1097 if (BGP_DEBUG (normal, NORMAL))
1098 {
1099 if (! orf_refresh)
ajs6b514742004-12-08 21:03:23 +00001100 zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001101 peer->host, afi, safi);
ajs6b514742004-12-08 21:03:23 +00001102 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001103 peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
1104 BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
1105 }
1106
paul718e3742002-12-13 20:15:29 +00001107 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -04001108 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +00001109
pauleb821182004-05-01 08:44:08 +00001110 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001111}
1112
1113/* Send capability message to the peer. */
1114void
1115bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
1116 int capability_code, int action)
1117{
1118 struct stream *s;
paul718e3742002-12-13 20:15:29 +00001119 int length;
1120
1121 /* Adjust safi code. */
1122 if (safi == SAFI_MPLS_VPN)
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001123 safi = SAFI_MPLS_LABELED_VPN;
paul718e3742002-12-13 20:15:29 +00001124
1125 s = stream_new (BGP_MAX_PACKET_SIZE);
1126
1127 /* Make BGP update packet. */
1128 bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
1129
1130 /* Encode MP_EXT capability. */
1131 if (capability_code == CAPABILITY_CODE_MP)
1132 {
1133 stream_putc (s, action);
1134 stream_putc (s, CAPABILITY_CODE_MP);
1135 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1136 stream_putw (s, afi);
1137 stream_putc (s, 0);
1138 stream_putc (s, safi);
1139
1140 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001141 zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001142 peer->host, action == CAPABILITY_ACTION_SET ?
1143 "Advertising" : "Removing", afi, safi);
1144 }
1145
paul718e3742002-12-13 20:15:29 +00001146 /* Set packet size. */
1147 length = bgp_packet_set_size (s);
1148
paul718e3742002-12-13 20:15:29 +00001149
1150 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -04001151 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +00001152
1153 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001154 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001155 peer->host, BGP_MSG_CAPABILITY, length);
1156
pauleb821182004-05-01 08:44:08 +00001157 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001158}
David Lamparter6b0655a2014-06-04 06:53:35 +02001159
paul718e3742002-12-13 20:15:29 +00001160/* RFC1771 6.8 Connection collision detection. */
paul94f2b392005-06-28 12:44:16 +00001161static int
pauleb821182004-05-01 08:44:08 +00001162bgp_collision_detect (struct peer *new, struct in_addr remote_id)
paul718e3742002-12-13 20:15:29 +00001163{
pauleb821182004-05-01 08:44:08 +00001164 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +00001165 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001166 struct bgp *bgp;
1167
1168 bgp = bgp_get_default ();
1169 if (! bgp)
1170 return 0;
1171
1172 /* Upon receipt of an OPEN message, the local system must examine
1173 all of its connections that are in the OpenConfirm state. A BGP
1174 speaker may also examine connections in an OpenSent state if it
1175 knows the BGP Identifier of the peer by means outside of the
1176 protocol. If among these connections there is a connection to a
1177 remote BGP speaker whose BGP Identifier equals the one in the
1178 OPEN message, then the local system performs the following
1179 collision resolution procedure: */
1180
paul1eb8ef22005-04-07 07:30:20 +00001181 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00001182 {
1183 /* Under OpenConfirm status, local peer structure already hold
1184 remote router ID. */
pauleb821182004-05-01 08:44:08 +00001185
1186 if (peer != new
1187 && (peer->status == OpenConfirm || peer->status == OpenSent)
1188 && sockunion_same (&peer->su, &new->su))
1189 {
paul718e3742002-12-13 20:15:29 +00001190 /* 1. The BGP Identifier of the local system is compared to
1191 the BGP Identifier of the remote system (as specified in
1192 the OPEN message). */
1193
1194 if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
1195 {
1196 /* 2. If the value of the local BGP Identifier is less
1197 than the remote one, the local system closes BGP
1198 connection that already exists (the one that is
1199 already in the OpenConfirm state), and accepts BGP
1200 connection initiated by the remote system. */
1201
pauleb821182004-05-01 08:44:08 +00001202 if (peer->fd >= 0)
hassoe0701b72004-05-20 09:19:34 +00001203 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001204 return 1;
1205 }
1206 else
1207 {
1208 /* 3. Otherwise, the local system closes newly created
1209 BGP connection (the one associated with the newly
1210 received OPEN message), and continues to use the
1211 existing one (the one that is already in the
1212 OpenConfirm state). */
1213
pauleb821182004-05-01 08:44:08 +00001214 if (new->fd >= 0)
paulf5ba3872004-07-09 12:11:31 +00001215 bgp_notify_send (new, BGP_NOTIFY_CEASE,
1216 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001217 return -1;
1218 }
pauleb821182004-05-01 08:44:08 +00001219 }
1220 }
paul718e3742002-12-13 20:15:29 +00001221 return 0;
1222}
1223
paul94f2b392005-06-28 12:44:16 +00001224static int
paul718e3742002-12-13 20:15:29 +00001225bgp_open_receive (struct peer *peer, bgp_size_t size)
1226{
1227 int ret;
1228 u_char version;
1229 u_char optlen;
1230 u_int16_t holdtime;
1231 u_int16_t send_holdtime;
1232 as_t remote_as;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001233 as_t as4 = 0;
paul718e3742002-12-13 20:15:29 +00001234 struct peer *realpeer;
1235 struct in_addr remote_id;
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001236 int mp_capability;
paul5228ad22004-06-04 17:58:18 +00001237 u_int8_t notify_data_remote_as[2];
1238 u_int8_t notify_data_remote_id[4];
paul718e3742002-12-13 20:15:29 +00001239
1240 realpeer = NULL;
1241
1242 /* Parse open packet. */
1243 version = stream_getc (peer->ibuf);
1244 memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1245 remote_as = stream_getw (peer->ibuf);
1246 holdtime = stream_getw (peer->ibuf);
1247 memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1248 remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1249
1250 /* Receive OPEN message log */
1251 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001252 zlog_debug ("%s rcv OPEN, version %d, remote-as (in open) %u,"
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001253 " holdtime %d, id %s",
1254 peer->host, version, remote_as, holdtime,
1255 inet_ntoa (remote_id));
1256
1257 /* BEGIN to read the capability here, but dont do it yet */
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001258 mp_capability = 0;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001259 optlen = stream_getc (peer->ibuf);
1260
1261 if (optlen != 0)
1262 {
1263 /* We need the as4 capability value *right now* because
1264 * if it is there, we have not got the remote_as yet, and without
1265 * that we do not know which peer is connecting to us now.
1266 */
1267 as4 = peek_for_as4_capability (peer, optlen);
1268 }
1269
1270 /* Just in case we have a silly peer who sends AS4 capability set to 0 */
1271 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) && !as4)
1272 {
1273 zlog_err ("%s bad OPEN, got AS4 capability, but AS4 set to 0",
1274 peer->host);
1275 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1276 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1277 return -1;
1278 }
1279
1280 if (remote_as == BGP_AS_TRANS)
1281 {
1282 /* Take the AS4 from the capability. We must have received the
1283 * capability now! Otherwise we have a asn16 peer who uses
1284 * BGP_AS_TRANS, for some unknown reason.
1285 */
1286 if (as4 == BGP_AS_TRANS)
1287 {
1288 zlog_err ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
1289 peer->host);
1290 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1291 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1292 return -1;
1293 }
1294
1295 if (!as4 && BGP_DEBUG (as4, AS4))
1296 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
1297 " Odd, but proceeding.", peer->host);
1298 else if (as4 < BGP_AS_MAX && BGP_DEBUG (as4, AS4))
Paul Jakma0df7c912008-07-21 21:02:49 +00001299 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits "
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001300 "in 2-bytes, very odd peer.", peer->host, as4);
1301 if (as4)
1302 remote_as = as4;
1303 }
1304 else
1305 {
1306 /* We may have a partner with AS4 who has an asno < BGP_AS_MAX */
1307 /* If we have got the capability, peer->as4cap must match remote_as */
1308 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)
1309 && as4 != remote_as)
1310 {
1311 /* raise error, log this, close session */
1312 zlog_err ("%s bad OPEN, got AS4 capability, but remote_as %u"
1313 " mismatch with 16bit 'myasn' %u in open",
1314 peer->host, as4, remote_as);
1315 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1316 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1317 return -1;
1318 }
1319 }
1320
paul718e3742002-12-13 20:15:29 +00001321 /* Lookup peer from Open packet. */
1322 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1323 {
1324 int as = 0;
1325
1326 realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1327
1328 if (! realpeer)
1329 {
1330 /* Peer's source IP address is check in bgp_accept(), so this
1331 must be AS number mismatch or remote-id configuration
1332 mismatch. */
1333 if (as)
1334 {
1335 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001336 zlog_debug ("%s bad OPEN, wrong router identifier %s",
1337 peer->host, inet_ntoa (remote_id));
1338 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1339 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1340 notify_data_remote_id, 4);
paul718e3742002-12-13 20:15:29 +00001341 }
1342 else
1343 {
1344 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001345 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
ajs6b514742004-12-08 21:03:23 +00001346 peer->host, remote_as, peer->as);
1347 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1348 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1349 notify_data_remote_as, 2);
paul718e3742002-12-13 20:15:29 +00001350 }
1351 return -1;
1352 }
1353 }
1354
1355 /* When collision is detected and this peer is closed. Retrun
1356 immidiately. */
1357 ret = bgp_collision_detect (peer, remote_id);
1358 if (ret < 0)
1359 return ret;
1360
pauleb821182004-05-01 08:44:08 +00001361 /* Hack part. */
1362 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1363 {
hasso93406d82005-02-02 14:40:33 +00001364 if (realpeer->status == Established
1365 && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1366 {
1367 realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1368 SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1369 }
1370 else if (ret == 0 && realpeer->status != Active
1371 && realpeer->status != OpenSent
Paul Jakma6e199262008-09-09 17:14:33 +01001372 && realpeer->status != OpenConfirm
1373 && realpeer->status != Connect)
pauleb821182004-05-01 08:44:08 +00001374 {
Paul Jakma2b2fc562008-09-06 13:09:35 +01001375 /* XXX: This is an awful problem..
1376 *
1377 * According to the RFC we should just let this connection (of the
1378 * accepted 'peer') continue on to Established if the other
1379 * connection (the 'realpeer' one) is in state Connect, and deal
1380 * with the more larval FSM as/when it gets far enough to receive
1381 * an Open. We don't do that though, we instead close the (more
1382 * developed) accepted connection.
1383 *
1384 * This means there's a race, which if hit, can loop:
1385 *
1386 * FSM for A FSM for B
1387 * realpeer accept-peer realpeer accept-peer
1388 *
1389 * Connect Connect
1390 * Active
1391 * OpenSent OpenSent
1392 * <arrive here,
1393 * Notify, delete>
1394 * Idle Active
1395 * OpenSent OpenSent
1396 * <arrive here,
1397 * Notify, delete>
1398 * Idle
1399 * <wait> <wait>
1400 * Connect Connect
1401 *
1402 *
1403 * If both sides are Quagga, they're almost certain to wait for
1404 * the same amount of time of course (which doesn't preclude other
1405 * implementations also waiting for same time). The race is
1406 * exacerbated by high-latency (in bgpd and/or the network).
1407 *
1408 * The reason we do this is because our FSM is tied to our peer
1409 * structure, which carries our configuration information, etc.
1410 * I.e. we can't let the accepted-peer FSM continue on as it is,
1411 * cause it's not associated with any actual peer configuration -
1412 * it's just a dummy.
1413 *
1414 * It's possible we could hack-fix this by just bgp_stop'ing the
1415 * realpeer and continueing on with the 'transfer FSM' below.
1416 * Ideally, we need to seperate FSMs from struct peer.
1417 *
1418 * Setting one side to passive avoids the race, as a workaround.
1419 */
pauleb821182004-05-01 08:44:08 +00001420 if (BGP_DEBUG (events, EVENTS))
hasso93406d82005-02-02 14:40:33 +00001421 zlog_debug ("%s peer status is %s close connection",
1422 realpeer->host, LOOKUP (bgp_status_msg,
1423 realpeer->status));
1424 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1425 BGP_NOTIFY_CEASE_CONNECT_REJECT);
1426
pauleb821182004-05-01 08:44:08 +00001427 return -1;
1428 }
1429
1430 if (BGP_DEBUG (events, EVENTS))
Paul Jakma6e199262008-09-09 17:14:33 +01001431 zlog_debug ("%s [Event] Transfer accept BGP peer to real (state %s)",
1432 peer->host,
1433 LOOKUP (bgp_status_msg, realpeer->status));
pauleb821182004-05-01 08:44:08 +00001434
1435 bgp_stop (realpeer);
1436
1437 /* Transfer file descriptor. */
1438 realpeer->fd = peer->fd;
1439 peer->fd = -1;
1440
1441 /* Transfer input buffer. */
1442 stream_free (realpeer->ibuf);
1443 realpeer->ibuf = peer->ibuf;
1444 realpeer->packet_size = peer->packet_size;
1445 peer->ibuf = NULL;
1446
1447 /* Transfer status. */
1448 realpeer->status = peer->status;
1449 bgp_stop (peer);
paul200df112005-06-01 11:17:05 +00001450
pauleb821182004-05-01 08:44:08 +00001451 /* peer pointer change. Open packet send to neighbor. */
1452 peer = realpeer;
1453 bgp_open_send (peer);
1454 if (peer->fd < 0)
1455 {
1456 zlog_err ("bgp_open_receive peer's fd is negative value %d",
1457 peer->fd);
1458 return -1;
1459 }
1460 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1461 }
1462
paul718e3742002-12-13 20:15:29 +00001463 /* remote router-id check. */
1464 if (remote_id.s_addr == 0
Denis Ovsienko733cd9e2011-12-17 19:39:30 +04001465 || IPV4_CLASS_DE (ntohl (remote_id.s_addr))
paul718e3742002-12-13 20:15:29 +00001466 || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1467 {
1468 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001469 zlog_debug ("%s bad OPEN, wrong router identifier %s",
paul718e3742002-12-13 20:15:29 +00001470 peer->host, inet_ntoa (remote_id));
1471 bgp_notify_send_with_data (peer,
1472 BGP_NOTIFY_OPEN_ERR,
1473 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1474 notify_data_remote_id, 4);
1475 return -1;
1476 }
1477
1478 /* Set remote router-id */
1479 peer->remote_id = remote_id;
1480
1481 /* Peer BGP version check. */
1482 if (version != BGP_VERSION_4)
1483 {
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001484 u_int16_t maxver = htons(BGP_VERSION_4);
1485 /* XXX this reply may not be correct if version < 4 XXX */
paul718e3742002-12-13 20:15:29 +00001486 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001487 zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
paul718e3742002-12-13 20:15:29 +00001488 peer->host, version, BGP_VERSION_4);
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001489 /* Data must be in network byte order here */
paul718e3742002-12-13 20:15:29 +00001490 bgp_notify_send_with_data (peer,
1491 BGP_NOTIFY_OPEN_ERR,
1492 BGP_NOTIFY_OPEN_UNSUP_VERSION,
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001493 (u_int8_t *) &maxver, 2);
paul718e3742002-12-13 20:15:29 +00001494 return -1;
1495 }
1496
1497 /* Check neighbor as number. */
1498 if (remote_as != peer->as)
1499 {
1500 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001501 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
paul718e3742002-12-13 20:15:29 +00001502 peer->host, remote_as, peer->as);
1503 bgp_notify_send_with_data (peer,
1504 BGP_NOTIFY_OPEN_ERR,
1505 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1506 notify_data_remote_as, 2);
1507 return -1;
1508 }
1509
1510 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1511 calculate the value of the Hold Timer by using the smaller of its
1512 configured Hold Time and the Hold Time received in the OPEN message.
1513 The Hold Time MUST be either zero or at least three seconds. An
1514 implementation may reject connections on the basis of the Hold Time. */
1515
1516 if (holdtime < 3 && holdtime != 0)
1517 {
1518 bgp_notify_send (peer,
1519 BGP_NOTIFY_OPEN_ERR,
1520 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
1521 return -1;
1522 }
1523
1524 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1525 would be one third of the Hold Time interval. KEEPALIVE messages
1526 MUST NOT be sent more frequently than one per second. An
1527 implementation MAY adjust the rate at which it sends KEEPALIVE
1528 messages as a function of the Hold Time interval. */
1529
1530 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1531 send_holdtime = peer->holdtime;
1532 else
1533 send_holdtime = peer->bgp->default_holdtime;
1534
1535 if (holdtime < send_holdtime)
1536 peer->v_holdtime = holdtime;
1537 else
1538 peer->v_holdtime = send_holdtime;
1539
1540 peer->v_keepalive = peer->v_holdtime / 3;
1541
1542 /* Open option part parse. */
paul718e3742002-12-13 20:15:29 +00001543 if (optlen != 0)
1544 {
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001545 if ((ret = bgp_open_option_parse (peer, optlen, &mp_capability)) < 0)
Paul Jakma58617392012-01-09 20:59:26 +00001546 {
1547 bgp_notify_send (peer,
1548 BGP_NOTIFY_OPEN_ERR,
Paul Jakma68ec4242015-11-25 17:14:34 +00001549 BGP_NOTIFY_OPEN_UNSPECIFIC);
Paul Jakma58617392012-01-09 20:59:26 +00001550 return ret;
1551 }
paul718e3742002-12-13 20:15:29 +00001552 }
1553 else
1554 {
1555 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001556 zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
paul718e3742002-12-13 20:15:29 +00001557 peer->host);
1558 }
1559
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001560 /*
1561 * Assume that the peer supports the locally configured set of
1562 * AFI/SAFIs if the peer did not send us any Mulitiprotocol
1563 * capabilities, or if 'override-capability' is configured.
1564 */
1565 if (! mp_capability ||
1566 CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
paul718e3742002-12-13 20:15:29 +00001567 {
1568 peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1569 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1570 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1571 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1572 }
1573
1574 /* Get sockname. */
1575 bgp_getsockname (peer);
Timo Teräs0edba8b2015-10-22 11:35:17 +03001576 peer->rtt = sockopt_tcp_rtt (peer->fd);
paul718e3742002-12-13 20:15:29 +00001577
1578 BGP_EVENT_ADD (peer, Receive_OPEN_message);
1579
1580 peer->packet_size = 0;
1581 if (peer->ibuf)
1582 stream_reset (peer->ibuf);
1583
1584 return 0;
1585}
1586
1587/* Parse BGP Update packet and make attribute object. */
paul94f2b392005-06-28 12:44:16 +00001588static int
paul718e3742002-12-13 20:15:29 +00001589bgp_update_receive (struct peer *peer, bgp_size_t size)
1590{
1591 int ret;
1592 u_char *end;
1593 struct stream *s;
1594 struct attr attr;
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001595 struct attr_extra extra;
paul718e3742002-12-13 20:15:29 +00001596 bgp_size_t attribute_len;
1597 bgp_size_t update_len;
1598 bgp_size_t withdraw_len;
1599 struct bgp_nlri update;
1600 struct bgp_nlri withdraw;
1601 struct bgp_nlri mp_update;
1602 struct bgp_nlri mp_withdraw;
paul718e3742002-12-13 20:15:29 +00001603
1604 /* Status must be Established. */
1605 if (peer->status != Established)
1606 {
1607 zlog_err ("%s [FSM] Update packet received under status %s",
1608 peer->host, LOOKUP (bgp_status_msg, peer->status));
1609 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1610 return -1;
1611 }
1612
1613 /* Set initial values. */
1614 memset (&attr, 0, sizeof (struct attr));
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001615 memset (&extra, 0, sizeof (struct attr_extra));
paul718e3742002-12-13 20:15:29 +00001616 memset (&update, 0, sizeof (struct bgp_nlri));
1617 memset (&withdraw, 0, sizeof (struct bgp_nlri));
1618 memset (&mp_update, 0, sizeof (struct bgp_nlri));
1619 memset (&mp_withdraw, 0, sizeof (struct bgp_nlri));
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001620 attr.extra = &extra;
paul718e3742002-12-13 20:15:29 +00001621
1622 s = peer->ibuf;
1623 end = stream_pnt (s) + size;
1624
1625 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1626 Length is too large (i.e., if Unfeasible Routes Length + Total
1627 Attribute Length + 23 exceeds the message Length), then the Error
1628 Subcode is set to Malformed Attribute List. */
1629 if (stream_pnt (s) + 2 > end)
1630 {
1631 zlog_err ("%s [Error] Update packet error"
1632 " (packet length is short for unfeasible length)",
1633 peer->host);
1634 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1635 BGP_NOTIFY_UPDATE_MAL_ATTR);
1636 return -1;
1637 }
1638
1639 /* Unfeasible Route Length. */
1640 withdraw_len = stream_getw (s);
1641
1642 /* Unfeasible Route Length check. */
1643 if (stream_pnt (s) + withdraw_len > end)
1644 {
1645 zlog_err ("%s [Error] Update packet error"
1646 " (packet unfeasible length overflow %d)",
1647 peer->host, withdraw_len);
1648 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1649 BGP_NOTIFY_UPDATE_MAL_ATTR);
1650 return -1;
1651 }
1652
1653 /* Unfeasible Route packet format check. */
1654 if (withdraw_len > 0)
1655 {
1656 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), withdraw_len);
1657 if (ret < 0)
1658 return -1;
1659
1660 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001661 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001662
1663 withdraw.afi = AFI_IP;
1664 withdraw.safi = SAFI_UNICAST;
1665 withdraw.nlri = stream_pnt (s);
1666 withdraw.length = withdraw_len;
paul9985f832005-02-09 15:51:56 +00001667 stream_forward_getp (s, withdraw_len);
paul718e3742002-12-13 20:15:29 +00001668 }
1669
1670 /* Attribute total length check. */
1671 if (stream_pnt (s) + 2 > end)
1672 {
1673 zlog_warn ("%s [Error] Packet Error"
1674 " (update packet is short for attribute length)",
1675 peer->host);
1676 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1677 BGP_NOTIFY_UPDATE_MAL_ATTR);
1678 return -1;
1679 }
1680
1681 /* Fetch attribute total length. */
1682 attribute_len = stream_getw (s);
1683
1684 /* Attribute length check. */
1685 if (stream_pnt (s) + attribute_len > end)
1686 {
1687 zlog_warn ("%s [Error] Packet Error"
1688 " (update packet attribute length overflow %d)",
1689 peer->host, attribute_len);
1690 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1691 BGP_NOTIFY_UPDATE_MAL_ATTR);
1692 return -1;
1693 }
Paul Jakmab881c702010-11-23 16:35:42 +00001694
1695 /* Certain attribute parsing errors should not be considered bad enough
1696 * to reset the session for, most particularly any partial/optional
1697 * attributes that have 'tunneled' over speakers that don't understand
1698 * them. Instead we withdraw only the prefix concerned.
1699 *
1700 * Complicates the flow a little though..
1701 */
1702 bgp_attr_parse_ret_t attr_parse_ret = BGP_ATTR_PARSE_PROCEED;
1703 /* This define morphs the update case into a withdraw when lower levels
1704 * have signalled an error condition where this is best.
1705 */
1706#define NLRI_ATTR_ARG (attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : NULL)
paul718e3742002-12-13 20:15:29 +00001707
1708 /* Parse attribute when it exists. */
1709 if (attribute_len)
1710 {
Paul Jakmab881c702010-11-23 16:35:42 +00001711 attr_parse_ret = bgp_attr_parse (peer, &attr, attribute_len,
paul718e3742002-12-13 20:15:29 +00001712 &mp_update, &mp_withdraw);
Paul Jakmab881c702010-11-23 16:35:42 +00001713 if (attr_parse_ret == BGP_ATTR_PARSE_ERROR)
David Lamparterf80f8382014-06-04 01:00:51 +02001714 {
1715 bgp_attr_unintern_sub (&attr);
1716 return -1;
1717 }
paul718e3742002-12-13 20:15:29 +00001718 }
Paul Jakmab881c702010-11-23 16:35:42 +00001719
paul718e3742002-12-13 20:15:29 +00001720 /* Logging the attribute. */
Paul Jakmab881c702010-11-23 16:35:42 +00001721 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW
1722 || BGP_DEBUG (update, UPDATE_IN))
paul718e3742002-12-13 20:15:29 +00001723 {
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +00001724 char attrstr[BUFSIZ];
1725 attrstr[0] = '\0';
1726
paule01f9cb2004-07-09 17:48:53 +00001727 ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
Paul Jakmab881c702010-11-23 16:35:42 +00001728 int lvl = (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1729 ? LOG_ERR : LOG_DEBUG;
1730
1731 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1732 zlog (peer->log, LOG_ERR,
1733 "%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
1734 peer->host);
paule01f9cb2004-07-09 17:48:53 +00001735
1736 if (ret)
Paul Jakmab881c702010-11-23 16:35:42 +00001737 zlog (peer->log, lvl, "%s rcvd UPDATE w/ attr: %s",
paule01f9cb2004-07-09 17:48:53 +00001738 peer->host, attrstr);
paul718e3742002-12-13 20:15:29 +00001739 }
Paul Jakmab881c702010-11-23 16:35:42 +00001740
paul718e3742002-12-13 20:15:29 +00001741 /* Network Layer Reachability Information. */
1742 update_len = end - stream_pnt (s);
1743
1744 if (update_len)
1745 {
1746 /* Check NLRI packet format and prefix length. */
1747 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), update_len);
1748 if (ret < 0)
Paul Jakmab881c702010-11-23 16:35:42 +00001749 {
1750 bgp_attr_unintern_sub (&attr);
Paul Jakmab881c702010-11-23 16:35:42 +00001751 return -1;
1752 }
paul718e3742002-12-13 20:15:29 +00001753
1754 /* Set NLRI portion to structure. */
1755 update.afi = AFI_IP;
1756 update.safi = SAFI_UNICAST;
1757 update.nlri = stream_pnt (s);
1758 update.length = update_len;
paul9985f832005-02-09 15:51:56 +00001759 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001760 }
1761
1762 /* NLRI is processed only when the peer is configured specific
1763 Address Family and Subsequent Address Family. */
1764 if (peer->afc[AFI_IP][SAFI_UNICAST])
1765 {
1766 if (withdraw.length)
1767 bgp_nlri_parse (peer, NULL, &withdraw);
1768
1769 if (update.length)
Paul Jakmab881c702010-11-23 16:35:42 +00001770 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &update);
paule01f9cb2004-07-09 17:48:53 +00001771
hassof4184462005-02-01 20:13:16 +00001772 if (mp_update.length
1773 && mp_update.afi == AFI_IP
1774 && mp_update.safi == SAFI_UNICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001775 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
hassof4184462005-02-01 20:13:16 +00001776
1777 if (mp_withdraw.length
1778 && mp_withdraw.afi == AFI_IP
1779 && mp_withdraw.safi == SAFI_UNICAST)
1780 bgp_nlri_parse (peer, NULL, &mp_withdraw);
1781
paule01f9cb2004-07-09 17:48:53 +00001782 if (! attribute_len && ! withdraw_len)
1783 {
1784 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001785 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],
1786 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001787
hasso93406d82005-02-02 14:40:33 +00001788 /* NSF delete stale route */
1789 if (peer->nsf[AFI_IP][SAFI_UNICAST])
1790 bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);
1791
1792 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001793 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001794 peer->host);
1795 }
paul718e3742002-12-13 20:15:29 +00001796 }
1797 if (peer->afc[AFI_IP][SAFI_MULTICAST])
1798 {
1799 if (mp_update.length
Lou Berger9da04bc2016-01-12 13:41:55 -05001800 && mp_update.afi == AFI_IP
paul718e3742002-12-13 20:15:29 +00001801 && mp_update.safi == SAFI_MULTICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001802 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001803
1804 if (mp_withdraw.length
Lou Berger9da04bc2016-01-12 13:41:55 -05001805 && mp_withdraw.afi == AFI_IP
paul718e3742002-12-13 20:15:29 +00001806 && mp_withdraw.safi == SAFI_MULTICAST)
1807 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001808
hasso93406d82005-02-02 14:40:33 +00001809 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001810 && mp_withdraw.afi == AFI_IP
1811 && mp_withdraw.safi == SAFI_MULTICAST
1812 && mp_withdraw.length == 0)
1813 {
1814 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001815 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
1816 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001817
hasso93406d82005-02-02 14:40:33 +00001818 /* NSF delete stale route */
1819 if (peer->nsf[AFI_IP][SAFI_MULTICAST])
1820 bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);
1821
1822 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001823 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001824 peer->host);
1825 }
paul718e3742002-12-13 20:15:29 +00001826 }
1827 if (peer->afc[AFI_IP6][SAFI_UNICAST])
1828 {
1829 if (mp_update.length
1830 && mp_update.afi == AFI_IP6
1831 && mp_update.safi == SAFI_UNICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001832 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001833
1834 if (mp_withdraw.length
1835 && mp_withdraw.afi == AFI_IP6
1836 && mp_withdraw.safi == SAFI_UNICAST)
1837 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001838
hasso93406d82005-02-02 14:40:33 +00001839 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001840 && mp_withdraw.afi == AFI_IP6
1841 && mp_withdraw.safi == SAFI_UNICAST
1842 && mp_withdraw.length == 0)
1843 {
1844 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001845 SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001846
hasso93406d82005-02-02 14:40:33 +00001847 /* NSF delete stale route */
1848 if (peer->nsf[AFI_IP6][SAFI_UNICAST])
1849 bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST);
1850
1851 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001852 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001853 peer->host);
1854 }
paul718e3742002-12-13 20:15:29 +00001855 }
1856 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
1857 {
1858 if (mp_update.length
1859 && mp_update.afi == AFI_IP6
1860 && mp_update.safi == SAFI_MULTICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001861 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001862
1863 if (mp_withdraw.length
1864 && mp_withdraw.afi == AFI_IP6
1865 && mp_withdraw.safi == SAFI_MULTICAST)
1866 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001867
hasso93406d82005-02-02 14:40:33 +00001868 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001869 && mp_withdraw.afi == AFI_IP6
1870 && mp_withdraw.safi == SAFI_MULTICAST
1871 && mp_withdraw.length == 0)
1872 {
1873 /* End-of-RIB received */
1874
hasso93406d82005-02-02 14:40:33 +00001875 /* NSF delete stale route */
1876 if (peer->nsf[AFI_IP6][SAFI_MULTICAST])
1877 bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST);
1878
paule01f9cb2004-07-09 17:48:53 +00001879 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001880 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001881 peer->host);
1882 }
paul718e3742002-12-13 20:15:29 +00001883 }
1884 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
1885 {
1886 if (mp_update.length
1887 && mp_update.afi == AFI_IP
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001888 && mp_update.safi == SAFI_MPLS_LABELED_VPN)
Lou Berger9da04bc2016-01-12 13:41:55 -05001889 bgp_nlri_parse_vpn (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001890
1891 if (mp_withdraw.length
1892 && mp_withdraw.afi == AFI_IP
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001893 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN)
Lou Berger9da04bc2016-01-12 13:41:55 -05001894 bgp_nlri_parse_vpn (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001895
hasso93406d82005-02-02 14:40:33 +00001896 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001897 && mp_withdraw.afi == AFI_IP
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001898 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN
paule01f9cb2004-07-09 17:48:53 +00001899 && mp_withdraw.length == 0)
1900 {
1901 /* End-of-RIB received */
1902
1903 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001904 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001905 peer->host);
1906 }
paul718e3742002-12-13 20:15:29 +00001907 }
Lou Berger9da04bc2016-01-12 13:41:55 -05001908 if (peer->afc[AFI_IP6][SAFI_MPLS_VPN])
1909 {
1910 if (mp_update.length
1911 && mp_update.afi == AFI_IP6
1912 && mp_update.safi == SAFI_MPLS_LABELED_VPN)
1913 bgp_nlri_parse_vpn (peer, NLRI_ATTR_ARG, &mp_update);
1914
1915 if (mp_withdraw.length
1916 && mp_withdraw.afi == AFI_IP6
1917 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN)
1918 bgp_nlri_parse_vpn (peer, NULL, &mp_withdraw);
1919
1920 if (! withdraw_len
1921 && mp_withdraw.afi == AFI_IP6
1922 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN
1923 && mp_withdraw.length == 0)
1924 {
1925 /* End-of-RIB received */
1926
1927 if (BGP_DEBUG (update, UPDATE_IN))
1928 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s",
1929 peer->host);
1930 }
1931 }
paul718e3742002-12-13 20:15:29 +00001932
1933 /* Everything is done. We unintern temporary structures which
1934 interned in bgp_attr_parse(). */
Paul Jakmab881c702010-11-23 16:35:42 +00001935 bgp_attr_unintern_sub (&attr);
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001936
paul718e3742002-12-13 20:15:29 +00001937 /* If peering is stopped due to some reason, do not generate BGP
1938 event. */
1939 if (peer->status != Established)
1940 return 0;
1941
1942 /* Increment packet counter. */
1943 peer->update_in++;
Stephen Hemminger65957882010-01-15 16:22:10 +03001944 peer->update_time = bgp_clock ();
paul718e3742002-12-13 20:15:29 +00001945
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02001946 /* Rearm holdtime timer */
Jorge Boncompte [DTI2]6a4677b2012-05-07 16:53:07 +00001947 BGP_TIMER_OFF (peer->t_holdtime);
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02001948 bgp_timer_set (peer);
paul718e3742002-12-13 20:15:29 +00001949
1950 return 0;
1951}
1952
1953/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00001954static void
paul718e3742002-12-13 20:15:29 +00001955bgp_notify_receive (struct peer *peer, bgp_size_t size)
1956{
1957 struct bgp_notify bgp_notify;
1958
1959 if (peer->notify.data)
1960 {
1961 XFREE (MTYPE_TMP, peer->notify.data);
1962 peer->notify.data = NULL;
1963 peer->notify.length = 0;
1964 }
1965
1966 bgp_notify.code = stream_getc (peer->ibuf);
1967 bgp_notify.subcode = stream_getc (peer->ibuf);
1968 bgp_notify.length = size - 2;
1969 bgp_notify.data = NULL;
1970
1971 /* Preserv notify code and sub code. */
1972 peer->notify.code = bgp_notify.code;
1973 peer->notify.subcode = bgp_notify.subcode;
1974 /* For further diagnostic record returned Data. */
1975 if (bgp_notify.length)
1976 {
1977 peer->notify.length = size - 2;
1978 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
1979 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
1980 }
1981
1982 /* For debug */
1983 {
1984 int i;
1985 int first = 0;
1986 char c[4];
1987
1988 if (bgp_notify.length)
1989 {
1990 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
1991 for (i = 0; i < bgp_notify.length; i++)
1992 if (first)
1993 {
1994 sprintf (c, " %02x", stream_getc (peer->ibuf));
1995 strcat (bgp_notify.data, c);
1996 }
1997 else
1998 {
1999 first = 1;
2000 sprintf (c, "%02x", stream_getc (peer->ibuf));
2001 strcpy (bgp_notify.data, c);
2002 }
2003 }
2004
2005 bgp_notify_print(peer, &bgp_notify, "received");
2006 if (bgp_notify.data)
Daniel Walton363c9032015-10-21 06:42:54 -07002007 {
2008 XFREE (MTYPE_TMP, bgp_notify.data);
2009 bgp_notify.data = NULL;
2010 bgp_notify.length = 0;
2011 }
paul718e3742002-12-13 20:15:29 +00002012 }
2013
2014 /* peer count update */
2015 peer->notify_in++;
2016
hassoe0701b72004-05-20 09:19:34 +00002017 if (peer->status == Established)
2018 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
2019
paul718e3742002-12-13 20:15:29 +00002020 /* We have to check for Notify with Unsupported Optional Parameter.
2021 in that case we fallback to open without the capability option.
2022 But this done in bgp_stop. We just mark it here to avoid changing
2023 the fsm tables. */
2024 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
2025 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
2026 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
2027
paul718e3742002-12-13 20:15:29 +00002028 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
2029}
2030
2031/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00002032static void
paul718e3742002-12-13 20:15:29 +00002033bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
2034{
2035 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00002036 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00002037
2038 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
2039}
2040
2041/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00002042static void
paul718e3742002-12-13 20:15:29 +00002043bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
2044{
2045 afi_t afi;
2046 safi_t safi;
paul718e3742002-12-13 20:15:29 +00002047 struct stream *s;
2048
2049 /* If peer does not have the capability, send notification. */
2050 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
2051 {
2052 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
2053 peer->host);
2054 bgp_notify_send (peer,
2055 BGP_NOTIFY_HEADER_ERR,
2056 BGP_NOTIFY_HEADER_BAD_MESTYPE);
2057 return;
2058 }
2059
2060 /* Status must be Established. */
2061 if (peer->status != Established)
2062 {
2063 plog_err (peer->log,
2064 "%s [Error] Route refresh packet received under status %s",
2065 peer->host, LOOKUP (bgp_status_msg, peer->status));
2066 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
2067 return;
2068 }
2069
2070 s = peer->ibuf;
2071
2072 /* Parse packet. */
2073 afi = stream_getw (s);
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002074 /* reserved byte */
2075 stream_getc (s);
paul718e3742002-12-13 20:15:29 +00002076 safi = stream_getc (s);
2077
2078 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002079 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00002080 peer->host, afi, safi);
2081
2082 /* Check AFI and SAFI. */
2083 if ((afi != AFI_IP && afi != AFI_IP6)
2084 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
Denis Ovsienko42e6d742011-07-14 12:36:19 +04002085 && safi != SAFI_MPLS_LABELED_VPN))
paul718e3742002-12-13 20:15:29 +00002086 {
2087 if (BGP_DEBUG (normal, NORMAL))
2088 {
ajs6b514742004-12-08 21:03:23 +00002089 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00002090 peer->host, afi, safi);
2091 }
2092 return;
2093 }
2094
2095 /* Adjust safi code. */
Denis Ovsienko42e6d742011-07-14 12:36:19 +04002096 if (safi == SAFI_MPLS_LABELED_VPN)
paul718e3742002-12-13 20:15:29 +00002097 safi = SAFI_MPLS_VPN;
2098
2099 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
2100 {
2101 u_char *end;
2102 u_char when_to_refresh;
2103 u_char orf_type;
2104 u_int16_t orf_len;
2105
2106 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
2107 {
2108 zlog_info ("%s ORF route refresh length error", peer->host);
2109 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2110 return;
2111 }
2112
2113 when_to_refresh = stream_getc (s);
2114 end = stream_pnt (s) + (size - 5);
2115
Paul Jakma370b64a2007-12-22 16:49:52 +00002116 while ((stream_pnt (s) + 2) < end)
paul718e3742002-12-13 20:15:29 +00002117 {
2118 orf_type = stream_getc (s);
2119 orf_len = stream_getw (s);
Paul Jakma370b64a2007-12-22 16:49:52 +00002120
2121 /* orf_len in bounds? */
2122 if ((stream_pnt (s) + orf_len) > end)
2123 break; /* XXX: Notify instead?? */
paul718e3742002-12-13 20:15:29 +00002124 if (orf_type == ORF_TYPE_PREFIX
2125 || orf_type == ORF_TYPE_PREFIX_OLD)
2126 {
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002127 uint8_t *p_pnt = stream_pnt (s);
2128 uint8_t *p_end = stream_pnt (s) + orf_len;
paul718e3742002-12-13 20:15:29 +00002129 struct orf_prefix orfp;
2130 u_char common = 0;
2131 u_int32_t seq;
2132 int psize;
2133 char name[BUFSIZ];
paul718e3742002-12-13 20:15:29 +00002134 int ret;
2135
2136 if (BGP_DEBUG (normal, NORMAL))
2137 {
ajs6b514742004-12-08 21:03:23 +00002138 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00002139 peer->host, orf_type, orf_len);
2140 }
2141
Paul Jakma370b64a2007-12-22 16:49:52 +00002142 /* we're going to read at least 1 byte of common ORF header,
2143 * and 7 bytes of ORF Address-filter entry from the stream
2144 */
2145 if (orf_len < 7)
2146 break;
2147
paul718e3742002-12-13 20:15:29 +00002148 /* ORF prefix-list name */
2149 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
2150
2151 while (p_pnt < p_end)
2152 {
Chris Halld64379e2010-05-14 16:38:39 +04002153 /* If the ORF entry is malformed, want to read as much of it
2154 * as possible without going beyond the bounds of the entry,
2155 * to maximise debug information.
2156 */
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002157 int ok;
paul718e3742002-12-13 20:15:29 +00002158 memset (&orfp, 0, sizeof (struct orf_prefix));
2159 common = *p_pnt++;
Chris Halld64379e2010-05-14 16:38:39 +04002160 /* after ++: p_pnt <= p_end */
paul718e3742002-12-13 20:15:29 +00002161 if (common & ORF_COMMON_PART_REMOVE_ALL)
2162 {
2163 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002164 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
David Lamparterc9c06d02015-04-13 10:21:35 +02002165 prefix_bgp_orf_remove_all (afi, name);
paul718e3742002-12-13 20:15:29 +00002166 break;
2167 }
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002168 ok = ((size_t)(p_end - p_pnt) >= sizeof(u_int32_t)) ;
Denis Ovsienkobb915f52011-12-13 21:11:39 +04002169 if (ok)
Chris Halld64379e2010-05-14 16:38:39 +04002170 {
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002171 memcpy (&seq, p_pnt, sizeof (u_int32_t));
2172 p_pnt += sizeof (u_int32_t);
2173 orfp.seq = ntohl (seq);
Chris Halld64379e2010-05-14 16:38:39 +04002174 }
2175 else
2176 p_pnt = p_end ;
2177
2178 if ((ok = (p_pnt < p_end)))
2179 orfp.ge = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2180 if ((ok = (p_pnt < p_end)))
2181 orfp.le = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2182 if ((ok = (p_pnt < p_end)))
2183 orfp.p.prefixlen = *p_pnt++ ;
2184 orfp.p.family = afi2family (afi); /* afi checked already */
2185
2186 psize = PSIZE (orfp.p.prefixlen); /* 0 if not ok */
2187 if (psize > prefix_blen(&orfp.p)) /* valid for family ? */
2188 {
2189 ok = 0 ;
2190 psize = prefix_blen(&orfp.p) ;
2191 }
2192 if (psize > (p_end - p_pnt)) /* valid for packet ? */
2193 {
2194 ok = 0 ;
2195 psize = p_end - p_pnt ;
2196 }
2197
2198 if (psize > 0)
2199 memcpy (&orfp.p.u.prefix, p_pnt, psize);
paul718e3742002-12-13 20:15:29 +00002200 p_pnt += psize;
2201
2202 if (BGP_DEBUG (normal, NORMAL))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +00002203 {
2204 char buf[INET6_BUFSIZ];
2205
2206 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
2207 peer->host,
2208 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
2209 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
2210 orfp.seq,
2211 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, INET6_BUFSIZ),
2212 orfp.p.prefixlen, orfp.ge, orfp.le,
2213 ok ? "" : " MALFORMED");
2214 }
2215
Chris Halld64379e2010-05-14 16:38:39 +04002216 if (ok)
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002217 ret = prefix_bgp_orf_set (name, afi, &orfp,
2218 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
2219 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002220
2221 if (!ok || (ok && ret != CMD_SUCCESS))
paul718e3742002-12-13 20:15:29 +00002222 {
2223 if (BGP_DEBUG (normal, NORMAL))
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002224 zlog_debug ("%s Received misformatted prefixlist ORF."
2225 " Remove All pfxlist", peer->host);
David Lamparterc9c06d02015-04-13 10:21:35 +02002226 prefix_bgp_orf_remove_all (afi, name);
paul718e3742002-12-13 20:15:29 +00002227 break;
2228 }
2229 }
2230 peer->orf_plist[afi][safi] =
David Lamparterc9c06d02015-04-13 10:21:35 +02002231 prefix_bgp_orf_lookup (afi, name);
paul718e3742002-12-13 20:15:29 +00002232 }
paul9985f832005-02-09 15:51:56 +00002233 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00002234 }
2235 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002236 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00002237 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
2238 if (when_to_refresh == REFRESH_DEFER)
2239 return;
2240 }
2241
2242 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2243 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
2244 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
2245
2246 /* Perform route refreshment to the peer */
2247 bgp_announce_route (peer, afi, safi);
2248}
2249
paul94f2b392005-06-28 12:44:16 +00002250static int
paul718e3742002-12-13 20:15:29 +00002251bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
2252{
2253 u_char *end;
Paul Jakma6d582722007-08-06 15:21:45 +00002254 struct capability_mp_data mpc;
2255 struct capability_header *hdr;
paul718e3742002-12-13 20:15:29 +00002256 u_char action;
paul718e3742002-12-13 20:15:29 +00002257 afi_t afi;
2258 safi_t safi;
2259
paul718e3742002-12-13 20:15:29 +00002260 end = pnt + length;
2261
2262 while (pnt < end)
Paul Jakma6d582722007-08-06 15:21:45 +00002263 {
paul718e3742002-12-13 20:15:29 +00002264 /* We need at least action, capability code and capability length. */
2265 if (pnt + 3 > end)
2266 {
2267 zlog_info ("%s Capability length error", peer->host);
2268 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2269 return -1;
2270 }
paul718e3742002-12-13 20:15:29 +00002271 action = *pnt;
Paul Jakma6d582722007-08-06 15:21:45 +00002272 hdr = (struct capability_header *)(pnt + 1);
2273
paul718e3742002-12-13 20:15:29 +00002274 /* Action value check. */
2275 if (action != CAPABILITY_ACTION_SET
2276 && action != CAPABILITY_ACTION_UNSET)
2277 {
2278 zlog_info ("%s Capability Action Value error %d",
2279 peer->host, action);
2280 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2281 return -1;
2282 }
2283
2284 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002285 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
Paul Jakma6d582722007-08-06 15:21:45 +00002286 peer->host, action, hdr->code, hdr->length);
paul718e3742002-12-13 20:15:29 +00002287
2288 /* Capability length check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002289 if ((pnt + hdr->length + 3) > end)
paul718e3742002-12-13 20:15:29 +00002290 {
2291 zlog_info ("%s Capability length error", peer->host);
2292 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2293 return -1;
2294 }
2295
Paul Jakma6d582722007-08-06 15:21:45 +00002296 /* Fetch structure to the byte stream. */
2297 memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
2298
paul718e3742002-12-13 20:15:29 +00002299 /* We know MP Capability Code. */
Paul Jakma6d582722007-08-06 15:21:45 +00002300 if (hdr->code == CAPABILITY_CODE_MP)
paul718e3742002-12-13 20:15:29 +00002301 {
Paul Jakma6d582722007-08-06 15:21:45 +00002302 afi = ntohs (mpc.afi);
2303 safi = mpc.safi;
paul718e3742002-12-13 20:15:29 +00002304
2305 /* Ignore capability when override-capability is set. */
2306 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2307 continue;
Paul Jakma6d582722007-08-06 15:21:45 +00002308
2309 if (!bgp_afi_safi_valid_indices (afi, &safi))
2310 {
2311 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002312 zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
2313 "(%u/%u)", peer->host, afi, safi);
Paul Jakma6d582722007-08-06 15:21:45 +00002314 continue;
2315 }
2316
paul718e3742002-12-13 20:15:29 +00002317 /* Address family check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002318 if (BGP_DEBUG (normal, NORMAL))
2319 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2320 peer->host,
2321 action == CAPABILITY_ACTION_SET
2322 ? "Advertising" : "Removing",
2323 ntohs(mpc.afi) , mpc.safi);
2324
2325 if (action == CAPABILITY_ACTION_SET)
2326 {
2327 peer->afc_recv[afi][safi] = 1;
2328 if (peer->afc[afi][safi])
2329 {
2330 peer->afc_nego[afi][safi] = 1;
2331 bgp_announce_route (peer, afi, safi);
2332 }
2333 }
2334 else
2335 {
2336 peer->afc_recv[afi][safi] = 0;
2337 peer->afc_nego[afi][safi] = 0;
paul718e3742002-12-13 20:15:29 +00002338
Paul Jakma6d582722007-08-06 15:21:45 +00002339 if (peer_active_nego (peer))
Chris Caputo228da422009-07-18 05:44:03 +00002340 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
Paul Jakma6d582722007-08-06 15:21:45 +00002341 else
2342 BGP_EVENT_ADD (peer, BGP_Stop);
2343 }
paul718e3742002-12-13 20:15:29 +00002344 }
paul718e3742002-12-13 20:15:29 +00002345 else
2346 {
2347 zlog_warn ("%s unrecognized capability code: %d - ignored",
Paul Jakma6d582722007-08-06 15:21:45 +00002348 peer->host, hdr->code);
paul718e3742002-12-13 20:15:29 +00002349 }
Paul Jakma6d582722007-08-06 15:21:45 +00002350 pnt += hdr->length + 3;
paul718e3742002-12-13 20:15:29 +00002351 }
2352 return 0;
2353}
2354
Paul Jakma01b7ce22009-06-18 12:34:43 +01002355/* Dynamic Capability is received.
2356 *
2357 * This is exported for unit-test purposes
2358 */
Paul Jakma6d582722007-08-06 15:21:45 +00002359int
paul718e3742002-12-13 20:15:29 +00002360bgp_capability_receive (struct peer *peer, bgp_size_t size)
2361{
2362 u_char *pnt;
paul718e3742002-12-13 20:15:29 +00002363
2364 /* Fetch pointer. */
2365 pnt = stream_pnt (peer->ibuf);
2366
2367 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002368 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002369
2370 /* If peer does not have the capability, send notification. */
2371 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2372 {
2373 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2374 peer->host);
2375 bgp_notify_send (peer,
2376 BGP_NOTIFY_HEADER_ERR,
2377 BGP_NOTIFY_HEADER_BAD_MESTYPE);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002378 return -1;
paul718e3742002-12-13 20:15:29 +00002379 }
2380
2381 /* Status must be Established. */
2382 if (peer->status != Established)
2383 {
2384 plog_err (peer->log,
2385 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2386 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002387 return -1;
paul718e3742002-12-13 20:15:29 +00002388 }
2389
2390 /* Parse packet. */
Paul Jakma6d582722007-08-06 15:21:45 +00002391 return bgp_capability_msg_parse (peer, pnt, size);
paul718e3742002-12-13 20:15:29 +00002392}
David Lamparter6b0655a2014-06-04 06:53:35 +02002393
paul718e3742002-12-13 20:15:29 +00002394/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002395static int
paul718e3742002-12-13 20:15:29 +00002396bgp_read_packet (struct peer *peer)
2397{
2398 int nbytes;
2399 int readsize;
2400
paul9985f832005-02-09 15:51:56 +00002401 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002402
2403 /* If size is zero then return. */
2404 if (! readsize)
2405 return 0;
2406
2407 /* Read packet from fd. */
Stephen Hemminger35398582010-08-05 10:26:23 -07002408 nbytes = stream_read_try (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002409
2410 /* If read byte is smaller than zero then error occured. */
2411 if (nbytes < 0)
2412 {
Stephen Hemminger35398582010-08-05 10:26:23 -07002413 /* Transient error should retry */
2414 if (nbytes == -2)
paul718e3742002-12-13 20:15:29 +00002415 return -1;
2416
2417 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002418 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002419
2420 if (peer->status == Established)
2421 {
2422 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2423 {
2424 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2425 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2426 }
2427 else
2428 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2429 }
2430
paul718e3742002-12-13 20:15:29 +00002431 BGP_EVENT_ADD (peer, TCP_fatal_error);
2432 return -1;
2433 }
2434
2435 /* When read byte is zero : clear bgp peer and return */
2436 if (nbytes == 0)
2437 {
2438 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002439 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002440 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002441
2442 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002443 {
2444 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2445 {
2446 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2447 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2448 }
2449 else
2450 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2451 }
hassoe0701b72004-05-20 09:19:34 +00002452
paul718e3742002-12-13 20:15:29 +00002453 BGP_EVENT_ADD (peer, TCP_connection_closed);
2454 return -1;
2455 }
2456
2457 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002458 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002459 return -1;
2460
2461 return 0;
2462}
2463
2464/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002465static int
paul718e3742002-12-13 20:15:29 +00002466bgp_marker_all_one (struct stream *s, int length)
2467{
2468 int i;
2469
2470 for (i = 0; i < length; i++)
2471 if (s->data[i] != 0xff)
2472 return 0;
2473
2474 return 1;
2475}
2476
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002477/* Recent thread time.
2478 On same clock base as bgp_clock (MONOTONIC)
2479 but can be time of last context switch to bgp_read thread. */
2480static time_t
2481bgp_recent_clock (void)
2482{
2483 return recent_relative_time().tv_sec;
2484}
2485
paul718e3742002-12-13 20:15:29 +00002486/* Starting point of packet process function. */
2487int
2488bgp_read (struct thread *thread)
2489{
2490 int ret;
2491 u_char type = 0;
2492 struct peer *peer;
2493 bgp_size_t size;
2494 char notify_data_length[2];
2495
2496 /* Yes first of all get peer pointer. */
2497 peer = THREAD_ARG (thread);
2498 peer->t_read = NULL;
2499
2500 /* For non-blocking IO check. */
2501 if (peer->status == Connect)
2502 {
2503 bgp_connect_check (peer);
2504 goto done;
2505 }
2506 else
2507 {
pauleb821182004-05-01 08:44:08 +00002508 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002509 {
pauleb821182004-05-01 08:44:08 +00002510 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002511 return -1;
2512 }
pauleb821182004-05-01 08:44:08 +00002513 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002514 }
2515
2516 /* Read packet header to determine type of the packet */
2517 if (peer->packet_size == 0)
2518 peer->packet_size = BGP_HEADER_SIZE;
2519
paul9985f832005-02-09 15:51:56 +00002520 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002521 {
2522 ret = bgp_read_packet (peer);
2523
2524 /* Header read error or partial read packet. */
2525 if (ret < 0)
2526 goto done;
2527
2528 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002529 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002530 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2531 size = stream_getw (peer->ibuf);
2532 type = stream_getc (peer->ibuf);
2533
2534 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002535 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002536 peer->host, type, size - BGP_HEADER_SIZE);
2537
2538 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002539 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002540 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2541 {
2542 bgp_notify_send (peer,
2543 BGP_NOTIFY_HEADER_ERR,
2544 BGP_NOTIFY_HEADER_NOT_SYNC);
2545 goto done;
2546 }
2547
2548 /* BGP type check. */
2549 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2550 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2551 && type != BGP_MSG_ROUTE_REFRESH_NEW
2552 && type != BGP_MSG_ROUTE_REFRESH_OLD
2553 && type != BGP_MSG_CAPABILITY)
2554 {
2555 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002556 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002557 "%s unknown message type 0x%02x",
2558 peer->host, type);
2559 bgp_notify_send_with_data (peer,
2560 BGP_NOTIFY_HEADER_ERR,
2561 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2562 &type, 1);
2563 goto done;
2564 }
2565 /* Mimimum packet length check. */
2566 if ((size < BGP_HEADER_SIZE)
2567 || (size > BGP_MAX_PACKET_SIZE)
2568 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2569 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2570 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2571 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2572 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2573 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2574 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2575 {
2576 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002577 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002578 "%s bad message length - %d for %s",
2579 peer->host, size,
2580 type == 128 ? "ROUTE-REFRESH" :
2581 bgp_type_str[(int) type]);
2582 bgp_notify_send_with_data (peer,
2583 BGP_NOTIFY_HEADER_ERR,
2584 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002585 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002586 goto done;
2587 }
2588
2589 /* Adjust size to message length. */
2590 peer->packet_size = size;
2591 }
2592
2593 ret = bgp_read_packet (peer);
2594 if (ret < 0)
2595 goto done;
2596
2597 /* Get size and type again. */
2598 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2599 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2600
2601 /* BGP packet dump function. */
2602 bgp_dump_packet (peer, type, peer->ibuf);
2603
2604 size = (peer->packet_size - BGP_HEADER_SIZE);
2605
2606 /* Read rest of the packet and call each sort of packet routine */
2607 switch (type)
2608 {
2609 case BGP_MSG_OPEN:
2610 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002611 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002612 break;
2613 case BGP_MSG_UPDATE:
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002614 peer->readtime = bgp_recent_clock ();
paul718e3742002-12-13 20:15:29 +00002615 bgp_update_receive (peer, size);
2616 break;
2617 case BGP_MSG_NOTIFY:
2618 bgp_notify_receive (peer, size);
2619 break;
2620 case BGP_MSG_KEEPALIVE:
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002621 peer->readtime = bgp_recent_clock ();
paul718e3742002-12-13 20:15:29 +00002622 bgp_keepalive_receive (peer, size);
2623 break;
2624 case BGP_MSG_ROUTE_REFRESH_NEW:
2625 case BGP_MSG_ROUTE_REFRESH_OLD:
2626 peer->refresh_in++;
2627 bgp_route_refresh_receive (peer, size);
2628 break;
2629 case BGP_MSG_CAPABILITY:
2630 peer->dynamic_cap_in++;
2631 bgp_capability_receive (peer, size);
2632 break;
2633 }
2634
2635 /* Clear input buffer. */
2636 peer->packet_size = 0;
2637 if (peer->ibuf)
2638 stream_reset (peer->ibuf);
2639
2640 done:
2641 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2642 {
2643 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002644 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002645 peer_delete (peer);
paul718e3742002-12-13 20:15:29 +00002646 }
2647 return 0;
2648}