blob: 2ec595f79e10c36bff7d92119556843137179a44 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* BGP packet management routine.
2 Copyright (C) 1999 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include <zebra.h>
22
23#include "thread.h"
24#include "stream.h"
25#include "network.h"
26#include "prefix.h"
27#include "command.h"
28#include "log.h"
29#include "memory.h"
30#include "sockunion.h" /* for inet_ntop () */
Timo Teräsef757702015-04-29 09:43:04 +030031#include "sockopt.h"
paul718e3742002-12-13 20:15:29 +000032#include "linklist.h"
33#include "plist.h"
Donald Sharp04907292016-01-07 10:03:01 -050034#include "filter.h"
paul718e3742002-12-13 20:15:29 +000035
36#include "bgpd/bgpd.h"
37#include "bgpd/bgp_table.h"
38#include "bgpd/bgp_dump.h"
39#include "bgpd/bgp_attr.h"
40#include "bgpd/bgp_debug.h"
41#include "bgpd/bgp_fsm.h"
42#include "bgpd/bgp_route.h"
43#include "bgpd/bgp_packet.h"
44#include "bgpd/bgp_open.h"
45#include "bgpd/bgp_aspath.h"
46#include "bgpd/bgp_community.h"
47#include "bgpd/bgp_ecommunity.h"
48#include "bgpd/bgp_network.h"
49#include "bgpd/bgp_mplsvpn.h"
Lou Berger298cc2f2016-01-12 13:42:02 -050050#include "bgpd/bgp_encap.h"
paul718e3742002-12-13 20:15:29 +000051#include "bgpd/bgp_advertise.h"
hasso93406d82005-02-02 14:40:33 +000052#include "bgpd/bgp_vty.h"
paul718e3742002-12-13 20:15:29 +000053
54int stream_put_prefix (struct stream *, struct prefix *);
David Lamparter6b0655a2014-06-04 06:53:35 +020055
paul718e3742002-12-13 20:15:29 +000056/* Set up BGP packet marker and packet type. */
57static int
58bgp_packet_set_marker (struct stream *s, u_char type)
59{
60 int i;
61
62 /* Fill in marker. */
63 for (i = 0; i < BGP_MARKER_SIZE; i++)
64 stream_putc (s, 0xff);
65
66 /* Dummy total length. This field is should be filled in later on. */
67 stream_putw (s, 0);
68
69 /* BGP packet type. */
70 stream_putc (s, type);
71
72 /* Return current stream size. */
paul9985f832005-02-09 15:51:56 +000073 return stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +000074}
75
76/* Set BGP packet header size entry. If size is zero then use current
77 stream size. */
78static int
79bgp_packet_set_size (struct stream *s)
80{
81 int cp;
82
83 /* Preserve current pointer. */
paul9985f832005-02-09 15:51:56 +000084 cp = stream_get_endp (s);
85 stream_putw_at (s, BGP_MARKER_SIZE, cp);
paul718e3742002-12-13 20:15:29 +000086
87 return cp;
88}
89
90/* Add new packet to the peer. */
paul94f2b392005-06-28 12:44:16 +000091static void
paul718e3742002-12-13 20:15:29 +000092bgp_packet_add (struct peer *peer, struct stream *s)
93{
94 /* Add packet to the end of list. */
95 stream_fifo_push (peer->obuf, s);
96}
97
98/* Free first packet. */
paul94f2b392005-06-28 12:44:16 +000099static void
paul718e3742002-12-13 20:15:29 +0000100bgp_packet_delete (struct peer *peer)
101{
102 stream_free (stream_fifo_pop (peer->obuf));
103}
104
paul718e3742002-12-13 20:15:29 +0000105/* Check file descriptor whether connect is established. */
Dinesh Duttd9ab53a2015-05-19 17:47:21 -0700106int
107bgp_connect_check (struct peer *peer, int change_state)
paul718e3742002-12-13 20:15:29 +0000108{
109 int status;
paul5228ad22004-06-04 17:58:18 +0000110 socklen_t slen;
paul718e3742002-12-13 20:15:29 +0000111 int ret;
112
113 /* Anyway I have to reset read and write thread. */
114 BGP_READ_OFF (peer->t_read);
115 BGP_WRITE_OFF (peer->t_write);
116
117 /* Check file descriptor. */
118 slen = sizeof (status);
pauleb821182004-05-01 08:44:08 +0000119 ret = getsockopt(peer->fd, SOL_SOCKET, SO_ERROR, (void *) &status, &slen);
paul718e3742002-12-13 20:15:29 +0000120
121 /* If getsockopt is fail, this is fatal error. */
122 if (ret < 0)
123 {
124 zlog (peer->log, LOG_INFO, "can't get sockopt for nonblocking connect");
125 BGP_EVENT_ADD (peer, TCP_fatal_error);
Dinesh Duttd9ab53a2015-05-19 17:47:21 -0700126 return -1;
paul718e3742002-12-13 20:15:29 +0000127 }
128
129 /* When status is 0 then TCP connection is established. */
130 if (status == 0)
131 {
132 BGP_EVENT_ADD (peer, TCP_connection_open);
Dinesh Duttd9ab53a2015-05-19 17:47:21 -0700133 return 1;
paul718e3742002-12-13 20:15:29 +0000134 }
135 else
136 {
137 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +0000138 plog_debug (peer->log, "%s [Event] Connect failed (%s)",
ajs6099b3b2004-11-20 02:06:59 +0000139 peer->host, safe_strerror (errno));
Dinesh Duttd9ab53a2015-05-19 17:47:21 -0700140 if (change_state)
141 BGP_EVENT_ADD (peer, TCP_connection_open_failed);
142 return 0;
paul718e3742002-12-13 20:15:29 +0000143 }
144}
145
146/* Make BGP update packet. */
paul94f2b392005-06-28 12:44:16 +0000147static struct stream *
paul718e3742002-12-13 20:15:29 +0000148bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi)
149{
150 struct stream *s;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000151 struct stream *snlri;
paul718e3742002-12-13 20:15:29 +0000152 struct bgp_adj_out *adj;
153 struct bgp_advertise *adv;
154 struct stream *packet;
155 struct bgp_node *rn = NULL;
156 struct bgp_info *binfo = NULL;
157 bgp_size_t total_attr_len = 0;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000158 unsigned long attrlen_pos = 0;
Daniel Walton5bcd7542015-05-19 17:58:10 -0700159 int space_remaining = 0;
160 int space_needed = 0;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000161 size_t mpattrlen_pos = 0;
162 size_t mpattr_pos = 0;
paul718e3742002-12-13 20:15:29 +0000163
164 s = peer->work;
165 stream_reset (s);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000166 snlri = peer->scratch;
167 stream_reset (snlri);
paul718e3742002-12-13 20:15:29 +0000168
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100169 adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update);
paul718e3742002-12-13 20:15:29 +0000170
171 while (adv)
172 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000173 assert (adv->rn);
174 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000175 adj = adv->adj;
176 if (adv->binfo)
177 binfo = adv->binfo;
paul718e3742002-12-13 20:15:29 +0000178
Daniel Walton5bcd7542015-05-19 17:58:10 -0700179 space_remaining = STREAM_CONCAT_REMAIN (s, snlri, STREAM_SIZE(s)) -
180 BGP_MAX_PACKET_SIZE_OVERFLOW;
181 space_needed = BGP_NLRI_LENGTH + bgp_packet_mpattr_prefix_size (afi, safi, &rn->p);
182
paul718e3742002-12-13 20:15:29 +0000183 /* When remaining space can't include NLRI and it's length. */
Daniel Walton5bcd7542015-05-19 17:58:10 -0700184 if (space_remaining < space_needed)
paul718e3742002-12-13 20:15:29 +0000185 break;
186
187 /* If packet is empty, set attribute. */
188 if (stream_empty (s))
189 {
Lou Berger050defe2016-01-12 13:41:59 -0500190 struct prefix_rd *prd = NULL;
191 u_char *tag = NULL;
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000192 struct peer *from = NULL;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000193
Lou Berger050defe2016-01-12 13:41:59 -0500194 if (rn->prn)
195 prd = (struct prefix_rd *) &rn->prn->p;
Greg Troxeld3ddb222010-09-17 10:47:49 -0400196 if (binfo)
Lou Berger050defe2016-01-12 13:41:59 -0500197 {
198 from = binfo->peer;
199 if (binfo->extra)
200 tag = binfo->extra->tag;
201 }
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000202
203 /* 1: Write the BGP message header - 16 bytes marker, 2 bytes length,
204 * one byte message type.
205 */
paul718e3742002-12-13 20:15:29 +0000206 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000207
208 /* 2: withdrawn routes length */
paul718e3742002-12-13 20:15:29 +0000209 stream_putw (s, 0);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000210
211 /* 3: total attributes length - attrlen_pos stores the position */
212 attrlen_pos = stream_get_endp (s);
213 stream_putw (s, 0);
214
215 /* 4: if there is MP_REACH_NLRI attribute, that should be the first
216 * attribute, according to draft-ietf-idr-error-handling. Save the
217 * position.
218 */
219 mpattr_pos = stream_get_endp(s);
220
221 /* 5: Encode all the attributes, except MP_REACH_NLRI attr. */
222 total_attr_len = bgp_packet_attribute (NULL, peer, s,
paul5228ad22004-06-04 17:58:18 +0000223 adv->baa->attr,
Lou Berger298cc2f2016-01-12 13:42:02 -0500224 ((afi == AFI_IP && safi == SAFI_UNICAST) ?
225 &rn->p : NULL),
226 afi, safi,
Lou Berger050defe2016-01-12 13:41:59 -0500227 from, prd, tag);
Daniel Walton5bcd7542015-05-19 17:58:10 -0700228 space_remaining = STREAM_CONCAT_REMAIN (s, snlri, STREAM_SIZE(s)) -
229 BGP_MAX_PACKET_SIZE_OVERFLOW;
230 space_needed = BGP_NLRI_LENGTH + bgp_packet_mpattr_prefix_size (afi, safi, &rn->p);;
231
232 /* If the attributes alone do not leave any room for NLRI then
233 * return */
234 if (space_remaining < space_needed)
235 {
236 zlog_err ("%s cannot send UPDATE, the attributes do not leave "
237 "room for NLRI", peer->host);
238 /* Flush the FIFO update queue */
239 while (adv)
240 adv = bgp_advertise_clean (peer, adv->adj, afi, safi);
241 return NULL;
242 }
243
paul718e3742002-12-13 20:15:29 +0000244 }
245
246 if (afi == AFI_IP && safi == SAFI_UNICAST)
247 stream_put_prefix (s, &rn->p);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000248 else
249 {
250 /* Encode the prefix in MP_REACH_NLRI attribute */
251 struct prefix_rd *prd = NULL;
252 u_char *tag = NULL;
253
254 if (rn->prn)
255 prd = (struct prefix_rd *) &rn->prn->p;
256 if (binfo && binfo->extra)
257 tag = binfo->extra->tag;
258
259 if (stream_empty(snlri))
260 mpattrlen_pos = bgp_packet_mpattr_start(snlri, afi, safi,
261 adv->baa->attr);
262 bgp_packet_mpattr_prefix(snlri, afi, safi, &rn->p, prd, tag);
263 }
paul718e3742002-12-13 20:15:29 +0000264 if (BGP_DEBUG (update, UPDATE_OUT))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000265 {
266 char buf[INET6_BUFSIZ];
267
268 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d",
269 peer->host,
270 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, INET6_BUFSIZ),
271 rn->p.prefixlen);
272 }
paul718e3742002-12-13 20:15:29 +0000273
274 /* Synchnorize attribute. */
275 if (adj->attr)
Paul Jakmaf6f434b2010-11-23 21:28:03 +0000276 bgp_attr_unintern (&adj->attr);
paul718e3742002-12-13 20:15:29 +0000277 else
278 peer->scount[afi][safi]++;
279
280 adj->attr = bgp_attr_intern (adv->baa->attr);
281
282 adv = bgp_advertise_clean (peer, adj, afi, safi);
paul718e3742002-12-13 20:15:29 +0000283 }
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000284
paul718e3742002-12-13 20:15:29 +0000285 if (! stream_empty (s))
286 {
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000287 if (!stream_empty(snlri))
288 {
289 bgp_packet_mpattr_end(snlri, mpattrlen_pos);
290 total_attr_len += stream_get_endp(snlri);
291 }
292
293 /* set the total attribute length correctly */
294 stream_putw_at (s, attrlen_pos, total_attr_len);
295
296 if (!stream_empty(snlri))
297 packet = stream_dupcat(s, snlri, mpattr_pos);
298 else
299 packet = stream_dup (s);
300 bgp_packet_set_size (packet);
paul718e3742002-12-13 20:15:29 +0000301 bgp_packet_add (peer, packet);
pauleb821182004-05-01 08:44:08 +0000302 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000303 stream_reset (s);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000304 stream_reset (snlri);
paul718e3742002-12-13 20:15:29 +0000305 return packet;
306 }
307 return NULL;
hasso93406d82005-02-02 14:40:33 +0000308}
paul718e3742002-12-13 20:15:29 +0000309
paul94f2b392005-06-28 12:44:16 +0000310static struct stream *
hasso93406d82005-02-02 14:40:33 +0000311bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
312{
313 struct stream *s;
hasso93406d82005-02-02 14:40:33 +0000314
Paul Jakma750e8142008-07-22 21:11:48 +0000315 if (DISABLE_BGP_ANNOUNCE)
316 return NULL;
hasso93406d82005-02-02 14:40:33 +0000317
318 if (BGP_DEBUG (normal, NORMAL))
319 zlog_debug ("send End-of-RIB for %s to %s", afi_safi_print (afi, safi), peer->host);
320
321 s = stream_new (BGP_MAX_PACKET_SIZE);
322
323 /* Make BGP update packet. */
324 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
325
326 /* Unfeasible Routes Length */
327 stream_putw (s, 0);
328
329 if (afi == AFI_IP && safi == SAFI_UNICAST)
330 {
331 /* Total Path Attribute Length */
332 stream_putw (s, 0);
333 }
334 else
335 {
336 /* Total Path Attribute Length */
337 stream_putw (s, 6);
338 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
339 stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
340 stream_putc (s, 3);
341 stream_putw (s, afi);
342 stream_putc (s, safi);
343 }
344
345 bgp_packet_set_size (s);
Donald Sharpa752c3b2015-08-18 08:48:53 -0400346 bgp_packet_add (peer, s);
347 return s;
paul718e3742002-12-13 20:15:29 +0000348}
349
350/* Make BGP withdraw packet. */
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000351/* For ipv4 unicast:
352 16-octet marker | 2-octet length | 1-octet type |
353 2-octet withdrawn route length | withdrawn prefixes | 2-octet attrlen (=0)
354*/
355/* For other afi/safis:
356 16-octet marker | 2-octet length | 1-octet type |
357 2-octet withdrawn route length (=0) | 2-octet attrlen |
358 mp_unreach attr type | attr len | afi | safi | withdrawn prefixes
359*/
paul94f2b392005-06-28 12:44:16 +0000360static struct stream *
paul718e3742002-12-13 20:15:29 +0000361bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi)
362{
363 struct stream *s;
364 struct stream *packet;
365 struct bgp_adj_out *adj;
366 struct bgp_advertise *adv;
367 struct bgp_node *rn;
paul718e3742002-12-13 20:15:29 +0000368 bgp_size_t unfeasible_len;
369 bgp_size_t total_attr_len;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000370 size_t mp_start = 0;
371 size_t attrlen_pos = 0;
372 size_t mplen_pos = 0;
373 u_char first_time = 1;
Daniel Walton5bcd7542015-05-19 17:58:10 -0700374 int space_remaining = 0;
375 int space_needed = 0;
paul718e3742002-12-13 20:15:29 +0000376
377 s = peer->work;
378 stream_reset (s);
379
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100380 while ((adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL)
paul718e3742002-12-13 20:15:29 +0000381 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000382 assert (adv->rn);
paul718e3742002-12-13 20:15:29 +0000383 adj = adv->adj;
384 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000385
Daniel Walton5bcd7542015-05-19 17:58:10 -0700386 space_remaining = STREAM_REMAIN (s) -
387 BGP_MAX_PACKET_SIZE_OVERFLOW;
388 space_needed = (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN +
389 bgp_packet_mpattr_prefix_size (afi, safi, &rn->p));
390
391 if (space_remaining < space_needed)
paul718e3742002-12-13 20:15:29 +0000392 break;
393
394 if (stream_empty (s))
395 {
396 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000397 stream_putw (s, 0); /* unfeasible routes length */
paul718e3742002-12-13 20:15:29 +0000398 }
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000399 else
400 first_time = 0;
paul718e3742002-12-13 20:15:29 +0000401
402 if (afi == AFI_IP && safi == SAFI_UNICAST)
403 stream_put_prefix (s, &rn->p);
404 else
405 {
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000406 struct prefix_rd *prd = NULL;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000407
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000408 if (rn->prn)
409 prd = (struct prefix_rd *) &rn->prn->p;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000410
411 /* If first time, format the MP_UNREACH header */
412 if (first_time)
413 {
414 attrlen_pos = stream_get_endp (s);
415 /* total attr length = 0 for now. reevaluate later */
416 stream_putw (s, 0);
417 mp_start = stream_get_endp (s);
418 mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
419 }
420
421 bgp_packet_mpunreach_prefix(s, &rn->p, afi, safi, prd, NULL);
paul718e3742002-12-13 20:15:29 +0000422 }
423
424 if (BGP_DEBUG (update, UPDATE_OUT))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000425 {
426 char buf[INET6_BUFSIZ];
427
428 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
429 peer->host,
430 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, INET6_BUFSIZ),
431 rn->p.prefixlen);
432 }
paul718e3742002-12-13 20:15:29 +0000433
434 peer->scount[afi][safi]--;
435
436 bgp_adj_out_remove (rn, adj, peer, afi, safi);
437 bgp_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +0000438 }
439
440 if (! stream_empty (s))
441 {
442 if (afi == AFI_IP && safi == SAFI_UNICAST)
443 {
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000444 unfeasible_len
paul9985f832005-02-09 15:51:56 +0000445 = stream_get_endp (s) - BGP_HEADER_SIZE - BGP_UNFEASIBLE_LEN;
paul718e3742002-12-13 20:15:29 +0000446 stream_putw_at (s, BGP_HEADER_SIZE, unfeasible_len);
447 stream_putw (s, 0);
448 }
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000449 else
450 {
451 /* Set the mp_unreach attr's length */
452 bgp_packet_mpunreach_end(s, mplen_pos);
453
454 /* Set total path attribute length. */
455 total_attr_len = stream_get_endp(s) - mp_start;
456 stream_putw_at (s, attrlen_pos, total_attr_len);
457 }
paul718e3742002-12-13 20:15:29 +0000458 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000459 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000460 bgp_packet_add (peer, packet);
461 stream_reset (s);
462 return packet;
463 }
464
465 return NULL;
466}
467
468void
469bgp_default_update_send (struct peer *peer, struct attr *attr,
470 afi_t afi, safi_t safi, struct peer *from)
471{
472 struct stream *s;
paul718e3742002-12-13 20:15:29 +0000473 struct prefix p;
474 unsigned long pos;
475 bgp_size_t total_attr_len;
paul718e3742002-12-13 20:15:29 +0000476
Paul Jakma750e8142008-07-22 21:11:48 +0000477 if (DISABLE_BGP_ANNOUNCE)
478 return;
paul718e3742002-12-13 20:15:29 +0000479
480 if (afi == AFI_IP)
481 str2prefix ("0.0.0.0/0", &p);
paul718e3742002-12-13 20:15:29 +0000482 else
483 str2prefix ("::/0", &p);
paul718e3742002-12-13 20:15:29 +0000484
485 /* Logging the attribute. */
486 if (BGP_DEBUG (update, UPDATE_OUT))
487 {
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000488 char attrstr[BUFSIZ];
489 char buf[INET6_BUFSIZ];
490 attrstr[0] = '\0';
491
paul718e3742002-12-13 20:15:29 +0000492 bgp_dump_attr (peer, attr, attrstr, BUFSIZ);
ajs6b514742004-12-08 21:03:23 +0000493 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d %s",
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000494 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, INET6_BUFSIZ),
paul718e3742002-12-13 20:15:29 +0000495 p.prefixlen, attrstr);
496 }
497
498 s = stream_new (BGP_MAX_PACKET_SIZE);
499
500 /* Make BGP update packet. */
501 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
502
503 /* Unfeasible Routes Length. */
504 stream_putw (s, 0);
505
506 /* Make place for total attribute length. */
paul9985f832005-02-09 15:51:56 +0000507 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000508 stream_putw (s, 0);
509 total_attr_len = bgp_packet_attribute (NULL, peer, s, attr, &p, afi, safi, from, NULL, NULL);
510
511 /* Set Total Path Attribute Length. */
512 stream_putw_at (s, pos, total_attr_len);
513
514 /* NLRI set. */
515 if (p.family == AF_INET && safi == SAFI_UNICAST)
516 stream_put_prefix (s, &p);
517
518 /* Set size. */
519 bgp_packet_set_size (s);
520
paul718e3742002-12-13 20:15:29 +0000521 /* Dump packet if debug option is set. */
522#ifdef DEBUG
jardin2d74db52005-10-01 00:07:50 +0000523 /* bgp_packet_dump (packet); */
paul718e3742002-12-13 20:15:29 +0000524#endif /* DEBUG */
525
526 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -0400527 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +0000528
pauleb821182004-05-01 08:44:08 +0000529 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000530}
531
532void
533bgp_default_withdraw_send (struct peer *peer, afi_t afi, safi_t safi)
534{
535 struct stream *s;
paul718e3742002-12-13 20:15:29 +0000536 struct prefix p;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000537 unsigned long attrlen_pos = 0;
paul718e3742002-12-13 20:15:29 +0000538 unsigned long cp;
539 bgp_size_t unfeasible_len;
540 bgp_size_t total_attr_len;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000541 size_t mp_start = 0;
542 size_t mplen_pos = 0;
paul718e3742002-12-13 20:15:29 +0000543
Paul Jakma750e8142008-07-22 21:11:48 +0000544 if (DISABLE_BGP_ANNOUNCE)
545 return;
paul718e3742002-12-13 20:15:29 +0000546
547 if (afi == AFI_IP)
548 str2prefix ("0.0.0.0/0", &p);
paul718e3742002-12-13 20:15:29 +0000549 else
550 str2prefix ("::/0", &p);
paul718e3742002-12-13 20:15:29 +0000551
552 total_attr_len = 0;
paul718e3742002-12-13 20:15:29 +0000553
554 if (BGP_DEBUG (update, UPDATE_OUT))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000555 {
556 char buf[INET6_BUFSIZ];
557
558 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
559 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, INET6_BUFSIZ),
560 p.prefixlen);
561 }
paul718e3742002-12-13 20:15:29 +0000562
563 s = stream_new (BGP_MAX_PACKET_SIZE);
564
565 /* Make BGP update packet. */
566 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
567
568 /* Unfeasible Routes Length. */;
paul9985f832005-02-09 15:51:56 +0000569 cp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000570 stream_putw (s, 0);
571
572 /* Withdrawn Routes. */
573 if (p.family == AF_INET && safi == SAFI_UNICAST)
574 {
575 stream_put_prefix (s, &p);
576
paul9985f832005-02-09 15:51:56 +0000577 unfeasible_len = stream_get_endp (s) - cp - 2;
paul718e3742002-12-13 20:15:29 +0000578
579 /* Set unfeasible len. */
580 stream_putw_at (s, cp, unfeasible_len);
581
582 /* Set total path attribute length. */
583 stream_putw (s, 0);
584 }
585 else
586 {
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000587 attrlen_pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000588 stream_putw (s, 0);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000589 mp_start = stream_get_endp (s);
590 mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
591 bgp_packet_mpunreach_prefix(s, &p, afi, safi, NULL, NULL);
592
593 /* Set the mp_unreach attr's length */
594 bgp_packet_mpunreach_end(s, mplen_pos);
paul718e3742002-12-13 20:15:29 +0000595
596 /* Set total path attribute length. */
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000597 total_attr_len = stream_get_endp(s) - mp_start;
598 stream_putw_at (s, attrlen_pos, total_attr_len);
paul718e3742002-12-13 20:15:29 +0000599 }
600
601 bgp_packet_set_size (s);
602
paul718e3742002-12-13 20:15:29 +0000603 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -0400604 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +0000605
pauleb821182004-05-01 08:44:08 +0000606 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000607}
608
609/* Get next packet to be written. */
paul94f2b392005-06-28 12:44:16 +0000610static struct stream *
paul718e3742002-12-13 20:15:29 +0000611bgp_write_packet (struct peer *peer)
612{
613 afi_t afi;
614 safi_t safi;
615 struct stream *s = NULL;
616 struct bgp_advertise *adv;
617
618 s = stream_fifo_head (peer->obuf);
619 if (s)
620 return s;
621
622 for (afi = AFI_IP; afi < AFI_MAX; afi++)
623 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
624 {
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100625 adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->withdraw);
paul718e3742002-12-13 20:15:29 +0000626 if (adv)
627 {
628 s = bgp_withdraw_packet (peer, afi, safi);
629 if (s)
630 return s;
631 }
632 }
633
634 for (afi = AFI_IP; afi < AFI_MAX; afi++)
635 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
636 {
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100637 adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update);
paul718e3742002-12-13 20:15:29 +0000638 if (adv)
639 {
640 if (adv->binfo && adv->binfo->uptime < peer->synctime)
hasso93406d82005-02-02 14:40:33 +0000641 {
642 if (CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_RCV)
643 && CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_ADV)
Vipin Kumardd49eb12014-09-30 14:36:38 -0700644 && ! (CHECK_FLAG (adv->binfo->peer->cap,
645 PEER_CAP_RESTART_BIT_RCV) &&
646 CHECK_FLAG (adv->binfo->peer->cap,
647 PEER_CAP_RESTART_BIT_ADV))
hasso93406d82005-02-02 14:40:33 +0000648 && ! CHECK_FLAG (adv->binfo->flags, BGP_INFO_STALE)
649 && safi != SAFI_MPLS_VPN)
650 {
651 if (CHECK_FLAG (adv->binfo->peer->af_sflags[afi][safi],
652 PEER_STATUS_EOR_RECEIVED))
653 s = bgp_update_packet (peer, afi, safi);
654 }
655 else
656 s = bgp_update_packet (peer, afi, safi);
657 }
paul718e3742002-12-13 20:15:29 +0000658
659 if (s)
660 return s;
661 }
hasso93406d82005-02-02 14:40:33 +0000662
663 if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV))
664 {
665 if (peer->afc_nego[afi][safi] && peer->synctime
666 && ! CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND)
667 && safi != SAFI_MPLS_VPN)
668 {
669 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND);
670 return bgp_update_packet_eor (peer, afi, safi);
671 }
672 }
paul718e3742002-12-13 20:15:29 +0000673 }
674
675 return NULL;
676}
677
678/* Is there partially written packet or updates we can send right
679 now. */
paul94f2b392005-06-28 12:44:16 +0000680static int
paul718e3742002-12-13 20:15:29 +0000681bgp_write_proceed (struct peer *peer)
682{
683 afi_t afi;
684 safi_t safi;
685 struct bgp_advertise *adv;
686
687 if (stream_fifo_head (peer->obuf))
688 return 1;
689
690 for (afi = AFI_IP; afi < AFI_MAX; afi++)
691 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
692 if (FIFO_HEAD (&peer->sync[afi][safi]->withdraw))
693 return 1;
694
695 for (afi = AFI_IP; afi < AFI_MAX; afi++)
696 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100697 if ((adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update)) != NULL)
paul718e3742002-12-13 20:15:29 +0000698 if (adv->binfo->uptime < peer->synctime)
699 return 1;
700
701 return 0;
702}
703
704/* Write packet to the peer. */
705int
706bgp_write (struct thread *thread)
707{
708 struct peer *peer;
709 u_char type;
710 struct stream *s;
711 int num;
paulfd79ac92004-10-13 05:06:08 +0000712 unsigned int count = 0;
paul718e3742002-12-13 20:15:29 +0000713
714 /* Yes first of all get peer pointer. */
715 peer = THREAD_ARG (thread);
716 peer->t_write = NULL;
717
718 /* For non-blocking IO check. */
719 if (peer->status == Connect)
720 {
Dinesh Duttd9ab53a2015-05-19 17:47:21 -0700721 bgp_connect_check (peer, 1);
paul718e3742002-12-13 20:15:29 +0000722 return 0;
723 }
724
Stephen Hemmingereac57022010-08-05 10:26:25 -0700725 s = bgp_write_packet (peer);
726 if (!s)
727 return 0; /* nothing to send */
728
729 sockopt_cork (peer->fd, 1);
730
731 /* Nonblocking write until TCP output buffer is full. */
732 do
paul718e3742002-12-13 20:15:29 +0000733 {
734 int writenum;
paul718e3742002-12-13 20:15:29 +0000735
736 /* Number of bytes to be sent. */
737 writenum = stream_get_endp (s) - stream_get_getp (s);
738
739 /* Call write() system call. */
pauleb821182004-05-01 08:44:08 +0000740 num = write (peer->fd, STREAM_PNT (s), writenum);
Stephen Hemminger35398582010-08-05 10:26:23 -0700741 if (num < 0)
paul718e3742002-12-13 20:15:29 +0000742 {
Stephen Hemmingereac57022010-08-05 10:26:25 -0700743 /* write failed either retry needed or error */
744 if (ERRNO_IO_RETRY(errno))
745 break;
746
747 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000748 return 0;
749 }
Stephen Hemminger35398582010-08-05 10:26:23 -0700750
paul718e3742002-12-13 20:15:29 +0000751 if (num != writenum)
752 {
Stephen Hemminger35398582010-08-05 10:26:23 -0700753 /* Partial write */
paul9985f832005-02-09 15:51:56 +0000754 stream_forward_getp (s, num);
Stephen Hemmingereac57022010-08-05 10:26:25 -0700755 break;
paul718e3742002-12-13 20:15:29 +0000756 }
757
758 /* Retrieve BGP packet type. */
759 stream_set_getp (s, BGP_MARKER_SIZE + 2);
760 type = stream_getc (s);
761
762 switch (type)
763 {
764 case BGP_MSG_OPEN:
765 peer->open_out++;
766 break;
767 case BGP_MSG_UPDATE:
768 peer->update_out++;
769 break;
770 case BGP_MSG_NOTIFY:
771 peer->notify_out++;
772 /* Double start timer. */
773 peer->v_start *= 2;
774
775 /* Overflow check. */
776 if (peer->v_start >= (60 * 2))
777 peer->v_start = (60 * 2);
778
Paul Jakmaca058a32006-09-14 02:58:49 +0000779 /* Flush any existing events */
Paul Jakmadcdf3992006-10-15 23:39:59 +0000780 BGP_EVENT_ADD (peer, BGP_Stop);
Stephen Hemminger3a69f742013-01-11 18:27:23 +0000781 goto done;
782
paul718e3742002-12-13 20:15:29 +0000783 case BGP_MSG_KEEPALIVE:
784 peer->keepalive_out++;
785 break;
786 case BGP_MSG_ROUTE_REFRESH_NEW:
787 case BGP_MSG_ROUTE_REFRESH_OLD:
788 peer->refresh_out++;
789 break;
790 case BGP_MSG_CAPABILITY:
791 peer->dynamic_cap_out++;
792 break;
793 }
794
795 /* OK we send packet so delete it. */
796 bgp_packet_delete (peer);
paul718e3742002-12-13 20:15:29 +0000797 }
Stephen Hemmingereac57022010-08-05 10:26:25 -0700798 while (++count < BGP_WRITE_PACKET_MAX &&
799 (s = bgp_write_packet (peer)) != NULL);
paul718e3742002-12-13 20:15:29 +0000800
801 if (bgp_write_proceed (peer))
pauleb821182004-05-01 08:44:08 +0000802 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
Stephen Hemminger3a69f742013-01-11 18:27:23 +0000803
804 done:
805 sockopt_cork (peer->fd, 0);
paul718e3742002-12-13 20:15:29 +0000806 return 0;
807}
808
809/* This is only for sending NOTIFICATION message to neighbor. */
paul94f2b392005-06-28 12:44:16 +0000810static int
paul718e3742002-12-13 20:15:29 +0000811bgp_write_notify (struct peer *peer)
812{
Stephen Hemminger35398582010-08-05 10:26:23 -0700813 int ret, val;
paul718e3742002-12-13 20:15:29 +0000814 u_char type;
815 struct stream *s;
816
817 /* There should be at least one packet. */
818 s = stream_fifo_head (peer->obuf);
819 if (!s)
820 return 0;
821 assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
822
Leonid Rosenboim86998bc2012-12-14 19:12:17 +0000823 /* Stop collecting data within the socket */
824 sockopt_cork (peer->fd, 0);
825
David Lamparter8ff202e2013-07-31 14:39:41 +0200826 /* socket is in nonblocking mode, if we can't deliver the NOTIFY, well,
827 * we only care about getting a clean shutdown at this point. */
Leonid Rosenboim86998bc2012-12-14 19:12:17 +0000828 ret = write (peer->fd, STREAM_DATA (s), stream_get_endp (s));
David Lamparter8ff202e2013-07-31 14:39:41 +0200829
830 /* only connection reset/close gets counted as TCP_fatal_error, failure
831 * to write the entire NOTIFY doesn't get different FSM treatment */
paul718e3742002-12-13 20:15:29 +0000832 if (ret <= 0)
833 {
Paul Jakmadcdf3992006-10-15 23:39:59 +0000834 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000835 return 0;
836 }
837
Leonid Rosenboim86998bc2012-12-14 19:12:17 +0000838 /* Disable Nagle, make NOTIFY packet go out right away */
839 val = 1;
840 (void) setsockopt (peer->fd, IPPROTO_TCP, TCP_NODELAY,
841 (char *) &val, sizeof (val));
842
paul718e3742002-12-13 20:15:29 +0000843 /* Retrieve BGP packet type. */
844 stream_set_getp (s, BGP_MARKER_SIZE + 2);
845 type = stream_getc (s);
846
847 assert (type == BGP_MSG_NOTIFY);
848
849 /* Type should be notify. */
850 peer->notify_out++;
851
852 /* Double start timer. */
853 peer->v_start *= 2;
854
855 /* Overflow check. */
856 if (peer->v_start >= (60 * 2))
857 peer->v_start = (60 * 2);
858
Paul Jakmadcdf3992006-10-15 23:39:59 +0000859 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000860
861 return 0;
862}
863
864/* Make keepalive packet and send it to the peer. */
865void
866bgp_keepalive_send (struct peer *peer)
867{
868 struct stream *s;
869 int length;
870
871 s = stream_new (BGP_MAX_PACKET_SIZE);
872
873 /* Make keepalive packet. */
874 bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
875
876 /* Set packet size. */
877 length = bgp_packet_set_size (s);
878
879 /* Dump packet if debug option is set. */
880 /* bgp_packet_dump (s); */
881
882 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +0000883 zlog_debug ("%s sending KEEPALIVE", peer->host);
paul718e3742002-12-13 20:15:29 +0000884 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000885 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000886 peer->host, BGP_MSG_KEEPALIVE, length);
887
888 /* Add packet to the peer. */
889 bgp_packet_add (peer, s);
890
pauleb821182004-05-01 08:44:08 +0000891 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000892}
893
894/* Make open packet and send it to the peer. */
895void
896bgp_open_send (struct peer *peer)
897{
898 struct stream *s;
899 int length;
900 u_int16_t send_holdtime;
901 as_t local_as;
902
903 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
904 send_holdtime = peer->holdtime;
905 else
906 send_holdtime = peer->bgp->default_holdtime;
907
908 /* local-as Change */
909 if (peer->change_local_as)
910 local_as = peer->change_local_as;
911 else
912 local_as = peer->local_as;
913
914 s = stream_new (BGP_MAX_PACKET_SIZE);
915
916 /* Make open packet. */
917 bgp_packet_set_marker (s, BGP_MSG_OPEN);
918
919 /* Set open packet values. */
920 stream_putc (s, BGP_VERSION_4); /* BGP version */
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000921 stream_putw (s, (local_as <= BGP_AS_MAX) ? (u_int16_t) local_as
922 : BGP_AS_TRANS);
paul718e3742002-12-13 20:15:29 +0000923 stream_putw (s, send_holdtime); /* Hold Time */
924 stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
925
926 /* Set capability code. */
927 bgp_open_capability (s, peer);
928
929 /* Set BGP packet length. */
930 length = bgp_packet_set_size (s);
931
932 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400933 zlog_debug ("%s sending OPEN, version %d, my as %u, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +0000934 peer->host, BGP_VERSION_4, local_as,
935 send_holdtime, inet_ntoa (peer->local_id));
936
937 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000938 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000939 peer->host, BGP_MSG_OPEN, length);
940
941 /* Dump packet if debug option is set. */
942 /* bgp_packet_dump (s); */
943
944 /* Add packet to the peer. */
945 bgp_packet_add (peer, s);
946
pauleb821182004-05-01 08:44:08 +0000947 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000948}
949
950/* Send BGP notify packet with data potion. */
951void
952bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
953 u_char *data, size_t datalen)
954{
955 struct stream *s;
956 int length;
957
958 /* Allocate new stream. */
959 s = stream_new (BGP_MAX_PACKET_SIZE);
960
961 /* Make nitify packet. */
962 bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
963
964 /* Set notify packet values. */
965 stream_putc (s, code); /* BGP notify code */
966 stream_putc (s, sub_code); /* BGP notify sub_code */
967
968 /* If notify data is present. */
969 if (data)
970 stream_write (s, data, datalen);
971
972 /* Set BGP packet length. */
973 length = bgp_packet_set_size (s);
974
975 /* Add packet to the peer. */
976 stream_fifo_clean (peer->obuf);
977 bgp_packet_add (peer, s);
978
979 /* For debug */
980 {
981 struct bgp_notify bgp_notify;
982 int first = 0;
983 int i;
984 char c[4];
985
986 bgp_notify.code = code;
987 bgp_notify.subcode = sub_code;
988 bgp_notify.data = NULL;
989 bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
990
991 if (bgp_notify.length)
992 {
993 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
994 for (i = 0; i < bgp_notify.length; i++)
995 if (first)
996 {
997 sprintf (c, " %02x", data[i]);
998 strcat (bgp_notify.data, c);
999 }
1000 else
1001 {
1002 first = 1;
1003 sprintf (c, "%02x", data[i]);
1004 strcpy (bgp_notify.data, c);
1005 }
1006 }
1007 bgp_notify_print (peer, &bgp_notify, "sending");
Daniel Walton363c9032015-10-21 06:42:54 -07001008
paul718e3742002-12-13 20:15:29 +00001009 if (bgp_notify.data)
Daniel Walton363c9032015-10-21 06:42:54 -07001010 {
1011 XFREE (MTYPE_TMP, bgp_notify.data);
1012 bgp_notify.data = NULL;
1013 bgp_notify.length = 0;
1014 }
paul718e3742002-12-13 20:15:29 +00001015 }
1016
1017 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001018 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001019 peer->host, BGP_MSG_NOTIFY, length);
1020
hassoe0701b72004-05-20 09:19:34 +00001021 /* peer reset cause */
1022 if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
1023 {
1024 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
heasley1212dc12011-09-12 13:27:52 +04001025 {
1026 peer->last_reset = PEER_DOWN_USER_RESET;
1027 zlog_info ("Notification sent to neighbor %s: User reset", peer->host);
1028 }
hassoe0701b72004-05-20 09:19:34 +00001029 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
heasley1212dc12011-09-12 13:27:52 +04001030 {
1031 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
1032 zlog_info ("Notification sent to neighbor %s: shutdown", peer->host);
1033 }
hassoe0701b72004-05-20 09:19:34 +00001034 else
heasley1212dc12011-09-12 13:27:52 +04001035 {
1036 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
1037 zlog_info ("Notification sent to neighbor %s: type %u/%u",
1038 peer->host, code, sub_code);
1039 }
hassoe0701b72004-05-20 09:19:34 +00001040 }
heasley1212dc12011-09-12 13:27:52 +04001041 else
1042 zlog_info ("Notification sent to neighbor %s: configuration change",
1043 peer->host);
hassoe0701b72004-05-20 09:19:34 +00001044
Denis Ovsienko7ccf5e52011-09-10 16:53:30 +04001045 /* Call immediately. */
paul718e3742002-12-13 20:15:29 +00001046 BGP_WRITE_OFF (peer->t_write);
1047
1048 bgp_write_notify (peer);
1049}
1050
1051/* Send BGP notify packet. */
1052void
1053bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
1054{
1055 bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
1056}
1057
paul718e3742002-12-13 20:15:29 +00001058/* Send route refresh message to the peer. */
1059void
1060bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
1061 u_char orf_type, u_char when_to_refresh, int remove)
1062{
1063 struct stream *s;
paul718e3742002-12-13 20:15:29 +00001064 int length;
1065 struct bgp_filter *filter;
1066 int orf_refresh = 0;
1067
Paul Jakma750e8142008-07-22 21:11:48 +00001068 if (DISABLE_BGP_ANNOUNCE)
1069 return;
paul718e3742002-12-13 20:15:29 +00001070
1071 filter = &peer->filter[afi][safi];
1072
1073 /* Adjust safi code. */
1074 if (safi == SAFI_MPLS_VPN)
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001075 safi = SAFI_MPLS_LABELED_VPN;
paul718e3742002-12-13 20:15:29 +00001076
1077 s = stream_new (BGP_MAX_PACKET_SIZE);
1078
1079 /* Make BGP update packet. */
1080 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
1081 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
1082 else
1083 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
1084
1085 /* Encode Route Refresh message. */
1086 stream_putw (s, afi);
1087 stream_putc (s, 0);
1088 stream_putc (s, safi);
1089
1090 if (orf_type == ORF_TYPE_PREFIX
1091 || orf_type == ORF_TYPE_PREFIX_OLD)
1092 if (remove || filter->plist[FILTER_IN].plist)
1093 {
1094 u_int16_t orf_len;
1095 unsigned long orfp;
1096
1097 orf_refresh = 1;
1098 stream_putc (s, when_to_refresh);
1099 stream_putc (s, orf_type);
paul9985f832005-02-09 15:51:56 +00001100 orfp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00001101 stream_putw (s, 0);
1102
1103 if (remove)
1104 {
1105 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1106 stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
1107 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001108 zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001109 peer->host, orf_type,
1110 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1111 afi, safi);
1112 }
1113 else
1114 {
1115 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1116 prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
1117 ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
1118 ORF_COMMON_PART_DENY);
1119 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001120 zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001121 peer->host, orf_type,
1122 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1123 afi, safi);
1124 }
1125
1126 /* Total ORF Entry Len. */
paul9985f832005-02-09 15:51:56 +00001127 orf_len = stream_get_endp (s) - orfp - 2;
paul718e3742002-12-13 20:15:29 +00001128 stream_putw_at (s, orfp, orf_len);
1129 }
1130
1131 /* Set packet size. */
1132 length = bgp_packet_set_size (s);
1133
1134 if (BGP_DEBUG (normal, NORMAL))
1135 {
1136 if (! orf_refresh)
ajs6b514742004-12-08 21:03:23 +00001137 zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001138 peer->host, afi, safi);
ajs6b514742004-12-08 21:03:23 +00001139 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001140 peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
1141 BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
1142 }
1143
paul718e3742002-12-13 20:15:29 +00001144 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -04001145 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +00001146
pauleb821182004-05-01 08:44:08 +00001147 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001148}
1149
1150/* Send capability message to the peer. */
1151void
1152bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
1153 int capability_code, int action)
1154{
1155 struct stream *s;
paul718e3742002-12-13 20:15:29 +00001156 int length;
1157
1158 /* Adjust safi code. */
1159 if (safi == SAFI_MPLS_VPN)
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001160 safi = SAFI_MPLS_LABELED_VPN;
paul718e3742002-12-13 20:15:29 +00001161
1162 s = stream_new (BGP_MAX_PACKET_SIZE);
1163
1164 /* Make BGP update packet. */
1165 bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
1166
1167 /* Encode MP_EXT capability. */
1168 if (capability_code == CAPABILITY_CODE_MP)
1169 {
1170 stream_putc (s, action);
1171 stream_putc (s, CAPABILITY_CODE_MP);
1172 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1173 stream_putw (s, afi);
1174 stream_putc (s, 0);
1175 stream_putc (s, safi);
1176
1177 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001178 zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001179 peer->host, action == CAPABILITY_ACTION_SET ?
1180 "Advertising" : "Removing", afi, safi);
1181 }
1182
paul718e3742002-12-13 20:15:29 +00001183 /* Set packet size. */
1184 length = bgp_packet_set_size (s);
1185
paul718e3742002-12-13 20:15:29 +00001186
1187 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -04001188 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +00001189
1190 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001191 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001192 peer->host, BGP_MSG_CAPABILITY, length);
1193
pauleb821182004-05-01 08:44:08 +00001194 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001195}
David Lamparter6b0655a2014-06-04 06:53:35 +02001196
paul718e3742002-12-13 20:15:29 +00001197/* RFC1771 6.8 Connection collision detection. */
paul94f2b392005-06-28 12:44:16 +00001198static int
pauleb821182004-05-01 08:44:08 +00001199bgp_collision_detect (struct peer *new, struct in_addr remote_id)
paul718e3742002-12-13 20:15:29 +00001200{
pauleb821182004-05-01 08:44:08 +00001201 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +00001202 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001203 struct bgp *bgp;
1204
1205 bgp = bgp_get_default ();
1206 if (! bgp)
1207 return 0;
1208
1209 /* Upon receipt of an OPEN message, the local system must examine
1210 all of its connections that are in the OpenConfirm state. A BGP
1211 speaker may also examine connections in an OpenSent state if it
1212 knows the BGP Identifier of the peer by means outside of the
1213 protocol. If among these connections there is a connection to a
1214 remote BGP speaker whose BGP Identifier equals the one in the
1215 OPEN message, then the local system performs the following
1216 collision resolution procedure: */
1217
paul1eb8ef22005-04-07 07:30:20 +00001218 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00001219 {
1220 /* Under OpenConfirm status, local peer structure already hold
1221 remote router ID. */
pauleb821182004-05-01 08:44:08 +00001222
1223 if (peer != new
1224 && (peer->status == OpenConfirm || peer->status == OpenSent)
1225 && sockunion_same (&peer->su, &new->su))
1226 {
paul718e3742002-12-13 20:15:29 +00001227 /* 1. The BGP Identifier of the local system is compared to
1228 the BGP Identifier of the remote system (as specified in
1229 the OPEN message). */
1230
1231 if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
1232 {
1233 /* 2. If the value of the local BGP Identifier is less
1234 than the remote one, the local system closes BGP
1235 connection that already exists (the one that is
1236 already in the OpenConfirm state), and accepts BGP
1237 connection initiated by the remote system. */
1238
pauleb821182004-05-01 08:44:08 +00001239 if (peer->fd >= 0)
hassoe0701b72004-05-20 09:19:34 +00001240 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001241 return 1;
1242 }
1243 else
1244 {
1245 /* 3. Otherwise, the local system closes newly created
1246 BGP connection (the one associated with the newly
1247 received OPEN message), and continues to use the
1248 existing one (the one that is already in the
1249 OpenConfirm state). */
1250
pauleb821182004-05-01 08:44:08 +00001251 if (new->fd >= 0)
paulf5ba3872004-07-09 12:11:31 +00001252 bgp_notify_send (new, BGP_NOTIFY_CEASE,
1253 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001254 return -1;
1255 }
pauleb821182004-05-01 08:44:08 +00001256 }
1257 }
paul718e3742002-12-13 20:15:29 +00001258 return 0;
1259}
1260
paul94f2b392005-06-28 12:44:16 +00001261static int
paul718e3742002-12-13 20:15:29 +00001262bgp_open_receive (struct peer *peer, bgp_size_t size)
1263{
1264 int ret;
1265 u_char version;
1266 u_char optlen;
1267 u_int16_t holdtime;
1268 u_int16_t send_holdtime;
1269 as_t remote_as;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001270 as_t as4 = 0;
paul718e3742002-12-13 20:15:29 +00001271 struct peer *realpeer;
1272 struct in_addr remote_id;
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001273 int mp_capability;
paul5228ad22004-06-04 17:58:18 +00001274 u_int8_t notify_data_remote_as[2];
1275 u_int8_t notify_data_remote_id[4];
Daniel Waltonc6969872015-05-19 18:03:43 -07001276 u_int16_t *holdtime_ptr;
paul718e3742002-12-13 20:15:29 +00001277
1278 realpeer = NULL;
1279
1280 /* Parse open packet. */
1281 version = stream_getc (peer->ibuf);
1282 memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1283 remote_as = stream_getw (peer->ibuf);
Daniel Waltonc6969872015-05-19 18:03:43 -07001284 holdtime_ptr = (u_int16_t *)stream_pnt (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00001285 holdtime = stream_getw (peer->ibuf);
1286 memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1287 remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1288
1289 /* Receive OPEN message log */
1290 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001291 zlog_debug ("%s rcv OPEN, version %d, remote-as (in open) %u,"
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001292 " holdtime %d, id %s",
1293 peer->host, version, remote_as, holdtime,
1294 inet_ntoa (remote_id));
1295
1296 /* BEGIN to read the capability here, but dont do it yet */
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001297 mp_capability = 0;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001298 optlen = stream_getc (peer->ibuf);
1299
1300 if (optlen != 0)
1301 {
1302 /* We need the as4 capability value *right now* because
1303 * if it is there, we have not got the remote_as yet, and without
1304 * that we do not know which peer is connecting to us now.
1305 */
1306 as4 = peek_for_as4_capability (peer, optlen);
1307 }
1308
1309 /* Just in case we have a silly peer who sends AS4 capability set to 0 */
1310 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) && !as4)
1311 {
1312 zlog_err ("%s bad OPEN, got AS4 capability, but AS4 set to 0",
1313 peer->host);
1314 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1315 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1316 return -1;
1317 }
1318
1319 if (remote_as == BGP_AS_TRANS)
1320 {
1321 /* Take the AS4 from the capability. We must have received the
1322 * capability now! Otherwise we have a asn16 peer who uses
1323 * BGP_AS_TRANS, for some unknown reason.
1324 */
1325 if (as4 == BGP_AS_TRANS)
1326 {
1327 zlog_err ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
1328 peer->host);
1329 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1330 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1331 return -1;
1332 }
1333
1334 if (!as4 && BGP_DEBUG (as4, AS4))
1335 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
1336 " Odd, but proceeding.", peer->host);
1337 else if (as4 < BGP_AS_MAX && BGP_DEBUG (as4, AS4))
Paul Jakma0df7c912008-07-21 21:02:49 +00001338 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits "
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001339 "in 2-bytes, very odd peer.", peer->host, as4);
1340 if (as4)
1341 remote_as = as4;
1342 }
1343 else
1344 {
1345 /* We may have a partner with AS4 who has an asno < BGP_AS_MAX */
1346 /* If we have got the capability, peer->as4cap must match remote_as */
1347 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)
1348 && as4 != remote_as)
1349 {
1350 /* raise error, log this, close session */
1351 zlog_err ("%s bad OPEN, got AS4 capability, but remote_as %u"
1352 " mismatch with 16bit 'myasn' %u in open",
1353 peer->host, as4, remote_as);
1354 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1355 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1356 return -1;
1357 }
1358 }
1359
paul718e3742002-12-13 20:15:29 +00001360 /* Lookup peer from Open packet. */
1361 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1362 {
1363 int as = 0;
1364
1365 realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1366
1367 if (! realpeer)
1368 {
1369 /* Peer's source IP address is check in bgp_accept(), so this
1370 must be AS number mismatch or remote-id configuration
1371 mismatch. */
1372 if (as)
1373 {
1374 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001375 zlog_debug ("%s bad OPEN, wrong router identifier %s",
1376 peer->host, inet_ntoa (remote_id));
1377 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1378 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1379 notify_data_remote_id, 4);
paul718e3742002-12-13 20:15:29 +00001380 }
1381 else
1382 {
1383 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001384 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
ajs6b514742004-12-08 21:03:23 +00001385 peer->host, remote_as, peer->as);
1386 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1387 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1388 notify_data_remote_as, 2);
paul718e3742002-12-13 20:15:29 +00001389 }
1390 return -1;
1391 }
1392 }
1393
1394 /* When collision is detected and this peer is closed. Retrun
1395 immidiately. */
1396 ret = bgp_collision_detect (peer, remote_id);
1397 if (ret < 0)
1398 return ret;
1399
pauleb821182004-05-01 08:44:08 +00001400 /* Hack part. */
1401 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1402 {
hasso93406d82005-02-02 14:40:33 +00001403 if (realpeer->status == Established
1404 && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1405 {
1406 realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1407 SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1408 }
1409 else if (ret == 0 && realpeer->status != Active
1410 && realpeer->status != OpenSent
Paul Jakma6e199262008-09-09 17:14:33 +01001411 && realpeer->status != OpenConfirm
1412 && realpeer->status != Connect)
pauleb821182004-05-01 08:44:08 +00001413 {
Paul Jakma2b2fc562008-09-06 13:09:35 +01001414 /* XXX: This is an awful problem..
1415 *
1416 * According to the RFC we should just let this connection (of the
1417 * accepted 'peer') continue on to Established if the other
1418 * connection (the 'realpeer' one) is in state Connect, and deal
1419 * with the more larval FSM as/when it gets far enough to receive
1420 * an Open. We don't do that though, we instead close the (more
1421 * developed) accepted connection.
1422 *
1423 * This means there's a race, which if hit, can loop:
1424 *
1425 * FSM for A FSM for B
1426 * realpeer accept-peer realpeer accept-peer
1427 *
1428 * Connect Connect
1429 * Active
1430 * OpenSent OpenSent
1431 * <arrive here,
1432 * Notify, delete>
1433 * Idle Active
1434 * OpenSent OpenSent
1435 * <arrive here,
1436 * Notify, delete>
1437 * Idle
1438 * <wait> <wait>
1439 * Connect Connect
1440 *
1441 *
1442 * If both sides are Quagga, they're almost certain to wait for
1443 * the same amount of time of course (which doesn't preclude other
1444 * implementations also waiting for same time). The race is
1445 * exacerbated by high-latency (in bgpd and/or the network).
1446 *
1447 * The reason we do this is because our FSM is tied to our peer
1448 * structure, which carries our configuration information, etc.
1449 * I.e. we can't let the accepted-peer FSM continue on as it is,
1450 * cause it's not associated with any actual peer configuration -
1451 * it's just a dummy.
1452 *
1453 * It's possible we could hack-fix this by just bgp_stop'ing the
1454 * realpeer and continueing on with the 'transfer FSM' below.
1455 * Ideally, we need to seperate FSMs from struct peer.
1456 *
1457 * Setting one side to passive avoids the race, as a workaround.
1458 */
pauleb821182004-05-01 08:44:08 +00001459 if (BGP_DEBUG (events, EVENTS))
hasso93406d82005-02-02 14:40:33 +00001460 zlog_debug ("%s peer status is %s close connection",
1461 realpeer->host, LOOKUP (bgp_status_msg,
1462 realpeer->status));
1463 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1464 BGP_NOTIFY_CEASE_CONNECT_REJECT);
1465
pauleb821182004-05-01 08:44:08 +00001466 return -1;
1467 }
1468
1469 if (BGP_DEBUG (events, EVENTS))
Paul Jakma6e199262008-09-09 17:14:33 +01001470 zlog_debug ("%s [Event] Transfer accept BGP peer to real (state %s)",
1471 peer->host,
1472 LOOKUP (bgp_status_msg, realpeer->status));
pauleb821182004-05-01 08:44:08 +00001473
1474 bgp_stop (realpeer);
1475
1476 /* Transfer file descriptor. */
1477 realpeer->fd = peer->fd;
1478 peer->fd = -1;
1479
1480 /* Transfer input buffer. */
1481 stream_free (realpeer->ibuf);
1482 realpeer->ibuf = peer->ibuf;
1483 realpeer->packet_size = peer->packet_size;
1484 peer->ibuf = NULL;
1485
1486 /* Transfer status. */
1487 realpeer->status = peer->status;
1488 bgp_stop (peer);
paul200df112005-06-01 11:17:05 +00001489
pauleb821182004-05-01 08:44:08 +00001490 /* peer pointer change. Open packet send to neighbor. */
1491 peer = realpeer;
1492 bgp_open_send (peer);
1493 if (peer->fd < 0)
1494 {
1495 zlog_err ("bgp_open_receive peer's fd is negative value %d",
1496 peer->fd);
1497 return -1;
1498 }
1499 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1500 }
1501
paul718e3742002-12-13 20:15:29 +00001502 /* remote router-id check. */
1503 if (remote_id.s_addr == 0
Denis Ovsienko733cd9e2011-12-17 19:39:30 +04001504 || IPV4_CLASS_DE (ntohl (remote_id.s_addr))
paul718e3742002-12-13 20:15:29 +00001505 || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1506 {
1507 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001508 zlog_debug ("%s bad OPEN, wrong router identifier %s",
paul718e3742002-12-13 20:15:29 +00001509 peer->host, inet_ntoa (remote_id));
1510 bgp_notify_send_with_data (peer,
1511 BGP_NOTIFY_OPEN_ERR,
1512 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1513 notify_data_remote_id, 4);
1514 return -1;
1515 }
1516
1517 /* Set remote router-id */
1518 peer->remote_id = remote_id;
1519
1520 /* Peer BGP version check. */
1521 if (version != BGP_VERSION_4)
1522 {
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001523 u_int16_t maxver = htons(BGP_VERSION_4);
1524 /* XXX this reply may not be correct if version < 4 XXX */
paul718e3742002-12-13 20:15:29 +00001525 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001526 zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
paul718e3742002-12-13 20:15:29 +00001527 peer->host, version, BGP_VERSION_4);
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001528 /* Data must be in network byte order here */
paul718e3742002-12-13 20:15:29 +00001529 bgp_notify_send_with_data (peer,
1530 BGP_NOTIFY_OPEN_ERR,
1531 BGP_NOTIFY_OPEN_UNSUP_VERSION,
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001532 (u_int8_t *) &maxver, 2);
paul718e3742002-12-13 20:15:29 +00001533 return -1;
1534 }
1535
1536 /* Check neighbor as number. */
1537 if (remote_as != peer->as)
1538 {
1539 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001540 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
paul718e3742002-12-13 20:15:29 +00001541 peer->host, remote_as, peer->as);
1542 bgp_notify_send_with_data (peer,
1543 BGP_NOTIFY_OPEN_ERR,
1544 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1545 notify_data_remote_as, 2);
1546 return -1;
1547 }
1548
1549 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1550 calculate the value of the Hold Timer by using the smaller of its
1551 configured Hold Time and the Hold Time received in the OPEN message.
1552 The Hold Time MUST be either zero or at least three seconds. An
1553 implementation may reject connections on the basis of the Hold Time. */
1554
1555 if (holdtime < 3 && holdtime != 0)
1556 {
Daniel Waltonc6969872015-05-19 18:03:43 -07001557 bgp_notify_send_with_data (peer,
1558 BGP_NOTIFY_OPEN_ERR,
1559 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME,
1560 (u_int8_t *)holdtime_ptr, 2);
paul718e3742002-12-13 20:15:29 +00001561 return -1;
1562 }
1563
1564 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1565 would be one third of the Hold Time interval. KEEPALIVE messages
1566 MUST NOT be sent more frequently than one per second. An
1567 implementation MAY adjust the rate at which it sends KEEPALIVE
1568 messages as a function of the Hold Time interval. */
1569
1570 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1571 send_holdtime = peer->holdtime;
1572 else
1573 send_holdtime = peer->bgp->default_holdtime;
1574
1575 if (holdtime < send_holdtime)
1576 peer->v_holdtime = holdtime;
1577 else
1578 peer->v_holdtime = send_holdtime;
1579
1580 peer->v_keepalive = peer->v_holdtime / 3;
1581
1582 /* Open option part parse. */
paul718e3742002-12-13 20:15:29 +00001583 if (optlen != 0)
1584 {
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001585 if ((ret = bgp_open_option_parse (peer, optlen, &mp_capability)) < 0)
Paul Jakma58617392012-01-09 20:59:26 +00001586 {
1587 bgp_notify_send (peer,
1588 BGP_NOTIFY_OPEN_ERR,
Paul Jakma68ec4242015-11-25 17:14:34 +00001589 BGP_NOTIFY_OPEN_UNSPECIFIC);
Paul Jakma58617392012-01-09 20:59:26 +00001590 return ret;
1591 }
paul718e3742002-12-13 20:15:29 +00001592 }
1593 else
1594 {
1595 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001596 zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
paul718e3742002-12-13 20:15:29 +00001597 peer->host);
1598 }
1599
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001600 /*
1601 * Assume that the peer supports the locally configured set of
1602 * AFI/SAFIs if the peer did not send us any Mulitiprotocol
1603 * capabilities, or if 'override-capability' is configured.
1604 */
1605 if (! mp_capability ||
1606 CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
paul718e3742002-12-13 20:15:29 +00001607 {
1608 peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1609 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1610 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1611 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1612 }
1613
1614 /* Get sockname. */
1615 bgp_getsockname (peer);
Timo Teräs0edba8b2015-10-22 11:35:17 +03001616 peer->rtt = sockopt_tcp_rtt (peer->fd);
paul718e3742002-12-13 20:15:29 +00001617
1618 BGP_EVENT_ADD (peer, Receive_OPEN_message);
1619
1620 peer->packet_size = 0;
1621 if (peer->ibuf)
1622 stream_reset (peer->ibuf);
1623
1624 return 0;
1625}
1626
Paul Jakma518a4b72016-02-04 13:27:04 +00001627/* Frontend for NLRI parsing, to fan-out to AFI/SAFI specific parsers */
1628int
1629bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
1630{
1631 switch (packet->safi)
1632 {
1633 case SAFI_UNICAST:
1634 case SAFI_MULTICAST:
1635 return bgp_nlri_parse_ip (peer, attr, packet);
1636 case SAFI_MPLS_VPN:
1637 case SAFI_MPLS_LABELED_VPN:
1638 return bgp_nlri_parse_vpn (peer, attr, packet);
1639 case SAFI_ENCAP:
1640 return bgp_nlri_parse_encap (peer, attr, packet);
1641 }
1642 return -1;
1643}
1644
paul718e3742002-12-13 20:15:29 +00001645/* Parse BGP Update packet and make attribute object. */
paul94f2b392005-06-28 12:44:16 +00001646static int
paul718e3742002-12-13 20:15:29 +00001647bgp_update_receive (struct peer *peer, bgp_size_t size)
1648{
Paul Jakma518a4b72016-02-04 13:27:04 +00001649 int ret, nlri_ret;
paul718e3742002-12-13 20:15:29 +00001650 u_char *end;
1651 struct stream *s;
1652 struct attr attr;
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001653 struct attr_extra extra;
paul718e3742002-12-13 20:15:29 +00001654 bgp_size_t attribute_len;
1655 bgp_size_t update_len;
1656 bgp_size_t withdraw_len;
Paul Jakma518a4b72016-02-04 13:27:04 +00001657 int i;
1658
1659 enum NLRI_TYPES {
1660 NLRI_UPDATE,
1661 NLRI_WITHDRAW,
1662 NLRI_MP_UPDATE,
1663 NLRI_MP_WITHDRAW,
1664 NLRI_TYPE_MAX,
1665 };
1666 struct bgp_nlri nlris[NLRI_TYPE_MAX];
paul718e3742002-12-13 20:15:29 +00001667
1668 /* Status must be Established. */
1669 if (peer->status != Established)
1670 {
1671 zlog_err ("%s [FSM] Update packet received under status %s",
1672 peer->host, LOOKUP (bgp_status_msg, peer->status));
1673 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1674 return -1;
1675 }
1676
1677 /* Set initial values. */
1678 memset (&attr, 0, sizeof (struct attr));
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001679 memset (&extra, 0, sizeof (struct attr_extra));
Paul Jakma518a4b72016-02-04 13:27:04 +00001680 memset (&nlris, 0, sizeof nlris);
Paul Jakma3b847ef2016-04-22 12:48:49 +01001681
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001682 attr.extra = &extra;
paul718e3742002-12-13 20:15:29 +00001683
1684 s = peer->ibuf;
1685 end = stream_pnt (s) + size;
1686
1687 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1688 Length is too large (i.e., if Unfeasible Routes Length + Total
1689 Attribute Length + 23 exceeds the message Length), then the Error
1690 Subcode is set to Malformed Attribute List. */
1691 if (stream_pnt (s) + 2 > end)
1692 {
1693 zlog_err ("%s [Error] Update packet error"
1694 " (packet length is short for unfeasible length)",
1695 peer->host);
1696 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1697 BGP_NOTIFY_UPDATE_MAL_ATTR);
1698 return -1;
1699 }
1700
1701 /* Unfeasible Route Length. */
1702 withdraw_len = stream_getw (s);
1703
1704 /* Unfeasible Route Length check. */
1705 if (stream_pnt (s) + withdraw_len > end)
1706 {
1707 zlog_err ("%s [Error] Update packet error"
1708 " (packet unfeasible length overflow %d)",
1709 peer->host, withdraw_len);
1710 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1711 BGP_NOTIFY_UPDATE_MAL_ATTR);
1712 return -1;
1713 }
1714
1715 /* Unfeasible Route packet format check. */
1716 if (withdraw_len > 0)
1717 {
Paul Jakma518a4b72016-02-04 13:27:04 +00001718 nlris[NLRI_WITHDRAW].afi = AFI_IP;
1719 nlris[NLRI_WITHDRAW].safi = SAFI_UNICAST;
1720 nlris[NLRI_WITHDRAW].nlri = stream_pnt (s);
1721 nlris[NLRI_WITHDRAW].length = withdraw_len;
1722
paul718e3742002-12-13 20:15:29 +00001723 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001724 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001725
paul9985f832005-02-09 15:51:56 +00001726 stream_forward_getp (s, withdraw_len);
paul718e3742002-12-13 20:15:29 +00001727 }
1728
1729 /* Attribute total length check. */
1730 if (stream_pnt (s) + 2 > end)
1731 {
1732 zlog_warn ("%s [Error] Packet Error"
1733 " (update packet is short for attribute length)",
1734 peer->host);
1735 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1736 BGP_NOTIFY_UPDATE_MAL_ATTR);
1737 return -1;
1738 }
1739
1740 /* Fetch attribute total length. */
1741 attribute_len = stream_getw (s);
1742
1743 /* Attribute length check. */
1744 if (stream_pnt (s) + attribute_len > end)
1745 {
1746 zlog_warn ("%s [Error] Packet Error"
1747 " (update packet attribute length overflow %d)",
1748 peer->host, attribute_len);
1749 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1750 BGP_NOTIFY_UPDATE_MAL_ATTR);
1751 return -1;
1752 }
Paul Jakmab881c702010-11-23 16:35:42 +00001753
1754 /* Certain attribute parsing errors should not be considered bad enough
1755 * to reset the session for, most particularly any partial/optional
1756 * attributes that have 'tunneled' over speakers that don't understand
1757 * them. Instead we withdraw only the prefix concerned.
1758 *
1759 * Complicates the flow a little though..
1760 */
1761 bgp_attr_parse_ret_t attr_parse_ret = BGP_ATTR_PARSE_PROCEED;
1762 /* This define morphs the update case into a withdraw when lower levels
1763 * have signalled an error condition where this is best.
1764 */
1765#define NLRI_ATTR_ARG (attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : NULL)
paul718e3742002-12-13 20:15:29 +00001766
1767 /* Parse attribute when it exists. */
1768 if (attribute_len)
1769 {
Paul Jakmab881c702010-11-23 16:35:42 +00001770 attr_parse_ret = bgp_attr_parse (peer, &attr, attribute_len,
Paul Jakma518a4b72016-02-04 13:27:04 +00001771 &nlris[NLRI_MP_UPDATE], &nlris[NLRI_MP_WITHDRAW]);
Paul Jakmab881c702010-11-23 16:35:42 +00001772 if (attr_parse_ret == BGP_ATTR_PARSE_ERROR)
David Lamparterf80f8382014-06-04 01:00:51 +02001773 {
1774 bgp_attr_unintern_sub (&attr);
Lou Berger050defe2016-01-12 13:41:59 -05001775 bgp_attr_flush (&attr);
David Lamparterf80f8382014-06-04 01:00:51 +02001776 return -1;
1777 }
paul718e3742002-12-13 20:15:29 +00001778 }
Paul Jakmab881c702010-11-23 16:35:42 +00001779
paul718e3742002-12-13 20:15:29 +00001780 /* Logging the attribute. */
Paul Jakmab881c702010-11-23 16:35:42 +00001781 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW
1782 || BGP_DEBUG (update, UPDATE_IN))
paul718e3742002-12-13 20:15:29 +00001783 {
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +00001784 char attrstr[BUFSIZ];
1785 attrstr[0] = '\0';
1786
paule01f9cb2004-07-09 17:48:53 +00001787 ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
Paul Jakmab881c702010-11-23 16:35:42 +00001788 int lvl = (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1789 ? LOG_ERR : LOG_DEBUG;
1790
1791 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1792 zlog (peer->log, LOG_ERR,
1793 "%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
1794 peer->host);
paule01f9cb2004-07-09 17:48:53 +00001795
1796 if (ret)
Paul Jakmab881c702010-11-23 16:35:42 +00001797 zlog (peer->log, lvl, "%s rcvd UPDATE w/ attr: %s",
paule01f9cb2004-07-09 17:48:53 +00001798 peer->host, attrstr);
paul718e3742002-12-13 20:15:29 +00001799 }
Paul Jakmab881c702010-11-23 16:35:42 +00001800
paul718e3742002-12-13 20:15:29 +00001801 /* Network Layer Reachability Information. */
1802 update_len = end - stream_pnt (s);
1803
1804 if (update_len)
1805 {
Paul Jakma18ab08b2016-01-27 16:37:33 +00001806 /* Set NLRI portion to structure. */
Paul Jakma518a4b72016-02-04 13:27:04 +00001807 nlris[NLRI_UPDATE].afi = AFI_IP;
1808 nlris[NLRI_UPDATE].safi = SAFI_UNICAST;
1809 nlris[NLRI_UPDATE].nlri = stream_pnt (s);
1810 nlris[NLRI_UPDATE].length = update_len;
Paul Jakma18ab08b2016-01-27 16:37:33 +00001811
paul9985f832005-02-09 15:51:56 +00001812 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001813 }
Paul Jakma518a4b72016-02-04 13:27:04 +00001814
1815 /* Parse any given NLRIs */
1816 for (i = NLRI_UPDATE; i < NLRI_TYPE_MAX; i++)
paul718e3742002-12-13 20:15:29 +00001817 {
Paul Jakma3b847ef2016-04-22 12:48:49 +01001818 if (!nlris[i].nlri) continue;
1819
Paul Jakma518a4b72016-02-04 13:27:04 +00001820 /* We use afi and safi as indices into tables and what not. It would
1821 * be impossible, at this time, to support unknown afi/safis. And
1822 * anyway, the peer needs to be configured to enable the afi/safi
1823 * explicitly which requires UI support.
1824 *
1825 * Ignore unknown afi/safi NLRIs.
1826 *
1827 * Note: this means nlri[x].afi/safi still can not be trusted for
1828 * indexing later in this function!
1829 *
1830 * Note2: This will also remap the wire code-point for VPN safi to the
1831 * internal safi_t point, as needs be.
1832 */
1833 if (!bgp_afi_safi_valid_indices (nlris[i].afi, &nlris[i].safi))
1834 {
1835 plog_info (peer->log,
1836 "%s [Info] UPDATE with unsupported AFI/SAFI %u/%u",
1837 peer->host, nlris[i].afi, nlris[i].safi);
1838 continue;
1839 }
1840
1841 /* NLRI is processed only when the peer is configured specific
1842 Address Family and Subsequent Address Family. */
1843 if (!peer->afc[nlris[i].afi][nlris[i].safi])
1844 {
1845 plog_info (peer->log,
1846 "%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u",
1847 peer->host, nlris[i].afi, nlris[i].safi);
1848 continue;
1849 }
1850
1851 /* EoR handled later */
1852 if (nlris[i].length == 0)
1853 continue;
1854
1855 switch (i)
1856 {
1857 case NLRI_UPDATE:
1858 case NLRI_MP_UPDATE:
1859 nlri_ret = bgp_nlri_parse (peer, NLRI_ATTR_ARG, &nlris[i]);
1860 break;
1861 case NLRI_WITHDRAW:
1862 case NLRI_MP_WITHDRAW:
1863 nlri_ret = bgp_nlri_parse (peer, NULL, &nlris[i]);
1864 }
1865
1866 if (nlri_ret < 0)
1867 {
1868 plog_err (peer->log,
1869 "%s [Error] Error parsing NLRI", peer->host);
1870 if (peer->status == Established)
1871 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1872 i <= NLRI_WITHDRAW
1873 ? BGP_NOTIFY_UPDATE_INVAL_NETWORK
1874 : BGP_NOTIFY_UPDATE_OPT_ATTR_ERR);
1875 bgp_attr_unintern_sub (&attr);
1876 return -1;
1877 }
1878 }
1879
1880 /* EoR checks.
1881 *
1882 * Non-MP IPv4/Unicast EoR is a completely empty UPDATE
1883 * and MP EoR should have only an empty MP_UNREACH
1884 */
1885 if (!update_len && !withdraw_len
1886 && nlris[NLRI_MP_UPDATE].length == 0)
1887 {
1888 afi_t afi = 0;
1889 safi_t safi;
1890
1891 /* Non-MP IPv4/Unicast is a completely empty UPDATE - already
1892 * checked update and withdraw NLRI lengths are 0.
1893 */
1894 if (!attribute_len)
1895 {
1896 afi = AFI_IP;
1897 safi = SAFI_UNICAST;
1898 }
1899 /* otherwise MP AFI/SAFI is an empty update, other than an empty
1900 * MP_UNREACH_NLRI attr (with an AFI/SAFI we recognise).
1901 */
1902 else if (attr.flag == BGP_ATTR_MP_UNREACH_NLRI
1903 && nlris[NLRI_MP_WITHDRAW].length == 0
1904 && bgp_afi_safi_valid_indices (nlris[NLRI_MP_WITHDRAW].afi,
1905 &nlris[NLRI_MP_WITHDRAW].safi))
1906 {
1907 afi = nlris[NLRI_MP_WITHDRAW].afi;
1908 safi = nlris[NLRI_MP_WITHDRAW].safi;
1909 }
1910
1911 if (afi && peer->afc[afi][safi])
1912 {
paule01f9cb2004-07-09 17:48:53 +00001913 /* End-of-RIB received */
Paul Jakma518a4b72016-02-04 13:27:04 +00001914 SET_FLAG (peer->af_sflags[afi][safi],
hasso93406d82005-02-02 14:40:33 +00001915 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001916
hasso93406d82005-02-02 14:40:33 +00001917 /* NSF delete stale route */
Paul Jakma518a4b72016-02-04 13:27:04 +00001918 if (peer->nsf[afi][safi])
1919 bgp_clear_stale_route (peer, afi, safi);
hasso93406d82005-02-02 14:40:33 +00001920
1921 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma518a4b72016-02-04 13:27:04 +00001922 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for %s from %s",
1923 peer->host, afi_safi_print (afi, safi));
1924 }
paul718e3742002-12-13 20:15:29 +00001925 }
Paul Jakma518a4b72016-02-04 13:27:04 +00001926
paul718e3742002-12-13 20:15:29 +00001927 /* Everything is done. We unintern temporary structures which
1928 interned in bgp_attr_parse(). */
Paul Jakmab881c702010-11-23 16:35:42 +00001929 bgp_attr_unintern_sub (&attr);
Lou Berger050defe2016-01-12 13:41:59 -05001930 bgp_attr_flush (&attr);
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001931
paul718e3742002-12-13 20:15:29 +00001932 /* If peering is stopped due to some reason, do not generate BGP
1933 event. */
1934 if (peer->status != Established)
1935 return 0;
1936
1937 /* Increment packet counter. */
1938 peer->update_in++;
Stephen Hemminger65957882010-01-15 16:22:10 +03001939 peer->update_time = bgp_clock ();
paul718e3742002-12-13 20:15:29 +00001940
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02001941 /* Rearm holdtime timer */
Jorge Boncompte [DTI2]6a4677b2012-05-07 16:53:07 +00001942 BGP_TIMER_OFF (peer->t_holdtime);
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02001943 bgp_timer_set (peer);
paul718e3742002-12-13 20:15:29 +00001944
1945 return 0;
1946}
1947
1948/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00001949static void
paul718e3742002-12-13 20:15:29 +00001950bgp_notify_receive (struct peer *peer, bgp_size_t size)
1951{
1952 struct bgp_notify bgp_notify;
1953
1954 if (peer->notify.data)
1955 {
1956 XFREE (MTYPE_TMP, peer->notify.data);
1957 peer->notify.data = NULL;
1958 peer->notify.length = 0;
1959 }
1960
1961 bgp_notify.code = stream_getc (peer->ibuf);
1962 bgp_notify.subcode = stream_getc (peer->ibuf);
1963 bgp_notify.length = size - 2;
1964 bgp_notify.data = NULL;
1965
1966 /* Preserv notify code and sub code. */
1967 peer->notify.code = bgp_notify.code;
1968 peer->notify.subcode = bgp_notify.subcode;
1969 /* For further diagnostic record returned Data. */
1970 if (bgp_notify.length)
1971 {
1972 peer->notify.length = size - 2;
1973 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
1974 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
1975 }
1976
1977 /* For debug */
1978 {
1979 int i;
1980 int first = 0;
1981 char c[4];
1982
1983 if (bgp_notify.length)
1984 {
1985 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
1986 for (i = 0; i < bgp_notify.length; i++)
1987 if (first)
1988 {
1989 sprintf (c, " %02x", stream_getc (peer->ibuf));
1990 strcat (bgp_notify.data, c);
1991 }
1992 else
1993 {
1994 first = 1;
1995 sprintf (c, "%02x", stream_getc (peer->ibuf));
1996 strcpy (bgp_notify.data, c);
1997 }
1998 }
1999
2000 bgp_notify_print(peer, &bgp_notify, "received");
2001 if (bgp_notify.data)
Daniel Walton363c9032015-10-21 06:42:54 -07002002 {
2003 XFREE (MTYPE_TMP, bgp_notify.data);
2004 bgp_notify.data = NULL;
2005 bgp_notify.length = 0;
2006 }
paul718e3742002-12-13 20:15:29 +00002007 }
2008
2009 /* peer count update */
2010 peer->notify_in++;
2011
hassoe0701b72004-05-20 09:19:34 +00002012 if (peer->status == Established)
2013 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
2014
paul718e3742002-12-13 20:15:29 +00002015 /* We have to check for Notify with Unsupported Optional Parameter.
2016 in that case we fallback to open without the capability option.
2017 But this done in bgp_stop. We just mark it here to avoid changing
2018 the fsm tables. */
2019 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
2020 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
2021 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
2022
paul718e3742002-12-13 20:15:29 +00002023 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
2024}
2025
2026/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00002027static void
paul718e3742002-12-13 20:15:29 +00002028bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
2029{
2030 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00002031 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00002032
2033 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
2034}
2035
2036/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00002037static void
paul718e3742002-12-13 20:15:29 +00002038bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
2039{
2040 afi_t afi;
2041 safi_t safi;
paul718e3742002-12-13 20:15:29 +00002042 struct stream *s;
2043
2044 /* If peer does not have the capability, send notification. */
2045 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
2046 {
2047 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
2048 peer->host);
2049 bgp_notify_send (peer,
2050 BGP_NOTIFY_HEADER_ERR,
2051 BGP_NOTIFY_HEADER_BAD_MESTYPE);
2052 return;
2053 }
2054
2055 /* Status must be Established. */
2056 if (peer->status != Established)
2057 {
2058 plog_err (peer->log,
2059 "%s [Error] Route refresh packet received under status %s",
2060 peer->host, LOOKUP (bgp_status_msg, peer->status));
2061 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
2062 return;
2063 }
2064
2065 s = peer->ibuf;
2066
2067 /* Parse packet. */
2068 afi = stream_getw (s);
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002069 /* reserved byte */
2070 stream_getc (s);
paul718e3742002-12-13 20:15:29 +00002071 safi = stream_getc (s);
2072
2073 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002074 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00002075 peer->host, afi, safi);
2076
2077 /* Check AFI and SAFI. */
2078 if ((afi != AFI_IP && afi != AFI_IP6)
2079 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
Denis Ovsienko42e6d742011-07-14 12:36:19 +04002080 && safi != SAFI_MPLS_LABELED_VPN))
paul718e3742002-12-13 20:15:29 +00002081 {
2082 if (BGP_DEBUG (normal, NORMAL))
2083 {
ajs6b514742004-12-08 21:03:23 +00002084 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00002085 peer->host, afi, safi);
2086 }
2087 return;
2088 }
2089
2090 /* Adjust safi code. */
Denis Ovsienko42e6d742011-07-14 12:36:19 +04002091 if (safi == SAFI_MPLS_LABELED_VPN)
paul718e3742002-12-13 20:15:29 +00002092 safi = SAFI_MPLS_VPN;
2093
2094 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
2095 {
2096 u_char *end;
2097 u_char when_to_refresh;
2098 u_char orf_type;
2099 u_int16_t orf_len;
2100
2101 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
2102 {
2103 zlog_info ("%s ORF route refresh length error", peer->host);
2104 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2105 return;
2106 }
2107
2108 when_to_refresh = stream_getc (s);
2109 end = stream_pnt (s) + (size - 5);
2110
Paul Jakma370b64a2007-12-22 16:49:52 +00002111 while ((stream_pnt (s) + 2) < end)
paul718e3742002-12-13 20:15:29 +00002112 {
2113 orf_type = stream_getc (s);
2114 orf_len = stream_getw (s);
Paul Jakma370b64a2007-12-22 16:49:52 +00002115
2116 /* orf_len in bounds? */
2117 if ((stream_pnt (s) + orf_len) > end)
2118 break; /* XXX: Notify instead?? */
paul718e3742002-12-13 20:15:29 +00002119 if (orf_type == ORF_TYPE_PREFIX
2120 || orf_type == ORF_TYPE_PREFIX_OLD)
2121 {
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002122 uint8_t *p_pnt = stream_pnt (s);
2123 uint8_t *p_end = stream_pnt (s) + orf_len;
paul718e3742002-12-13 20:15:29 +00002124 struct orf_prefix orfp;
2125 u_char common = 0;
2126 u_int32_t seq;
2127 int psize;
2128 char name[BUFSIZ];
paul718e3742002-12-13 20:15:29 +00002129 int ret;
2130
2131 if (BGP_DEBUG (normal, NORMAL))
2132 {
ajs6b514742004-12-08 21:03:23 +00002133 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00002134 peer->host, orf_type, orf_len);
2135 }
2136
Paul Jakma370b64a2007-12-22 16:49:52 +00002137 /* we're going to read at least 1 byte of common ORF header,
2138 * and 7 bytes of ORF Address-filter entry from the stream
2139 */
2140 if (orf_len < 7)
2141 break;
2142
paul718e3742002-12-13 20:15:29 +00002143 /* ORF prefix-list name */
2144 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
2145
2146 while (p_pnt < p_end)
2147 {
Chris Halld64379e2010-05-14 16:38:39 +04002148 /* If the ORF entry is malformed, want to read as much of it
2149 * as possible without going beyond the bounds of the entry,
2150 * to maximise debug information.
2151 */
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002152 int ok;
paul718e3742002-12-13 20:15:29 +00002153 memset (&orfp, 0, sizeof (struct orf_prefix));
2154 common = *p_pnt++;
Chris Halld64379e2010-05-14 16:38:39 +04002155 /* after ++: p_pnt <= p_end */
paul718e3742002-12-13 20:15:29 +00002156 if (common & ORF_COMMON_PART_REMOVE_ALL)
2157 {
2158 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002159 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
David Lamparterc9c06d02015-04-13 10:21:35 +02002160 prefix_bgp_orf_remove_all (afi, name);
paul718e3742002-12-13 20:15:29 +00002161 break;
2162 }
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002163 ok = ((size_t)(p_end - p_pnt) >= sizeof(u_int32_t)) ;
Denis Ovsienkobb915f52011-12-13 21:11:39 +04002164 if (ok)
Chris Halld64379e2010-05-14 16:38:39 +04002165 {
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002166 memcpy (&seq, p_pnt, sizeof (u_int32_t));
2167 p_pnt += sizeof (u_int32_t);
2168 orfp.seq = ntohl (seq);
Chris Halld64379e2010-05-14 16:38:39 +04002169 }
2170 else
2171 p_pnt = p_end ;
2172
2173 if ((ok = (p_pnt < p_end)))
2174 orfp.ge = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2175 if ((ok = (p_pnt < p_end)))
2176 orfp.le = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2177 if ((ok = (p_pnt < p_end)))
2178 orfp.p.prefixlen = *p_pnt++ ;
2179 orfp.p.family = afi2family (afi); /* afi checked already */
2180
2181 psize = PSIZE (orfp.p.prefixlen); /* 0 if not ok */
2182 if (psize > prefix_blen(&orfp.p)) /* valid for family ? */
2183 {
2184 ok = 0 ;
2185 psize = prefix_blen(&orfp.p) ;
2186 }
2187 if (psize > (p_end - p_pnt)) /* valid for packet ? */
2188 {
2189 ok = 0 ;
2190 psize = p_end - p_pnt ;
2191 }
2192
2193 if (psize > 0)
2194 memcpy (&orfp.p.u.prefix, p_pnt, psize);
paul718e3742002-12-13 20:15:29 +00002195 p_pnt += psize;
2196
2197 if (BGP_DEBUG (normal, NORMAL))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +00002198 {
2199 char buf[INET6_BUFSIZ];
2200
2201 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
2202 peer->host,
2203 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
2204 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
2205 orfp.seq,
2206 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, INET6_BUFSIZ),
2207 orfp.p.prefixlen, orfp.ge, orfp.le,
2208 ok ? "" : " MALFORMED");
2209 }
2210
Chris Halld64379e2010-05-14 16:38:39 +04002211 if (ok)
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002212 ret = prefix_bgp_orf_set (name, afi, &orfp,
2213 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
2214 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002215
2216 if (!ok || (ok && ret != CMD_SUCCESS))
paul718e3742002-12-13 20:15:29 +00002217 {
2218 if (BGP_DEBUG (normal, NORMAL))
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002219 zlog_debug ("%s Received misformatted prefixlist ORF."
2220 " Remove All pfxlist", peer->host);
David Lamparterc9c06d02015-04-13 10:21:35 +02002221 prefix_bgp_orf_remove_all (afi, name);
paul718e3742002-12-13 20:15:29 +00002222 break;
2223 }
2224 }
2225 peer->orf_plist[afi][safi] =
David Lamparterc9c06d02015-04-13 10:21:35 +02002226 prefix_bgp_orf_lookup (afi, name);
paul718e3742002-12-13 20:15:29 +00002227 }
paul9985f832005-02-09 15:51:56 +00002228 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00002229 }
2230 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002231 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00002232 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
2233 if (when_to_refresh == REFRESH_DEFER)
2234 return;
2235 }
2236
2237 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2238 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
2239 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
2240
2241 /* Perform route refreshment to the peer */
2242 bgp_announce_route (peer, afi, safi);
2243}
2244
paul94f2b392005-06-28 12:44:16 +00002245static int
paul718e3742002-12-13 20:15:29 +00002246bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
2247{
2248 u_char *end;
Paul Jakma6d582722007-08-06 15:21:45 +00002249 struct capability_mp_data mpc;
2250 struct capability_header *hdr;
paul718e3742002-12-13 20:15:29 +00002251 u_char action;
paul718e3742002-12-13 20:15:29 +00002252 afi_t afi;
2253 safi_t safi;
2254
paul718e3742002-12-13 20:15:29 +00002255 end = pnt + length;
2256
2257 while (pnt < end)
Paul Jakma6d582722007-08-06 15:21:45 +00002258 {
paul718e3742002-12-13 20:15:29 +00002259 /* We need at least action, capability code and capability length. */
2260 if (pnt + 3 > end)
2261 {
2262 zlog_info ("%s Capability length error", peer->host);
2263 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2264 return -1;
2265 }
paul718e3742002-12-13 20:15:29 +00002266 action = *pnt;
Paul Jakma6d582722007-08-06 15:21:45 +00002267 hdr = (struct capability_header *)(pnt + 1);
2268
paul718e3742002-12-13 20:15:29 +00002269 /* Action value check. */
2270 if (action != CAPABILITY_ACTION_SET
2271 && action != CAPABILITY_ACTION_UNSET)
2272 {
2273 zlog_info ("%s Capability Action Value error %d",
2274 peer->host, action);
2275 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2276 return -1;
2277 }
2278
2279 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002280 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
Paul Jakma6d582722007-08-06 15:21:45 +00002281 peer->host, action, hdr->code, hdr->length);
paul718e3742002-12-13 20:15:29 +00002282
2283 /* Capability length check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002284 if ((pnt + hdr->length + 3) > end)
paul718e3742002-12-13 20:15:29 +00002285 {
2286 zlog_info ("%s Capability length error", peer->host);
2287 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2288 return -1;
2289 }
2290
Paul Jakma6d582722007-08-06 15:21:45 +00002291 /* Fetch structure to the byte stream. */
2292 memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
2293
paul718e3742002-12-13 20:15:29 +00002294 /* We know MP Capability Code. */
Paul Jakma6d582722007-08-06 15:21:45 +00002295 if (hdr->code == CAPABILITY_CODE_MP)
paul718e3742002-12-13 20:15:29 +00002296 {
Paul Jakma6d582722007-08-06 15:21:45 +00002297 afi = ntohs (mpc.afi);
2298 safi = mpc.safi;
paul718e3742002-12-13 20:15:29 +00002299
2300 /* Ignore capability when override-capability is set. */
2301 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2302 continue;
Paul Jakma6d582722007-08-06 15:21:45 +00002303
2304 if (!bgp_afi_safi_valid_indices (afi, &safi))
2305 {
2306 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002307 zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
2308 "(%u/%u)", peer->host, afi, safi);
Paul Jakma6d582722007-08-06 15:21:45 +00002309 continue;
2310 }
2311
paul718e3742002-12-13 20:15:29 +00002312 /* Address family check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002313 if (BGP_DEBUG (normal, NORMAL))
2314 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2315 peer->host,
2316 action == CAPABILITY_ACTION_SET
2317 ? "Advertising" : "Removing",
2318 ntohs(mpc.afi) , mpc.safi);
2319
2320 if (action == CAPABILITY_ACTION_SET)
2321 {
2322 peer->afc_recv[afi][safi] = 1;
2323 if (peer->afc[afi][safi])
2324 {
2325 peer->afc_nego[afi][safi] = 1;
2326 bgp_announce_route (peer, afi, safi);
2327 }
2328 }
2329 else
2330 {
2331 peer->afc_recv[afi][safi] = 0;
2332 peer->afc_nego[afi][safi] = 0;
paul718e3742002-12-13 20:15:29 +00002333
Paul Jakma6d582722007-08-06 15:21:45 +00002334 if (peer_active_nego (peer))
Chris Caputo228da422009-07-18 05:44:03 +00002335 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
Paul Jakma6d582722007-08-06 15:21:45 +00002336 else
2337 BGP_EVENT_ADD (peer, BGP_Stop);
2338 }
paul718e3742002-12-13 20:15:29 +00002339 }
paul718e3742002-12-13 20:15:29 +00002340 else
2341 {
2342 zlog_warn ("%s unrecognized capability code: %d - ignored",
Paul Jakma6d582722007-08-06 15:21:45 +00002343 peer->host, hdr->code);
paul718e3742002-12-13 20:15:29 +00002344 }
Paul Jakma6d582722007-08-06 15:21:45 +00002345 pnt += hdr->length + 3;
paul718e3742002-12-13 20:15:29 +00002346 }
2347 return 0;
2348}
2349
Paul Jakma01b7ce22009-06-18 12:34:43 +01002350/* Dynamic Capability is received.
2351 *
2352 * This is exported for unit-test purposes
2353 */
Paul Jakma6d582722007-08-06 15:21:45 +00002354int
paul718e3742002-12-13 20:15:29 +00002355bgp_capability_receive (struct peer *peer, bgp_size_t size)
2356{
2357 u_char *pnt;
paul718e3742002-12-13 20:15:29 +00002358
2359 /* Fetch pointer. */
2360 pnt = stream_pnt (peer->ibuf);
2361
2362 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002363 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002364
2365 /* If peer does not have the capability, send notification. */
2366 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2367 {
2368 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2369 peer->host);
2370 bgp_notify_send (peer,
2371 BGP_NOTIFY_HEADER_ERR,
2372 BGP_NOTIFY_HEADER_BAD_MESTYPE);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002373 return -1;
paul718e3742002-12-13 20:15:29 +00002374 }
2375
2376 /* Status must be Established. */
2377 if (peer->status != Established)
2378 {
2379 plog_err (peer->log,
2380 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2381 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002382 return -1;
paul718e3742002-12-13 20:15:29 +00002383 }
2384
2385 /* Parse packet. */
Paul Jakma6d582722007-08-06 15:21:45 +00002386 return bgp_capability_msg_parse (peer, pnt, size);
paul718e3742002-12-13 20:15:29 +00002387}
David Lamparter6b0655a2014-06-04 06:53:35 +02002388
paul718e3742002-12-13 20:15:29 +00002389/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002390static int
paul718e3742002-12-13 20:15:29 +00002391bgp_read_packet (struct peer *peer)
2392{
2393 int nbytes;
2394 int readsize;
2395
paul9985f832005-02-09 15:51:56 +00002396 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002397
2398 /* If size is zero then return. */
2399 if (! readsize)
2400 return 0;
2401
2402 /* Read packet from fd. */
Stephen Hemminger35398582010-08-05 10:26:23 -07002403 nbytes = stream_read_try (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002404
2405 /* If read byte is smaller than zero then error occured. */
2406 if (nbytes < 0)
2407 {
Stephen Hemminger35398582010-08-05 10:26:23 -07002408 /* Transient error should retry */
2409 if (nbytes == -2)
paul718e3742002-12-13 20:15:29 +00002410 return -1;
2411
2412 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002413 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002414
2415 if (peer->status == Established)
2416 {
2417 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2418 {
2419 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2420 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2421 }
2422 else
2423 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2424 }
2425
paul718e3742002-12-13 20:15:29 +00002426 BGP_EVENT_ADD (peer, TCP_fatal_error);
2427 return -1;
2428 }
2429
2430 /* When read byte is zero : clear bgp peer and return */
2431 if (nbytes == 0)
2432 {
2433 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002434 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002435 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002436
2437 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002438 {
2439 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2440 {
2441 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2442 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2443 }
2444 else
2445 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2446 }
hassoe0701b72004-05-20 09:19:34 +00002447
paul718e3742002-12-13 20:15:29 +00002448 BGP_EVENT_ADD (peer, TCP_connection_closed);
2449 return -1;
2450 }
2451
2452 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002453 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002454 return -1;
2455
2456 return 0;
2457}
2458
2459/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002460static int
paul718e3742002-12-13 20:15:29 +00002461bgp_marker_all_one (struct stream *s, int length)
2462{
2463 int i;
2464
2465 for (i = 0; i < length; i++)
2466 if (s->data[i] != 0xff)
2467 return 0;
2468
2469 return 1;
2470}
2471
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002472/* Recent thread time.
2473 On same clock base as bgp_clock (MONOTONIC)
2474 but can be time of last context switch to bgp_read thread. */
2475static time_t
2476bgp_recent_clock (void)
2477{
2478 return recent_relative_time().tv_sec;
2479}
2480
paul718e3742002-12-13 20:15:29 +00002481/* Starting point of packet process function. */
2482int
2483bgp_read (struct thread *thread)
2484{
2485 int ret;
2486 u_char type = 0;
2487 struct peer *peer;
2488 bgp_size_t size;
2489 char notify_data_length[2];
2490
2491 /* Yes first of all get peer pointer. */
2492 peer = THREAD_ARG (thread);
2493 peer->t_read = NULL;
2494
2495 /* For non-blocking IO check. */
2496 if (peer->status == Connect)
2497 {
Dinesh Duttd9ab53a2015-05-19 17:47:21 -07002498 bgp_connect_check (peer, 1);
paul718e3742002-12-13 20:15:29 +00002499 goto done;
2500 }
2501 else
2502 {
pauleb821182004-05-01 08:44:08 +00002503 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002504 {
pauleb821182004-05-01 08:44:08 +00002505 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002506 return -1;
2507 }
pauleb821182004-05-01 08:44:08 +00002508 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002509 }
2510
2511 /* Read packet header to determine type of the packet */
2512 if (peer->packet_size == 0)
2513 peer->packet_size = BGP_HEADER_SIZE;
2514
paul9985f832005-02-09 15:51:56 +00002515 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002516 {
2517 ret = bgp_read_packet (peer);
2518
2519 /* Header read error or partial read packet. */
2520 if (ret < 0)
2521 goto done;
2522
2523 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002524 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002525 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2526 size = stream_getw (peer->ibuf);
2527 type = stream_getc (peer->ibuf);
2528
2529 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002530 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002531 peer->host, type, size - BGP_HEADER_SIZE);
2532
2533 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002534 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002535 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2536 {
2537 bgp_notify_send (peer,
2538 BGP_NOTIFY_HEADER_ERR,
2539 BGP_NOTIFY_HEADER_NOT_SYNC);
2540 goto done;
2541 }
2542
2543 /* BGP type check. */
2544 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2545 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2546 && type != BGP_MSG_ROUTE_REFRESH_NEW
2547 && type != BGP_MSG_ROUTE_REFRESH_OLD
2548 && type != BGP_MSG_CAPABILITY)
2549 {
2550 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002551 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002552 "%s unknown message type 0x%02x",
2553 peer->host, type);
2554 bgp_notify_send_with_data (peer,
2555 BGP_NOTIFY_HEADER_ERR,
2556 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2557 &type, 1);
2558 goto done;
2559 }
2560 /* Mimimum packet length check. */
2561 if ((size < BGP_HEADER_SIZE)
2562 || (size > BGP_MAX_PACKET_SIZE)
2563 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2564 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2565 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2566 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2567 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2568 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2569 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2570 {
2571 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002572 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002573 "%s bad message length - %d for %s",
2574 peer->host, size,
2575 type == 128 ? "ROUTE-REFRESH" :
2576 bgp_type_str[(int) type]);
2577 bgp_notify_send_with_data (peer,
2578 BGP_NOTIFY_HEADER_ERR,
2579 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002580 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002581 goto done;
2582 }
2583
2584 /* Adjust size to message length. */
2585 peer->packet_size = size;
2586 }
2587
2588 ret = bgp_read_packet (peer);
2589 if (ret < 0)
2590 goto done;
2591
2592 /* Get size and type again. */
2593 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2594 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2595
2596 /* BGP packet dump function. */
2597 bgp_dump_packet (peer, type, peer->ibuf);
2598
2599 size = (peer->packet_size - BGP_HEADER_SIZE);
2600
2601 /* Read rest of the packet and call each sort of packet routine */
2602 switch (type)
2603 {
2604 case BGP_MSG_OPEN:
2605 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002606 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002607 break;
2608 case BGP_MSG_UPDATE:
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002609 peer->readtime = bgp_recent_clock ();
paul718e3742002-12-13 20:15:29 +00002610 bgp_update_receive (peer, size);
2611 break;
2612 case BGP_MSG_NOTIFY:
2613 bgp_notify_receive (peer, size);
2614 break;
2615 case BGP_MSG_KEEPALIVE:
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002616 peer->readtime = bgp_recent_clock ();
paul718e3742002-12-13 20:15:29 +00002617 bgp_keepalive_receive (peer, size);
2618 break;
2619 case BGP_MSG_ROUTE_REFRESH_NEW:
2620 case BGP_MSG_ROUTE_REFRESH_OLD:
2621 peer->refresh_in++;
2622 bgp_route_refresh_receive (peer, size);
2623 break;
2624 case BGP_MSG_CAPABILITY:
2625 peer->dynamic_cap_in++;
2626 bgp_capability_receive (peer, size);
2627 break;
2628 }
2629
2630 /* Clear input buffer. */
2631 peer->packet_size = 0;
2632 if (peer->ibuf)
2633 stream_reset (peer->ibuf);
2634
2635 done:
2636 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2637 {
2638 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002639 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002640 peer_delete (peer);
paul718e3742002-12-13 20:15:29 +00002641 }
2642 return 0;
2643}