blob: 740b0f1ce6038fbfe13ab5aa5498c6bc25d24473 [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. */
106static void
107bgp_connect_check (struct peer *peer)
108{
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);
126 return;
127 }
128
129 /* When status is 0 then TCP connection is established. */
130 if (status == 0)
131 {
132 BGP_EVENT_ADD (peer, TCP_connection_open);
133 }
134 else
135 {
136 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +0000137 plog_debug (peer->log, "%s [Event] Connect failed (%s)",
ajs6099b3b2004-11-20 02:06:59 +0000138 peer->host, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000139 BGP_EVENT_ADD (peer, TCP_connection_open_failed);
140 }
141}
142
143/* Make BGP update packet. */
paul94f2b392005-06-28 12:44:16 +0000144static struct stream *
paul718e3742002-12-13 20:15:29 +0000145bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi)
146{
147 struct stream *s;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000148 struct stream *snlri;
paul718e3742002-12-13 20:15:29 +0000149 struct bgp_adj_out *adj;
150 struct bgp_advertise *adv;
151 struct stream *packet;
152 struct bgp_node *rn = NULL;
153 struct bgp_info *binfo = NULL;
154 bgp_size_t total_attr_len = 0;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000155 unsigned long attrlen_pos = 0;
156 size_t mpattrlen_pos = 0;
157 size_t mpattr_pos = 0;
paul718e3742002-12-13 20:15:29 +0000158
159 s = peer->work;
160 stream_reset (s);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000161 snlri = peer->scratch;
162 stream_reset (snlri);
paul718e3742002-12-13 20:15:29 +0000163
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100164 adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update);
paul718e3742002-12-13 20:15:29 +0000165
166 while (adv)
167 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000168 assert (adv->rn);
169 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000170 adj = adv->adj;
171 if (adv->binfo)
172 binfo = adv->binfo;
paul718e3742002-12-13 20:15:29 +0000173
174 /* When remaining space can't include NLRI and it's length. */
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000175 if (STREAM_CONCAT_REMAIN (s, snlri, STREAM_SIZE(s)) <=
Lou Berger050defe2016-01-12 13:41:59 -0500176 (BGP_NLRI_LENGTH + bgp_packet_mpattr_prefix_size(afi,safi,&rn->p)))
paul718e3742002-12-13 20:15:29 +0000177 break;
178
179 /* If packet is empty, set attribute. */
180 if (stream_empty (s))
181 {
Lou Berger050defe2016-01-12 13:41:59 -0500182 struct prefix_rd *prd = NULL;
183 u_char *tag = NULL;
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000184 struct peer *from = NULL;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000185
Lou Berger050defe2016-01-12 13:41:59 -0500186 if (rn->prn)
187 prd = (struct prefix_rd *) &rn->prn->p;
Greg Troxeld3ddb222010-09-17 10:47:49 -0400188 if (binfo)
Lou Berger050defe2016-01-12 13:41:59 -0500189 {
190 from = binfo->peer;
191 if (binfo->extra)
192 tag = binfo->extra->tag;
193 }
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000194
195 /* 1: Write the BGP message header - 16 bytes marker, 2 bytes length,
196 * one byte message type.
197 */
paul718e3742002-12-13 20:15:29 +0000198 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000199
200 /* 2: withdrawn routes length */
paul718e3742002-12-13 20:15:29 +0000201 stream_putw (s, 0);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000202
203 /* 3: total attributes length - attrlen_pos stores the position */
204 attrlen_pos = stream_get_endp (s);
205 stream_putw (s, 0);
206
207 /* 4: if there is MP_REACH_NLRI attribute, that should be the first
208 * attribute, according to draft-ietf-idr-error-handling. Save the
209 * position.
210 */
211 mpattr_pos = stream_get_endp(s);
212
213 /* 5: Encode all the attributes, except MP_REACH_NLRI attr. */
214 total_attr_len = bgp_packet_attribute (NULL, peer, s,
paul5228ad22004-06-04 17:58:18 +0000215 adv->baa->attr,
Lou Berger298cc2f2016-01-12 13:42:02 -0500216 ((afi == AFI_IP && safi == SAFI_UNICAST) ?
217 &rn->p : NULL),
218 afi, safi,
Lou Berger050defe2016-01-12 13:41:59 -0500219 from, prd, tag);
paul718e3742002-12-13 20:15:29 +0000220 }
221
222 if (afi == AFI_IP && safi == SAFI_UNICAST)
223 stream_put_prefix (s, &rn->p);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000224 else
225 {
226 /* Encode the prefix in MP_REACH_NLRI attribute */
227 struct prefix_rd *prd = NULL;
228 u_char *tag = NULL;
229
230 if (rn->prn)
231 prd = (struct prefix_rd *) &rn->prn->p;
232 if (binfo && binfo->extra)
233 tag = binfo->extra->tag;
234
235 if (stream_empty(snlri))
236 mpattrlen_pos = bgp_packet_mpattr_start(snlri, afi, safi,
237 adv->baa->attr);
238 bgp_packet_mpattr_prefix(snlri, afi, safi, &rn->p, prd, tag);
239 }
paul718e3742002-12-13 20:15:29 +0000240 if (BGP_DEBUG (update, UPDATE_OUT))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000241 {
242 char buf[INET6_BUFSIZ];
243
244 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d",
245 peer->host,
246 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, INET6_BUFSIZ),
247 rn->p.prefixlen);
248 }
paul718e3742002-12-13 20:15:29 +0000249
250 /* Synchnorize attribute. */
251 if (adj->attr)
Paul Jakmaf6f434b2010-11-23 21:28:03 +0000252 bgp_attr_unintern (&adj->attr);
paul718e3742002-12-13 20:15:29 +0000253 else
254 peer->scount[afi][safi]++;
255
256 adj->attr = bgp_attr_intern (adv->baa->attr);
257
258 adv = bgp_advertise_clean (peer, adj, afi, safi);
paul718e3742002-12-13 20:15:29 +0000259 }
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000260
paul718e3742002-12-13 20:15:29 +0000261 if (! stream_empty (s))
262 {
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000263 if (!stream_empty(snlri))
264 {
265 bgp_packet_mpattr_end(snlri, mpattrlen_pos);
266 total_attr_len += stream_get_endp(snlri);
267 }
268
269 /* set the total attribute length correctly */
270 stream_putw_at (s, attrlen_pos, total_attr_len);
271
272 if (!stream_empty(snlri))
273 packet = stream_dupcat(s, snlri, mpattr_pos);
274 else
275 packet = stream_dup (s);
276 bgp_packet_set_size (packet);
paul718e3742002-12-13 20:15:29 +0000277 bgp_packet_add (peer, packet);
pauleb821182004-05-01 08:44:08 +0000278 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000279 stream_reset (s);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000280 stream_reset (snlri);
paul718e3742002-12-13 20:15:29 +0000281 return packet;
282 }
283 return NULL;
hasso93406d82005-02-02 14:40:33 +0000284}
paul718e3742002-12-13 20:15:29 +0000285
paul94f2b392005-06-28 12:44:16 +0000286static struct stream *
hasso93406d82005-02-02 14:40:33 +0000287bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
288{
289 struct stream *s;
hasso93406d82005-02-02 14:40:33 +0000290
Paul Jakma750e8142008-07-22 21:11:48 +0000291 if (DISABLE_BGP_ANNOUNCE)
292 return NULL;
hasso93406d82005-02-02 14:40:33 +0000293
294 if (BGP_DEBUG (normal, NORMAL))
295 zlog_debug ("send End-of-RIB for %s to %s", afi_safi_print (afi, safi), peer->host);
296
297 s = stream_new (BGP_MAX_PACKET_SIZE);
298
299 /* Make BGP update packet. */
300 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
301
302 /* Unfeasible Routes Length */
303 stream_putw (s, 0);
304
305 if (afi == AFI_IP && safi == SAFI_UNICAST)
306 {
307 /* Total Path Attribute Length */
308 stream_putw (s, 0);
309 }
310 else
311 {
312 /* Total Path Attribute Length */
313 stream_putw (s, 6);
314 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
315 stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
316 stream_putc (s, 3);
317 stream_putw (s, afi);
318 stream_putc (s, safi);
319 }
320
321 bgp_packet_set_size (s);
Donald Sharpa752c3b2015-08-18 08:48:53 -0400322 bgp_packet_add (peer, s);
323 return s;
paul718e3742002-12-13 20:15:29 +0000324}
325
326/* Make BGP withdraw packet. */
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000327/* For ipv4 unicast:
328 16-octet marker | 2-octet length | 1-octet type |
329 2-octet withdrawn route length | withdrawn prefixes | 2-octet attrlen (=0)
330*/
331/* For other afi/safis:
332 16-octet marker | 2-octet length | 1-octet type |
333 2-octet withdrawn route length (=0) | 2-octet attrlen |
334 mp_unreach attr type | attr len | afi | safi | withdrawn prefixes
335*/
paul94f2b392005-06-28 12:44:16 +0000336static struct stream *
paul718e3742002-12-13 20:15:29 +0000337bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi)
338{
339 struct stream *s;
340 struct stream *packet;
341 struct bgp_adj_out *adj;
342 struct bgp_advertise *adv;
343 struct bgp_node *rn;
paul718e3742002-12-13 20:15:29 +0000344 bgp_size_t unfeasible_len;
345 bgp_size_t total_attr_len;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000346 size_t mp_start = 0;
347 size_t attrlen_pos = 0;
348 size_t mplen_pos = 0;
349 u_char first_time = 1;
paul718e3742002-12-13 20:15:29 +0000350
351 s = peer->work;
352 stream_reset (s);
353
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100354 while ((adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL)
paul718e3742002-12-13 20:15:29 +0000355 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000356 assert (adv->rn);
paul718e3742002-12-13 20:15:29 +0000357 adj = adv->adj;
358 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000359
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000360 if (STREAM_REMAIN (s)
hasso4372df72004-05-20 10:20:02 +0000361 < (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN + PSIZE (rn->p.prefixlen)))
paul718e3742002-12-13 20:15:29 +0000362 break;
363
364 if (stream_empty (s))
365 {
366 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000367 stream_putw (s, 0); /* unfeasible routes length */
paul718e3742002-12-13 20:15:29 +0000368 }
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000369 else
370 first_time = 0;
paul718e3742002-12-13 20:15:29 +0000371
372 if (afi == AFI_IP && safi == SAFI_UNICAST)
373 stream_put_prefix (s, &rn->p);
374 else
375 {
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000376 struct prefix_rd *prd = NULL;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000377
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000378 if (rn->prn)
379 prd = (struct prefix_rd *) &rn->prn->p;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000380
381 /* If first time, format the MP_UNREACH header */
382 if (first_time)
383 {
384 attrlen_pos = stream_get_endp (s);
385 /* total attr length = 0 for now. reevaluate later */
386 stream_putw (s, 0);
387 mp_start = stream_get_endp (s);
388 mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
389 }
390
391 bgp_packet_mpunreach_prefix(s, &rn->p, afi, safi, prd, NULL);
paul718e3742002-12-13 20:15:29 +0000392 }
393
394 if (BGP_DEBUG (update, UPDATE_OUT))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000395 {
396 char buf[INET6_BUFSIZ];
397
398 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
399 peer->host,
400 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, INET6_BUFSIZ),
401 rn->p.prefixlen);
402 }
paul718e3742002-12-13 20:15:29 +0000403
404 peer->scount[afi][safi]--;
405
406 bgp_adj_out_remove (rn, adj, peer, afi, safi);
407 bgp_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +0000408 }
409
410 if (! stream_empty (s))
411 {
412 if (afi == AFI_IP && safi == SAFI_UNICAST)
413 {
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000414 unfeasible_len
paul9985f832005-02-09 15:51:56 +0000415 = stream_get_endp (s) - BGP_HEADER_SIZE - BGP_UNFEASIBLE_LEN;
paul718e3742002-12-13 20:15:29 +0000416 stream_putw_at (s, BGP_HEADER_SIZE, unfeasible_len);
417 stream_putw (s, 0);
418 }
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000419 else
420 {
421 /* Set the mp_unreach attr's length */
422 bgp_packet_mpunreach_end(s, mplen_pos);
423
424 /* Set total path attribute length. */
425 total_attr_len = stream_get_endp(s) - mp_start;
426 stream_putw_at (s, attrlen_pos, total_attr_len);
427 }
paul718e3742002-12-13 20:15:29 +0000428 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000429 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000430 bgp_packet_add (peer, packet);
431 stream_reset (s);
432 return packet;
433 }
434
435 return NULL;
436}
437
438void
439bgp_default_update_send (struct peer *peer, struct attr *attr,
440 afi_t afi, safi_t safi, struct peer *from)
441{
442 struct stream *s;
paul718e3742002-12-13 20:15:29 +0000443 struct prefix p;
444 unsigned long pos;
445 bgp_size_t total_attr_len;
paul718e3742002-12-13 20:15:29 +0000446
Paul Jakma750e8142008-07-22 21:11:48 +0000447 if (DISABLE_BGP_ANNOUNCE)
448 return;
paul718e3742002-12-13 20:15:29 +0000449
450 if (afi == AFI_IP)
451 str2prefix ("0.0.0.0/0", &p);
paul718e3742002-12-13 20:15:29 +0000452 else
453 str2prefix ("::/0", &p);
paul718e3742002-12-13 20:15:29 +0000454
455 /* Logging the attribute. */
456 if (BGP_DEBUG (update, UPDATE_OUT))
457 {
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000458 char attrstr[BUFSIZ];
459 char buf[INET6_BUFSIZ];
460 attrstr[0] = '\0';
461
paul718e3742002-12-13 20:15:29 +0000462 bgp_dump_attr (peer, attr, attrstr, BUFSIZ);
ajs6b514742004-12-08 21:03:23 +0000463 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d %s",
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000464 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, INET6_BUFSIZ),
paul718e3742002-12-13 20:15:29 +0000465 p.prefixlen, attrstr);
466 }
467
468 s = stream_new (BGP_MAX_PACKET_SIZE);
469
470 /* Make BGP update packet. */
471 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
472
473 /* Unfeasible Routes Length. */
474 stream_putw (s, 0);
475
476 /* Make place for total attribute length. */
paul9985f832005-02-09 15:51:56 +0000477 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000478 stream_putw (s, 0);
479 total_attr_len = bgp_packet_attribute (NULL, peer, s, attr, &p, afi, safi, from, NULL, NULL);
480
481 /* Set Total Path Attribute Length. */
482 stream_putw_at (s, pos, total_attr_len);
483
484 /* NLRI set. */
485 if (p.family == AF_INET && safi == SAFI_UNICAST)
486 stream_put_prefix (s, &p);
487
488 /* Set size. */
489 bgp_packet_set_size (s);
490
paul718e3742002-12-13 20:15:29 +0000491 /* Dump packet if debug option is set. */
492#ifdef DEBUG
jardin2d74db52005-10-01 00:07:50 +0000493 /* bgp_packet_dump (packet); */
paul718e3742002-12-13 20:15:29 +0000494#endif /* DEBUG */
495
496 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -0400497 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +0000498
pauleb821182004-05-01 08:44:08 +0000499 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000500}
501
502void
503bgp_default_withdraw_send (struct peer *peer, afi_t afi, safi_t safi)
504{
505 struct stream *s;
paul718e3742002-12-13 20:15:29 +0000506 struct prefix p;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000507 unsigned long attrlen_pos = 0;
paul718e3742002-12-13 20:15:29 +0000508 unsigned long cp;
509 bgp_size_t unfeasible_len;
510 bgp_size_t total_attr_len;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000511 size_t mp_start = 0;
512 size_t mplen_pos = 0;
paul718e3742002-12-13 20:15:29 +0000513
Paul Jakma750e8142008-07-22 21:11:48 +0000514 if (DISABLE_BGP_ANNOUNCE)
515 return;
paul718e3742002-12-13 20:15:29 +0000516
517 if (afi == AFI_IP)
518 str2prefix ("0.0.0.0/0", &p);
paul718e3742002-12-13 20:15:29 +0000519 else
520 str2prefix ("::/0", &p);
paul718e3742002-12-13 20:15:29 +0000521
522 total_attr_len = 0;
paul718e3742002-12-13 20:15:29 +0000523
524 if (BGP_DEBUG (update, UPDATE_OUT))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000525 {
526 char buf[INET6_BUFSIZ];
527
528 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
529 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, INET6_BUFSIZ),
530 p.prefixlen);
531 }
paul718e3742002-12-13 20:15:29 +0000532
533 s = stream_new (BGP_MAX_PACKET_SIZE);
534
535 /* Make BGP update packet. */
536 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
537
538 /* Unfeasible Routes Length. */;
paul9985f832005-02-09 15:51:56 +0000539 cp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000540 stream_putw (s, 0);
541
542 /* Withdrawn Routes. */
543 if (p.family == AF_INET && safi == SAFI_UNICAST)
544 {
545 stream_put_prefix (s, &p);
546
paul9985f832005-02-09 15:51:56 +0000547 unfeasible_len = stream_get_endp (s) - cp - 2;
paul718e3742002-12-13 20:15:29 +0000548
549 /* Set unfeasible len. */
550 stream_putw_at (s, cp, unfeasible_len);
551
552 /* Set total path attribute length. */
553 stream_putw (s, 0);
554 }
555 else
556 {
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000557 attrlen_pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000558 stream_putw (s, 0);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000559 mp_start = stream_get_endp (s);
560 mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
561 bgp_packet_mpunreach_prefix(s, &p, afi, safi, NULL, NULL);
562
563 /* Set the mp_unreach attr's length */
564 bgp_packet_mpunreach_end(s, mplen_pos);
paul718e3742002-12-13 20:15:29 +0000565
566 /* Set total path attribute length. */
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000567 total_attr_len = stream_get_endp(s) - mp_start;
568 stream_putw_at (s, attrlen_pos, total_attr_len);
paul718e3742002-12-13 20:15:29 +0000569 }
570
571 bgp_packet_set_size (s);
572
paul718e3742002-12-13 20:15:29 +0000573 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -0400574 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +0000575
pauleb821182004-05-01 08:44:08 +0000576 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000577}
578
579/* Get next packet to be written. */
paul94f2b392005-06-28 12:44:16 +0000580static struct stream *
paul718e3742002-12-13 20:15:29 +0000581bgp_write_packet (struct peer *peer)
582{
583 afi_t afi;
584 safi_t safi;
585 struct stream *s = NULL;
586 struct bgp_advertise *adv;
587
588 s = stream_fifo_head (peer->obuf);
589 if (s)
590 return s;
591
592 for (afi = AFI_IP; afi < AFI_MAX; afi++)
593 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
594 {
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100595 adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->withdraw);
paul718e3742002-12-13 20:15:29 +0000596 if (adv)
597 {
598 s = bgp_withdraw_packet (peer, afi, safi);
599 if (s)
600 return s;
601 }
602 }
603
604 for (afi = AFI_IP; afi < AFI_MAX; afi++)
605 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
606 {
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100607 adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update);
paul718e3742002-12-13 20:15:29 +0000608 if (adv)
609 {
610 if (adv->binfo && adv->binfo->uptime < peer->synctime)
hasso93406d82005-02-02 14:40:33 +0000611 {
612 if (CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_RCV)
613 && CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_ADV)
Vipin Kumardd49eb12014-09-30 14:36:38 -0700614 && ! (CHECK_FLAG (adv->binfo->peer->cap,
615 PEER_CAP_RESTART_BIT_RCV) &&
616 CHECK_FLAG (adv->binfo->peer->cap,
617 PEER_CAP_RESTART_BIT_ADV))
hasso93406d82005-02-02 14:40:33 +0000618 && ! CHECK_FLAG (adv->binfo->flags, BGP_INFO_STALE)
619 && safi != SAFI_MPLS_VPN)
620 {
621 if (CHECK_FLAG (adv->binfo->peer->af_sflags[afi][safi],
622 PEER_STATUS_EOR_RECEIVED))
623 s = bgp_update_packet (peer, afi, safi);
624 }
625 else
626 s = bgp_update_packet (peer, afi, safi);
627 }
paul718e3742002-12-13 20:15:29 +0000628
629 if (s)
630 return s;
631 }
hasso93406d82005-02-02 14:40:33 +0000632
633 if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV))
634 {
635 if (peer->afc_nego[afi][safi] && peer->synctime
636 && ! CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND)
637 && safi != SAFI_MPLS_VPN)
638 {
639 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND);
640 return bgp_update_packet_eor (peer, afi, safi);
641 }
642 }
paul718e3742002-12-13 20:15:29 +0000643 }
644
645 return NULL;
646}
647
648/* Is there partially written packet or updates we can send right
649 now. */
paul94f2b392005-06-28 12:44:16 +0000650static int
paul718e3742002-12-13 20:15:29 +0000651bgp_write_proceed (struct peer *peer)
652{
653 afi_t afi;
654 safi_t safi;
655 struct bgp_advertise *adv;
656
657 if (stream_fifo_head (peer->obuf))
658 return 1;
659
660 for (afi = AFI_IP; afi < AFI_MAX; afi++)
661 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
662 if (FIFO_HEAD (&peer->sync[afi][safi]->withdraw))
663 return 1;
664
665 for (afi = AFI_IP; afi < AFI_MAX; afi++)
666 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100667 if ((adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update)) != NULL)
paul718e3742002-12-13 20:15:29 +0000668 if (adv->binfo->uptime < peer->synctime)
669 return 1;
670
671 return 0;
672}
673
674/* Write packet to the peer. */
675int
676bgp_write (struct thread *thread)
677{
678 struct peer *peer;
679 u_char type;
680 struct stream *s;
681 int num;
paulfd79ac92004-10-13 05:06:08 +0000682 unsigned int count = 0;
paul718e3742002-12-13 20:15:29 +0000683
684 /* Yes first of all get peer pointer. */
685 peer = THREAD_ARG (thread);
686 peer->t_write = NULL;
687
688 /* For non-blocking IO check. */
689 if (peer->status == Connect)
690 {
691 bgp_connect_check (peer);
692 return 0;
693 }
694
Stephen Hemmingereac57022010-08-05 10:26:25 -0700695 s = bgp_write_packet (peer);
696 if (!s)
697 return 0; /* nothing to send */
698
699 sockopt_cork (peer->fd, 1);
700
701 /* Nonblocking write until TCP output buffer is full. */
702 do
paul718e3742002-12-13 20:15:29 +0000703 {
704 int writenum;
paul718e3742002-12-13 20:15:29 +0000705
706 /* Number of bytes to be sent. */
707 writenum = stream_get_endp (s) - stream_get_getp (s);
708
709 /* Call write() system call. */
pauleb821182004-05-01 08:44:08 +0000710 num = write (peer->fd, STREAM_PNT (s), writenum);
Stephen Hemminger35398582010-08-05 10:26:23 -0700711 if (num < 0)
paul718e3742002-12-13 20:15:29 +0000712 {
Stephen Hemmingereac57022010-08-05 10:26:25 -0700713 /* write failed either retry needed or error */
714 if (ERRNO_IO_RETRY(errno))
715 break;
716
717 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000718 return 0;
719 }
Stephen Hemminger35398582010-08-05 10:26:23 -0700720
paul718e3742002-12-13 20:15:29 +0000721 if (num != writenum)
722 {
Stephen Hemminger35398582010-08-05 10:26:23 -0700723 /* Partial write */
paul9985f832005-02-09 15:51:56 +0000724 stream_forward_getp (s, num);
Stephen Hemmingereac57022010-08-05 10:26:25 -0700725 break;
paul718e3742002-12-13 20:15:29 +0000726 }
727
728 /* Retrieve BGP packet type. */
729 stream_set_getp (s, BGP_MARKER_SIZE + 2);
730 type = stream_getc (s);
731
732 switch (type)
733 {
734 case BGP_MSG_OPEN:
735 peer->open_out++;
736 break;
737 case BGP_MSG_UPDATE:
738 peer->update_out++;
739 break;
740 case BGP_MSG_NOTIFY:
741 peer->notify_out++;
742 /* Double start timer. */
743 peer->v_start *= 2;
744
745 /* Overflow check. */
746 if (peer->v_start >= (60 * 2))
747 peer->v_start = (60 * 2);
748
Paul Jakmaca058a32006-09-14 02:58:49 +0000749 /* Flush any existing events */
Paul Jakmadcdf3992006-10-15 23:39:59 +0000750 BGP_EVENT_ADD (peer, BGP_Stop);
Stephen Hemminger3a69f742013-01-11 18:27:23 +0000751 goto done;
752
paul718e3742002-12-13 20:15:29 +0000753 case BGP_MSG_KEEPALIVE:
754 peer->keepalive_out++;
755 break;
756 case BGP_MSG_ROUTE_REFRESH_NEW:
757 case BGP_MSG_ROUTE_REFRESH_OLD:
758 peer->refresh_out++;
759 break;
760 case BGP_MSG_CAPABILITY:
761 peer->dynamic_cap_out++;
762 break;
763 }
764
765 /* OK we send packet so delete it. */
766 bgp_packet_delete (peer);
paul718e3742002-12-13 20:15:29 +0000767 }
Stephen Hemmingereac57022010-08-05 10:26:25 -0700768 while (++count < BGP_WRITE_PACKET_MAX &&
769 (s = bgp_write_packet (peer)) != NULL);
paul718e3742002-12-13 20:15:29 +0000770
771 if (bgp_write_proceed (peer))
pauleb821182004-05-01 08:44:08 +0000772 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
Stephen Hemminger3a69f742013-01-11 18:27:23 +0000773
774 done:
775 sockopt_cork (peer->fd, 0);
paul718e3742002-12-13 20:15:29 +0000776 return 0;
777}
778
779/* This is only for sending NOTIFICATION message to neighbor. */
paul94f2b392005-06-28 12:44:16 +0000780static int
paul718e3742002-12-13 20:15:29 +0000781bgp_write_notify (struct peer *peer)
782{
Stephen Hemminger35398582010-08-05 10:26:23 -0700783 int ret, val;
paul718e3742002-12-13 20:15:29 +0000784 u_char type;
785 struct stream *s;
786
787 /* There should be at least one packet. */
788 s = stream_fifo_head (peer->obuf);
789 if (!s)
790 return 0;
791 assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
792
Leonid Rosenboim86998bc2012-12-14 19:12:17 +0000793 /* Stop collecting data within the socket */
794 sockopt_cork (peer->fd, 0);
795
David Lamparter8ff202e2013-07-31 14:39:41 +0200796 /* socket is in nonblocking mode, if we can't deliver the NOTIFY, well,
797 * we only care about getting a clean shutdown at this point. */
Leonid Rosenboim86998bc2012-12-14 19:12:17 +0000798 ret = write (peer->fd, STREAM_DATA (s), stream_get_endp (s));
David Lamparter8ff202e2013-07-31 14:39:41 +0200799
800 /* only connection reset/close gets counted as TCP_fatal_error, failure
801 * to write the entire NOTIFY doesn't get different FSM treatment */
paul718e3742002-12-13 20:15:29 +0000802 if (ret <= 0)
803 {
Paul Jakmadcdf3992006-10-15 23:39:59 +0000804 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000805 return 0;
806 }
807
Leonid Rosenboim86998bc2012-12-14 19:12:17 +0000808 /* Disable Nagle, make NOTIFY packet go out right away */
809 val = 1;
810 (void) setsockopt (peer->fd, IPPROTO_TCP, TCP_NODELAY,
811 (char *) &val, sizeof (val));
812
paul718e3742002-12-13 20:15:29 +0000813 /* Retrieve BGP packet type. */
814 stream_set_getp (s, BGP_MARKER_SIZE + 2);
815 type = stream_getc (s);
816
817 assert (type == BGP_MSG_NOTIFY);
818
819 /* Type should be notify. */
820 peer->notify_out++;
821
822 /* Double start timer. */
823 peer->v_start *= 2;
824
825 /* Overflow check. */
826 if (peer->v_start >= (60 * 2))
827 peer->v_start = (60 * 2);
828
Paul Jakmadcdf3992006-10-15 23:39:59 +0000829 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000830
831 return 0;
832}
833
834/* Make keepalive packet and send it to the peer. */
835void
836bgp_keepalive_send (struct peer *peer)
837{
838 struct stream *s;
839 int length;
840
841 s = stream_new (BGP_MAX_PACKET_SIZE);
842
843 /* Make keepalive packet. */
844 bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
845
846 /* Set packet size. */
847 length = bgp_packet_set_size (s);
848
849 /* Dump packet if debug option is set. */
850 /* bgp_packet_dump (s); */
851
852 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +0000853 zlog_debug ("%s sending KEEPALIVE", peer->host);
paul718e3742002-12-13 20:15:29 +0000854 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000855 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000856 peer->host, BGP_MSG_KEEPALIVE, length);
857
858 /* Add packet to the peer. */
859 bgp_packet_add (peer, s);
860
pauleb821182004-05-01 08:44:08 +0000861 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000862}
863
864/* Make open packet and send it to the peer. */
865void
866bgp_open_send (struct peer *peer)
867{
868 struct stream *s;
869 int length;
870 u_int16_t send_holdtime;
871 as_t local_as;
872
873 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
874 send_holdtime = peer->holdtime;
875 else
876 send_holdtime = peer->bgp->default_holdtime;
877
878 /* local-as Change */
879 if (peer->change_local_as)
880 local_as = peer->change_local_as;
881 else
882 local_as = peer->local_as;
883
884 s = stream_new (BGP_MAX_PACKET_SIZE);
885
886 /* Make open packet. */
887 bgp_packet_set_marker (s, BGP_MSG_OPEN);
888
889 /* Set open packet values. */
890 stream_putc (s, BGP_VERSION_4); /* BGP version */
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000891 stream_putw (s, (local_as <= BGP_AS_MAX) ? (u_int16_t) local_as
892 : BGP_AS_TRANS);
paul718e3742002-12-13 20:15:29 +0000893 stream_putw (s, send_holdtime); /* Hold Time */
894 stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
895
896 /* Set capability code. */
897 bgp_open_capability (s, peer);
898
899 /* Set BGP packet length. */
900 length = bgp_packet_set_size (s);
901
902 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400903 zlog_debug ("%s sending OPEN, version %d, my as %u, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +0000904 peer->host, BGP_VERSION_4, local_as,
905 send_holdtime, inet_ntoa (peer->local_id));
906
907 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000908 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000909 peer->host, BGP_MSG_OPEN, length);
910
911 /* Dump packet if debug option is set. */
912 /* bgp_packet_dump (s); */
913
914 /* Add packet to the peer. */
915 bgp_packet_add (peer, s);
916
pauleb821182004-05-01 08:44:08 +0000917 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000918}
919
920/* Send BGP notify packet with data potion. */
921void
922bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
923 u_char *data, size_t datalen)
924{
925 struct stream *s;
926 int length;
927
928 /* Allocate new stream. */
929 s = stream_new (BGP_MAX_PACKET_SIZE);
930
931 /* Make nitify packet. */
932 bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
933
934 /* Set notify packet values. */
935 stream_putc (s, code); /* BGP notify code */
936 stream_putc (s, sub_code); /* BGP notify sub_code */
937
938 /* If notify data is present. */
939 if (data)
940 stream_write (s, data, datalen);
941
942 /* Set BGP packet length. */
943 length = bgp_packet_set_size (s);
944
945 /* Add packet to the peer. */
946 stream_fifo_clean (peer->obuf);
947 bgp_packet_add (peer, s);
948
949 /* For debug */
950 {
951 struct bgp_notify bgp_notify;
952 int first = 0;
953 int i;
954 char c[4];
955
956 bgp_notify.code = code;
957 bgp_notify.subcode = sub_code;
958 bgp_notify.data = NULL;
959 bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
960
961 if (bgp_notify.length)
962 {
963 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
964 for (i = 0; i < bgp_notify.length; i++)
965 if (first)
966 {
967 sprintf (c, " %02x", data[i]);
968 strcat (bgp_notify.data, c);
969 }
970 else
971 {
972 first = 1;
973 sprintf (c, "%02x", data[i]);
974 strcpy (bgp_notify.data, c);
975 }
976 }
977 bgp_notify_print (peer, &bgp_notify, "sending");
Daniel Walton363c9032015-10-21 06:42:54 -0700978
paul718e3742002-12-13 20:15:29 +0000979 if (bgp_notify.data)
Daniel Walton363c9032015-10-21 06:42:54 -0700980 {
981 XFREE (MTYPE_TMP, bgp_notify.data);
982 bgp_notify.data = NULL;
983 bgp_notify.length = 0;
984 }
paul718e3742002-12-13 20:15:29 +0000985 }
986
987 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000988 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000989 peer->host, BGP_MSG_NOTIFY, length);
990
hassoe0701b72004-05-20 09:19:34 +0000991 /* peer reset cause */
992 if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
993 {
994 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
heasley1212dc12011-09-12 13:27:52 +0400995 {
996 peer->last_reset = PEER_DOWN_USER_RESET;
997 zlog_info ("Notification sent to neighbor %s: User reset", peer->host);
998 }
hassoe0701b72004-05-20 09:19:34 +0000999 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
heasley1212dc12011-09-12 13:27:52 +04001000 {
1001 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
1002 zlog_info ("Notification sent to neighbor %s: shutdown", peer->host);
1003 }
hassoe0701b72004-05-20 09:19:34 +00001004 else
heasley1212dc12011-09-12 13:27:52 +04001005 {
1006 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
1007 zlog_info ("Notification sent to neighbor %s: type %u/%u",
1008 peer->host, code, sub_code);
1009 }
hassoe0701b72004-05-20 09:19:34 +00001010 }
heasley1212dc12011-09-12 13:27:52 +04001011 else
1012 zlog_info ("Notification sent to neighbor %s: configuration change",
1013 peer->host);
hassoe0701b72004-05-20 09:19:34 +00001014
Denis Ovsienko7ccf5e52011-09-10 16:53:30 +04001015 /* Call immediately. */
paul718e3742002-12-13 20:15:29 +00001016 BGP_WRITE_OFF (peer->t_write);
1017
1018 bgp_write_notify (peer);
1019}
1020
1021/* Send BGP notify packet. */
1022void
1023bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
1024{
1025 bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
1026}
1027
paul718e3742002-12-13 20:15:29 +00001028/* Send route refresh message to the peer. */
1029void
1030bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
1031 u_char orf_type, u_char when_to_refresh, int remove)
1032{
1033 struct stream *s;
paul718e3742002-12-13 20:15:29 +00001034 int length;
1035 struct bgp_filter *filter;
1036 int orf_refresh = 0;
1037
Paul Jakma750e8142008-07-22 21:11:48 +00001038 if (DISABLE_BGP_ANNOUNCE)
1039 return;
paul718e3742002-12-13 20:15:29 +00001040
1041 filter = &peer->filter[afi][safi];
1042
1043 /* Adjust safi code. */
1044 if (safi == SAFI_MPLS_VPN)
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001045 safi = SAFI_MPLS_LABELED_VPN;
paul718e3742002-12-13 20:15:29 +00001046
1047 s = stream_new (BGP_MAX_PACKET_SIZE);
1048
1049 /* Make BGP update packet. */
1050 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
1051 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
1052 else
1053 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
1054
1055 /* Encode Route Refresh message. */
1056 stream_putw (s, afi);
1057 stream_putc (s, 0);
1058 stream_putc (s, safi);
1059
1060 if (orf_type == ORF_TYPE_PREFIX
1061 || orf_type == ORF_TYPE_PREFIX_OLD)
1062 if (remove || filter->plist[FILTER_IN].plist)
1063 {
1064 u_int16_t orf_len;
1065 unsigned long orfp;
1066
1067 orf_refresh = 1;
1068 stream_putc (s, when_to_refresh);
1069 stream_putc (s, orf_type);
paul9985f832005-02-09 15:51:56 +00001070 orfp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00001071 stream_putw (s, 0);
1072
1073 if (remove)
1074 {
1075 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1076 stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
1077 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001078 zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001079 peer->host, orf_type,
1080 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1081 afi, safi);
1082 }
1083 else
1084 {
1085 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1086 prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
1087 ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
1088 ORF_COMMON_PART_DENY);
1089 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001090 zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001091 peer->host, orf_type,
1092 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1093 afi, safi);
1094 }
1095
1096 /* Total ORF Entry Len. */
paul9985f832005-02-09 15:51:56 +00001097 orf_len = stream_get_endp (s) - orfp - 2;
paul718e3742002-12-13 20:15:29 +00001098 stream_putw_at (s, orfp, orf_len);
1099 }
1100
1101 /* Set packet size. */
1102 length = bgp_packet_set_size (s);
1103
1104 if (BGP_DEBUG (normal, NORMAL))
1105 {
1106 if (! orf_refresh)
ajs6b514742004-12-08 21:03:23 +00001107 zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001108 peer->host, afi, safi);
ajs6b514742004-12-08 21:03:23 +00001109 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001110 peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
1111 BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
1112 }
1113
paul718e3742002-12-13 20:15:29 +00001114 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -04001115 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +00001116
pauleb821182004-05-01 08:44:08 +00001117 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001118}
1119
1120/* Send capability message to the peer. */
1121void
1122bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
1123 int capability_code, int action)
1124{
1125 struct stream *s;
paul718e3742002-12-13 20:15:29 +00001126 int length;
1127
1128 /* Adjust safi code. */
1129 if (safi == SAFI_MPLS_VPN)
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001130 safi = SAFI_MPLS_LABELED_VPN;
paul718e3742002-12-13 20:15:29 +00001131
1132 s = stream_new (BGP_MAX_PACKET_SIZE);
1133
1134 /* Make BGP update packet. */
1135 bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
1136
1137 /* Encode MP_EXT capability. */
1138 if (capability_code == CAPABILITY_CODE_MP)
1139 {
1140 stream_putc (s, action);
1141 stream_putc (s, CAPABILITY_CODE_MP);
1142 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1143 stream_putw (s, afi);
1144 stream_putc (s, 0);
1145 stream_putc (s, safi);
1146
1147 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001148 zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001149 peer->host, action == CAPABILITY_ACTION_SET ?
1150 "Advertising" : "Removing", afi, safi);
1151 }
1152
paul718e3742002-12-13 20:15:29 +00001153 /* Set packet size. */
1154 length = bgp_packet_set_size (s);
1155
paul718e3742002-12-13 20:15:29 +00001156
1157 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -04001158 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +00001159
1160 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001161 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001162 peer->host, BGP_MSG_CAPABILITY, length);
1163
pauleb821182004-05-01 08:44:08 +00001164 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001165}
David Lamparter6b0655a2014-06-04 06:53:35 +02001166
paul718e3742002-12-13 20:15:29 +00001167/* RFC1771 6.8 Connection collision detection. */
paul94f2b392005-06-28 12:44:16 +00001168static int
pauleb821182004-05-01 08:44:08 +00001169bgp_collision_detect (struct peer *new, struct in_addr remote_id)
paul718e3742002-12-13 20:15:29 +00001170{
pauleb821182004-05-01 08:44:08 +00001171 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +00001172 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001173 struct bgp *bgp;
1174
1175 bgp = bgp_get_default ();
1176 if (! bgp)
1177 return 0;
1178
1179 /* Upon receipt of an OPEN message, the local system must examine
1180 all of its connections that are in the OpenConfirm state. A BGP
1181 speaker may also examine connections in an OpenSent state if it
1182 knows the BGP Identifier of the peer by means outside of the
1183 protocol. If among these connections there is a connection to a
1184 remote BGP speaker whose BGP Identifier equals the one in the
1185 OPEN message, then the local system performs the following
1186 collision resolution procedure: */
1187
paul1eb8ef22005-04-07 07:30:20 +00001188 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00001189 {
1190 /* Under OpenConfirm status, local peer structure already hold
1191 remote router ID. */
pauleb821182004-05-01 08:44:08 +00001192
1193 if (peer != new
1194 && (peer->status == OpenConfirm || peer->status == OpenSent)
1195 && sockunion_same (&peer->su, &new->su))
1196 {
paul718e3742002-12-13 20:15:29 +00001197 /* 1. The BGP Identifier of the local system is compared to
1198 the BGP Identifier of the remote system (as specified in
1199 the OPEN message). */
1200
1201 if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
1202 {
1203 /* 2. If the value of the local BGP Identifier is less
1204 than the remote one, the local system closes BGP
1205 connection that already exists (the one that is
1206 already in the OpenConfirm state), and accepts BGP
1207 connection initiated by the remote system. */
1208
pauleb821182004-05-01 08:44:08 +00001209 if (peer->fd >= 0)
hassoe0701b72004-05-20 09:19:34 +00001210 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001211 return 1;
1212 }
1213 else
1214 {
1215 /* 3. Otherwise, the local system closes newly created
1216 BGP connection (the one associated with the newly
1217 received OPEN message), and continues to use the
1218 existing one (the one that is already in the
1219 OpenConfirm state). */
1220
pauleb821182004-05-01 08:44:08 +00001221 if (new->fd >= 0)
paulf5ba3872004-07-09 12:11:31 +00001222 bgp_notify_send (new, BGP_NOTIFY_CEASE,
1223 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001224 return -1;
1225 }
pauleb821182004-05-01 08:44:08 +00001226 }
1227 }
paul718e3742002-12-13 20:15:29 +00001228 return 0;
1229}
1230
paul94f2b392005-06-28 12:44:16 +00001231static int
paul718e3742002-12-13 20:15:29 +00001232bgp_open_receive (struct peer *peer, bgp_size_t size)
1233{
1234 int ret;
1235 u_char version;
1236 u_char optlen;
1237 u_int16_t holdtime;
1238 u_int16_t send_holdtime;
1239 as_t remote_as;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001240 as_t as4 = 0;
paul718e3742002-12-13 20:15:29 +00001241 struct peer *realpeer;
1242 struct in_addr remote_id;
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001243 int mp_capability;
paul5228ad22004-06-04 17:58:18 +00001244 u_int8_t notify_data_remote_as[2];
1245 u_int8_t notify_data_remote_id[4];
paul718e3742002-12-13 20:15:29 +00001246
1247 realpeer = NULL;
1248
1249 /* Parse open packet. */
1250 version = stream_getc (peer->ibuf);
1251 memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1252 remote_as = stream_getw (peer->ibuf);
1253 holdtime = stream_getw (peer->ibuf);
1254 memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1255 remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1256
1257 /* Receive OPEN message log */
1258 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001259 zlog_debug ("%s rcv OPEN, version %d, remote-as (in open) %u,"
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001260 " holdtime %d, id %s",
1261 peer->host, version, remote_as, holdtime,
1262 inet_ntoa (remote_id));
1263
1264 /* BEGIN to read the capability here, but dont do it yet */
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001265 mp_capability = 0;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001266 optlen = stream_getc (peer->ibuf);
1267
1268 if (optlen != 0)
1269 {
1270 /* We need the as4 capability value *right now* because
1271 * if it is there, we have not got the remote_as yet, and without
1272 * that we do not know which peer is connecting to us now.
1273 */
1274 as4 = peek_for_as4_capability (peer, optlen);
1275 }
1276
1277 /* Just in case we have a silly peer who sends AS4 capability set to 0 */
1278 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) && !as4)
1279 {
1280 zlog_err ("%s bad OPEN, got AS4 capability, but AS4 set to 0",
1281 peer->host);
1282 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1283 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1284 return -1;
1285 }
1286
1287 if (remote_as == BGP_AS_TRANS)
1288 {
1289 /* Take the AS4 from the capability. We must have received the
1290 * capability now! Otherwise we have a asn16 peer who uses
1291 * BGP_AS_TRANS, for some unknown reason.
1292 */
1293 if (as4 == BGP_AS_TRANS)
1294 {
1295 zlog_err ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
1296 peer->host);
1297 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1298 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1299 return -1;
1300 }
1301
1302 if (!as4 && BGP_DEBUG (as4, AS4))
1303 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
1304 " Odd, but proceeding.", peer->host);
1305 else if (as4 < BGP_AS_MAX && BGP_DEBUG (as4, AS4))
Paul Jakma0df7c912008-07-21 21:02:49 +00001306 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits "
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001307 "in 2-bytes, very odd peer.", peer->host, as4);
1308 if (as4)
1309 remote_as = as4;
1310 }
1311 else
1312 {
1313 /* We may have a partner with AS4 who has an asno < BGP_AS_MAX */
1314 /* If we have got the capability, peer->as4cap must match remote_as */
1315 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)
1316 && as4 != remote_as)
1317 {
1318 /* raise error, log this, close session */
1319 zlog_err ("%s bad OPEN, got AS4 capability, but remote_as %u"
1320 " mismatch with 16bit 'myasn' %u in open",
1321 peer->host, as4, remote_as);
1322 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1323 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1324 return -1;
1325 }
1326 }
1327
paul718e3742002-12-13 20:15:29 +00001328 /* Lookup peer from Open packet. */
1329 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1330 {
1331 int as = 0;
1332
1333 realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1334
1335 if (! realpeer)
1336 {
1337 /* Peer's source IP address is check in bgp_accept(), so this
1338 must be AS number mismatch or remote-id configuration
1339 mismatch. */
1340 if (as)
1341 {
1342 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001343 zlog_debug ("%s bad OPEN, wrong router identifier %s",
1344 peer->host, inet_ntoa (remote_id));
1345 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1346 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1347 notify_data_remote_id, 4);
paul718e3742002-12-13 20:15:29 +00001348 }
1349 else
1350 {
1351 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001352 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
ajs6b514742004-12-08 21:03:23 +00001353 peer->host, remote_as, peer->as);
1354 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1355 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1356 notify_data_remote_as, 2);
paul718e3742002-12-13 20:15:29 +00001357 }
1358 return -1;
1359 }
1360 }
1361
1362 /* When collision is detected and this peer is closed. Retrun
1363 immidiately. */
1364 ret = bgp_collision_detect (peer, remote_id);
1365 if (ret < 0)
1366 return ret;
1367
pauleb821182004-05-01 08:44:08 +00001368 /* Hack part. */
1369 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1370 {
hasso93406d82005-02-02 14:40:33 +00001371 if (realpeer->status == Established
1372 && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1373 {
1374 realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1375 SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1376 }
1377 else if (ret == 0 && realpeer->status != Active
1378 && realpeer->status != OpenSent
Paul Jakma6e199262008-09-09 17:14:33 +01001379 && realpeer->status != OpenConfirm
1380 && realpeer->status != Connect)
pauleb821182004-05-01 08:44:08 +00001381 {
Paul Jakma2b2fc562008-09-06 13:09:35 +01001382 /* XXX: This is an awful problem..
1383 *
1384 * According to the RFC we should just let this connection (of the
1385 * accepted 'peer') continue on to Established if the other
1386 * connection (the 'realpeer' one) is in state Connect, and deal
1387 * with the more larval FSM as/when it gets far enough to receive
1388 * an Open. We don't do that though, we instead close the (more
1389 * developed) accepted connection.
1390 *
1391 * This means there's a race, which if hit, can loop:
1392 *
1393 * FSM for A FSM for B
1394 * realpeer accept-peer realpeer accept-peer
1395 *
1396 * Connect Connect
1397 * Active
1398 * OpenSent OpenSent
1399 * <arrive here,
1400 * Notify, delete>
1401 * Idle Active
1402 * OpenSent OpenSent
1403 * <arrive here,
1404 * Notify, delete>
1405 * Idle
1406 * <wait> <wait>
1407 * Connect Connect
1408 *
1409 *
1410 * If both sides are Quagga, they're almost certain to wait for
1411 * the same amount of time of course (which doesn't preclude other
1412 * implementations also waiting for same time). The race is
1413 * exacerbated by high-latency (in bgpd and/or the network).
1414 *
1415 * The reason we do this is because our FSM is tied to our peer
1416 * structure, which carries our configuration information, etc.
1417 * I.e. we can't let the accepted-peer FSM continue on as it is,
1418 * cause it's not associated with any actual peer configuration -
1419 * it's just a dummy.
1420 *
1421 * It's possible we could hack-fix this by just bgp_stop'ing the
1422 * realpeer and continueing on with the 'transfer FSM' below.
1423 * Ideally, we need to seperate FSMs from struct peer.
1424 *
1425 * Setting one side to passive avoids the race, as a workaround.
1426 */
pauleb821182004-05-01 08:44:08 +00001427 if (BGP_DEBUG (events, EVENTS))
hasso93406d82005-02-02 14:40:33 +00001428 zlog_debug ("%s peer status is %s close connection",
1429 realpeer->host, LOOKUP (bgp_status_msg,
1430 realpeer->status));
1431 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1432 BGP_NOTIFY_CEASE_CONNECT_REJECT);
1433
pauleb821182004-05-01 08:44:08 +00001434 return -1;
1435 }
1436
1437 if (BGP_DEBUG (events, EVENTS))
Paul Jakma6e199262008-09-09 17:14:33 +01001438 zlog_debug ("%s [Event] Transfer accept BGP peer to real (state %s)",
1439 peer->host,
1440 LOOKUP (bgp_status_msg, realpeer->status));
pauleb821182004-05-01 08:44:08 +00001441
1442 bgp_stop (realpeer);
1443
1444 /* Transfer file descriptor. */
1445 realpeer->fd = peer->fd;
1446 peer->fd = -1;
1447
1448 /* Transfer input buffer. */
1449 stream_free (realpeer->ibuf);
1450 realpeer->ibuf = peer->ibuf;
1451 realpeer->packet_size = peer->packet_size;
1452 peer->ibuf = NULL;
1453
1454 /* Transfer status. */
1455 realpeer->status = peer->status;
1456 bgp_stop (peer);
paul200df112005-06-01 11:17:05 +00001457
pauleb821182004-05-01 08:44:08 +00001458 /* peer pointer change. Open packet send to neighbor. */
1459 peer = realpeer;
1460 bgp_open_send (peer);
1461 if (peer->fd < 0)
1462 {
1463 zlog_err ("bgp_open_receive peer's fd is negative value %d",
1464 peer->fd);
1465 return -1;
1466 }
1467 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1468 }
1469
paul718e3742002-12-13 20:15:29 +00001470 /* remote router-id check. */
1471 if (remote_id.s_addr == 0
Denis Ovsienko733cd9e2011-12-17 19:39:30 +04001472 || IPV4_CLASS_DE (ntohl (remote_id.s_addr))
paul718e3742002-12-13 20:15:29 +00001473 || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1474 {
1475 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001476 zlog_debug ("%s bad OPEN, wrong router identifier %s",
paul718e3742002-12-13 20:15:29 +00001477 peer->host, inet_ntoa (remote_id));
1478 bgp_notify_send_with_data (peer,
1479 BGP_NOTIFY_OPEN_ERR,
1480 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1481 notify_data_remote_id, 4);
1482 return -1;
1483 }
1484
1485 /* Set remote router-id */
1486 peer->remote_id = remote_id;
1487
1488 /* Peer BGP version check. */
1489 if (version != BGP_VERSION_4)
1490 {
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001491 u_int16_t maxver = htons(BGP_VERSION_4);
1492 /* XXX this reply may not be correct if version < 4 XXX */
paul718e3742002-12-13 20:15:29 +00001493 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001494 zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
paul718e3742002-12-13 20:15:29 +00001495 peer->host, version, BGP_VERSION_4);
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001496 /* Data must be in network byte order here */
paul718e3742002-12-13 20:15:29 +00001497 bgp_notify_send_with_data (peer,
1498 BGP_NOTIFY_OPEN_ERR,
1499 BGP_NOTIFY_OPEN_UNSUP_VERSION,
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001500 (u_int8_t *) &maxver, 2);
paul718e3742002-12-13 20:15:29 +00001501 return -1;
1502 }
1503
1504 /* Check neighbor as number. */
1505 if (remote_as != peer->as)
1506 {
1507 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001508 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
paul718e3742002-12-13 20:15:29 +00001509 peer->host, remote_as, peer->as);
1510 bgp_notify_send_with_data (peer,
1511 BGP_NOTIFY_OPEN_ERR,
1512 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1513 notify_data_remote_as, 2);
1514 return -1;
1515 }
1516
1517 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1518 calculate the value of the Hold Timer by using the smaller of its
1519 configured Hold Time and the Hold Time received in the OPEN message.
1520 The Hold Time MUST be either zero or at least three seconds. An
1521 implementation may reject connections on the basis of the Hold Time. */
1522
1523 if (holdtime < 3 && holdtime != 0)
1524 {
1525 bgp_notify_send (peer,
1526 BGP_NOTIFY_OPEN_ERR,
1527 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
1528 return -1;
1529 }
1530
1531 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1532 would be one third of the Hold Time interval. KEEPALIVE messages
1533 MUST NOT be sent more frequently than one per second. An
1534 implementation MAY adjust the rate at which it sends KEEPALIVE
1535 messages as a function of the Hold Time interval. */
1536
1537 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1538 send_holdtime = peer->holdtime;
1539 else
1540 send_holdtime = peer->bgp->default_holdtime;
1541
1542 if (holdtime < send_holdtime)
1543 peer->v_holdtime = holdtime;
1544 else
1545 peer->v_holdtime = send_holdtime;
1546
1547 peer->v_keepalive = peer->v_holdtime / 3;
1548
1549 /* Open option part parse. */
paul718e3742002-12-13 20:15:29 +00001550 if (optlen != 0)
1551 {
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001552 if ((ret = bgp_open_option_parse (peer, optlen, &mp_capability)) < 0)
Paul Jakma58617392012-01-09 20:59:26 +00001553 {
1554 bgp_notify_send (peer,
1555 BGP_NOTIFY_OPEN_ERR,
Paul Jakma68ec4242015-11-25 17:14:34 +00001556 BGP_NOTIFY_OPEN_UNSPECIFIC);
Paul Jakma58617392012-01-09 20:59:26 +00001557 return ret;
1558 }
paul718e3742002-12-13 20:15:29 +00001559 }
1560 else
1561 {
1562 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001563 zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
paul718e3742002-12-13 20:15:29 +00001564 peer->host);
1565 }
1566
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001567 /*
1568 * Assume that the peer supports the locally configured set of
1569 * AFI/SAFIs if the peer did not send us any Mulitiprotocol
1570 * capabilities, or if 'override-capability' is configured.
1571 */
1572 if (! mp_capability ||
1573 CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
paul718e3742002-12-13 20:15:29 +00001574 {
1575 peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1576 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1577 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1578 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1579 }
1580
1581 /* Get sockname. */
1582 bgp_getsockname (peer);
Timo Teräs0edba8b2015-10-22 11:35:17 +03001583 peer->rtt = sockopt_tcp_rtt (peer->fd);
paul718e3742002-12-13 20:15:29 +00001584
1585 BGP_EVENT_ADD (peer, Receive_OPEN_message);
1586
1587 peer->packet_size = 0;
1588 if (peer->ibuf)
1589 stream_reset (peer->ibuf);
1590
1591 return 0;
1592}
1593
Paul Jakma518a4b72016-02-04 13:27:04 +00001594/* Frontend for NLRI parsing, to fan-out to AFI/SAFI specific parsers */
1595int
1596bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
1597{
1598 switch (packet->safi)
1599 {
1600 case SAFI_UNICAST:
1601 case SAFI_MULTICAST:
1602 return bgp_nlri_parse_ip (peer, attr, packet);
1603 case SAFI_MPLS_VPN:
1604 case SAFI_MPLS_LABELED_VPN:
1605 return bgp_nlri_parse_vpn (peer, attr, packet);
1606 case SAFI_ENCAP:
1607 return bgp_nlri_parse_encap (peer, attr, packet);
1608 }
1609 return -1;
1610}
1611
paul718e3742002-12-13 20:15:29 +00001612/* Parse BGP Update packet and make attribute object. */
paul94f2b392005-06-28 12:44:16 +00001613static int
paul718e3742002-12-13 20:15:29 +00001614bgp_update_receive (struct peer *peer, bgp_size_t size)
1615{
Paul Jakma518a4b72016-02-04 13:27:04 +00001616 int ret, nlri_ret;
paul718e3742002-12-13 20:15:29 +00001617 u_char *end;
1618 struct stream *s;
1619 struct attr attr;
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001620 struct attr_extra extra;
paul718e3742002-12-13 20:15:29 +00001621 bgp_size_t attribute_len;
1622 bgp_size_t update_len;
1623 bgp_size_t withdraw_len;
Paul Jakma518a4b72016-02-04 13:27:04 +00001624 int i;
1625
1626 enum NLRI_TYPES {
1627 NLRI_UPDATE,
1628 NLRI_WITHDRAW,
1629 NLRI_MP_UPDATE,
1630 NLRI_MP_WITHDRAW,
1631 NLRI_TYPE_MAX,
1632 };
1633 struct bgp_nlri nlris[NLRI_TYPE_MAX];
paul718e3742002-12-13 20:15:29 +00001634
1635 /* Status must be Established. */
1636 if (peer->status != Established)
1637 {
1638 zlog_err ("%s [FSM] Update packet received under status %s",
1639 peer->host, LOOKUP (bgp_status_msg, peer->status));
1640 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1641 return -1;
1642 }
1643
1644 /* Set initial values. */
1645 memset (&attr, 0, sizeof (struct attr));
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001646 memset (&extra, 0, sizeof (struct attr_extra));
Paul Jakma518a4b72016-02-04 13:27:04 +00001647 memset (&nlris, 0, sizeof nlris);
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001648 attr.extra = &extra;
paul718e3742002-12-13 20:15:29 +00001649
1650 s = peer->ibuf;
1651 end = stream_pnt (s) + size;
1652
1653 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1654 Length is too large (i.e., if Unfeasible Routes Length + Total
1655 Attribute Length + 23 exceeds the message Length), then the Error
1656 Subcode is set to Malformed Attribute List. */
1657 if (stream_pnt (s) + 2 > end)
1658 {
1659 zlog_err ("%s [Error] Update packet error"
1660 " (packet length is short for unfeasible length)",
1661 peer->host);
1662 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1663 BGP_NOTIFY_UPDATE_MAL_ATTR);
1664 return -1;
1665 }
1666
1667 /* Unfeasible Route Length. */
1668 withdraw_len = stream_getw (s);
1669
1670 /* Unfeasible Route Length check. */
1671 if (stream_pnt (s) + withdraw_len > end)
1672 {
1673 zlog_err ("%s [Error] Update packet error"
1674 " (packet unfeasible length overflow %d)",
1675 peer->host, withdraw_len);
1676 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1677 BGP_NOTIFY_UPDATE_MAL_ATTR);
1678 return -1;
1679 }
1680
1681 /* Unfeasible Route packet format check. */
1682 if (withdraw_len > 0)
1683 {
Paul Jakma518a4b72016-02-04 13:27:04 +00001684 nlris[NLRI_WITHDRAW].afi = AFI_IP;
1685 nlris[NLRI_WITHDRAW].safi = SAFI_UNICAST;
1686 nlris[NLRI_WITHDRAW].nlri = stream_pnt (s);
1687 nlris[NLRI_WITHDRAW].length = withdraw_len;
1688
paul718e3742002-12-13 20:15:29 +00001689 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001690 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001691
paul9985f832005-02-09 15:51:56 +00001692 stream_forward_getp (s, withdraw_len);
paul718e3742002-12-13 20:15:29 +00001693 }
1694
1695 /* Attribute total length check. */
1696 if (stream_pnt (s) + 2 > end)
1697 {
1698 zlog_warn ("%s [Error] Packet Error"
1699 " (update packet is short for attribute length)",
1700 peer->host);
1701 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1702 BGP_NOTIFY_UPDATE_MAL_ATTR);
1703 return -1;
1704 }
1705
1706 /* Fetch attribute total length. */
1707 attribute_len = stream_getw (s);
1708
1709 /* Attribute length check. */
1710 if (stream_pnt (s) + attribute_len > end)
1711 {
1712 zlog_warn ("%s [Error] Packet Error"
1713 " (update packet attribute length overflow %d)",
1714 peer->host, attribute_len);
1715 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1716 BGP_NOTIFY_UPDATE_MAL_ATTR);
1717 return -1;
1718 }
Paul Jakmab881c702010-11-23 16:35:42 +00001719
1720 /* Certain attribute parsing errors should not be considered bad enough
1721 * to reset the session for, most particularly any partial/optional
1722 * attributes that have 'tunneled' over speakers that don't understand
1723 * them. Instead we withdraw only the prefix concerned.
1724 *
1725 * Complicates the flow a little though..
1726 */
1727 bgp_attr_parse_ret_t attr_parse_ret = BGP_ATTR_PARSE_PROCEED;
1728 /* This define morphs the update case into a withdraw when lower levels
1729 * have signalled an error condition where this is best.
1730 */
1731#define NLRI_ATTR_ARG (attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : NULL)
paul718e3742002-12-13 20:15:29 +00001732
1733 /* Parse attribute when it exists. */
1734 if (attribute_len)
1735 {
Paul Jakmab881c702010-11-23 16:35:42 +00001736 attr_parse_ret = bgp_attr_parse (peer, &attr, attribute_len,
Paul Jakma518a4b72016-02-04 13:27:04 +00001737 &nlris[NLRI_MP_UPDATE], &nlris[NLRI_MP_WITHDRAW]);
Paul Jakmab881c702010-11-23 16:35:42 +00001738 if (attr_parse_ret == BGP_ATTR_PARSE_ERROR)
David Lamparterf80f8382014-06-04 01:00:51 +02001739 {
1740 bgp_attr_unintern_sub (&attr);
Lou Berger050defe2016-01-12 13:41:59 -05001741 bgp_attr_flush (&attr);
David Lamparterf80f8382014-06-04 01:00:51 +02001742 return -1;
1743 }
paul718e3742002-12-13 20:15:29 +00001744 }
Paul Jakmab881c702010-11-23 16:35:42 +00001745
paul718e3742002-12-13 20:15:29 +00001746 /* Logging the attribute. */
Paul Jakmab881c702010-11-23 16:35:42 +00001747 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW
1748 || BGP_DEBUG (update, UPDATE_IN))
paul718e3742002-12-13 20:15:29 +00001749 {
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +00001750 char attrstr[BUFSIZ];
1751 attrstr[0] = '\0';
1752
paule01f9cb2004-07-09 17:48:53 +00001753 ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
Paul Jakmab881c702010-11-23 16:35:42 +00001754 int lvl = (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1755 ? LOG_ERR : LOG_DEBUG;
1756
1757 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1758 zlog (peer->log, LOG_ERR,
1759 "%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
1760 peer->host);
paule01f9cb2004-07-09 17:48:53 +00001761
1762 if (ret)
Paul Jakmab881c702010-11-23 16:35:42 +00001763 zlog (peer->log, lvl, "%s rcvd UPDATE w/ attr: %s",
paule01f9cb2004-07-09 17:48:53 +00001764 peer->host, attrstr);
paul718e3742002-12-13 20:15:29 +00001765 }
Paul Jakmab881c702010-11-23 16:35:42 +00001766
paul718e3742002-12-13 20:15:29 +00001767 /* Network Layer Reachability Information. */
1768 update_len = end - stream_pnt (s);
1769
1770 if (update_len)
1771 {
Paul Jakma18ab08b2016-01-27 16:37:33 +00001772 /* Set NLRI portion to structure. */
Paul Jakma518a4b72016-02-04 13:27:04 +00001773 nlris[NLRI_UPDATE].afi = AFI_IP;
1774 nlris[NLRI_UPDATE].safi = SAFI_UNICAST;
1775 nlris[NLRI_UPDATE].nlri = stream_pnt (s);
1776 nlris[NLRI_UPDATE].length = update_len;
Paul Jakma18ab08b2016-01-27 16:37:33 +00001777
paul9985f832005-02-09 15:51:56 +00001778 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001779 }
Paul Jakma518a4b72016-02-04 13:27:04 +00001780
1781 /* Parse any given NLRIs */
1782 for (i = NLRI_UPDATE; i < NLRI_TYPE_MAX; i++)
paul718e3742002-12-13 20:15:29 +00001783 {
Paul Jakma518a4b72016-02-04 13:27:04 +00001784 /* We use afi and safi as indices into tables and what not. It would
1785 * be impossible, at this time, to support unknown afi/safis. And
1786 * anyway, the peer needs to be configured to enable the afi/safi
1787 * explicitly which requires UI support.
1788 *
1789 * Ignore unknown afi/safi NLRIs.
1790 *
1791 * Note: this means nlri[x].afi/safi still can not be trusted for
1792 * indexing later in this function!
1793 *
1794 * Note2: This will also remap the wire code-point for VPN safi to the
1795 * internal safi_t point, as needs be.
1796 */
1797 if (!bgp_afi_safi_valid_indices (nlris[i].afi, &nlris[i].safi))
1798 {
1799 plog_info (peer->log,
1800 "%s [Info] UPDATE with unsupported AFI/SAFI %u/%u",
1801 peer->host, nlris[i].afi, nlris[i].safi);
1802 continue;
1803 }
1804
1805 /* NLRI is processed only when the peer is configured specific
1806 Address Family and Subsequent Address Family. */
1807 if (!peer->afc[nlris[i].afi][nlris[i].safi])
1808 {
1809 plog_info (peer->log,
1810 "%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u",
1811 peer->host, nlris[i].afi, nlris[i].safi);
1812 continue;
1813 }
1814
1815 /* EoR handled later */
1816 if (nlris[i].length == 0)
1817 continue;
1818
1819 switch (i)
1820 {
1821 case NLRI_UPDATE:
1822 case NLRI_MP_UPDATE:
1823 nlri_ret = bgp_nlri_parse (peer, NLRI_ATTR_ARG, &nlris[i]);
1824 break;
1825 case NLRI_WITHDRAW:
1826 case NLRI_MP_WITHDRAW:
1827 nlri_ret = bgp_nlri_parse (peer, NULL, &nlris[i]);
1828 }
1829
1830 if (nlri_ret < 0)
1831 {
1832 plog_err (peer->log,
1833 "%s [Error] Error parsing NLRI", peer->host);
1834 if (peer->status == Established)
1835 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1836 i <= NLRI_WITHDRAW
1837 ? BGP_NOTIFY_UPDATE_INVAL_NETWORK
1838 : BGP_NOTIFY_UPDATE_OPT_ATTR_ERR);
1839 bgp_attr_unintern_sub (&attr);
1840 return -1;
1841 }
1842 }
1843
1844 /* EoR checks.
1845 *
1846 * Non-MP IPv4/Unicast EoR is a completely empty UPDATE
1847 * and MP EoR should have only an empty MP_UNREACH
1848 */
1849 if (!update_len && !withdraw_len
1850 && nlris[NLRI_MP_UPDATE].length == 0)
1851 {
1852 afi_t afi = 0;
1853 safi_t safi;
1854
1855 /* Non-MP IPv4/Unicast is a completely empty UPDATE - already
1856 * checked update and withdraw NLRI lengths are 0.
1857 */
1858 if (!attribute_len)
1859 {
1860 afi = AFI_IP;
1861 safi = SAFI_UNICAST;
1862 }
1863 /* otherwise MP AFI/SAFI is an empty update, other than an empty
1864 * MP_UNREACH_NLRI attr (with an AFI/SAFI we recognise).
1865 */
1866 else if (attr.flag == BGP_ATTR_MP_UNREACH_NLRI
1867 && nlris[NLRI_MP_WITHDRAW].length == 0
1868 && bgp_afi_safi_valid_indices (nlris[NLRI_MP_WITHDRAW].afi,
1869 &nlris[NLRI_MP_WITHDRAW].safi))
1870 {
1871 afi = nlris[NLRI_MP_WITHDRAW].afi;
1872 safi = nlris[NLRI_MP_WITHDRAW].safi;
1873 }
1874
1875 if (afi && peer->afc[afi][safi])
1876 {
paule01f9cb2004-07-09 17:48:53 +00001877 /* End-of-RIB received */
Paul Jakma518a4b72016-02-04 13:27:04 +00001878 SET_FLAG (peer->af_sflags[afi][safi],
hasso93406d82005-02-02 14:40:33 +00001879 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001880
hasso93406d82005-02-02 14:40:33 +00001881 /* NSF delete stale route */
Paul Jakma518a4b72016-02-04 13:27:04 +00001882 if (peer->nsf[afi][safi])
1883 bgp_clear_stale_route (peer, afi, safi);
hasso93406d82005-02-02 14:40:33 +00001884
1885 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma518a4b72016-02-04 13:27:04 +00001886 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for %s from %s",
1887 peer->host, afi_safi_print (afi, safi));
1888 }
paul718e3742002-12-13 20:15:29 +00001889 }
Paul Jakma518a4b72016-02-04 13:27:04 +00001890
paul718e3742002-12-13 20:15:29 +00001891 /* Everything is done. We unintern temporary structures which
1892 interned in bgp_attr_parse(). */
Paul Jakmab881c702010-11-23 16:35:42 +00001893 bgp_attr_unintern_sub (&attr);
Lou Berger050defe2016-01-12 13:41:59 -05001894 bgp_attr_flush (&attr);
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001895
paul718e3742002-12-13 20:15:29 +00001896 /* If peering is stopped due to some reason, do not generate BGP
1897 event. */
1898 if (peer->status != Established)
1899 return 0;
1900
1901 /* Increment packet counter. */
1902 peer->update_in++;
Stephen Hemminger65957882010-01-15 16:22:10 +03001903 peer->update_time = bgp_clock ();
paul718e3742002-12-13 20:15:29 +00001904
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02001905 /* Rearm holdtime timer */
Jorge Boncompte [DTI2]6a4677b2012-05-07 16:53:07 +00001906 BGP_TIMER_OFF (peer->t_holdtime);
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02001907 bgp_timer_set (peer);
paul718e3742002-12-13 20:15:29 +00001908
1909 return 0;
1910}
1911
1912/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00001913static void
paul718e3742002-12-13 20:15:29 +00001914bgp_notify_receive (struct peer *peer, bgp_size_t size)
1915{
1916 struct bgp_notify bgp_notify;
1917
1918 if (peer->notify.data)
1919 {
1920 XFREE (MTYPE_TMP, peer->notify.data);
1921 peer->notify.data = NULL;
1922 peer->notify.length = 0;
1923 }
1924
1925 bgp_notify.code = stream_getc (peer->ibuf);
1926 bgp_notify.subcode = stream_getc (peer->ibuf);
1927 bgp_notify.length = size - 2;
1928 bgp_notify.data = NULL;
1929
1930 /* Preserv notify code and sub code. */
1931 peer->notify.code = bgp_notify.code;
1932 peer->notify.subcode = bgp_notify.subcode;
1933 /* For further diagnostic record returned Data. */
1934 if (bgp_notify.length)
1935 {
1936 peer->notify.length = size - 2;
1937 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
1938 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
1939 }
1940
1941 /* For debug */
1942 {
1943 int i;
1944 int first = 0;
1945 char c[4];
1946
1947 if (bgp_notify.length)
1948 {
1949 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
1950 for (i = 0; i < bgp_notify.length; i++)
1951 if (first)
1952 {
1953 sprintf (c, " %02x", stream_getc (peer->ibuf));
1954 strcat (bgp_notify.data, c);
1955 }
1956 else
1957 {
1958 first = 1;
1959 sprintf (c, "%02x", stream_getc (peer->ibuf));
1960 strcpy (bgp_notify.data, c);
1961 }
1962 }
1963
1964 bgp_notify_print(peer, &bgp_notify, "received");
1965 if (bgp_notify.data)
Daniel Walton363c9032015-10-21 06:42:54 -07001966 {
1967 XFREE (MTYPE_TMP, bgp_notify.data);
1968 bgp_notify.data = NULL;
1969 bgp_notify.length = 0;
1970 }
paul718e3742002-12-13 20:15:29 +00001971 }
1972
1973 /* peer count update */
1974 peer->notify_in++;
1975
hassoe0701b72004-05-20 09:19:34 +00001976 if (peer->status == Established)
1977 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
1978
paul718e3742002-12-13 20:15:29 +00001979 /* We have to check for Notify with Unsupported Optional Parameter.
1980 in that case we fallback to open without the capability option.
1981 But this done in bgp_stop. We just mark it here to avoid changing
1982 the fsm tables. */
1983 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1984 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
1985 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1986
paul718e3742002-12-13 20:15:29 +00001987 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
1988}
1989
1990/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00001991static void
paul718e3742002-12-13 20:15:29 +00001992bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
1993{
1994 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00001995 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00001996
1997 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
1998}
1999
2000/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00002001static void
paul718e3742002-12-13 20:15:29 +00002002bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
2003{
2004 afi_t afi;
2005 safi_t safi;
paul718e3742002-12-13 20:15:29 +00002006 struct stream *s;
2007
2008 /* If peer does not have the capability, send notification. */
2009 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
2010 {
2011 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
2012 peer->host);
2013 bgp_notify_send (peer,
2014 BGP_NOTIFY_HEADER_ERR,
2015 BGP_NOTIFY_HEADER_BAD_MESTYPE);
2016 return;
2017 }
2018
2019 /* Status must be Established. */
2020 if (peer->status != Established)
2021 {
2022 plog_err (peer->log,
2023 "%s [Error] Route refresh packet received under status %s",
2024 peer->host, LOOKUP (bgp_status_msg, peer->status));
2025 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
2026 return;
2027 }
2028
2029 s = peer->ibuf;
2030
2031 /* Parse packet. */
2032 afi = stream_getw (s);
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002033 /* reserved byte */
2034 stream_getc (s);
paul718e3742002-12-13 20:15:29 +00002035 safi = stream_getc (s);
2036
2037 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002038 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00002039 peer->host, afi, safi);
2040
2041 /* Check AFI and SAFI. */
2042 if ((afi != AFI_IP && afi != AFI_IP6)
2043 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
Denis Ovsienko42e6d742011-07-14 12:36:19 +04002044 && safi != SAFI_MPLS_LABELED_VPN))
paul718e3742002-12-13 20:15:29 +00002045 {
2046 if (BGP_DEBUG (normal, NORMAL))
2047 {
ajs6b514742004-12-08 21:03:23 +00002048 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00002049 peer->host, afi, safi);
2050 }
2051 return;
2052 }
2053
2054 /* Adjust safi code. */
Denis Ovsienko42e6d742011-07-14 12:36:19 +04002055 if (safi == SAFI_MPLS_LABELED_VPN)
paul718e3742002-12-13 20:15:29 +00002056 safi = SAFI_MPLS_VPN;
2057
2058 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
2059 {
2060 u_char *end;
2061 u_char when_to_refresh;
2062 u_char orf_type;
2063 u_int16_t orf_len;
2064
2065 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
2066 {
2067 zlog_info ("%s ORF route refresh length error", peer->host);
2068 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2069 return;
2070 }
2071
2072 when_to_refresh = stream_getc (s);
2073 end = stream_pnt (s) + (size - 5);
2074
Paul Jakma370b64a2007-12-22 16:49:52 +00002075 while ((stream_pnt (s) + 2) < end)
paul718e3742002-12-13 20:15:29 +00002076 {
2077 orf_type = stream_getc (s);
2078 orf_len = stream_getw (s);
Paul Jakma370b64a2007-12-22 16:49:52 +00002079
2080 /* orf_len in bounds? */
2081 if ((stream_pnt (s) + orf_len) > end)
2082 break; /* XXX: Notify instead?? */
paul718e3742002-12-13 20:15:29 +00002083 if (orf_type == ORF_TYPE_PREFIX
2084 || orf_type == ORF_TYPE_PREFIX_OLD)
2085 {
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002086 uint8_t *p_pnt = stream_pnt (s);
2087 uint8_t *p_end = stream_pnt (s) + orf_len;
paul718e3742002-12-13 20:15:29 +00002088 struct orf_prefix orfp;
2089 u_char common = 0;
2090 u_int32_t seq;
2091 int psize;
2092 char name[BUFSIZ];
paul718e3742002-12-13 20:15:29 +00002093 int ret;
2094
2095 if (BGP_DEBUG (normal, NORMAL))
2096 {
ajs6b514742004-12-08 21:03:23 +00002097 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00002098 peer->host, orf_type, orf_len);
2099 }
2100
Paul Jakma370b64a2007-12-22 16:49:52 +00002101 /* we're going to read at least 1 byte of common ORF header,
2102 * and 7 bytes of ORF Address-filter entry from the stream
2103 */
2104 if (orf_len < 7)
2105 break;
2106
paul718e3742002-12-13 20:15:29 +00002107 /* ORF prefix-list name */
2108 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
2109
2110 while (p_pnt < p_end)
2111 {
Chris Halld64379e2010-05-14 16:38:39 +04002112 /* If the ORF entry is malformed, want to read as much of it
2113 * as possible without going beyond the bounds of the entry,
2114 * to maximise debug information.
2115 */
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002116 int ok;
paul718e3742002-12-13 20:15:29 +00002117 memset (&orfp, 0, sizeof (struct orf_prefix));
2118 common = *p_pnt++;
Chris Halld64379e2010-05-14 16:38:39 +04002119 /* after ++: p_pnt <= p_end */
paul718e3742002-12-13 20:15:29 +00002120 if (common & ORF_COMMON_PART_REMOVE_ALL)
2121 {
2122 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002123 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
David Lamparterc9c06d02015-04-13 10:21:35 +02002124 prefix_bgp_orf_remove_all (afi, name);
paul718e3742002-12-13 20:15:29 +00002125 break;
2126 }
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002127 ok = ((size_t)(p_end - p_pnt) >= sizeof(u_int32_t)) ;
Denis Ovsienkobb915f52011-12-13 21:11:39 +04002128 if (ok)
Chris Halld64379e2010-05-14 16:38:39 +04002129 {
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002130 memcpy (&seq, p_pnt, sizeof (u_int32_t));
2131 p_pnt += sizeof (u_int32_t);
2132 orfp.seq = ntohl (seq);
Chris Halld64379e2010-05-14 16:38:39 +04002133 }
2134 else
2135 p_pnt = p_end ;
2136
2137 if ((ok = (p_pnt < p_end)))
2138 orfp.ge = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2139 if ((ok = (p_pnt < p_end)))
2140 orfp.le = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2141 if ((ok = (p_pnt < p_end)))
2142 orfp.p.prefixlen = *p_pnt++ ;
2143 orfp.p.family = afi2family (afi); /* afi checked already */
2144
2145 psize = PSIZE (orfp.p.prefixlen); /* 0 if not ok */
2146 if (psize > prefix_blen(&orfp.p)) /* valid for family ? */
2147 {
2148 ok = 0 ;
2149 psize = prefix_blen(&orfp.p) ;
2150 }
2151 if (psize > (p_end - p_pnt)) /* valid for packet ? */
2152 {
2153 ok = 0 ;
2154 psize = p_end - p_pnt ;
2155 }
2156
2157 if (psize > 0)
2158 memcpy (&orfp.p.u.prefix, p_pnt, psize);
paul718e3742002-12-13 20:15:29 +00002159 p_pnt += psize;
2160
2161 if (BGP_DEBUG (normal, NORMAL))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +00002162 {
2163 char buf[INET6_BUFSIZ];
2164
2165 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
2166 peer->host,
2167 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
2168 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
2169 orfp.seq,
2170 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, INET6_BUFSIZ),
2171 orfp.p.prefixlen, orfp.ge, orfp.le,
2172 ok ? "" : " MALFORMED");
2173 }
2174
Chris Halld64379e2010-05-14 16:38:39 +04002175 if (ok)
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002176 ret = prefix_bgp_orf_set (name, afi, &orfp,
2177 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
2178 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002179
2180 if (!ok || (ok && ret != CMD_SUCCESS))
paul718e3742002-12-13 20:15:29 +00002181 {
2182 if (BGP_DEBUG (normal, NORMAL))
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002183 zlog_debug ("%s Received misformatted prefixlist ORF."
2184 " Remove All pfxlist", peer->host);
David Lamparterc9c06d02015-04-13 10:21:35 +02002185 prefix_bgp_orf_remove_all (afi, name);
paul718e3742002-12-13 20:15:29 +00002186 break;
2187 }
2188 }
2189 peer->orf_plist[afi][safi] =
David Lamparterc9c06d02015-04-13 10:21:35 +02002190 prefix_bgp_orf_lookup (afi, name);
paul718e3742002-12-13 20:15:29 +00002191 }
paul9985f832005-02-09 15:51:56 +00002192 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00002193 }
2194 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002195 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00002196 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
2197 if (when_to_refresh == REFRESH_DEFER)
2198 return;
2199 }
2200
2201 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2202 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
2203 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
2204
2205 /* Perform route refreshment to the peer */
2206 bgp_announce_route (peer, afi, safi);
2207}
2208
paul94f2b392005-06-28 12:44:16 +00002209static int
paul718e3742002-12-13 20:15:29 +00002210bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
2211{
2212 u_char *end;
Paul Jakma6d582722007-08-06 15:21:45 +00002213 struct capability_mp_data mpc;
2214 struct capability_header *hdr;
paul718e3742002-12-13 20:15:29 +00002215 u_char action;
paul718e3742002-12-13 20:15:29 +00002216 afi_t afi;
2217 safi_t safi;
2218
paul718e3742002-12-13 20:15:29 +00002219 end = pnt + length;
2220
2221 while (pnt < end)
Paul Jakma6d582722007-08-06 15:21:45 +00002222 {
paul718e3742002-12-13 20:15:29 +00002223 /* We need at least action, capability code and capability length. */
2224 if (pnt + 3 > end)
2225 {
2226 zlog_info ("%s Capability length error", peer->host);
2227 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2228 return -1;
2229 }
paul718e3742002-12-13 20:15:29 +00002230 action = *pnt;
Paul Jakma6d582722007-08-06 15:21:45 +00002231 hdr = (struct capability_header *)(pnt + 1);
2232
paul718e3742002-12-13 20:15:29 +00002233 /* Action value check. */
2234 if (action != CAPABILITY_ACTION_SET
2235 && action != CAPABILITY_ACTION_UNSET)
2236 {
2237 zlog_info ("%s Capability Action Value error %d",
2238 peer->host, action);
2239 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2240 return -1;
2241 }
2242
2243 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002244 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
Paul Jakma6d582722007-08-06 15:21:45 +00002245 peer->host, action, hdr->code, hdr->length);
paul718e3742002-12-13 20:15:29 +00002246
2247 /* Capability length check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002248 if ((pnt + hdr->length + 3) > end)
paul718e3742002-12-13 20:15:29 +00002249 {
2250 zlog_info ("%s Capability length error", peer->host);
2251 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2252 return -1;
2253 }
2254
Paul Jakma6d582722007-08-06 15:21:45 +00002255 /* Fetch structure to the byte stream. */
2256 memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
2257
paul718e3742002-12-13 20:15:29 +00002258 /* We know MP Capability Code. */
Paul Jakma6d582722007-08-06 15:21:45 +00002259 if (hdr->code == CAPABILITY_CODE_MP)
paul718e3742002-12-13 20:15:29 +00002260 {
Paul Jakma6d582722007-08-06 15:21:45 +00002261 afi = ntohs (mpc.afi);
2262 safi = mpc.safi;
paul718e3742002-12-13 20:15:29 +00002263
2264 /* Ignore capability when override-capability is set. */
2265 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2266 continue;
Paul Jakma6d582722007-08-06 15:21:45 +00002267
2268 if (!bgp_afi_safi_valid_indices (afi, &safi))
2269 {
2270 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002271 zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
2272 "(%u/%u)", peer->host, afi, safi);
Paul Jakma6d582722007-08-06 15:21:45 +00002273 continue;
2274 }
2275
paul718e3742002-12-13 20:15:29 +00002276 /* Address family check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002277 if (BGP_DEBUG (normal, NORMAL))
2278 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2279 peer->host,
2280 action == CAPABILITY_ACTION_SET
2281 ? "Advertising" : "Removing",
2282 ntohs(mpc.afi) , mpc.safi);
2283
2284 if (action == CAPABILITY_ACTION_SET)
2285 {
2286 peer->afc_recv[afi][safi] = 1;
2287 if (peer->afc[afi][safi])
2288 {
2289 peer->afc_nego[afi][safi] = 1;
2290 bgp_announce_route (peer, afi, safi);
2291 }
2292 }
2293 else
2294 {
2295 peer->afc_recv[afi][safi] = 0;
2296 peer->afc_nego[afi][safi] = 0;
paul718e3742002-12-13 20:15:29 +00002297
Paul Jakma6d582722007-08-06 15:21:45 +00002298 if (peer_active_nego (peer))
Chris Caputo228da422009-07-18 05:44:03 +00002299 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
Paul Jakma6d582722007-08-06 15:21:45 +00002300 else
2301 BGP_EVENT_ADD (peer, BGP_Stop);
2302 }
paul718e3742002-12-13 20:15:29 +00002303 }
paul718e3742002-12-13 20:15:29 +00002304 else
2305 {
2306 zlog_warn ("%s unrecognized capability code: %d - ignored",
Paul Jakma6d582722007-08-06 15:21:45 +00002307 peer->host, hdr->code);
paul718e3742002-12-13 20:15:29 +00002308 }
Paul Jakma6d582722007-08-06 15:21:45 +00002309 pnt += hdr->length + 3;
paul718e3742002-12-13 20:15:29 +00002310 }
2311 return 0;
2312}
2313
Paul Jakma01b7ce22009-06-18 12:34:43 +01002314/* Dynamic Capability is received.
2315 *
2316 * This is exported for unit-test purposes
2317 */
Paul Jakma6d582722007-08-06 15:21:45 +00002318int
paul718e3742002-12-13 20:15:29 +00002319bgp_capability_receive (struct peer *peer, bgp_size_t size)
2320{
2321 u_char *pnt;
paul718e3742002-12-13 20:15:29 +00002322
2323 /* Fetch pointer. */
2324 pnt = stream_pnt (peer->ibuf);
2325
2326 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002327 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002328
2329 /* If peer does not have the capability, send notification. */
2330 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2331 {
2332 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2333 peer->host);
2334 bgp_notify_send (peer,
2335 BGP_NOTIFY_HEADER_ERR,
2336 BGP_NOTIFY_HEADER_BAD_MESTYPE);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002337 return -1;
paul718e3742002-12-13 20:15:29 +00002338 }
2339
2340 /* Status must be Established. */
2341 if (peer->status != Established)
2342 {
2343 plog_err (peer->log,
2344 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2345 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002346 return -1;
paul718e3742002-12-13 20:15:29 +00002347 }
2348
2349 /* Parse packet. */
Paul Jakma6d582722007-08-06 15:21:45 +00002350 return bgp_capability_msg_parse (peer, pnt, size);
paul718e3742002-12-13 20:15:29 +00002351}
David Lamparter6b0655a2014-06-04 06:53:35 +02002352
paul718e3742002-12-13 20:15:29 +00002353/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002354static int
paul718e3742002-12-13 20:15:29 +00002355bgp_read_packet (struct peer *peer)
2356{
2357 int nbytes;
2358 int readsize;
2359
paul9985f832005-02-09 15:51:56 +00002360 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002361
2362 /* If size is zero then return. */
2363 if (! readsize)
2364 return 0;
2365
2366 /* Read packet from fd. */
Stephen Hemminger35398582010-08-05 10:26:23 -07002367 nbytes = stream_read_try (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002368
2369 /* If read byte is smaller than zero then error occured. */
2370 if (nbytes < 0)
2371 {
Stephen Hemminger35398582010-08-05 10:26:23 -07002372 /* Transient error should retry */
2373 if (nbytes == -2)
paul718e3742002-12-13 20:15:29 +00002374 return -1;
2375
2376 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002377 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002378
2379 if (peer->status == Established)
2380 {
2381 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2382 {
2383 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2384 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2385 }
2386 else
2387 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2388 }
2389
paul718e3742002-12-13 20:15:29 +00002390 BGP_EVENT_ADD (peer, TCP_fatal_error);
2391 return -1;
2392 }
2393
2394 /* When read byte is zero : clear bgp peer and return */
2395 if (nbytes == 0)
2396 {
2397 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002398 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002399 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002400
2401 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002402 {
2403 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2404 {
2405 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2406 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2407 }
2408 else
2409 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2410 }
hassoe0701b72004-05-20 09:19:34 +00002411
paul718e3742002-12-13 20:15:29 +00002412 BGP_EVENT_ADD (peer, TCP_connection_closed);
2413 return -1;
2414 }
2415
2416 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002417 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002418 return -1;
2419
2420 return 0;
2421}
2422
2423/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002424static int
paul718e3742002-12-13 20:15:29 +00002425bgp_marker_all_one (struct stream *s, int length)
2426{
2427 int i;
2428
2429 for (i = 0; i < length; i++)
2430 if (s->data[i] != 0xff)
2431 return 0;
2432
2433 return 1;
2434}
2435
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002436/* Recent thread time.
2437 On same clock base as bgp_clock (MONOTONIC)
2438 but can be time of last context switch to bgp_read thread. */
2439static time_t
2440bgp_recent_clock (void)
2441{
2442 return recent_relative_time().tv_sec;
2443}
2444
paul718e3742002-12-13 20:15:29 +00002445/* Starting point of packet process function. */
2446int
2447bgp_read (struct thread *thread)
2448{
2449 int ret;
2450 u_char type = 0;
2451 struct peer *peer;
2452 bgp_size_t size;
2453 char notify_data_length[2];
2454
2455 /* Yes first of all get peer pointer. */
2456 peer = THREAD_ARG (thread);
2457 peer->t_read = NULL;
2458
2459 /* For non-blocking IO check. */
2460 if (peer->status == Connect)
2461 {
2462 bgp_connect_check (peer);
2463 goto done;
2464 }
2465 else
2466 {
pauleb821182004-05-01 08:44:08 +00002467 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002468 {
pauleb821182004-05-01 08:44:08 +00002469 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002470 return -1;
2471 }
pauleb821182004-05-01 08:44:08 +00002472 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002473 }
2474
2475 /* Read packet header to determine type of the packet */
2476 if (peer->packet_size == 0)
2477 peer->packet_size = BGP_HEADER_SIZE;
2478
paul9985f832005-02-09 15:51:56 +00002479 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002480 {
2481 ret = bgp_read_packet (peer);
2482
2483 /* Header read error or partial read packet. */
2484 if (ret < 0)
2485 goto done;
2486
2487 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002488 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002489 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2490 size = stream_getw (peer->ibuf);
2491 type = stream_getc (peer->ibuf);
2492
2493 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002494 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002495 peer->host, type, size - BGP_HEADER_SIZE);
2496
2497 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002498 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002499 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2500 {
2501 bgp_notify_send (peer,
2502 BGP_NOTIFY_HEADER_ERR,
2503 BGP_NOTIFY_HEADER_NOT_SYNC);
2504 goto done;
2505 }
2506
2507 /* BGP type check. */
2508 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2509 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2510 && type != BGP_MSG_ROUTE_REFRESH_NEW
2511 && type != BGP_MSG_ROUTE_REFRESH_OLD
2512 && type != BGP_MSG_CAPABILITY)
2513 {
2514 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002515 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002516 "%s unknown message type 0x%02x",
2517 peer->host, type);
2518 bgp_notify_send_with_data (peer,
2519 BGP_NOTIFY_HEADER_ERR,
2520 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2521 &type, 1);
2522 goto done;
2523 }
2524 /* Mimimum packet length check. */
2525 if ((size < BGP_HEADER_SIZE)
2526 || (size > BGP_MAX_PACKET_SIZE)
2527 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2528 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2529 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2530 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2531 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2532 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2533 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2534 {
2535 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002536 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002537 "%s bad message length - %d for %s",
2538 peer->host, size,
2539 type == 128 ? "ROUTE-REFRESH" :
2540 bgp_type_str[(int) type]);
2541 bgp_notify_send_with_data (peer,
2542 BGP_NOTIFY_HEADER_ERR,
2543 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002544 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002545 goto done;
2546 }
2547
2548 /* Adjust size to message length. */
2549 peer->packet_size = size;
2550 }
2551
2552 ret = bgp_read_packet (peer);
2553 if (ret < 0)
2554 goto done;
2555
2556 /* Get size and type again. */
2557 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2558 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2559
2560 /* BGP packet dump function. */
2561 bgp_dump_packet (peer, type, peer->ibuf);
2562
2563 size = (peer->packet_size - BGP_HEADER_SIZE);
2564
2565 /* Read rest of the packet and call each sort of packet routine */
2566 switch (type)
2567 {
2568 case BGP_MSG_OPEN:
2569 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002570 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002571 break;
2572 case BGP_MSG_UPDATE:
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002573 peer->readtime = bgp_recent_clock ();
paul718e3742002-12-13 20:15:29 +00002574 bgp_update_receive (peer, size);
2575 break;
2576 case BGP_MSG_NOTIFY:
2577 bgp_notify_receive (peer, size);
2578 break;
2579 case BGP_MSG_KEEPALIVE:
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002580 peer->readtime = bgp_recent_clock ();
paul718e3742002-12-13 20:15:29 +00002581 bgp_keepalive_receive (peer, size);
2582 break;
2583 case BGP_MSG_ROUTE_REFRESH_NEW:
2584 case BGP_MSG_ROUTE_REFRESH_OLD:
2585 peer->refresh_in++;
2586 bgp_route_refresh_receive (peer, size);
2587 break;
2588 case BGP_MSG_CAPABILITY:
2589 peer->dynamic_cap_in++;
2590 bgp_capability_receive (peer, size);
2591 break;
2592 }
2593
2594 /* Clear input buffer. */
2595 peer->packet_size = 0;
2596 if (peer->ibuf)
2597 stream_reset (peer->ibuf);
2598
2599 done:
2600 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2601 {
2602 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002603 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002604 peer_delete (peer);
paul718e3742002-12-13 20:15:29 +00002605 }
2606 return 0;
2607}