blob: ec60069dcff70a117e23adf76defebcc1500c13b [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
1800 && mp_update.afi == AFI_IP
1801 && 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
1805 && mp_withdraw.afi == AFI_IP
1806 && 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)
Paul Jakmab881c702010-11-23 16:35:42 +00001889 bgp_nlri_parse_vpnv4 (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)
paul718e3742002-12-13 20:15:29 +00001894 bgp_nlri_parse_vpnv4 (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 }
1908
1909 /* Everything is done. We unintern temporary structures which
1910 interned in bgp_attr_parse(). */
Paul Jakmab881c702010-11-23 16:35:42 +00001911 bgp_attr_unintern_sub (&attr);
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001912
paul718e3742002-12-13 20:15:29 +00001913 /* If peering is stopped due to some reason, do not generate BGP
1914 event. */
1915 if (peer->status != Established)
1916 return 0;
1917
1918 /* Increment packet counter. */
1919 peer->update_in++;
Stephen Hemminger65957882010-01-15 16:22:10 +03001920 peer->update_time = bgp_clock ();
paul718e3742002-12-13 20:15:29 +00001921
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02001922 /* Rearm holdtime timer */
Jorge Boncompte [DTI2]6a4677b2012-05-07 16:53:07 +00001923 BGP_TIMER_OFF (peer->t_holdtime);
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02001924 bgp_timer_set (peer);
paul718e3742002-12-13 20:15:29 +00001925
1926 return 0;
1927}
1928
1929/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00001930static void
paul718e3742002-12-13 20:15:29 +00001931bgp_notify_receive (struct peer *peer, bgp_size_t size)
1932{
1933 struct bgp_notify bgp_notify;
1934
1935 if (peer->notify.data)
1936 {
1937 XFREE (MTYPE_TMP, peer->notify.data);
1938 peer->notify.data = NULL;
1939 peer->notify.length = 0;
1940 }
1941
1942 bgp_notify.code = stream_getc (peer->ibuf);
1943 bgp_notify.subcode = stream_getc (peer->ibuf);
1944 bgp_notify.length = size - 2;
1945 bgp_notify.data = NULL;
1946
1947 /* Preserv notify code and sub code. */
1948 peer->notify.code = bgp_notify.code;
1949 peer->notify.subcode = bgp_notify.subcode;
1950 /* For further diagnostic record returned Data. */
1951 if (bgp_notify.length)
1952 {
1953 peer->notify.length = size - 2;
1954 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
1955 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
1956 }
1957
1958 /* For debug */
1959 {
1960 int i;
1961 int first = 0;
1962 char c[4];
1963
1964 if (bgp_notify.length)
1965 {
1966 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
1967 for (i = 0; i < bgp_notify.length; i++)
1968 if (first)
1969 {
1970 sprintf (c, " %02x", stream_getc (peer->ibuf));
1971 strcat (bgp_notify.data, c);
1972 }
1973 else
1974 {
1975 first = 1;
1976 sprintf (c, "%02x", stream_getc (peer->ibuf));
1977 strcpy (bgp_notify.data, c);
1978 }
1979 }
1980
1981 bgp_notify_print(peer, &bgp_notify, "received");
1982 if (bgp_notify.data)
Daniel Walton363c9032015-10-21 06:42:54 -07001983 {
1984 XFREE (MTYPE_TMP, bgp_notify.data);
1985 bgp_notify.data = NULL;
1986 bgp_notify.length = 0;
1987 }
paul718e3742002-12-13 20:15:29 +00001988 }
1989
1990 /* peer count update */
1991 peer->notify_in++;
1992
hassoe0701b72004-05-20 09:19:34 +00001993 if (peer->status == Established)
1994 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
1995
paul718e3742002-12-13 20:15:29 +00001996 /* We have to check for Notify with Unsupported Optional Parameter.
1997 in that case we fallback to open without the capability option.
1998 But this done in bgp_stop. We just mark it here to avoid changing
1999 the fsm tables. */
2000 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
2001 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
2002 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
2003
paul718e3742002-12-13 20:15:29 +00002004 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
2005}
2006
2007/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00002008static void
paul718e3742002-12-13 20:15:29 +00002009bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
2010{
2011 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00002012 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00002013
2014 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
2015}
2016
2017/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00002018static void
paul718e3742002-12-13 20:15:29 +00002019bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
2020{
2021 afi_t afi;
2022 safi_t safi;
paul718e3742002-12-13 20:15:29 +00002023 struct stream *s;
2024
2025 /* If peer does not have the capability, send notification. */
2026 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
2027 {
2028 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
2029 peer->host);
2030 bgp_notify_send (peer,
2031 BGP_NOTIFY_HEADER_ERR,
2032 BGP_NOTIFY_HEADER_BAD_MESTYPE);
2033 return;
2034 }
2035
2036 /* Status must be Established. */
2037 if (peer->status != Established)
2038 {
2039 plog_err (peer->log,
2040 "%s [Error] Route refresh packet received under status %s",
2041 peer->host, LOOKUP (bgp_status_msg, peer->status));
2042 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
2043 return;
2044 }
2045
2046 s = peer->ibuf;
2047
2048 /* Parse packet. */
2049 afi = stream_getw (s);
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002050 /* reserved byte */
2051 stream_getc (s);
paul718e3742002-12-13 20:15:29 +00002052 safi = stream_getc (s);
2053
2054 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002055 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00002056 peer->host, afi, safi);
2057
2058 /* Check AFI and SAFI. */
2059 if ((afi != AFI_IP && afi != AFI_IP6)
2060 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
Denis Ovsienko42e6d742011-07-14 12:36:19 +04002061 && safi != SAFI_MPLS_LABELED_VPN))
paul718e3742002-12-13 20:15:29 +00002062 {
2063 if (BGP_DEBUG (normal, NORMAL))
2064 {
ajs6b514742004-12-08 21:03:23 +00002065 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00002066 peer->host, afi, safi);
2067 }
2068 return;
2069 }
2070
2071 /* Adjust safi code. */
Denis Ovsienko42e6d742011-07-14 12:36:19 +04002072 if (safi == SAFI_MPLS_LABELED_VPN)
paul718e3742002-12-13 20:15:29 +00002073 safi = SAFI_MPLS_VPN;
2074
2075 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
2076 {
2077 u_char *end;
2078 u_char when_to_refresh;
2079 u_char orf_type;
2080 u_int16_t orf_len;
2081
2082 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
2083 {
2084 zlog_info ("%s ORF route refresh length error", peer->host);
2085 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2086 return;
2087 }
2088
2089 when_to_refresh = stream_getc (s);
2090 end = stream_pnt (s) + (size - 5);
2091
Paul Jakma370b64a2007-12-22 16:49:52 +00002092 while ((stream_pnt (s) + 2) < end)
paul718e3742002-12-13 20:15:29 +00002093 {
2094 orf_type = stream_getc (s);
2095 orf_len = stream_getw (s);
Paul Jakma370b64a2007-12-22 16:49:52 +00002096
2097 /* orf_len in bounds? */
2098 if ((stream_pnt (s) + orf_len) > end)
2099 break; /* XXX: Notify instead?? */
paul718e3742002-12-13 20:15:29 +00002100 if (orf_type == ORF_TYPE_PREFIX
2101 || orf_type == ORF_TYPE_PREFIX_OLD)
2102 {
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002103 uint8_t *p_pnt = stream_pnt (s);
2104 uint8_t *p_end = stream_pnt (s) + orf_len;
paul718e3742002-12-13 20:15:29 +00002105 struct orf_prefix orfp;
2106 u_char common = 0;
2107 u_int32_t seq;
2108 int psize;
2109 char name[BUFSIZ];
paul718e3742002-12-13 20:15:29 +00002110 int ret;
2111
2112 if (BGP_DEBUG (normal, NORMAL))
2113 {
ajs6b514742004-12-08 21:03:23 +00002114 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00002115 peer->host, orf_type, orf_len);
2116 }
2117
Paul Jakma370b64a2007-12-22 16:49:52 +00002118 /* we're going to read at least 1 byte of common ORF header,
2119 * and 7 bytes of ORF Address-filter entry from the stream
2120 */
2121 if (orf_len < 7)
2122 break;
2123
paul718e3742002-12-13 20:15:29 +00002124 /* ORF prefix-list name */
2125 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
2126
2127 while (p_pnt < p_end)
2128 {
Chris Halld64379e2010-05-14 16:38:39 +04002129 /* If the ORF entry is malformed, want to read as much of it
2130 * as possible without going beyond the bounds of the entry,
2131 * to maximise debug information.
2132 */
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002133 int ok;
paul718e3742002-12-13 20:15:29 +00002134 memset (&orfp, 0, sizeof (struct orf_prefix));
2135 common = *p_pnt++;
Chris Halld64379e2010-05-14 16:38:39 +04002136 /* after ++: p_pnt <= p_end */
paul718e3742002-12-13 20:15:29 +00002137 if (common & ORF_COMMON_PART_REMOVE_ALL)
2138 {
2139 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002140 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
David Lamparterc9c06d02015-04-13 10:21:35 +02002141 prefix_bgp_orf_remove_all (afi, name);
paul718e3742002-12-13 20:15:29 +00002142 break;
2143 }
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002144 ok = ((size_t)(p_end - p_pnt) >= sizeof(u_int32_t)) ;
Denis Ovsienkobb915f52011-12-13 21:11:39 +04002145 if (ok)
Chris Halld64379e2010-05-14 16:38:39 +04002146 {
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002147 memcpy (&seq, p_pnt, sizeof (u_int32_t));
2148 p_pnt += sizeof (u_int32_t);
2149 orfp.seq = ntohl (seq);
Chris Halld64379e2010-05-14 16:38:39 +04002150 }
2151 else
2152 p_pnt = p_end ;
2153
2154 if ((ok = (p_pnt < p_end)))
2155 orfp.ge = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2156 if ((ok = (p_pnt < p_end)))
2157 orfp.le = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2158 if ((ok = (p_pnt < p_end)))
2159 orfp.p.prefixlen = *p_pnt++ ;
2160 orfp.p.family = afi2family (afi); /* afi checked already */
2161
2162 psize = PSIZE (orfp.p.prefixlen); /* 0 if not ok */
2163 if (psize > prefix_blen(&orfp.p)) /* valid for family ? */
2164 {
2165 ok = 0 ;
2166 psize = prefix_blen(&orfp.p) ;
2167 }
2168 if (psize > (p_end - p_pnt)) /* valid for packet ? */
2169 {
2170 ok = 0 ;
2171 psize = p_end - p_pnt ;
2172 }
2173
2174 if (psize > 0)
2175 memcpy (&orfp.p.u.prefix, p_pnt, psize);
paul718e3742002-12-13 20:15:29 +00002176 p_pnt += psize;
2177
2178 if (BGP_DEBUG (normal, NORMAL))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +00002179 {
2180 char buf[INET6_BUFSIZ];
2181
2182 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
2183 peer->host,
2184 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
2185 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
2186 orfp.seq,
2187 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, INET6_BUFSIZ),
2188 orfp.p.prefixlen, orfp.ge, orfp.le,
2189 ok ? "" : " MALFORMED");
2190 }
2191
Chris Halld64379e2010-05-14 16:38:39 +04002192 if (ok)
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002193 ret = prefix_bgp_orf_set (name, afi, &orfp,
2194 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
2195 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002196
2197 if (!ok || (ok && ret != CMD_SUCCESS))
paul718e3742002-12-13 20:15:29 +00002198 {
2199 if (BGP_DEBUG (normal, NORMAL))
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002200 zlog_debug ("%s Received misformatted prefixlist ORF."
2201 " Remove All pfxlist", peer->host);
David Lamparterc9c06d02015-04-13 10:21:35 +02002202 prefix_bgp_orf_remove_all (afi, name);
paul718e3742002-12-13 20:15:29 +00002203 break;
2204 }
2205 }
2206 peer->orf_plist[afi][safi] =
David Lamparterc9c06d02015-04-13 10:21:35 +02002207 prefix_bgp_orf_lookup (afi, name);
paul718e3742002-12-13 20:15:29 +00002208 }
paul9985f832005-02-09 15:51:56 +00002209 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00002210 }
2211 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002212 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00002213 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
2214 if (when_to_refresh == REFRESH_DEFER)
2215 return;
2216 }
2217
2218 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2219 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
2220 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
2221
2222 /* Perform route refreshment to the peer */
2223 bgp_announce_route (peer, afi, safi);
2224}
2225
paul94f2b392005-06-28 12:44:16 +00002226static int
paul718e3742002-12-13 20:15:29 +00002227bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
2228{
2229 u_char *end;
Paul Jakma6d582722007-08-06 15:21:45 +00002230 struct capability_mp_data mpc;
2231 struct capability_header *hdr;
paul718e3742002-12-13 20:15:29 +00002232 u_char action;
paul718e3742002-12-13 20:15:29 +00002233 afi_t afi;
2234 safi_t safi;
2235
paul718e3742002-12-13 20:15:29 +00002236 end = pnt + length;
2237
2238 while (pnt < end)
Paul Jakma6d582722007-08-06 15:21:45 +00002239 {
paul718e3742002-12-13 20:15:29 +00002240 /* We need at least action, capability code and capability length. */
2241 if (pnt + 3 > end)
2242 {
2243 zlog_info ("%s Capability length error", peer->host);
2244 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2245 return -1;
2246 }
paul718e3742002-12-13 20:15:29 +00002247 action = *pnt;
Paul Jakma6d582722007-08-06 15:21:45 +00002248 hdr = (struct capability_header *)(pnt + 1);
2249
paul718e3742002-12-13 20:15:29 +00002250 /* Action value check. */
2251 if (action != CAPABILITY_ACTION_SET
2252 && action != CAPABILITY_ACTION_UNSET)
2253 {
2254 zlog_info ("%s Capability Action Value error %d",
2255 peer->host, action);
2256 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2257 return -1;
2258 }
2259
2260 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002261 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
Paul Jakma6d582722007-08-06 15:21:45 +00002262 peer->host, action, hdr->code, hdr->length);
paul718e3742002-12-13 20:15:29 +00002263
2264 /* Capability length check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002265 if ((pnt + hdr->length + 3) > end)
paul718e3742002-12-13 20:15:29 +00002266 {
2267 zlog_info ("%s Capability length error", peer->host);
2268 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2269 return -1;
2270 }
2271
Paul Jakma6d582722007-08-06 15:21:45 +00002272 /* Fetch structure to the byte stream. */
2273 memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
2274
paul718e3742002-12-13 20:15:29 +00002275 /* We know MP Capability Code. */
Paul Jakma6d582722007-08-06 15:21:45 +00002276 if (hdr->code == CAPABILITY_CODE_MP)
paul718e3742002-12-13 20:15:29 +00002277 {
Paul Jakma6d582722007-08-06 15:21:45 +00002278 afi = ntohs (mpc.afi);
2279 safi = mpc.safi;
paul718e3742002-12-13 20:15:29 +00002280
2281 /* Ignore capability when override-capability is set. */
2282 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2283 continue;
Paul Jakma6d582722007-08-06 15:21:45 +00002284
2285 if (!bgp_afi_safi_valid_indices (afi, &safi))
2286 {
2287 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002288 zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
2289 "(%u/%u)", peer->host, afi, safi);
Paul Jakma6d582722007-08-06 15:21:45 +00002290 continue;
2291 }
2292
paul718e3742002-12-13 20:15:29 +00002293 /* Address family check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002294 if (BGP_DEBUG (normal, NORMAL))
2295 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2296 peer->host,
2297 action == CAPABILITY_ACTION_SET
2298 ? "Advertising" : "Removing",
2299 ntohs(mpc.afi) , mpc.safi);
2300
2301 if (action == CAPABILITY_ACTION_SET)
2302 {
2303 peer->afc_recv[afi][safi] = 1;
2304 if (peer->afc[afi][safi])
2305 {
2306 peer->afc_nego[afi][safi] = 1;
2307 bgp_announce_route (peer, afi, safi);
2308 }
2309 }
2310 else
2311 {
2312 peer->afc_recv[afi][safi] = 0;
2313 peer->afc_nego[afi][safi] = 0;
paul718e3742002-12-13 20:15:29 +00002314
Paul Jakma6d582722007-08-06 15:21:45 +00002315 if (peer_active_nego (peer))
Chris Caputo228da422009-07-18 05:44:03 +00002316 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
Paul Jakma6d582722007-08-06 15:21:45 +00002317 else
2318 BGP_EVENT_ADD (peer, BGP_Stop);
2319 }
paul718e3742002-12-13 20:15:29 +00002320 }
paul718e3742002-12-13 20:15:29 +00002321 else
2322 {
2323 zlog_warn ("%s unrecognized capability code: %d - ignored",
Paul Jakma6d582722007-08-06 15:21:45 +00002324 peer->host, hdr->code);
paul718e3742002-12-13 20:15:29 +00002325 }
Paul Jakma6d582722007-08-06 15:21:45 +00002326 pnt += hdr->length + 3;
paul718e3742002-12-13 20:15:29 +00002327 }
2328 return 0;
2329}
2330
Paul Jakma01b7ce22009-06-18 12:34:43 +01002331/* Dynamic Capability is received.
2332 *
2333 * This is exported for unit-test purposes
2334 */
Paul Jakma6d582722007-08-06 15:21:45 +00002335int
paul718e3742002-12-13 20:15:29 +00002336bgp_capability_receive (struct peer *peer, bgp_size_t size)
2337{
2338 u_char *pnt;
paul718e3742002-12-13 20:15:29 +00002339
2340 /* Fetch pointer. */
2341 pnt = stream_pnt (peer->ibuf);
2342
2343 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002344 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002345
2346 /* If peer does not have the capability, send notification. */
2347 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2348 {
2349 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2350 peer->host);
2351 bgp_notify_send (peer,
2352 BGP_NOTIFY_HEADER_ERR,
2353 BGP_NOTIFY_HEADER_BAD_MESTYPE);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002354 return -1;
paul718e3742002-12-13 20:15:29 +00002355 }
2356
2357 /* Status must be Established. */
2358 if (peer->status != Established)
2359 {
2360 plog_err (peer->log,
2361 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2362 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002363 return -1;
paul718e3742002-12-13 20:15:29 +00002364 }
2365
2366 /* Parse packet. */
Paul Jakma6d582722007-08-06 15:21:45 +00002367 return bgp_capability_msg_parse (peer, pnt, size);
paul718e3742002-12-13 20:15:29 +00002368}
David Lamparter6b0655a2014-06-04 06:53:35 +02002369
paul718e3742002-12-13 20:15:29 +00002370/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002371static int
paul718e3742002-12-13 20:15:29 +00002372bgp_read_packet (struct peer *peer)
2373{
2374 int nbytes;
2375 int readsize;
2376
paul9985f832005-02-09 15:51:56 +00002377 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002378
2379 /* If size is zero then return. */
2380 if (! readsize)
2381 return 0;
2382
2383 /* Read packet from fd. */
Stephen Hemminger35398582010-08-05 10:26:23 -07002384 nbytes = stream_read_try (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002385
2386 /* If read byte is smaller than zero then error occured. */
2387 if (nbytes < 0)
2388 {
Stephen Hemminger35398582010-08-05 10:26:23 -07002389 /* Transient error should retry */
2390 if (nbytes == -2)
paul718e3742002-12-13 20:15:29 +00002391 return -1;
2392
2393 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002394 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002395
2396 if (peer->status == Established)
2397 {
2398 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2399 {
2400 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2401 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2402 }
2403 else
2404 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2405 }
2406
paul718e3742002-12-13 20:15:29 +00002407 BGP_EVENT_ADD (peer, TCP_fatal_error);
2408 return -1;
2409 }
2410
2411 /* When read byte is zero : clear bgp peer and return */
2412 if (nbytes == 0)
2413 {
2414 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002415 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002416 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002417
2418 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002419 {
2420 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2421 {
2422 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2423 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2424 }
2425 else
2426 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2427 }
hassoe0701b72004-05-20 09:19:34 +00002428
paul718e3742002-12-13 20:15:29 +00002429 BGP_EVENT_ADD (peer, TCP_connection_closed);
2430 return -1;
2431 }
2432
2433 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002434 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002435 return -1;
2436
2437 return 0;
2438}
2439
2440/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002441static int
paul718e3742002-12-13 20:15:29 +00002442bgp_marker_all_one (struct stream *s, int length)
2443{
2444 int i;
2445
2446 for (i = 0; i < length; i++)
2447 if (s->data[i] != 0xff)
2448 return 0;
2449
2450 return 1;
2451}
2452
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002453/* Recent thread time.
2454 On same clock base as bgp_clock (MONOTONIC)
2455 but can be time of last context switch to bgp_read thread. */
2456static time_t
2457bgp_recent_clock (void)
2458{
2459 return recent_relative_time().tv_sec;
2460}
2461
paul718e3742002-12-13 20:15:29 +00002462/* Starting point of packet process function. */
2463int
2464bgp_read (struct thread *thread)
2465{
2466 int ret;
2467 u_char type = 0;
2468 struct peer *peer;
2469 bgp_size_t size;
2470 char notify_data_length[2];
2471
2472 /* Yes first of all get peer pointer. */
2473 peer = THREAD_ARG (thread);
2474 peer->t_read = NULL;
2475
2476 /* For non-blocking IO check. */
2477 if (peer->status == Connect)
2478 {
2479 bgp_connect_check (peer);
2480 goto done;
2481 }
2482 else
2483 {
pauleb821182004-05-01 08:44:08 +00002484 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002485 {
pauleb821182004-05-01 08:44:08 +00002486 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002487 return -1;
2488 }
pauleb821182004-05-01 08:44:08 +00002489 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002490 }
2491
2492 /* Read packet header to determine type of the packet */
2493 if (peer->packet_size == 0)
2494 peer->packet_size = BGP_HEADER_SIZE;
2495
paul9985f832005-02-09 15:51:56 +00002496 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002497 {
2498 ret = bgp_read_packet (peer);
2499
2500 /* Header read error or partial read packet. */
2501 if (ret < 0)
2502 goto done;
2503
2504 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002505 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002506 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2507 size = stream_getw (peer->ibuf);
2508 type = stream_getc (peer->ibuf);
2509
2510 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002511 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002512 peer->host, type, size - BGP_HEADER_SIZE);
2513
2514 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002515 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002516 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2517 {
2518 bgp_notify_send (peer,
2519 BGP_NOTIFY_HEADER_ERR,
2520 BGP_NOTIFY_HEADER_NOT_SYNC);
2521 goto done;
2522 }
2523
2524 /* BGP type check. */
2525 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2526 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2527 && type != BGP_MSG_ROUTE_REFRESH_NEW
2528 && type != BGP_MSG_ROUTE_REFRESH_OLD
2529 && type != BGP_MSG_CAPABILITY)
2530 {
2531 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002532 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002533 "%s unknown message type 0x%02x",
2534 peer->host, type);
2535 bgp_notify_send_with_data (peer,
2536 BGP_NOTIFY_HEADER_ERR,
2537 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2538 &type, 1);
2539 goto done;
2540 }
2541 /* Mimimum packet length check. */
2542 if ((size < BGP_HEADER_SIZE)
2543 || (size > BGP_MAX_PACKET_SIZE)
2544 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2545 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2546 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2547 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2548 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2549 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2550 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2551 {
2552 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002553 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002554 "%s bad message length - %d for %s",
2555 peer->host, size,
2556 type == 128 ? "ROUTE-REFRESH" :
2557 bgp_type_str[(int) type]);
2558 bgp_notify_send_with_data (peer,
2559 BGP_NOTIFY_HEADER_ERR,
2560 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002561 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002562 goto done;
2563 }
2564
2565 /* Adjust size to message length. */
2566 peer->packet_size = size;
2567 }
2568
2569 ret = bgp_read_packet (peer);
2570 if (ret < 0)
2571 goto done;
2572
2573 /* Get size and type again. */
2574 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2575 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2576
2577 /* BGP packet dump function. */
2578 bgp_dump_packet (peer, type, peer->ibuf);
2579
2580 size = (peer->packet_size - BGP_HEADER_SIZE);
2581
2582 /* Read rest of the packet and call each sort of packet routine */
2583 switch (type)
2584 {
2585 case BGP_MSG_OPEN:
2586 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002587 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002588 break;
2589 case BGP_MSG_UPDATE:
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002590 peer->readtime = bgp_recent_clock ();
paul718e3742002-12-13 20:15:29 +00002591 bgp_update_receive (peer, size);
2592 break;
2593 case BGP_MSG_NOTIFY:
2594 bgp_notify_receive (peer, size);
2595 break;
2596 case BGP_MSG_KEEPALIVE:
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002597 peer->readtime = bgp_recent_clock ();
paul718e3742002-12-13 20:15:29 +00002598 bgp_keepalive_receive (peer, size);
2599 break;
2600 case BGP_MSG_ROUTE_REFRESH_NEW:
2601 case BGP_MSG_ROUTE_REFRESH_OLD:
2602 peer->refresh_in++;
2603 bgp_route_refresh_receive (peer, size);
2604 break;
2605 case BGP_MSG_CAPABILITY:
2606 peer->dynamic_cap_in++;
2607 bgp_capability_receive (peer, size);
2608 break;
2609 }
2610
2611 /* Clear input buffer. */
2612 peer->packet_size = 0;
2613 if (peer->ibuf)
2614 stream_reset (peer->ibuf);
2615
2616 done:
2617 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2618 {
2619 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002620 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002621 peer_delete (peer);
paul718e3742002-12-13 20:15:29 +00002622 }
2623 return 0;
2624}