blob: a90e56b50a1e36340e3d7994b511172aa4de63ae [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"
34
35#include "bgpd/bgpd.h"
36#include "bgpd/bgp_table.h"
37#include "bgpd/bgp_dump.h"
38#include "bgpd/bgp_attr.h"
39#include "bgpd/bgp_debug.h"
40#include "bgpd/bgp_fsm.h"
41#include "bgpd/bgp_route.h"
42#include "bgpd/bgp_packet.h"
43#include "bgpd/bgp_open.h"
44#include "bgpd/bgp_aspath.h"
45#include "bgpd/bgp_community.h"
46#include "bgpd/bgp_ecommunity.h"
47#include "bgpd/bgp_network.h"
48#include "bgpd/bgp_mplsvpn.h"
49#include "bgpd/bgp_advertise.h"
hasso93406d82005-02-02 14:40:33 +000050#include "bgpd/bgp_vty.h"
paul718e3742002-12-13 20:15:29 +000051
52int stream_put_prefix (struct stream *, struct prefix *);
David Lamparter6b0655a2014-06-04 06:53:35 +020053
paul718e3742002-12-13 20:15:29 +000054/* Set up BGP packet marker and packet type. */
55static int
56bgp_packet_set_marker (struct stream *s, u_char type)
57{
58 int i;
59
60 /* Fill in marker. */
61 for (i = 0; i < BGP_MARKER_SIZE; i++)
62 stream_putc (s, 0xff);
63
64 /* Dummy total length. This field is should be filled in later on. */
65 stream_putw (s, 0);
66
67 /* BGP packet type. */
68 stream_putc (s, type);
69
70 /* Return current stream size. */
paul9985f832005-02-09 15:51:56 +000071 return stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +000072}
73
74/* Set BGP packet header size entry. If size is zero then use current
75 stream size. */
76static int
77bgp_packet_set_size (struct stream *s)
78{
79 int cp;
80
81 /* Preserve current pointer. */
paul9985f832005-02-09 15:51:56 +000082 cp = stream_get_endp (s);
83 stream_putw_at (s, BGP_MARKER_SIZE, cp);
paul718e3742002-12-13 20:15:29 +000084
85 return cp;
86}
87
88/* Add new packet to the peer. */
paul94f2b392005-06-28 12:44:16 +000089static void
paul718e3742002-12-13 20:15:29 +000090bgp_packet_add (struct peer *peer, struct stream *s)
91{
92 /* Add packet to the end of list. */
93 stream_fifo_push (peer->obuf, s);
94}
95
96/* Free first packet. */
paul94f2b392005-06-28 12:44:16 +000097static void
paul718e3742002-12-13 20:15:29 +000098bgp_packet_delete (struct peer *peer)
99{
100 stream_free (stream_fifo_pop (peer->obuf));
101}
102
paul718e3742002-12-13 20:15:29 +0000103/* Check file descriptor whether connect is established. */
104static void
105bgp_connect_check (struct peer *peer)
106{
107 int status;
paul5228ad22004-06-04 17:58:18 +0000108 socklen_t slen;
paul718e3742002-12-13 20:15:29 +0000109 int ret;
110
111 /* Anyway I have to reset read and write thread. */
112 BGP_READ_OFF (peer->t_read);
113 BGP_WRITE_OFF (peer->t_write);
114
115 /* Check file descriptor. */
116 slen = sizeof (status);
pauleb821182004-05-01 08:44:08 +0000117 ret = getsockopt(peer->fd, SOL_SOCKET, SO_ERROR, (void *) &status, &slen);
paul718e3742002-12-13 20:15:29 +0000118
119 /* If getsockopt is fail, this is fatal error. */
120 if (ret < 0)
121 {
122 zlog (peer->log, LOG_INFO, "can't get sockopt for nonblocking connect");
123 BGP_EVENT_ADD (peer, TCP_fatal_error);
124 return;
125 }
126
127 /* When status is 0 then TCP connection is established. */
128 if (status == 0)
129 {
130 BGP_EVENT_ADD (peer, TCP_connection_open);
131 }
132 else
133 {
134 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +0000135 plog_debug (peer->log, "%s [Event] Connect failed (%s)",
ajs6099b3b2004-11-20 02:06:59 +0000136 peer->host, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000137 BGP_EVENT_ADD (peer, TCP_connection_open_failed);
138 }
139}
140
141/* Make BGP update packet. */
paul94f2b392005-06-28 12:44:16 +0000142static struct stream *
paul718e3742002-12-13 20:15:29 +0000143bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi)
144{
145 struct stream *s;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000146 struct stream *snlri;
paul718e3742002-12-13 20:15:29 +0000147 struct bgp_adj_out *adj;
148 struct bgp_advertise *adv;
149 struct stream *packet;
150 struct bgp_node *rn = NULL;
151 struct bgp_info *binfo = NULL;
152 bgp_size_t total_attr_len = 0;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000153 unsigned long attrlen_pos = 0;
154 size_t mpattrlen_pos = 0;
155 size_t mpattr_pos = 0;
paul718e3742002-12-13 20:15:29 +0000156
157 s = peer->work;
158 stream_reset (s);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000159 snlri = peer->scratch;
160 stream_reset (snlri);
paul718e3742002-12-13 20:15:29 +0000161
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100162 adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update);
paul718e3742002-12-13 20:15:29 +0000163
164 while (adv)
165 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000166 assert (adv->rn);
167 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000168 adj = adv->adj;
169 if (adv->binfo)
170 binfo = adv->binfo;
paul718e3742002-12-13 20:15:29 +0000171
172 /* When remaining space can't include NLRI and it's length. */
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000173 if (STREAM_CONCAT_REMAIN (s, snlri, STREAM_SIZE(s)) <=
174 (BGP_NLRI_LENGTH + PSIZE (rn->p.prefixlen)))
paul718e3742002-12-13 20:15:29 +0000175 break;
176
177 /* If packet is empty, set attribute. */
178 if (stream_empty (s))
179 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000180 struct peer *from = NULL;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000181
Greg Troxeld3ddb222010-09-17 10:47:49 -0400182 if (binfo)
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000183 from = binfo->peer;
184
185 /* 1: Write the BGP message header - 16 bytes marker, 2 bytes length,
186 * one byte message type.
187 */
paul718e3742002-12-13 20:15:29 +0000188 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000189
190 /* 2: withdrawn routes length */
paul718e3742002-12-13 20:15:29 +0000191 stream_putw (s, 0);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000192
193 /* 3: total attributes length - attrlen_pos stores the position */
194 attrlen_pos = stream_get_endp (s);
195 stream_putw (s, 0);
196
197 /* 4: if there is MP_REACH_NLRI attribute, that should be the first
198 * attribute, according to draft-ietf-idr-error-handling. Save the
199 * position.
200 */
201 mpattr_pos = stream_get_endp(s);
202
203 /* 5: Encode all the attributes, except MP_REACH_NLRI attr. */
204 total_attr_len = bgp_packet_attribute (NULL, peer, s,
paul5228ad22004-06-04 17:58:18 +0000205 adv->baa->attr,
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000206 NULL, afi, safi,
207 from, NULL, NULL);
paul718e3742002-12-13 20:15:29 +0000208 }
209
210 if (afi == AFI_IP && safi == SAFI_UNICAST)
211 stream_put_prefix (s, &rn->p);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000212 else
213 {
214 /* Encode the prefix in MP_REACH_NLRI attribute */
215 struct prefix_rd *prd = NULL;
216 u_char *tag = NULL;
217
218 if (rn->prn)
219 prd = (struct prefix_rd *) &rn->prn->p;
220 if (binfo && binfo->extra)
221 tag = binfo->extra->tag;
222
223 if (stream_empty(snlri))
224 mpattrlen_pos = bgp_packet_mpattr_start(snlri, afi, safi,
225 adv->baa->attr);
226 bgp_packet_mpattr_prefix(snlri, afi, safi, &rn->p, prd, tag);
227 }
paul718e3742002-12-13 20:15:29 +0000228 if (BGP_DEBUG (update, UPDATE_OUT))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000229 {
230 char buf[INET6_BUFSIZ];
231
232 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d",
233 peer->host,
234 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, INET6_BUFSIZ),
235 rn->p.prefixlen);
236 }
paul718e3742002-12-13 20:15:29 +0000237
238 /* Synchnorize attribute. */
239 if (adj->attr)
Paul Jakmaf6f434b2010-11-23 21:28:03 +0000240 bgp_attr_unintern (&adj->attr);
paul718e3742002-12-13 20:15:29 +0000241 else
242 peer->scount[afi][safi]++;
243
244 adj->attr = bgp_attr_intern (adv->baa->attr);
245
246 adv = bgp_advertise_clean (peer, adj, afi, safi);
paul718e3742002-12-13 20:15:29 +0000247 }
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000248
paul718e3742002-12-13 20:15:29 +0000249 if (! stream_empty (s))
250 {
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000251 if (!stream_empty(snlri))
252 {
253 bgp_packet_mpattr_end(snlri, mpattrlen_pos);
254 total_attr_len += stream_get_endp(snlri);
255 }
256
257 /* set the total attribute length correctly */
258 stream_putw_at (s, attrlen_pos, total_attr_len);
259
260 if (!stream_empty(snlri))
261 packet = stream_dupcat(s, snlri, mpattr_pos);
262 else
263 packet = stream_dup (s);
264 bgp_packet_set_size (packet);
paul718e3742002-12-13 20:15:29 +0000265 bgp_packet_add (peer, packet);
pauleb821182004-05-01 08:44:08 +0000266 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000267 stream_reset (s);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000268 stream_reset (snlri);
paul718e3742002-12-13 20:15:29 +0000269 return packet;
270 }
271 return NULL;
hasso93406d82005-02-02 14:40:33 +0000272}
paul718e3742002-12-13 20:15:29 +0000273
paul94f2b392005-06-28 12:44:16 +0000274static struct stream *
hasso93406d82005-02-02 14:40:33 +0000275bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
276{
277 struct stream *s;
hasso93406d82005-02-02 14:40:33 +0000278
Paul Jakma750e8142008-07-22 21:11:48 +0000279 if (DISABLE_BGP_ANNOUNCE)
280 return NULL;
hasso93406d82005-02-02 14:40:33 +0000281
282 if (BGP_DEBUG (normal, NORMAL))
283 zlog_debug ("send End-of-RIB for %s to %s", afi_safi_print (afi, safi), peer->host);
284
285 s = stream_new (BGP_MAX_PACKET_SIZE);
286
287 /* Make BGP update packet. */
288 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
289
290 /* Unfeasible Routes Length */
291 stream_putw (s, 0);
292
293 if (afi == AFI_IP && safi == SAFI_UNICAST)
294 {
295 /* Total Path Attribute Length */
296 stream_putw (s, 0);
297 }
298 else
299 {
300 /* Total Path Attribute Length */
301 stream_putw (s, 6);
302 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
303 stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
304 stream_putc (s, 3);
305 stream_putw (s, afi);
306 stream_putc (s, safi);
307 }
308
309 bgp_packet_set_size (s);
Donald Sharpa752c3b2015-08-18 08:48:53 -0400310 bgp_packet_add (peer, s);
311 return s;
paul718e3742002-12-13 20:15:29 +0000312}
313
314/* Make BGP withdraw packet. */
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000315/* For ipv4 unicast:
316 16-octet marker | 2-octet length | 1-octet type |
317 2-octet withdrawn route length | withdrawn prefixes | 2-octet attrlen (=0)
318*/
319/* For other afi/safis:
320 16-octet marker | 2-octet length | 1-octet type |
321 2-octet withdrawn route length (=0) | 2-octet attrlen |
322 mp_unreach attr type | attr len | afi | safi | withdrawn prefixes
323*/
paul94f2b392005-06-28 12:44:16 +0000324static struct stream *
paul718e3742002-12-13 20:15:29 +0000325bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi)
326{
327 struct stream *s;
328 struct stream *packet;
329 struct bgp_adj_out *adj;
330 struct bgp_advertise *adv;
331 struct bgp_node *rn;
paul718e3742002-12-13 20:15:29 +0000332 bgp_size_t unfeasible_len;
333 bgp_size_t total_attr_len;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000334 size_t mp_start = 0;
335 size_t attrlen_pos = 0;
336 size_t mplen_pos = 0;
337 u_char first_time = 1;
paul718e3742002-12-13 20:15:29 +0000338
339 s = peer->work;
340 stream_reset (s);
341
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100342 while ((adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL)
paul718e3742002-12-13 20:15:29 +0000343 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000344 assert (adv->rn);
paul718e3742002-12-13 20:15:29 +0000345 adj = adv->adj;
346 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000347
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000348 if (STREAM_REMAIN (s)
hasso4372df72004-05-20 10:20:02 +0000349 < (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN + PSIZE (rn->p.prefixlen)))
paul718e3742002-12-13 20:15:29 +0000350 break;
351
352 if (stream_empty (s))
353 {
354 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000355 stream_putw (s, 0); /* unfeasible routes length */
paul718e3742002-12-13 20:15:29 +0000356 }
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000357 else
358 first_time = 0;
paul718e3742002-12-13 20:15:29 +0000359
360 if (afi == AFI_IP && safi == SAFI_UNICAST)
361 stream_put_prefix (s, &rn->p);
362 else
363 {
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000364 struct prefix_rd *prd = NULL;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000365
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000366 if (rn->prn)
367 prd = (struct prefix_rd *) &rn->prn->p;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000368
369 /* If first time, format the MP_UNREACH header */
370 if (first_time)
371 {
372 attrlen_pos = stream_get_endp (s);
373 /* total attr length = 0 for now. reevaluate later */
374 stream_putw (s, 0);
375 mp_start = stream_get_endp (s);
376 mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
377 }
378
379 bgp_packet_mpunreach_prefix(s, &rn->p, afi, safi, prd, NULL);
paul718e3742002-12-13 20:15:29 +0000380 }
381
382 if (BGP_DEBUG (update, UPDATE_OUT))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000383 {
384 char buf[INET6_BUFSIZ];
385
386 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
387 peer->host,
388 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, INET6_BUFSIZ),
389 rn->p.prefixlen);
390 }
paul718e3742002-12-13 20:15:29 +0000391
392 peer->scount[afi][safi]--;
393
394 bgp_adj_out_remove (rn, adj, peer, afi, safi);
395 bgp_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +0000396 }
397
398 if (! stream_empty (s))
399 {
400 if (afi == AFI_IP && safi == SAFI_UNICAST)
401 {
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000402 unfeasible_len
paul9985f832005-02-09 15:51:56 +0000403 = stream_get_endp (s) - BGP_HEADER_SIZE - BGP_UNFEASIBLE_LEN;
paul718e3742002-12-13 20:15:29 +0000404 stream_putw_at (s, BGP_HEADER_SIZE, unfeasible_len);
405 stream_putw (s, 0);
406 }
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000407 else
408 {
409 /* Set the mp_unreach attr's length */
410 bgp_packet_mpunreach_end(s, mplen_pos);
411
412 /* Set total path attribute length. */
413 total_attr_len = stream_get_endp(s) - mp_start;
414 stream_putw_at (s, attrlen_pos, total_attr_len);
415 }
paul718e3742002-12-13 20:15:29 +0000416 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000417 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000418 bgp_packet_add (peer, packet);
419 stream_reset (s);
420 return packet;
421 }
422
423 return NULL;
424}
425
426void
427bgp_default_update_send (struct peer *peer, struct attr *attr,
428 afi_t afi, safi_t safi, struct peer *from)
429{
430 struct stream *s;
paul718e3742002-12-13 20:15:29 +0000431 struct prefix p;
432 unsigned long pos;
433 bgp_size_t total_attr_len;
paul718e3742002-12-13 20:15:29 +0000434
Paul Jakma750e8142008-07-22 21:11:48 +0000435 if (DISABLE_BGP_ANNOUNCE)
436 return;
paul718e3742002-12-13 20:15:29 +0000437
438 if (afi == AFI_IP)
439 str2prefix ("0.0.0.0/0", &p);
440#ifdef HAVE_IPV6
441 else
442 str2prefix ("::/0", &p);
443#endif /* HAVE_IPV6 */
444
445 /* Logging the attribute. */
446 if (BGP_DEBUG (update, UPDATE_OUT))
447 {
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000448 char attrstr[BUFSIZ];
449 char buf[INET6_BUFSIZ];
450 attrstr[0] = '\0';
451
paul718e3742002-12-13 20:15:29 +0000452 bgp_dump_attr (peer, attr, attrstr, BUFSIZ);
ajs6b514742004-12-08 21:03:23 +0000453 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d %s",
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000454 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, INET6_BUFSIZ),
paul718e3742002-12-13 20:15:29 +0000455 p.prefixlen, attrstr);
456 }
457
458 s = stream_new (BGP_MAX_PACKET_SIZE);
459
460 /* Make BGP update packet. */
461 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
462
463 /* Unfeasible Routes Length. */
464 stream_putw (s, 0);
465
466 /* Make place for total attribute length. */
paul9985f832005-02-09 15:51:56 +0000467 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000468 stream_putw (s, 0);
469 total_attr_len = bgp_packet_attribute (NULL, peer, s, attr, &p, afi, safi, from, NULL, NULL);
470
471 /* Set Total Path Attribute Length. */
472 stream_putw_at (s, pos, total_attr_len);
473
474 /* NLRI set. */
475 if (p.family == AF_INET && safi == SAFI_UNICAST)
476 stream_put_prefix (s, &p);
477
478 /* Set size. */
479 bgp_packet_set_size (s);
480
paul718e3742002-12-13 20:15:29 +0000481 /* Dump packet if debug option is set. */
482#ifdef DEBUG
jardin2d74db52005-10-01 00:07:50 +0000483 /* bgp_packet_dump (packet); */
paul718e3742002-12-13 20:15:29 +0000484#endif /* DEBUG */
485
486 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -0400487 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +0000488
pauleb821182004-05-01 08:44:08 +0000489 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000490}
491
492void
493bgp_default_withdraw_send (struct peer *peer, afi_t afi, safi_t safi)
494{
495 struct stream *s;
paul718e3742002-12-13 20:15:29 +0000496 struct prefix p;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000497 unsigned long attrlen_pos = 0;
paul718e3742002-12-13 20:15:29 +0000498 unsigned long cp;
499 bgp_size_t unfeasible_len;
500 bgp_size_t total_attr_len;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000501 size_t mp_start = 0;
502 size_t mplen_pos = 0;
paul718e3742002-12-13 20:15:29 +0000503
Paul Jakma750e8142008-07-22 21:11:48 +0000504 if (DISABLE_BGP_ANNOUNCE)
505 return;
paul718e3742002-12-13 20:15:29 +0000506
507 if (afi == AFI_IP)
508 str2prefix ("0.0.0.0/0", &p);
509#ifdef HAVE_IPV6
510 else
511 str2prefix ("::/0", &p);
512#endif /* HAVE_IPV6 */
513
514 total_attr_len = 0;
paul718e3742002-12-13 20:15:29 +0000515
516 if (BGP_DEBUG (update, UPDATE_OUT))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000517 {
518 char buf[INET6_BUFSIZ];
519
520 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
521 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, INET6_BUFSIZ),
522 p.prefixlen);
523 }
paul718e3742002-12-13 20:15:29 +0000524
525 s = stream_new (BGP_MAX_PACKET_SIZE);
526
527 /* Make BGP update packet. */
528 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
529
530 /* Unfeasible Routes Length. */;
paul9985f832005-02-09 15:51:56 +0000531 cp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000532 stream_putw (s, 0);
533
534 /* Withdrawn Routes. */
535 if (p.family == AF_INET && safi == SAFI_UNICAST)
536 {
537 stream_put_prefix (s, &p);
538
paul9985f832005-02-09 15:51:56 +0000539 unfeasible_len = stream_get_endp (s) - cp - 2;
paul718e3742002-12-13 20:15:29 +0000540
541 /* Set unfeasible len. */
542 stream_putw_at (s, cp, unfeasible_len);
543
544 /* Set total path attribute length. */
545 stream_putw (s, 0);
546 }
547 else
548 {
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000549 attrlen_pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000550 stream_putw (s, 0);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000551 mp_start = stream_get_endp (s);
552 mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
553 bgp_packet_mpunreach_prefix(s, &p, afi, safi, NULL, NULL);
554
555 /* Set the mp_unreach attr's length */
556 bgp_packet_mpunreach_end(s, mplen_pos);
paul718e3742002-12-13 20:15:29 +0000557
558 /* Set total path attribute length. */
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000559 total_attr_len = stream_get_endp(s) - mp_start;
560 stream_putw_at (s, attrlen_pos, total_attr_len);
paul718e3742002-12-13 20:15:29 +0000561 }
562
563 bgp_packet_set_size (s);
564
paul718e3742002-12-13 20:15:29 +0000565 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -0400566 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +0000567
pauleb821182004-05-01 08:44:08 +0000568 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000569}
570
571/* Get next packet to be written. */
paul94f2b392005-06-28 12:44:16 +0000572static struct stream *
paul718e3742002-12-13 20:15:29 +0000573bgp_write_packet (struct peer *peer)
574{
575 afi_t afi;
576 safi_t safi;
577 struct stream *s = NULL;
578 struct bgp_advertise *adv;
579
580 s = stream_fifo_head (peer->obuf);
581 if (s)
582 return s;
583
584 for (afi = AFI_IP; afi < AFI_MAX; afi++)
585 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
586 {
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100587 adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->withdraw);
paul718e3742002-12-13 20:15:29 +0000588 if (adv)
589 {
590 s = bgp_withdraw_packet (peer, afi, safi);
591 if (s)
592 return s;
593 }
594 }
595
596 for (afi = AFI_IP; afi < AFI_MAX; afi++)
597 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
598 {
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100599 adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update);
paul718e3742002-12-13 20:15:29 +0000600 if (adv)
601 {
602 if (adv->binfo && adv->binfo->uptime < peer->synctime)
hasso93406d82005-02-02 14:40:33 +0000603 {
604 if (CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_RCV)
605 && CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_ADV)
Vipin Kumardd49eb12014-09-30 14:36:38 -0700606 && ! (CHECK_FLAG (adv->binfo->peer->cap,
607 PEER_CAP_RESTART_BIT_RCV) &&
608 CHECK_FLAG (adv->binfo->peer->cap,
609 PEER_CAP_RESTART_BIT_ADV))
hasso93406d82005-02-02 14:40:33 +0000610 && ! CHECK_FLAG (adv->binfo->flags, BGP_INFO_STALE)
611 && safi != SAFI_MPLS_VPN)
612 {
613 if (CHECK_FLAG (adv->binfo->peer->af_sflags[afi][safi],
614 PEER_STATUS_EOR_RECEIVED))
615 s = bgp_update_packet (peer, afi, safi);
616 }
617 else
618 s = bgp_update_packet (peer, afi, safi);
619 }
paul718e3742002-12-13 20:15:29 +0000620
621 if (s)
622 return s;
623 }
hasso93406d82005-02-02 14:40:33 +0000624
625 if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV))
626 {
627 if (peer->afc_nego[afi][safi] && peer->synctime
628 && ! CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND)
629 && safi != SAFI_MPLS_VPN)
630 {
631 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND);
632 return bgp_update_packet_eor (peer, afi, safi);
633 }
634 }
paul718e3742002-12-13 20:15:29 +0000635 }
636
637 return NULL;
638}
639
640/* Is there partially written packet or updates we can send right
641 now. */
paul94f2b392005-06-28 12:44:16 +0000642static int
paul718e3742002-12-13 20:15:29 +0000643bgp_write_proceed (struct peer *peer)
644{
645 afi_t afi;
646 safi_t safi;
647 struct bgp_advertise *adv;
648
649 if (stream_fifo_head (peer->obuf))
650 return 1;
651
652 for (afi = AFI_IP; afi < AFI_MAX; afi++)
653 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
654 if (FIFO_HEAD (&peer->sync[afi][safi]->withdraw))
655 return 1;
656
657 for (afi = AFI_IP; afi < AFI_MAX; afi++)
658 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100659 if ((adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update)) != NULL)
paul718e3742002-12-13 20:15:29 +0000660 if (adv->binfo->uptime < peer->synctime)
661 return 1;
662
663 return 0;
664}
665
666/* Write packet to the peer. */
667int
668bgp_write (struct thread *thread)
669{
670 struct peer *peer;
671 u_char type;
672 struct stream *s;
673 int num;
paulfd79ac92004-10-13 05:06:08 +0000674 unsigned int count = 0;
paul718e3742002-12-13 20:15:29 +0000675
676 /* Yes first of all get peer pointer. */
677 peer = THREAD_ARG (thread);
678 peer->t_write = NULL;
679
680 /* For non-blocking IO check. */
681 if (peer->status == Connect)
682 {
683 bgp_connect_check (peer);
684 return 0;
685 }
686
Stephen Hemmingereac57022010-08-05 10:26:25 -0700687 s = bgp_write_packet (peer);
688 if (!s)
689 return 0; /* nothing to send */
690
691 sockopt_cork (peer->fd, 1);
692
693 /* Nonblocking write until TCP output buffer is full. */
694 do
paul718e3742002-12-13 20:15:29 +0000695 {
696 int writenum;
paul718e3742002-12-13 20:15:29 +0000697
698 /* Number of bytes to be sent. */
699 writenum = stream_get_endp (s) - stream_get_getp (s);
700
701 /* Call write() system call. */
pauleb821182004-05-01 08:44:08 +0000702 num = write (peer->fd, STREAM_PNT (s), writenum);
Stephen Hemminger35398582010-08-05 10:26:23 -0700703 if (num < 0)
paul718e3742002-12-13 20:15:29 +0000704 {
Stephen Hemmingereac57022010-08-05 10:26:25 -0700705 /* write failed either retry needed or error */
706 if (ERRNO_IO_RETRY(errno))
707 break;
708
709 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000710 return 0;
711 }
Stephen Hemminger35398582010-08-05 10:26:23 -0700712
paul718e3742002-12-13 20:15:29 +0000713 if (num != writenum)
714 {
Stephen Hemminger35398582010-08-05 10:26:23 -0700715 /* Partial write */
paul9985f832005-02-09 15:51:56 +0000716 stream_forward_getp (s, num);
Stephen Hemmingereac57022010-08-05 10:26:25 -0700717 break;
paul718e3742002-12-13 20:15:29 +0000718 }
719
720 /* Retrieve BGP packet type. */
721 stream_set_getp (s, BGP_MARKER_SIZE + 2);
722 type = stream_getc (s);
723
724 switch (type)
725 {
726 case BGP_MSG_OPEN:
727 peer->open_out++;
728 break;
729 case BGP_MSG_UPDATE:
730 peer->update_out++;
731 break;
732 case BGP_MSG_NOTIFY:
733 peer->notify_out++;
734 /* Double start timer. */
735 peer->v_start *= 2;
736
737 /* Overflow check. */
738 if (peer->v_start >= (60 * 2))
739 peer->v_start = (60 * 2);
740
Paul Jakmaca058a32006-09-14 02:58:49 +0000741 /* Flush any existing events */
Paul Jakmadcdf3992006-10-15 23:39:59 +0000742 BGP_EVENT_ADD (peer, BGP_Stop);
Stephen Hemminger3a69f742013-01-11 18:27:23 +0000743 goto done;
744
paul718e3742002-12-13 20:15:29 +0000745 case BGP_MSG_KEEPALIVE:
746 peer->keepalive_out++;
747 break;
748 case BGP_MSG_ROUTE_REFRESH_NEW:
749 case BGP_MSG_ROUTE_REFRESH_OLD:
750 peer->refresh_out++;
751 break;
752 case BGP_MSG_CAPABILITY:
753 peer->dynamic_cap_out++;
754 break;
755 }
756
757 /* OK we send packet so delete it. */
758 bgp_packet_delete (peer);
paul718e3742002-12-13 20:15:29 +0000759 }
Stephen Hemmingereac57022010-08-05 10:26:25 -0700760 while (++count < BGP_WRITE_PACKET_MAX &&
761 (s = bgp_write_packet (peer)) != NULL);
paul718e3742002-12-13 20:15:29 +0000762
763 if (bgp_write_proceed (peer))
pauleb821182004-05-01 08:44:08 +0000764 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
Stephen Hemminger3a69f742013-01-11 18:27:23 +0000765
766 done:
767 sockopt_cork (peer->fd, 0);
paul718e3742002-12-13 20:15:29 +0000768 return 0;
769}
770
771/* This is only for sending NOTIFICATION message to neighbor. */
paul94f2b392005-06-28 12:44:16 +0000772static int
paul718e3742002-12-13 20:15:29 +0000773bgp_write_notify (struct peer *peer)
774{
Stephen Hemminger35398582010-08-05 10:26:23 -0700775 int ret, val;
paul718e3742002-12-13 20:15:29 +0000776 u_char type;
777 struct stream *s;
778
779 /* There should be at least one packet. */
780 s = stream_fifo_head (peer->obuf);
781 if (!s)
782 return 0;
783 assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
784
Leonid Rosenboim86998bc2012-12-14 19:12:17 +0000785 /* Stop collecting data within the socket */
786 sockopt_cork (peer->fd, 0);
787
David Lamparter8ff202e2013-07-31 14:39:41 +0200788 /* socket is in nonblocking mode, if we can't deliver the NOTIFY, well,
789 * we only care about getting a clean shutdown at this point. */
Leonid Rosenboim86998bc2012-12-14 19:12:17 +0000790 ret = write (peer->fd, STREAM_DATA (s), stream_get_endp (s));
David Lamparter8ff202e2013-07-31 14:39:41 +0200791
792 /* only connection reset/close gets counted as TCP_fatal_error, failure
793 * to write the entire NOTIFY doesn't get different FSM treatment */
paul718e3742002-12-13 20:15:29 +0000794 if (ret <= 0)
795 {
Paul Jakmadcdf3992006-10-15 23:39:59 +0000796 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000797 return 0;
798 }
799
Leonid Rosenboim86998bc2012-12-14 19:12:17 +0000800 /* Disable Nagle, make NOTIFY packet go out right away */
801 val = 1;
802 (void) setsockopt (peer->fd, IPPROTO_TCP, TCP_NODELAY,
803 (char *) &val, sizeof (val));
804
paul718e3742002-12-13 20:15:29 +0000805 /* Retrieve BGP packet type. */
806 stream_set_getp (s, BGP_MARKER_SIZE + 2);
807 type = stream_getc (s);
808
809 assert (type == BGP_MSG_NOTIFY);
810
811 /* Type should be notify. */
812 peer->notify_out++;
813
814 /* Double start timer. */
815 peer->v_start *= 2;
816
817 /* Overflow check. */
818 if (peer->v_start >= (60 * 2))
819 peer->v_start = (60 * 2);
820
Paul Jakmadcdf3992006-10-15 23:39:59 +0000821 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000822
823 return 0;
824}
825
826/* Make keepalive packet and send it to the peer. */
827void
828bgp_keepalive_send (struct peer *peer)
829{
830 struct stream *s;
831 int length;
832
833 s = stream_new (BGP_MAX_PACKET_SIZE);
834
835 /* Make keepalive packet. */
836 bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
837
838 /* Set packet size. */
839 length = bgp_packet_set_size (s);
840
841 /* Dump packet if debug option is set. */
842 /* bgp_packet_dump (s); */
843
844 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +0000845 zlog_debug ("%s sending KEEPALIVE", peer->host);
paul718e3742002-12-13 20:15:29 +0000846 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000847 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000848 peer->host, BGP_MSG_KEEPALIVE, length);
849
850 /* Add packet to the peer. */
851 bgp_packet_add (peer, s);
852
pauleb821182004-05-01 08:44:08 +0000853 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000854}
855
856/* Make open packet and send it to the peer. */
857void
858bgp_open_send (struct peer *peer)
859{
860 struct stream *s;
861 int length;
862 u_int16_t send_holdtime;
863 as_t local_as;
864
865 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
866 send_holdtime = peer->holdtime;
867 else
868 send_holdtime = peer->bgp->default_holdtime;
869
870 /* local-as Change */
871 if (peer->change_local_as)
872 local_as = peer->change_local_as;
873 else
874 local_as = peer->local_as;
875
876 s = stream_new (BGP_MAX_PACKET_SIZE);
877
878 /* Make open packet. */
879 bgp_packet_set_marker (s, BGP_MSG_OPEN);
880
881 /* Set open packet values. */
882 stream_putc (s, BGP_VERSION_4); /* BGP version */
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000883 stream_putw (s, (local_as <= BGP_AS_MAX) ? (u_int16_t) local_as
884 : BGP_AS_TRANS);
paul718e3742002-12-13 20:15:29 +0000885 stream_putw (s, send_holdtime); /* Hold Time */
886 stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
887
888 /* Set capability code. */
889 bgp_open_capability (s, peer);
890
891 /* Set BGP packet length. */
892 length = bgp_packet_set_size (s);
893
894 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400895 zlog_debug ("%s sending OPEN, version %d, my as %u, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +0000896 peer->host, BGP_VERSION_4, local_as,
897 send_holdtime, inet_ntoa (peer->local_id));
898
899 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000900 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000901 peer->host, BGP_MSG_OPEN, length);
902
903 /* Dump packet if debug option is set. */
904 /* bgp_packet_dump (s); */
905
906 /* Add packet to the peer. */
907 bgp_packet_add (peer, s);
908
pauleb821182004-05-01 08:44:08 +0000909 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000910}
911
912/* Send BGP notify packet with data potion. */
913void
914bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
915 u_char *data, size_t datalen)
916{
917 struct stream *s;
918 int length;
919
920 /* Allocate new stream. */
921 s = stream_new (BGP_MAX_PACKET_SIZE);
922
923 /* Make nitify packet. */
924 bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
925
926 /* Set notify packet values. */
927 stream_putc (s, code); /* BGP notify code */
928 stream_putc (s, sub_code); /* BGP notify sub_code */
929
930 /* If notify data is present. */
931 if (data)
932 stream_write (s, data, datalen);
933
934 /* Set BGP packet length. */
935 length = bgp_packet_set_size (s);
936
937 /* Add packet to the peer. */
938 stream_fifo_clean (peer->obuf);
939 bgp_packet_add (peer, s);
940
941 /* For debug */
942 {
943 struct bgp_notify bgp_notify;
944 int first = 0;
945 int i;
946 char c[4];
947
948 bgp_notify.code = code;
949 bgp_notify.subcode = sub_code;
950 bgp_notify.data = NULL;
951 bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
952
953 if (bgp_notify.length)
954 {
955 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
956 for (i = 0; i < bgp_notify.length; i++)
957 if (first)
958 {
959 sprintf (c, " %02x", data[i]);
960 strcat (bgp_notify.data, c);
961 }
962 else
963 {
964 first = 1;
965 sprintf (c, "%02x", data[i]);
966 strcpy (bgp_notify.data, c);
967 }
968 }
969 bgp_notify_print (peer, &bgp_notify, "sending");
Daniel Walton363c9032015-10-21 06:42:54 -0700970
paul718e3742002-12-13 20:15:29 +0000971 if (bgp_notify.data)
Daniel Walton363c9032015-10-21 06:42:54 -0700972 {
973 XFREE (MTYPE_TMP, bgp_notify.data);
974 bgp_notify.data = NULL;
975 bgp_notify.length = 0;
976 }
paul718e3742002-12-13 20:15:29 +0000977 }
978
979 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000980 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000981 peer->host, BGP_MSG_NOTIFY, length);
982
hassoe0701b72004-05-20 09:19:34 +0000983 /* peer reset cause */
984 if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
985 {
986 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
heasley1212dc12011-09-12 13:27:52 +0400987 {
988 peer->last_reset = PEER_DOWN_USER_RESET;
989 zlog_info ("Notification sent to neighbor %s: User reset", peer->host);
990 }
hassoe0701b72004-05-20 09:19:34 +0000991 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
heasley1212dc12011-09-12 13:27:52 +0400992 {
993 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
994 zlog_info ("Notification sent to neighbor %s: shutdown", peer->host);
995 }
hassoe0701b72004-05-20 09:19:34 +0000996 else
heasley1212dc12011-09-12 13:27:52 +0400997 {
998 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
999 zlog_info ("Notification sent to neighbor %s: type %u/%u",
1000 peer->host, code, sub_code);
1001 }
hassoe0701b72004-05-20 09:19:34 +00001002 }
heasley1212dc12011-09-12 13:27:52 +04001003 else
1004 zlog_info ("Notification sent to neighbor %s: configuration change",
1005 peer->host);
hassoe0701b72004-05-20 09:19:34 +00001006
Denis Ovsienko7ccf5e52011-09-10 16:53:30 +04001007 /* Call immediately. */
paul718e3742002-12-13 20:15:29 +00001008 BGP_WRITE_OFF (peer->t_write);
1009
1010 bgp_write_notify (peer);
1011}
1012
1013/* Send BGP notify packet. */
1014void
1015bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
1016{
1017 bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
1018}
1019
paul718e3742002-12-13 20:15:29 +00001020/* Send route refresh message to the peer. */
1021void
1022bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
1023 u_char orf_type, u_char when_to_refresh, int remove)
1024{
1025 struct stream *s;
paul718e3742002-12-13 20:15:29 +00001026 int length;
1027 struct bgp_filter *filter;
1028 int orf_refresh = 0;
1029
Paul Jakma750e8142008-07-22 21:11:48 +00001030 if (DISABLE_BGP_ANNOUNCE)
1031 return;
paul718e3742002-12-13 20:15:29 +00001032
1033 filter = &peer->filter[afi][safi];
1034
1035 /* Adjust safi code. */
1036 if (safi == SAFI_MPLS_VPN)
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001037 safi = SAFI_MPLS_LABELED_VPN;
paul718e3742002-12-13 20:15:29 +00001038
1039 s = stream_new (BGP_MAX_PACKET_SIZE);
1040
1041 /* Make BGP update packet. */
1042 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
1043 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
1044 else
1045 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
1046
1047 /* Encode Route Refresh message. */
1048 stream_putw (s, afi);
1049 stream_putc (s, 0);
1050 stream_putc (s, safi);
1051
1052 if (orf_type == ORF_TYPE_PREFIX
1053 || orf_type == ORF_TYPE_PREFIX_OLD)
1054 if (remove || filter->plist[FILTER_IN].plist)
1055 {
1056 u_int16_t orf_len;
1057 unsigned long orfp;
1058
1059 orf_refresh = 1;
1060 stream_putc (s, when_to_refresh);
1061 stream_putc (s, orf_type);
paul9985f832005-02-09 15:51:56 +00001062 orfp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00001063 stream_putw (s, 0);
1064
1065 if (remove)
1066 {
1067 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1068 stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
1069 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001070 zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001071 peer->host, orf_type,
1072 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1073 afi, safi);
1074 }
1075 else
1076 {
1077 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1078 prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
1079 ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
1080 ORF_COMMON_PART_DENY);
1081 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001082 zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001083 peer->host, orf_type,
1084 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1085 afi, safi);
1086 }
1087
1088 /* Total ORF Entry Len. */
paul9985f832005-02-09 15:51:56 +00001089 orf_len = stream_get_endp (s) - orfp - 2;
paul718e3742002-12-13 20:15:29 +00001090 stream_putw_at (s, orfp, orf_len);
1091 }
1092
1093 /* Set packet size. */
1094 length = bgp_packet_set_size (s);
1095
1096 if (BGP_DEBUG (normal, NORMAL))
1097 {
1098 if (! orf_refresh)
ajs6b514742004-12-08 21:03:23 +00001099 zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001100 peer->host, afi, safi);
ajs6b514742004-12-08 21:03:23 +00001101 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001102 peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
1103 BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
1104 }
1105
paul718e3742002-12-13 20:15:29 +00001106 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -04001107 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +00001108
pauleb821182004-05-01 08:44:08 +00001109 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001110}
1111
1112/* Send capability message to the peer. */
1113void
1114bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
1115 int capability_code, int action)
1116{
1117 struct stream *s;
paul718e3742002-12-13 20:15:29 +00001118 int length;
1119
1120 /* Adjust safi code. */
1121 if (safi == SAFI_MPLS_VPN)
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001122 safi = SAFI_MPLS_LABELED_VPN;
paul718e3742002-12-13 20:15:29 +00001123
1124 s = stream_new (BGP_MAX_PACKET_SIZE);
1125
1126 /* Make BGP update packet. */
1127 bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
1128
1129 /* Encode MP_EXT capability. */
1130 if (capability_code == CAPABILITY_CODE_MP)
1131 {
1132 stream_putc (s, action);
1133 stream_putc (s, CAPABILITY_CODE_MP);
1134 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1135 stream_putw (s, afi);
1136 stream_putc (s, 0);
1137 stream_putc (s, safi);
1138
1139 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001140 zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001141 peer->host, action == CAPABILITY_ACTION_SET ?
1142 "Advertising" : "Removing", afi, safi);
1143 }
1144
paul718e3742002-12-13 20:15:29 +00001145 /* Set packet size. */
1146 length = bgp_packet_set_size (s);
1147
paul718e3742002-12-13 20:15:29 +00001148
1149 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -04001150 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +00001151
1152 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001153 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001154 peer->host, BGP_MSG_CAPABILITY, length);
1155
pauleb821182004-05-01 08:44:08 +00001156 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001157}
David Lamparter6b0655a2014-06-04 06:53:35 +02001158
paul718e3742002-12-13 20:15:29 +00001159/* RFC1771 6.8 Connection collision detection. */
paul94f2b392005-06-28 12:44:16 +00001160static int
pauleb821182004-05-01 08:44:08 +00001161bgp_collision_detect (struct peer *new, struct in_addr remote_id)
paul718e3742002-12-13 20:15:29 +00001162{
pauleb821182004-05-01 08:44:08 +00001163 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +00001164 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001165 struct bgp *bgp;
1166
1167 bgp = bgp_get_default ();
1168 if (! bgp)
1169 return 0;
1170
1171 /* Upon receipt of an OPEN message, the local system must examine
1172 all of its connections that are in the OpenConfirm state. A BGP
1173 speaker may also examine connections in an OpenSent state if it
1174 knows the BGP Identifier of the peer by means outside of the
1175 protocol. If among these connections there is a connection to a
1176 remote BGP speaker whose BGP Identifier equals the one in the
1177 OPEN message, then the local system performs the following
1178 collision resolution procedure: */
1179
paul1eb8ef22005-04-07 07:30:20 +00001180 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00001181 {
1182 /* Under OpenConfirm status, local peer structure already hold
1183 remote router ID. */
pauleb821182004-05-01 08:44:08 +00001184
1185 if (peer != new
1186 && (peer->status == OpenConfirm || peer->status == OpenSent)
1187 && sockunion_same (&peer->su, &new->su))
1188 {
paul718e3742002-12-13 20:15:29 +00001189 /* 1. The BGP Identifier of the local system is compared to
1190 the BGP Identifier of the remote system (as specified in
1191 the OPEN message). */
1192
1193 if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
1194 {
1195 /* 2. If the value of the local BGP Identifier is less
1196 than the remote one, the local system closes BGP
1197 connection that already exists (the one that is
1198 already in the OpenConfirm state), and accepts BGP
1199 connection initiated by the remote system. */
1200
pauleb821182004-05-01 08:44:08 +00001201 if (peer->fd >= 0)
hassoe0701b72004-05-20 09:19:34 +00001202 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001203 return 1;
1204 }
1205 else
1206 {
1207 /* 3. Otherwise, the local system closes newly created
1208 BGP connection (the one associated with the newly
1209 received OPEN message), and continues to use the
1210 existing one (the one that is already in the
1211 OpenConfirm state). */
1212
pauleb821182004-05-01 08:44:08 +00001213 if (new->fd >= 0)
paulf5ba3872004-07-09 12:11:31 +00001214 bgp_notify_send (new, BGP_NOTIFY_CEASE,
1215 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001216 return -1;
1217 }
pauleb821182004-05-01 08:44:08 +00001218 }
1219 }
paul718e3742002-12-13 20:15:29 +00001220 return 0;
1221}
1222
paul94f2b392005-06-28 12:44:16 +00001223static int
paul718e3742002-12-13 20:15:29 +00001224bgp_open_receive (struct peer *peer, bgp_size_t size)
1225{
1226 int ret;
1227 u_char version;
1228 u_char optlen;
1229 u_int16_t holdtime;
1230 u_int16_t send_holdtime;
1231 as_t remote_as;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001232 as_t as4 = 0;
paul718e3742002-12-13 20:15:29 +00001233 struct peer *realpeer;
1234 struct in_addr remote_id;
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001235 int mp_capability;
paul5228ad22004-06-04 17:58:18 +00001236 u_int8_t notify_data_remote_as[2];
1237 u_int8_t notify_data_remote_id[4];
paul718e3742002-12-13 20:15:29 +00001238
1239 realpeer = NULL;
1240
1241 /* Parse open packet. */
1242 version = stream_getc (peer->ibuf);
1243 memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1244 remote_as = stream_getw (peer->ibuf);
1245 holdtime = stream_getw (peer->ibuf);
1246 memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1247 remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1248
1249 /* Receive OPEN message log */
1250 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001251 zlog_debug ("%s rcv OPEN, version %d, remote-as (in open) %u,"
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001252 " holdtime %d, id %s",
1253 peer->host, version, remote_as, holdtime,
1254 inet_ntoa (remote_id));
1255
1256 /* BEGIN to read the capability here, but dont do it yet */
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001257 mp_capability = 0;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001258 optlen = stream_getc (peer->ibuf);
1259
1260 if (optlen != 0)
1261 {
1262 /* We need the as4 capability value *right now* because
1263 * if it is there, we have not got the remote_as yet, and without
1264 * that we do not know which peer is connecting to us now.
1265 */
1266 as4 = peek_for_as4_capability (peer, optlen);
1267 }
1268
1269 /* Just in case we have a silly peer who sends AS4 capability set to 0 */
1270 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) && !as4)
1271 {
1272 zlog_err ("%s bad OPEN, got AS4 capability, but AS4 set to 0",
1273 peer->host);
1274 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1275 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1276 return -1;
1277 }
1278
1279 if (remote_as == BGP_AS_TRANS)
1280 {
1281 /* Take the AS4 from the capability. We must have received the
1282 * capability now! Otherwise we have a asn16 peer who uses
1283 * BGP_AS_TRANS, for some unknown reason.
1284 */
1285 if (as4 == BGP_AS_TRANS)
1286 {
1287 zlog_err ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
1288 peer->host);
1289 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1290 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1291 return -1;
1292 }
1293
1294 if (!as4 && BGP_DEBUG (as4, AS4))
1295 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
1296 " Odd, but proceeding.", peer->host);
1297 else if (as4 < BGP_AS_MAX && BGP_DEBUG (as4, AS4))
Paul Jakma0df7c912008-07-21 21:02:49 +00001298 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits "
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001299 "in 2-bytes, very odd peer.", peer->host, as4);
1300 if (as4)
1301 remote_as = as4;
1302 }
1303 else
1304 {
1305 /* We may have a partner with AS4 who has an asno < BGP_AS_MAX */
1306 /* If we have got the capability, peer->as4cap must match remote_as */
1307 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)
1308 && as4 != remote_as)
1309 {
1310 /* raise error, log this, close session */
1311 zlog_err ("%s bad OPEN, got AS4 capability, but remote_as %u"
1312 " mismatch with 16bit 'myasn' %u in open",
1313 peer->host, as4, remote_as);
1314 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1315 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1316 return -1;
1317 }
1318 }
1319
paul718e3742002-12-13 20:15:29 +00001320 /* Lookup peer from Open packet. */
1321 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1322 {
1323 int as = 0;
1324
1325 realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1326
1327 if (! realpeer)
1328 {
1329 /* Peer's source IP address is check in bgp_accept(), so this
1330 must be AS number mismatch or remote-id configuration
1331 mismatch. */
1332 if (as)
1333 {
1334 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001335 zlog_debug ("%s bad OPEN, wrong router identifier %s",
1336 peer->host, inet_ntoa (remote_id));
1337 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1338 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1339 notify_data_remote_id, 4);
paul718e3742002-12-13 20:15:29 +00001340 }
1341 else
1342 {
1343 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001344 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
ajs6b514742004-12-08 21:03:23 +00001345 peer->host, remote_as, peer->as);
1346 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1347 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1348 notify_data_remote_as, 2);
paul718e3742002-12-13 20:15:29 +00001349 }
1350 return -1;
1351 }
1352 }
1353
1354 /* When collision is detected and this peer is closed. Retrun
1355 immidiately. */
1356 ret = bgp_collision_detect (peer, remote_id);
1357 if (ret < 0)
1358 return ret;
1359
pauleb821182004-05-01 08:44:08 +00001360 /* Hack part. */
1361 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1362 {
hasso93406d82005-02-02 14:40:33 +00001363 if (realpeer->status == Established
1364 && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1365 {
1366 realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1367 SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1368 }
1369 else if (ret == 0 && realpeer->status != Active
1370 && realpeer->status != OpenSent
Paul Jakma6e199262008-09-09 17:14:33 +01001371 && realpeer->status != OpenConfirm
1372 && realpeer->status != Connect)
pauleb821182004-05-01 08:44:08 +00001373 {
Paul Jakma2b2fc562008-09-06 13:09:35 +01001374 /* XXX: This is an awful problem..
1375 *
1376 * According to the RFC we should just let this connection (of the
1377 * accepted 'peer') continue on to Established if the other
1378 * connection (the 'realpeer' one) is in state Connect, and deal
1379 * with the more larval FSM as/when it gets far enough to receive
1380 * an Open. We don't do that though, we instead close the (more
1381 * developed) accepted connection.
1382 *
1383 * This means there's a race, which if hit, can loop:
1384 *
1385 * FSM for A FSM for B
1386 * realpeer accept-peer realpeer accept-peer
1387 *
1388 * Connect Connect
1389 * Active
1390 * OpenSent OpenSent
1391 * <arrive here,
1392 * Notify, delete>
1393 * Idle Active
1394 * OpenSent OpenSent
1395 * <arrive here,
1396 * Notify, delete>
1397 * Idle
1398 * <wait> <wait>
1399 * Connect Connect
1400 *
1401 *
1402 * If both sides are Quagga, they're almost certain to wait for
1403 * the same amount of time of course (which doesn't preclude other
1404 * implementations also waiting for same time). The race is
1405 * exacerbated by high-latency (in bgpd and/or the network).
1406 *
1407 * The reason we do this is because our FSM is tied to our peer
1408 * structure, which carries our configuration information, etc.
1409 * I.e. we can't let the accepted-peer FSM continue on as it is,
1410 * cause it's not associated with any actual peer configuration -
1411 * it's just a dummy.
1412 *
1413 * It's possible we could hack-fix this by just bgp_stop'ing the
1414 * realpeer and continueing on with the 'transfer FSM' below.
1415 * Ideally, we need to seperate FSMs from struct peer.
1416 *
1417 * Setting one side to passive avoids the race, as a workaround.
1418 */
pauleb821182004-05-01 08:44:08 +00001419 if (BGP_DEBUG (events, EVENTS))
hasso93406d82005-02-02 14:40:33 +00001420 zlog_debug ("%s peer status is %s close connection",
1421 realpeer->host, LOOKUP (bgp_status_msg,
1422 realpeer->status));
1423 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1424 BGP_NOTIFY_CEASE_CONNECT_REJECT);
1425
pauleb821182004-05-01 08:44:08 +00001426 return -1;
1427 }
1428
1429 if (BGP_DEBUG (events, EVENTS))
Paul Jakma6e199262008-09-09 17:14:33 +01001430 zlog_debug ("%s [Event] Transfer accept BGP peer to real (state %s)",
1431 peer->host,
1432 LOOKUP (bgp_status_msg, realpeer->status));
pauleb821182004-05-01 08:44:08 +00001433
1434 bgp_stop (realpeer);
1435
1436 /* Transfer file descriptor. */
1437 realpeer->fd = peer->fd;
1438 peer->fd = -1;
1439
1440 /* Transfer input buffer. */
1441 stream_free (realpeer->ibuf);
1442 realpeer->ibuf = peer->ibuf;
1443 realpeer->packet_size = peer->packet_size;
1444 peer->ibuf = NULL;
1445
1446 /* Transfer status. */
1447 realpeer->status = peer->status;
1448 bgp_stop (peer);
paul200df112005-06-01 11:17:05 +00001449
pauleb821182004-05-01 08:44:08 +00001450 /* peer pointer change. Open packet send to neighbor. */
1451 peer = realpeer;
1452 bgp_open_send (peer);
1453 if (peer->fd < 0)
1454 {
1455 zlog_err ("bgp_open_receive peer's fd is negative value %d",
1456 peer->fd);
1457 return -1;
1458 }
1459 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1460 }
1461
paul718e3742002-12-13 20:15:29 +00001462 /* remote router-id check. */
1463 if (remote_id.s_addr == 0
Denis Ovsienko733cd9e2011-12-17 19:39:30 +04001464 || IPV4_CLASS_DE (ntohl (remote_id.s_addr))
paul718e3742002-12-13 20:15:29 +00001465 || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1466 {
1467 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001468 zlog_debug ("%s bad OPEN, wrong router identifier %s",
paul718e3742002-12-13 20:15:29 +00001469 peer->host, inet_ntoa (remote_id));
1470 bgp_notify_send_with_data (peer,
1471 BGP_NOTIFY_OPEN_ERR,
1472 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1473 notify_data_remote_id, 4);
1474 return -1;
1475 }
1476
1477 /* Set remote router-id */
1478 peer->remote_id = remote_id;
1479
1480 /* Peer BGP version check. */
1481 if (version != BGP_VERSION_4)
1482 {
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001483 u_int16_t maxver = htons(BGP_VERSION_4);
1484 /* XXX this reply may not be correct if version < 4 XXX */
paul718e3742002-12-13 20:15:29 +00001485 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001486 zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
paul718e3742002-12-13 20:15:29 +00001487 peer->host, version, BGP_VERSION_4);
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001488 /* Data must be in network byte order here */
paul718e3742002-12-13 20:15:29 +00001489 bgp_notify_send_with_data (peer,
1490 BGP_NOTIFY_OPEN_ERR,
1491 BGP_NOTIFY_OPEN_UNSUP_VERSION,
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001492 (u_int8_t *) &maxver, 2);
paul718e3742002-12-13 20:15:29 +00001493 return -1;
1494 }
1495
1496 /* Check neighbor as number. */
1497 if (remote_as != peer->as)
1498 {
1499 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001500 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
paul718e3742002-12-13 20:15:29 +00001501 peer->host, remote_as, peer->as);
1502 bgp_notify_send_with_data (peer,
1503 BGP_NOTIFY_OPEN_ERR,
1504 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1505 notify_data_remote_as, 2);
1506 return -1;
1507 }
1508
1509 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1510 calculate the value of the Hold Timer by using the smaller of its
1511 configured Hold Time and the Hold Time received in the OPEN message.
1512 The Hold Time MUST be either zero or at least three seconds. An
1513 implementation may reject connections on the basis of the Hold Time. */
1514
1515 if (holdtime < 3 && holdtime != 0)
1516 {
1517 bgp_notify_send (peer,
1518 BGP_NOTIFY_OPEN_ERR,
1519 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
1520 return -1;
1521 }
1522
1523 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1524 would be one third of the Hold Time interval. KEEPALIVE messages
1525 MUST NOT be sent more frequently than one per second. An
1526 implementation MAY adjust the rate at which it sends KEEPALIVE
1527 messages as a function of the Hold Time interval. */
1528
1529 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1530 send_holdtime = peer->holdtime;
1531 else
1532 send_holdtime = peer->bgp->default_holdtime;
1533
1534 if (holdtime < send_holdtime)
1535 peer->v_holdtime = holdtime;
1536 else
1537 peer->v_holdtime = send_holdtime;
1538
1539 peer->v_keepalive = peer->v_holdtime / 3;
1540
1541 /* Open option part parse. */
paul718e3742002-12-13 20:15:29 +00001542 if (optlen != 0)
1543 {
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001544 if ((ret = bgp_open_option_parse (peer, optlen, &mp_capability)) < 0)
Paul Jakma58617392012-01-09 20:59:26 +00001545 {
1546 bgp_notify_send (peer,
1547 BGP_NOTIFY_OPEN_ERR,
1548 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
1549 return ret;
1550 }
paul718e3742002-12-13 20:15:29 +00001551 }
1552 else
1553 {
1554 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001555 zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
paul718e3742002-12-13 20:15:29 +00001556 peer->host);
1557 }
1558
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001559 /*
1560 * Assume that the peer supports the locally configured set of
1561 * AFI/SAFIs if the peer did not send us any Mulitiprotocol
1562 * capabilities, or if 'override-capability' is configured.
1563 */
1564 if (! mp_capability ||
1565 CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
paul718e3742002-12-13 20:15:29 +00001566 {
1567 peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1568 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1569 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1570 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1571 }
1572
1573 /* Get sockname. */
1574 bgp_getsockname (peer);
Timo Teräs0edba8b2015-10-22 11:35:17 +03001575 peer->rtt = sockopt_tcp_rtt (peer->fd);
paul718e3742002-12-13 20:15:29 +00001576
1577 BGP_EVENT_ADD (peer, Receive_OPEN_message);
1578
1579 peer->packet_size = 0;
1580 if (peer->ibuf)
1581 stream_reset (peer->ibuf);
1582
1583 return 0;
1584}
1585
1586/* Parse BGP Update packet and make attribute object. */
paul94f2b392005-06-28 12:44:16 +00001587static int
paul718e3742002-12-13 20:15:29 +00001588bgp_update_receive (struct peer *peer, bgp_size_t size)
1589{
1590 int ret;
1591 u_char *end;
1592 struct stream *s;
1593 struct attr attr;
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001594 struct attr_extra extra;
paul718e3742002-12-13 20:15:29 +00001595 bgp_size_t attribute_len;
1596 bgp_size_t update_len;
1597 bgp_size_t withdraw_len;
1598 struct bgp_nlri update;
1599 struct bgp_nlri withdraw;
1600 struct bgp_nlri mp_update;
1601 struct bgp_nlri mp_withdraw;
paul718e3742002-12-13 20:15:29 +00001602
1603 /* Status must be Established. */
1604 if (peer->status != Established)
1605 {
1606 zlog_err ("%s [FSM] Update packet received under status %s",
1607 peer->host, LOOKUP (bgp_status_msg, peer->status));
1608 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1609 return -1;
1610 }
1611
1612 /* Set initial values. */
1613 memset (&attr, 0, sizeof (struct attr));
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001614 memset (&extra, 0, sizeof (struct attr_extra));
paul718e3742002-12-13 20:15:29 +00001615 memset (&update, 0, sizeof (struct bgp_nlri));
1616 memset (&withdraw, 0, sizeof (struct bgp_nlri));
1617 memset (&mp_update, 0, sizeof (struct bgp_nlri));
1618 memset (&mp_withdraw, 0, sizeof (struct bgp_nlri));
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001619 attr.extra = &extra;
paul718e3742002-12-13 20:15:29 +00001620
1621 s = peer->ibuf;
1622 end = stream_pnt (s) + size;
1623
1624 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1625 Length is too large (i.e., if Unfeasible Routes Length + Total
1626 Attribute Length + 23 exceeds the message Length), then the Error
1627 Subcode is set to Malformed Attribute List. */
1628 if (stream_pnt (s) + 2 > end)
1629 {
1630 zlog_err ("%s [Error] Update packet error"
1631 " (packet length is short for unfeasible length)",
1632 peer->host);
1633 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1634 BGP_NOTIFY_UPDATE_MAL_ATTR);
1635 return -1;
1636 }
1637
1638 /* Unfeasible Route Length. */
1639 withdraw_len = stream_getw (s);
1640
1641 /* Unfeasible Route Length check. */
1642 if (stream_pnt (s) + withdraw_len > end)
1643 {
1644 zlog_err ("%s [Error] Update packet error"
1645 " (packet unfeasible length overflow %d)",
1646 peer->host, withdraw_len);
1647 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1648 BGP_NOTIFY_UPDATE_MAL_ATTR);
1649 return -1;
1650 }
1651
1652 /* Unfeasible Route packet format check. */
1653 if (withdraw_len > 0)
1654 {
1655 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), withdraw_len);
1656 if (ret < 0)
1657 return -1;
1658
1659 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001660 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001661
1662 withdraw.afi = AFI_IP;
1663 withdraw.safi = SAFI_UNICAST;
1664 withdraw.nlri = stream_pnt (s);
1665 withdraw.length = withdraw_len;
paul9985f832005-02-09 15:51:56 +00001666 stream_forward_getp (s, withdraw_len);
paul718e3742002-12-13 20:15:29 +00001667 }
1668
1669 /* Attribute total length check. */
1670 if (stream_pnt (s) + 2 > end)
1671 {
1672 zlog_warn ("%s [Error] Packet Error"
1673 " (update packet is short for attribute length)",
1674 peer->host);
1675 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1676 BGP_NOTIFY_UPDATE_MAL_ATTR);
1677 return -1;
1678 }
1679
1680 /* Fetch attribute total length. */
1681 attribute_len = stream_getw (s);
1682
1683 /* Attribute length check. */
1684 if (stream_pnt (s) + attribute_len > end)
1685 {
1686 zlog_warn ("%s [Error] Packet Error"
1687 " (update packet attribute length overflow %d)",
1688 peer->host, attribute_len);
1689 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1690 BGP_NOTIFY_UPDATE_MAL_ATTR);
1691 return -1;
1692 }
Paul Jakmab881c702010-11-23 16:35:42 +00001693
1694 /* Certain attribute parsing errors should not be considered bad enough
1695 * to reset the session for, most particularly any partial/optional
1696 * attributes that have 'tunneled' over speakers that don't understand
1697 * them. Instead we withdraw only the prefix concerned.
1698 *
1699 * Complicates the flow a little though..
1700 */
1701 bgp_attr_parse_ret_t attr_parse_ret = BGP_ATTR_PARSE_PROCEED;
1702 /* This define morphs the update case into a withdraw when lower levels
1703 * have signalled an error condition where this is best.
1704 */
1705#define NLRI_ATTR_ARG (attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : NULL)
paul718e3742002-12-13 20:15:29 +00001706
1707 /* Parse attribute when it exists. */
1708 if (attribute_len)
1709 {
Paul Jakmab881c702010-11-23 16:35:42 +00001710 attr_parse_ret = bgp_attr_parse (peer, &attr, attribute_len,
paul718e3742002-12-13 20:15:29 +00001711 &mp_update, &mp_withdraw);
Paul Jakmab881c702010-11-23 16:35:42 +00001712 if (attr_parse_ret == BGP_ATTR_PARSE_ERROR)
David Lamparterf80f8382014-06-04 01:00:51 +02001713 {
1714 bgp_attr_unintern_sub (&attr);
1715 return -1;
1716 }
paul718e3742002-12-13 20:15:29 +00001717 }
Paul Jakmab881c702010-11-23 16:35:42 +00001718
paul718e3742002-12-13 20:15:29 +00001719 /* Logging the attribute. */
Paul Jakmab881c702010-11-23 16:35:42 +00001720 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW
1721 || BGP_DEBUG (update, UPDATE_IN))
paul718e3742002-12-13 20:15:29 +00001722 {
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +00001723 char attrstr[BUFSIZ];
1724 attrstr[0] = '\0';
1725
paule01f9cb2004-07-09 17:48:53 +00001726 ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
Paul Jakmab881c702010-11-23 16:35:42 +00001727 int lvl = (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1728 ? LOG_ERR : LOG_DEBUG;
1729
1730 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1731 zlog (peer->log, LOG_ERR,
1732 "%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
1733 peer->host);
paule01f9cb2004-07-09 17:48:53 +00001734
1735 if (ret)
Paul Jakmab881c702010-11-23 16:35:42 +00001736 zlog (peer->log, lvl, "%s rcvd UPDATE w/ attr: %s",
paule01f9cb2004-07-09 17:48:53 +00001737 peer->host, attrstr);
paul718e3742002-12-13 20:15:29 +00001738 }
Paul Jakmab881c702010-11-23 16:35:42 +00001739
paul718e3742002-12-13 20:15:29 +00001740 /* Network Layer Reachability Information. */
1741 update_len = end - stream_pnt (s);
1742
1743 if (update_len)
1744 {
1745 /* Check NLRI packet format and prefix length. */
1746 ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), update_len);
1747 if (ret < 0)
Paul Jakmab881c702010-11-23 16:35:42 +00001748 {
1749 bgp_attr_unintern_sub (&attr);
Paul Jakmab881c702010-11-23 16:35:42 +00001750 return -1;
1751 }
paul718e3742002-12-13 20:15:29 +00001752
1753 /* Set NLRI portion to structure. */
1754 update.afi = AFI_IP;
1755 update.safi = SAFI_UNICAST;
1756 update.nlri = stream_pnt (s);
1757 update.length = update_len;
paul9985f832005-02-09 15:51:56 +00001758 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001759 }
1760
1761 /* NLRI is processed only when the peer is configured specific
1762 Address Family and Subsequent Address Family. */
1763 if (peer->afc[AFI_IP][SAFI_UNICAST])
1764 {
1765 if (withdraw.length)
1766 bgp_nlri_parse (peer, NULL, &withdraw);
1767
1768 if (update.length)
Paul Jakmab881c702010-11-23 16:35:42 +00001769 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &update);
paule01f9cb2004-07-09 17:48:53 +00001770
hassof4184462005-02-01 20:13:16 +00001771 if (mp_update.length
1772 && mp_update.afi == AFI_IP
1773 && mp_update.safi == SAFI_UNICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001774 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
hassof4184462005-02-01 20:13:16 +00001775
1776 if (mp_withdraw.length
1777 && mp_withdraw.afi == AFI_IP
1778 && mp_withdraw.safi == SAFI_UNICAST)
1779 bgp_nlri_parse (peer, NULL, &mp_withdraw);
1780
paule01f9cb2004-07-09 17:48:53 +00001781 if (! attribute_len && ! withdraw_len)
1782 {
1783 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001784 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],
1785 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001786
hasso93406d82005-02-02 14:40:33 +00001787 /* NSF delete stale route */
1788 if (peer->nsf[AFI_IP][SAFI_UNICAST])
1789 bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);
1790
1791 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001792 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001793 peer->host);
1794 }
paul718e3742002-12-13 20:15:29 +00001795 }
1796 if (peer->afc[AFI_IP][SAFI_MULTICAST])
1797 {
1798 if (mp_update.length
1799 && mp_update.afi == AFI_IP
1800 && mp_update.safi == SAFI_MULTICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001801 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001802
1803 if (mp_withdraw.length
1804 && mp_withdraw.afi == AFI_IP
1805 && mp_withdraw.safi == SAFI_MULTICAST)
1806 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001807
hasso93406d82005-02-02 14:40:33 +00001808 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001809 && mp_withdraw.afi == AFI_IP
1810 && mp_withdraw.safi == SAFI_MULTICAST
1811 && mp_withdraw.length == 0)
1812 {
1813 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001814 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
1815 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001816
hasso93406d82005-02-02 14:40:33 +00001817 /* NSF delete stale route */
1818 if (peer->nsf[AFI_IP][SAFI_MULTICAST])
1819 bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);
1820
1821 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001822 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001823 peer->host);
1824 }
paul718e3742002-12-13 20:15:29 +00001825 }
1826 if (peer->afc[AFI_IP6][SAFI_UNICAST])
1827 {
1828 if (mp_update.length
1829 && mp_update.afi == AFI_IP6
1830 && mp_update.safi == SAFI_UNICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001831 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001832
1833 if (mp_withdraw.length
1834 && mp_withdraw.afi == AFI_IP6
1835 && mp_withdraw.safi == SAFI_UNICAST)
1836 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001837
hasso93406d82005-02-02 14:40:33 +00001838 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001839 && mp_withdraw.afi == AFI_IP6
1840 && mp_withdraw.safi == SAFI_UNICAST
1841 && mp_withdraw.length == 0)
1842 {
1843 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001844 SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001845
hasso93406d82005-02-02 14:40:33 +00001846 /* NSF delete stale route */
1847 if (peer->nsf[AFI_IP6][SAFI_UNICAST])
1848 bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST);
1849
1850 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001851 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001852 peer->host);
1853 }
paul718e3742002-12-13 20:15:29 +00001854 }
1855 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
1856 {
1857 if (mp_update.length
1858 && mp_update.afi == AFI_IP6
1859 && mp_update.safi == SAFI_MULTICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001860 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001861
1862 if (mp_withdraw.length
1863 && mp_withdraw.afi == AFI_IP6
1864 && mp_withdraw.safi == SAFI_MULTICAST)
1865 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001866
hasso93406d82005-02-02 14:40:33 +00001867 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001868 && mp_withdraw.afi == AFI_IP6
1869 && mp_withdraw.safi == SAFI_MULTICAST
1870 && mp_withdraw.length == 0)
1871 {
1872 /* End-of-RIB received */
1873
hasso93406d82005-02-02 14:40:33 +00001874 /* NSF delete stale route */
1875 if (peer->nsf[AFI_IP6][SAFI_MULTICAST])
1876 bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST);
1877
paule01f9cb2004-07-09 17:48:53 +00001878 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001879 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001880 peer->host);
1881 }
paul718e3742002-12-13 20:15:29 +00001882 }
1883 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
1884 {
1885 if (mp_update.length
1886 && mp_update.afi == AFI_IP
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001887 && mp_update.safi == SAFI_MPLS_LABELED_VPN)
Paul Jakmab881c702010-11-23 16:35:42 +00001888 bgp_nlri_parse_vpnv4 (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001889
1890 if (mp_withdraw.length
1891 && mp_withdraw.afi == AFI_IP
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001892 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN)
paul718e3742002-12-13 20:15:29 +00001893 bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001894
hasso93406d82005-02-02 14:40:33 +00001895 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001896 && mp_withdraw.afi == AFI_IP
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001897 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN
paule01f9cb2004-07-09 17:48:53 +00001898 && mp_withdraw.length == 0)
1899 {
1900 /* End-of-RIB received */
1901
1902 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001903 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001904 peer->host);
1905 }
paul718e3742002-12-13 20:15:29 +00001906 }
1907
1908 /* Everything is done. We unintern temporary structures which
1909 interned in bgp_attr_parse(). */
Paul Jakmab881c702010-11-23 16:35:42 +00001910 bgp_attr_unintern_sub (&attr);
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001911
paul718e3742002-12-13 20:15:29 +00001912 /* If peering is stopped due to some reason, do not generate BGP
1913 event. */
1914 if (peer->status != Established)
1915 return 0;
1916
1917 /* Increment packet counter. */
1918 peer->update_in++;
Stephen Hemminger65957882010-01-15 16:22:10 +03001919 peer->update_time = bgp_clock ();
paul718e3742002-12-13 20:15:29 +00001920
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02001921 /* Rearm holdtime timer */
Jorge Boncompte [DTI2]6a4677b2012-05-07 16:53:07 +00001922 BGP_TIMER_OFF (peer->t_holdtime);
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02001923 bgp_timer_set (peer);
paul718e3742002-12-13 20:15:29 +00001924
1925 return 0;
1926}
1927
1928/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00001929static void
paul718e3742002-12-13 20:15:29 +00001930bgp_notify_receive (struct peer *peer, bgp_size_t size)
1931{
1932 struct bgp_notify bgp_notify;
1933
1934 if (peer->notify.data)
1935 {
1936 XFREE (MTYPE_TMP, peer->notify.data);
1937 peer->notify.data = NULL;
1938 peer->notify.length = 0;
1939 }
1940
1941 bgp_notify.code = stream_getc (peer->ibuf);
1942 bgp_notify.subcode = stream_getc (peer->ibuf);
1943 bgp_notify.length = size - 2;
1944 bgp_notify.data = NULL;
1945
1946 /* Preserv notify code and sub code. */
1947 peer->notify.code = bgp_notify.code;
1948 peer->notify.subcode = bgp_notify.subcode;
1949 /* For further diagnostic record returned Data. */
1950 if (bgp_notify.length)
1951 {
1952 peer->notify.length = size - 2;
1953 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
1954 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
1955 }
1956
1957 /* For debug */
1958 {
1959 int i;
1960 int first = 0;
1961 char c[4];
1962
1963 if (bgp_notify.length)
1964 {
1965 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
1966 for (i = 0; i < bgp_notify.length; i++)
1967 if (first)
1968 {
1969 sprintf (c, " %02x", stream_getc (peer->ibuf));
1970 strcat (bgp_notify.data, c);
1971 }
1972 else
1973 {
1974 first = 1;
1975 sprintf (c, "%02x", stream_getc (peer->ibuf));
1976 strcpy (bgp_notify.data, c);
1977 }
1978 }
1979
1980 bgp_notify_print(peer, &bgp_notify, "received");
1981 if (bgp_notify.data)
Daniel Walton363c9032015-10-21 06:42:54 -07001982 {
1983 XFREE (MTYPE_TMP, bgp_notify.data);
1984 bgp_notify.data = NULL;
1985 bgp_notify.length = 0;
1986 }
paul718e3742002-12-13 20:15:29 +00001987 }
1988
1989 /* peer count update */
1990 peer->notify_in++;
1991
hassoe0701b72004-05-20 09:19:34 +00001992 if (peer->status == Established)
1993 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
1994
paul718e3742002-12-13 20:15:29 +00001995 /* We have to check for Notify with Unsupported Optional Parameter.
1996 in that case we fallback to open without the capability option.
1997 But this done in bgp_stop. We just mark it here to avoid changing
1998 the fsm tables. */
1999 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
2000 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
2001 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
2002
paul718e3742002-12-13 20:15:29 +00002003 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
2004}
2005
2006/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00002007static void
paul718e3742002-12-13 20:15:29 +00002008bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
2009{
2010 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00002011 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00002012
2013 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
2014}
2015
2016/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00002017static void
paul718e3742002-12-13 20:15:29 +00002018bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
2019{
2020 afi_t afi;
2021 safi_t safi;
paul718e3742002-12-13 20:15:29 +00002022 struct stream *s;
2023
2024 /* If peer does not have the capability, send notification. */
2025 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
2026 {
2027 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
2028 peer->host);
2029 bgp_notify_send (peer,
2030 BGP_NOTIFY_HEADER_ERR,
2031 BGP_NOTIFY_HEADER_BAD_MESTYPE);
2032 return;
2033 }
2034
2035 /* Status must be Established. */
2036 if (peer->status != Established)
2037 {
2038 plog_err (peer->log,
2039 "%s [Error] Route refresh packet received under status %s",
2040 peer->host, LOOKUP (bgp_status_msg, peer->status));
2041 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
2042 return;
2043 }
2044
2045 s = peer->ibuf;
2046
2047 /* Parse packet. */
2048 afi = stream_getw (s);
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002049 /* reserved byte */
2050 stream_getc (s);
paul718e3742002-12-13 20:15:29 +00002051 safi = stream_getc (s);
2052
2053 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002054 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00002055 peer->host, afi, safi);
2056
2057 /* Check AFI and SAFI. */
2058 if ((afi != AFI_IP && afi != AFI_IP6)
2059 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
Denis Ovsienko42e6d742011-07-14 12:36:19 +04002060 && safi != SAFI_MPLS_LABELED_VPN))
paul718e3742002-12-13 20:15:29 +00002061 {
2062 if (BGP_DEBUG (normal, NORMAL))
2063 {
ajs6b514742004-12-08 21:03:23 +00002064 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00002065 peer->host, afi, safi);
2066 }
2067 return;
2068 }
2069
2070 /* Adjust safi code. */
Denis Ovsienko42e6d742011-07-14 12:36:19 +04002071 if (safi == SAFI_MPLS_LABELED_VPN)
paul718e3742002-12-13 20:15:29 +00002072 safi = SAFI_MPLS_VPN;
2073
2074 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
2075 {
2076 u_char *end;
2077 u_char when_to_refresh;
2078 u_char orf_type;
2079 u_int16_t orf_len;
2080
2081 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
2082 {
2083 zlog_info ("%s ORF route refresh length error", peer->host);
2084 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2085 return;
2086 }
2087
2088 when_to_refresh = stream_getc (s);
2089 end = stream_pnt (s) + (size - 5);
2090
Paul Jakma370b64a2007-12-22 16:49:52 +00002091 while ((stream_pnt (s) + 2) < end)
paul718e3742002-12-13 20:15:29 +00002092 {
2093 orf_type = stream_getc (s);
2094 orf_len = stream_getw (s);
Paul Jakma370b64a2007-12-22 16:49:52 +00002095
2096 /* orf_len in bounds? */
2097 if ((stream_pnt (s) + orf_len) > end)
2098 break; /* XXX: Notify instead?? */
paul718e3742002-12-13 20:15:29 +00002099 if (orf_type == ORF_TYPE_PREFIX
2100 || orf_type == ORF_TYPE_PREFIX_OLD)
2101 {
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002102 uint8_t *p_pnt = stream_pnt (s);
2103 uint8_t *p_end = stream_pnt (s) + orf_len;
paul718e3742002-12-13 20:15:29 +00002104 struct orf_prefix orfp;
2105 u_char common = 0;
2106 u_int32_t seq;
2107 int psize;
2108 char name[BUFSIZ];
paul718e3742002-12-13 20:15:29 +00002109 int ret;
2110
2111 if (BGP_DEBUG (normal, NORMAL))
2112 {
ajs6b514742004-12-08 21:03:23 +00002113 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00002114 peer->host, orf_type, orf_len);
2115 }
2116
Paul Jakma370b64a2007-12-22 16:49:52 +00002117 /* we're going to read at least 1 byte of common ORF header,
2118 * and 7 bytes of ORF Address-filter entry from the stream
2119 */
2120 if (orf_len < 7)
2121 break;
2122
paul718e3742002-12-13 20:15:29 +00002123 /* ORF prefix-list name */
2124 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
2125
2126 while (p_pnt < p_end)
2127 {
Chris Halld64379e2010-05-14 16:38:39 +04002128 /* If the ORF entry is malformed, want to read as much of it
2129 * as possible without going beyond the bounds of the entry,
2130 * to maximise debug information.
2131 */
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002132 int ok;
paul718e3742002-12-13 20:15:29 +00002133 memset (&orfp, 0, sizeof (struct orf_prefix));
2134 common = *p_pnt++;
Chris Halld64379e2010-05-14 16:38:39 +04002135 /* after ++: p_pnt <= p_end */
paul718e3742002-12-13 20:15:29 +00002136 if (common & ORF_COMMON_PART_REMOVE_ALL)
2137 {
2138 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002139 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
David Lamparterc9c06d02015-04-13 10:21:35 +02002140 prefix_bgp_orf_remove_all (afi, name);
paul718e3742002-12-13 20:15:29 +00002141 break;
2142 }
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002143 ok = ((size_t)(p_end - p_pnt) >= sizeof(u_int32_t)) ;
Denis Ovsienkobb915f52011-12-13 21:11:39 +04002144 if (ok)
Chris Halld64379e2010-05-14 16:38:39 +04002145 {
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002146 memcpy (&seq, p_pnt, sizeof (u_int32_t));
2147 p_pnt += sizeof (u_int32_t);
2148 orfp.seq = ntohl (seq);
Chris Halld64379e2010-05-14 16:38:39 +04002149 }
2150 else
2151 p_pnt = p_end ;
2152
2153 if ((ok = (p_pnt < p_end)))
2154 orfp.ge = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2155 if ((ok = (p_pnt < p_end)))
2156 orfp.le = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2157 if ((ok = (p_pnt < p_end)))
2158 orfp.p.prefixlen = *p_pnt++ ;
2159 orfp.p.family = afi2family (afi); /* afi checked already */
2160
2161 psize = PSIZE (orfp.p.prefixlen); /* 0 if not ok */
2162 if (psize > prefix_blen(&orfp.p)) /* valid for family ? */
2163 {
2164 ok = 0 ;
2165 psize = prefix_blen(&orfp.p) ;
2166 }
2167 if (psize > (p_end - p_pnt)) /* valid for packet ? */
2168 {
2169 ok = 0 ;
2170 psize = p_end - p_pnt ;
2171 }
2172
2173 if (psize > 0)
2174 memcpy (&orfp.p.u.prefix, p_pnt, psize);
paul718e3742002-12-13 20:15:29 +00002175 p_pnt += psize;
2176
2177 if (BGP_DEBUG (normal, NORMAL))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +00002178 {
2179 char buf[INET6_BUFSIZ];
2180
2181 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
2182 peer->host,
2183 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
2184 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
2185 orfp.seq,
2186 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, INET6_BUFSIZ),
2187 orfp.p.prefixlen, orfp.ge, orfp.le,
2188 ok ? "" : " MALFORMED");
2189 }
2190
Chris Halld64379e2010-05-14 16:38:39 +04002191 if (ok)
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002192 ret = prefix_bgp_orf_set (name, afi, &orfp,
2193 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
2194 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002195
2196 if (!ok || (ok && ret != CMD_SUCCESS))
paul718e3742002-12-13 20:15:29 +00002197 {
2198 if (BGP_DEBUG (normal, NORMAL))
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002199 zlog_debug ("%s Received misformatted prefixlist ORF."
2200 " Remove All pfxlist", peer->host);
David Lamparterc9c06d02015-04-13 10:21:35 +02002201 prefix_bgp_orf_remove_all (afi, name);
paul718e3742002-12-13 20:15:29 +00002202 break;
2203 }
2204 }
2205 peer->orf_plist[afi][safi] =
David Lamparterc9c06d02015-04-13 10:21:35 +02002206 prefix_bgp_orf_lookup (afi, name);
paul718e3742002-12-13 20:15:29 +00002207 }
paul9985f832005-02-09 15:51:56 +00002208 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00002209 }
2210 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002211 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00002212 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
2213 if (when_to_refresh == REFRESH_DEFER)
2214 return;
2215 }
2216
2217 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2218 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
2219 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
2220
2221 /* Perform route refreshment to the peer */
2222 bgp_announce_route (peer, afi, safi);
2223}
2224
paul94f2b392005-06-28 12:44:16 +00002225static int
paul718e3742002-12-13 20:15:29 +00002226bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
2227{
2228 u_char *end;
Paul Jakma6d582722007-08-06 15:21:45 +00002229 struct capability_mp_data mpc;
2230 struct capability_header *hdr;
paul718e3742002-12-13 20:15:29 +00002231 u_char action;
paul718e3742002-12-13 20:15:29 +00002232 afi_t afi;
2233 safi_t safi;
2234
paul718e3742002-12-13 20:15:29 +00002235 end = pnt + length;
2236
2237 while (pnt < end)
Paul Jakma6d582722007-08-06 15:21:45 +00002238 {
paul718e3742002-12-13 20:15:29 +00002239 /* We need at least action, capability code and capability length. */
2240 if (pnt + 3 > end)
2241 {
2242 zlog_info ("%s Capability length error", peer->host);
2243 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2244 return -1;
2245 }
paul718e3742002-12-13 20:15:29 +00002246 action = *pnt;
Paul Jakma6d582722007-08-06 15:21:45 +00002247 hdr = (struct capability_header *)(pnt + 1);
2248
paul718e3742002-12-13 20:15:29 +00002249 /* Action value check. */
2250 if (action != CAPABILITY_ACTION_SET
2251 && action != CAPABILITY_ACTION_UNSET)
2252 {
2253 zlog_info ("%s Capability Action Value error %d",
2254 peer->host, action);
2255 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2256 return -1;
2257 }
2258
2259 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002260 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
Paul Jakma6d582722007-08-06 15:21:45 +00002261 peer->host, action, hdr->code, hdr->length);
paul718e3742002-12-13 20:15:29 +00002262
2263 /* Capability length check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002264 if ((pnt + hdr->length + 3) > end)
paul718e3742002-12-13 20:15:29 +00002265 {
2266 zlog_info ("%s Capability length error", peer->host);
2267 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2268 return -1;
2269 }
2270
Paul Jakma6d582722007-08-06 15:21:45 +00002271 /* Fetch structure to the byte stream. */
2272 memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
2273
paul718e3742002-12-13 20:15:29 +00002274 /* We know MP Capability Code. */
Paul Jakma6d582722007-08-06 15:21:45 +00002275 if (hdr->code == CAPABILITY_CODE_MP)
paul718e3742002-12-13 20:15:29 +00002276 {
Paul Jakma6d582722007-08-06 15:21:45 +00002277 afi = ntohs (mpc.afi);
2278 safi = mpc.safi;
paul718e3742002-12-13 20:15:29 +00002279
2280 /* Ignore capability when override-capability is set. */
2281 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2282 continue;
Paul Jakma6d582722007-08-06 15:21:45 +00002283
2284 if (!bgp_afi_safi_valid_indices (afi, &safi))
2285 {
2286 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002287 zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
2288 "(%u/%u)", peer->host, afi, safi);
Paul Jakma6d582722007-08-06 15:21:45 +00002289 continue;
2290 }
2291
paul718e3742002-12-13 20:15:29 +00002292 /* Address family check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002293 if (BGP_DEBUG (normal, NORMAL))
2294 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2295 peer->host,
2296 action == CAPABILITY_ACTION_SET
2297 ? "Advertising" : "Removing",
2298 ntohs(mpc.afi) , mpc.safi);
2299
2300 if (action == CAPABILITY_ACTION_SET)
2301 {
2302 peer->afc_recv[afi][safi] = 1;
2303 if (peer->afc[afi][safi])
2304 {
2305 peer->afc_nego[afi][safi] = 1;
2306 bgp_announce_route (peer, afi, safi);
2307 }
2308 }
2309 else
2310 {
2311 peer->afc_recv[afi][safi] = 0;
2312 peer->afc_nego[afi][safi] = 0;
paul718e3742002-12-13 20:15:29 +00002313
Paul Jakma6d582722007-08-06 15:21:45 +00002314 if (peer_active_nego (peer))
Chris Caputo228da422009-07-18 05:44:03 +00002315 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
Paul Jakma6d582722007-08-06 15:21:45 +00002316 else
2317 BGP_EVENT_ADD (peer, BGP_Stop);
2318 }
paul718e3742002-12-13 20:15:29 +00002319 }
paul718e3742002-12-13 20:15:29 +00002320 else
2321 {
2322 zlog_warn ("%s unrecognized capability code: %d - ignored",
Paul Jakma6d582722007-08-06 15:21:45 +00002323 peer->host, hdr->code);
paul718e3742002-12-13 20:15:29 +00002324 }
Paul Jakma6d582722007-08-06 15:21:45 +00002325 pnt += hdr->length + 3;
paul718e3742002-12-13 20:15:29 +00002326 }
2327 return 0;
2328}
2329
Paul Jakma01b7ce22009-06-18 12:34:43 +01002330/* Dynamic Capability is received.
2331 *
2332 * This is exported for unit-test purposes
2333 */
Paul Jakma6d582722007-08-06 15:21:45 +00002334int
paul718e3742002-12-13 20:15:29 +00002335bgp_capability_receive (struct peer *peer, bgp_size_t size)
2336{
2337 u_char *pnt;
paul718e3742002-12-13 20:15:29 +00002338
2339 /* Fetch pointer. */
2340 pnt = stream_pnt (peer->ibuf);
2341
2342 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002343 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002344
2345 /* If peer does not have the capability, send notification. */
2346 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2347 {
2348 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2349 peer->host);
2350 bgp_notify_send (peer,
2351 BGP_NOTIFY_HEADER_ERR,
2352 BGP_NOTIFY_HEADER_BAD_MESTYPE);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002353 return -1;
paul718e3742002-12-13 20:15:29 +00002354 }
2355
2356 /* Status must be Established. */
2357 if (peer->status != Established)
2358 {
2359 plog_err (peer->log,
2360 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2361 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002362 return -1;
paul718e3742002-12-13 20:15:29 +00002363 }
2364
2365 /* Parse packet. */
Paul Jakma6d582722007-08-06 15:21:45 +00002366 return bgp_capability_msg_parse (peer, pnt, size);
paul718e3742002-12-13 20:15:29 +00002367}
David Lamparter6b0655a2014-06-04 06:53:35 +02002368
paul718e3742002-12-13 20:15:29 +00002369/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002370static int
paul718e3742002-12-13 20:15:29 +00002371bgp_read_packet (struct peer *peer)
2372{
2373 int nbytes;
2374 int readsize;
2375
paul9985f832005-02-09 15:51:56 +00002376 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002377
2378 /* If size is zero then return. */
2379 if (! readsize)
2380 return 0;
2381
2382 /* Read packet from fd. */
Stephen Hemminger35398582010-08-05 10:26:23 -07002383 nbytes = stream_read_try (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002384
2385 /* If read byte is smaller than zero then error occured. */
2386 if (nbytes < 0)
2387 {
Stephen Hemminger35398582010-08-05 10:26:23 -07002388 /* Transient error should retry */
2389 if (nbytes == -2)
paul718e3742002-12-13 20:15:29 +00002390 return -1;
2391
2392 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002393 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002394
2395 if (peer->status == Established)
2396 {
2397 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2398 {
2399 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2400 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2401 }
2402 else
2403 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2404 }
2405
paul718e3742002-12-13 20:15:29 +00002406 BGP_EVENT_ADD (peer, TCP_fatal_error);
2407 return -1;
2408 }
2409
2410 /* When read byte is zero : clear bgp peer and return */
2411 if (nbytes == 0)
2412 {
2413 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002414 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002415 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002416
2417 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002418 {
2419 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2420 {
2421 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2422 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2423 }
2424 else
2425 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2426 }
hassoe0701b72004-05-20 09:19:34 +00002427
paul718e3742002-12-13 20:15:29 +00002428 BGP_EVENT_ADD (peer, TCP_connection_closed);
2429 return -1;
2430 }
2431
2432 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002433 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002434 return -1;
2435
2436 return 0;
2437}
2438
2439/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002440static int
paul718e3742002-12-13 20:15:29 +00002441bgp_marker_all_one (struct stream *s, int length)
2442{
2443 int i;
2444
2445 for (i = 0; i < length; i++)
2446 if (s->data[i] != 0xff)
2447 return 0;
2448
2449 return 1;
2450}
2451
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002452/* Recent thread time.
2453 On same clock base as bgp_clock (MONOTONIC)
2454 but can be time of last context switch to bgp_read thread. */
2455static time_t
2456bgp_recent_clock (void)
2457{
2458 return recent_relative_time().tv_sec;
2459}
2460
paul718e3742002-12-13 20:15:29 +00002461/* Starting point of packet process function. */
2462int
2463bgp_read (struct thread *thread)
2464{
2465 int ret;
2466 u_char type = 0;
2467 struct peer *peer;
2468 bgp_size_t size;
2469 char notify_data_length[2];
2470
2471 /* Yes first of all get peer pointer. */
2472 peer = THREAD_ARG (thread);
2473 peer->t_read = NULL;
2474
2475 /* For non-blocking IO check. */
2476 if (peer->status == Connect)
2477 {
2478 bgp_connect_check (peer);
2479 goto done;
2480 }
2481 else
2482 {
pauleb821182004-05-01 08:44:08 +00002483 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002484 {
pauleb821182004-05-01 08:44:08 +00002485 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002486 return -1;
2487 }
pauleb821182004-05-01 08:44:08 +00002488 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002489 }
2490
2491 /* Read packet header to determine type of the packet */
2492 if (peer->packet_size == 0)
2493 peer->packet_size = BGP_HEADER_SIZE;
2494
paul9985f832005-02-09 15:51:56 +00002495 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002496 {
2497 ret = bgp_read_packet (peer);
2498
2499 /* Header read error or partial read packet. */
2500 if (ret < 0)
2501 goto done;
2502
2503 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002504 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002505 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2506 size = stream_getw (peer->ibuf);
2507 type = stream_getc (peer->ibuf);
2508
2509 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002510 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002511 peer->host, type, size - BGP_HEADER_SIZE);
2512
2513 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002514 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002515 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2516 {
2517 bgp_notify_send (peer,
2518 BGP_NOTIFY_HEADER_ERR,
2519 BGP_NOTIFY_HEADER_NOT_SYNC);
2520 goto done;
2521 }
2522
2523 /* BGP type check. */
2524 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2525 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2526 && type != BGP_MSG_ROUTE_REFRESH_NEW
2527 && type != BGP_MSG_ROUTE_REFRESH_OLD
2528 && type != BGP_MSG_CAPABILITY)
2529 {
2530 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002531 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002532 "%s unknown message type 0x%02x",
2533 peer->host, type);
2534 bgp_notify_send_with_data (peer,
2535 BGP_NOTIFY_HEADER_ERR,
2536 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2537 &type, 1);
2538 goto done;
2539 }
2540 /* Mimimum packet length check. */
2541 if ((size < BGP_HEADER_SIZE)
2542 || (size > BGP_MAX_PACKET_SIZE)
2543 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2544 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2545 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2546 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2547 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2548 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2549 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2550 {
2551 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002552 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002553 "%s bad message length - %d for %s",
2554 peer->host, size,
2555 type == 128 ? "ROUTE-REFRESH" :
2556 bgp_type_str[(int) type]);
2557 bgp_notify_send_with_data (peer,
2558 BGP_NOTIFY_HEADER_ERR,
2559 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002560 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002561 goto done;
2562 }
2563
2564 /* Adjust size to message length. */
2565 peer->packet_size = size;
2566 }
2567
2568 ret = bgp_read_packet (peer);
2569 if (ret < 0)
2570 goto done;
2571
2572 /* Get size and type again. */
2573 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2574 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2575
2576 /* BGP packet dump function. */
2577 bgp_dump_packet (peer, type, peer->ibuf);
2578
2579 size = (peer->packet_size - BGP_HEADER_SIZE);
2580
2581 /* Read rest of the packet and call each sort of packet routine */
2582 switch (type)
2583 {
2584 case BGP_MSG_OPEN:
2585 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002586 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002587 break;
2588 case BGP_MSG_UPDATE:
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002589 peer->readtime = bgp_recent_clock ();
paul718e3742002-12-13 20:15:29 +00002590 bgp_update_receive (peer, size);
2591 break;
2592 case BGP_MSG_NOTIFY:
2593 bgp_notify_receive (peer, size);
2594 break;
2595 case BGP_MSG_KEEPALIVE:
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002596 peer->readtime = bgp_recent_clock ();
paul718e3742002-12-13 20:15:29 +00002597 bgp_keepalive_receive (peer, size);
2598 break;
2599 case BGP_MSG_ROUTE_REFRESH_NEW:
2600 case BGP_MSG_ROUTE_REFRESH_OLD:
2601 peer->refresh_in++;
2602 bgp_route_refresh_receive (peer, size);
2603 break;
2604 case BGP_MSG_CAPABILITY:
2605 peer->dynamic_cap_in++;
2606 bgp_capability_receive (peer, size);
2607 break;
2608 }
2609
2610 /* Clear input buffer. */
2611 peer->packet_size = 0;
2612 if (peer->ibuf)
2613 stream_reset (peer->ibuf);
2614
2615 done:
2616 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2617 {
2618 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002619 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002620 peer_delete (peer);
paul718e3742002-12-13 20:15:29 +00002621 }
2622 return 0;
2623}