blob: 0c47ab546298eb9f1362e7f5ceae4b571def30b0 [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];
Daniel Waltonc6969872015-05-19 18:03:43 -07001246 u_int16_t *holdtime_ptr;
paul718e3742002-12-13 20:15:29 +00001247
1248 realpeer = NULL;
1249
1250 /* Parse open packet. */
1251 version = stream_getc (peer->ibuf);
1252 memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1253 remote_as = stream_getw (peer->ibuf);
Daniel Waltonc6969872015-05-19 18:03:43 -07001254 holdtime_ptr = (u_int16_t *)stream_pnt (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00001255 holdtime = stream_getw (peer->ibuf);
1256 memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1257 remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1258
1259 /* Receive OPEN message log */
1260 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001261 zlog_debug ("%s rcv OPEN, version %d, remote-as (in open) %u,"
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001262 " holdtime %d, id %s",
1263 peer->host, version, remote_as, holdtime,
1264 inet_ntoa (remote_id));
1265
1266 /* BEGIN to read the capability here, but dont do it yet */
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001267 mp_capability = 0;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001268 optlen = stream_getc (peer->ibuf);
1269
1270 if (optlen != 0)
1271 {
1272 /* We need the as4 capability value *right now* because
1273 * if it is there, we have not got the remote_as yet, and without
1274 * that we do not know which peer is connecting to us now.
1275 */
1276 as4 = peek_for_as4_capability (peer, optlen);
1277 }
1278
1279 /* Just in case we have a silly peer who sends AS4 capability set to 0 */
1280 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) && !as4)
1281 {
1282 zlog_err ("%s bad OPEN, got AS4 capability, but AS4 set to 0",
1283 peer->host);
1284 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1285 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1286 return -1;
1287 }
1288
1289 if (remote_as == BGP_AS_TRANS)
1290 {
1291 /* Take the AS4 from the capability. We must have received the
1292 * capability now! Otherwise we have a asn16 peer who uses
1293 * BGP_AS_TRANS, for some unknown reason.
1294 */
1295 if (as4 == BGP_AS_TRANS)
1296 {
1297 zlog_err ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
1298 peer->host);
1299 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1300 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1301 return -1;
1302 }
1303
1304 if (!as4 && BGP_DEBUG (as4, AS4))
1305 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
1306 " Odd, but proceeding.", peer->host);
1307 else if (as4 < BGP_AS_MAX && BGP_DEBUG (as4, AS4))
Paul Jakma0df7c912008-07-21 21:02:49 +00001308 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits "
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001309 "in 2-bytes, very odd peer.", peer->host, as4);
1310 if (as4)
1311 remote_as = as4;
1312 }
1313 else
1314 {
1315 /* We may have a partner with AS4 who has an asno < BGP_AS_MAX */
1316 /* If we have got the capability, peer->as4cap must match remote_as */
1317 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)
1318 && as4 != remote_as)
1319 {
1320 /* raise error, log this, close session */
1321 zlog_err ("%s bad OPEN, got AS4 capability, but remote_as %u"
1322 " mismatch with 16bit 'myasn' %u in open",
1323 peer->host, as4, remote_as);
1324 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1325 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1326 return -1;
1327 }
1328 }
1329
paul718e3742002-12-13 20:15:29 +00001330 /* Lookup peer from Open packet. */
1331 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1332 {
1333 int as = 0;
1334
1335 realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1336
1337 if (! realpeer)
1338 {
1339 /* Peer's source IP address is check in bgp_accept(), so this
1340 must be AS number mismatch or remote-id configuration
1341 mismatch. */
1342 if (as)
1343 {
1344 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001345 zlog_debug ("%s bad OPEN, wrong router identifier %s",
1346 peer->host, inet_ntoa (remote_id));
1347 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1348 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1349 notify_data_remote_id, 4);
paul718e3742002-12-13 20:15:29 +00001350 }
1351 else
1352 {
1353 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001354 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
ajs6b514742004-12-08 21:03:23 +00001355 peer->host, remote_as, peer->as);
1356 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1357 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1358 notify_data_remote_as, 2);
paul718e3742002-12-13 20:15:29 +00001359 }
1360 return -1;
1361 }
1362 }
1363
1364 /* When collision is detected and this peer is closed. Retrun
1365 immidiately. */
1366 ret = bgp_collision_detect (peer, remote_id);
1367 if (ret < 0)
1368 return ret;
1369
pauleb821182004-05-01 08:44:08 +00001370 /* Hack part. */
1371 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1372 {
hasso93406d82005-02-02 14:40:33 +00001373 if (realpeer->status == Established
1374 && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1375 {
1376 realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1377 SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1378 }
1379 else if (ret == 0 && realpeer->status != Active
1380 && realpeer->status != OpenSent
Paul Jakma6e199262008-09-09 17:14:33 +01001381 && realpeer->status != OpenConfirm
1382 && realpeer->status != Connect)
pauleb821182004-05-01 08:44:08 +00001383 {
Paul Jakma2b2fc562008-09-06 13:09:35 +01001384 /* XXX: This is an awful problem..
1385 *
1386 * According to the RFC we should just let this connection (of the
1387 * accepted 'peer') continue on to Established if the other
1388 * connection (the 'realpeer' one) is in state Connect, and deal
1389 * with the more larval FSM as/when it gets far enough to receive
1390 * an Open. We don't do that though, we instead close the (more
1391 * developed) accepted connection.
1392 *
1393 * This means there's a race, which if hit, can loop:
1394 *
1395 * FSM for A FSM for B
1396 * realpeer accept-peer realpeer accept-peer
1397 *
1398 * Connect Connect
1399 * Active
1400 * OpenSent OpenSent
1401 * <arrive here,
1402 * Notify, delete>
1403 * Idle Active
1404 * OpenSent OpenSent
1405 * <arrive here,
1406 * Notify, delete>
1407 * Idle
1408 * <wait> <wait>
1409 * Connect Connect
1410 *
1411 *
1412 * If both sides are Quagga, they're almost certain to wait for
1413 * the same amount of time of course (which doesn't preclude other
1414 * implementations also waiting for same time). The race is
1415 * exacerbated by high-latency (in bgpd and/or the network).
1416 *
1417 * The reason we do this is because our FSM is tied to our peer
1418 * structure, which carries our configuration information, etc.
1419 * I.e. we can't let the accepted-peer FSM continue on as it is,
1420 * cause it's not associated with any actual peer configuration -
1421 * it's just a dummy.
1422 *
1423 * It's possible we could hack-fix this by just bgp_stop'ing the
1424 * realpeer and continueing on with the 'transfer FSM' below.
1425 * Ideally, we need to seperate FSMs from struct peer.
1426 *
1427 * Setting one side to passive avoids the race, as a workaround.
1428 */
pauleb821182004-05-01 08:44:08 +00001429 if (BGP_DEBUG (events, EVENTS))
hasso93406d82005-02-02 14:40:33 +00001430 zlog_debug ("%s peer status is %s close connection",
1431 realpeer->host, LOOKUP (bgp_status_msg,
1432 realpeer->status));
1433 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1434 BGP_NOTIFY_CEASE_CONNECT_REJECT);
1435
pauleb821182004-05-01 08:44:08 +00001436 return -1;
1437 }
1438
1439 if (BGP_DEBUG (events, EVENTS))
Paul Jakma6e199262008-09-09 17:14:33 +01001440 zlog_debug ("%s [Event] Transfer accept BGP peer to real (state %s)",
1441 peer->host,
1442 LOOKUP (bgp_status_msg, realpeer->status));
pauleb821182004-05-01 08:44:08 +00001443
1444 bgp_stop (realpeer);
1445
1446 /* Transfer file descriptor. */
1447 realpeer->fd = peer->fd;
1448 peer->fd = -1;
1449
1450 /* Transfer input buffer. */
1451 stream_free (realpeer->ibuf);
1452 realpeer->ibuf = peer->ibuf;
1453 realpeer->packet_size = peer->packet_size;
1454 peer->ibuf = NULL;
1455
1456 /* Transfer status. */
1457 realpeer->status = peer->status;
1458 bgp_stop (peer);
paul200df112005-06-01 11:17:05 +00001459
pauleb821182004-05-01 08:44:08 +00001460 /* peer pointer change. Open packet send to neighbor. */
1461 peer = realpeer;
1462 bgp_open_send (peer);
1463 if (peer->fd < 0)
1464 {
1465 zlog_err ("bgp_open_receive peer's fd is negative value %d",
1466 peer->fd);
1467 return -1;
1468 }
1469 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1470 }
1471
paul718e3742002-12-13 20:15:29 +00001472 /* remote router-id check. */
1473 if (remote_id.s_addr == 0
Denis Ovsienko733cd9e2011-12-17 19:39:30 +04001474 || IPV4_CLASS_DE (ntohl (remote_id.s_addr))
paul718e3742002-12-13 20:15:29 +00001475 || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1476 {
1477 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001478 zlog_debug ("%s bad OPEN, wrong router identifier %s",
paul718e3742002-12-13 20:15:29 +00001479 peer->host, inet_ntoa (remote_id));
1480 bgp_notify_send_with_data (peer,
1481 BGP_NOTIFY_OPEN_ERR,
1482 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1483 notify_data_remote_id, 4);
1484 return -1;
1485 }
1486
1487 /* Set remote router-id */
1488 peer->remote_id = remote_id;
1489
1490 /* Peer BGP version check. */
1491 if (version != BGP_VERSION_4)
1492 {
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001493 u_int16_t maxver = htons(BGP_VERSION_4);
1494 /* XXX this reply may not be correct if version < 4 XXX */
paul718e3742002-12-13 20:15:29 +00001495 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001496 zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
paul718e3742002-12-13 20:15:29 +00001497 peer->host, version, BGP_VERSION_4);
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001498 /* Data must be in network byte order here */
paul718e3742002-12-13 20:15:29 +00001499 bgp_notify_send_with_data (peer,
1500 BGP_NOTIFY_OPEN_ERR,
1501 BGP_NOTIFY_OPEN_UNSUP_VERSION,
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001502 (u_int8_t *) &maxver, 2);
paul718e3742002-12-13 20:15:29 +00001503 return -1;
1504 }
1505
1506 /* Check neighbor as number. */
1507 if (remote_as != peer->as)
1508 {
1509 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001510 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
paul718e3742002-12-13 20:15:29 +00001511 peer->host, remote_as, peer->as);
1512 bgp_notify_send_with_data (peer,
1513 BGP_NOTIFY_OPEN_ERR,
1514 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1515 notify_data_remote_as, 2);
1516 return -1;
1517 }
1518
1519 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1520 calculate the value of the Hold Timer by using the smaller of its
1521 configured Hold Time and the Hold Time received in the OPEN message.
1522 The Hold Time MUST be either zero or at least three seconds. An
1523 implementation may reject connections on the basis of the Hold Time. */
1524
1525 if (holdtime < 3 && holdtime != 0)
1526 {
Daniel Waltonc6969872015-05-19 18:03:43 -07001527 bgp_notify_send_with_data (peer,
1528 BGP_NOTIFY_OPEN_ERR,
1529 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME,
1530 (u_int8_t *)holdtime_ptr, 2);
paul718e3742002-12-13 20:15:29 +00001531 return -1;
1532 }
1533
1534 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1535 would be one third of the Hold Time interval. KEEPALIVE messages
1536 MUST NOT be sent more frequently than one per second. An
1537 implementation MAY adjust the rate at which it sends KEEPALIVE
1538 messages as a function of the Hold Time interval. */
1539
1540 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1541 send_holdtime = peer->holdtime;
1542 else
1543 send_holdtime = peer->bgp->default_holdtime;
1544
1545 if (holdtime < send_holdtime)
1546 peer->v_holdtime = holdtime;
1547 else
1548 peer->v_holdtime = send_holdtime;
1549
1550 peer->v_keepalive = peer->v_holdtime / 3;
1551
1552 /* Open option part parse. */
paul718e3742002-12-13 20:15:29 +00001553 if (optlen != 0)
1554 {
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001555 if ((ret = bgp_open_option_parse (peer, optlen, &mp_capability)) < 0)
Paul Jakma58617392012-01-09 20:59:26 +00001556 {
1557 bgp_notify_send (peer,
1558 BGP_NOTIFY_OPEN_ERR,
Paul Jakma68ec4242015-11-25 17:14:34 +00001559 BGP_NOTIFY_OPEN_UNSPECIFIC);
Paul Jakma58617392012-01-09 20:59:26 +00001560 return ret;
1561 }
paul718e3742002-12-13 20:15:29 +00001562 }
1563 else
1564 {
1565 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001566 zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
paul718e3742002-12-13 20:15:29 +00001567 peer->host);
1568 }
1569
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001570 /*
1571 * Assume that the peer supports the locally configured set of
1572 * AFI/SAFIs if the peer did not send us any Mulitiprotocol
1573 * capabilities, or if 'override-capability' is configured.
1574 */
1575 if (! mp_capability ||
1576 CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
paul718e3742002-12-13 20:15:29 +00001577 {
1578 peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1579 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1580 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1581 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1582 }
1583
1584 /* Get sockname. */
1585 bgp_getsockname (peer);
Timo Teräs0edba8b2015-10-22 11:35:17 +03001586 peer->rtt = sockopt_tcp_rtt (peer->fd);
paul718e3742002-12-13 20:15:29 +00001587
1588 BGP_EVENT_ADD (peer, Receive_OPEN_message);
1589
1590 peer->packet_size = 0;
1591 if (peer->ibuf)
1592 stream_reset (peer->ibuf);
1593
1594 return 0;
1595}
1596
Paul Jakma518a4b72016-02-04 13:27:04 +00001597/* Frontend for NLRI parsing, to fan-out to AFI/SAFI specific parsers */
1598int
1599bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
1600{
1601 switch (packet->safi)
1602 {
1603 case SAFI_UNICAST:
1604 case SAFI_MULTICAST:
1605 return bgp_nlri_parse_ip (peer, attr, packet);
1606 case SAFI_MPLS_VPN:
1607 case SAFI_MPLS_LABELED_VPN:
1608 return bgp_nlri_parse_vpn (peer, attr, packet);
1609 case SAFI_ENCAP:
1610 return bgp_nlri_parse_encap (peer, attr, packet);
1611 }
1612 return -1;
1613}
1614
paul718e3742002-12-13 20:15:29 +00001615/* Parse BGP Update packet and make attribute object. */
paul94f2b392005-06-28 12:44:16 +00001616static int
paul718e3742002-12-13 20:15:29 +00001617bgp_update_receive (struct peer *peer, bgp_size_t size)
1618{
Paul Jakma518a4b72016-02-04 13:27:04 +00001619 int ret, nlri_ret;
paul718e3742002-12-13 20:15:29 +00001620 u_char *end;
1621 struct stream *s;
1622 struct attr attr;
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001623 struct attr_extra extra;
paul718e3742002-12-13 20:15:29 +00001624 bgp_size_t attribute_len;
1625 bgp_size_t update_len;
1626 bgp_size_t withdraw_len;
Paul Jakma518a4b72016-02-04 13:27:04 +00001627 int i;
1628
1629 enum NLRI_TYPES {
1630 NLRI_UPDATE,
1631 NLRI_WITHDRAW,
1632 NLRI_MP_UPDATE,
1633 NLRI_MP_WITHDRAW,
1634 NLRI_TYPE_MAX,
1635 };
1636 struct bgp_nlri nlris[NLRI_TYPE_MAX];
paul718e3742002-12-13 20:15:29 +00001637
1638 /* Status must be Established. */
1639 if (peer->status != Established)
1640 {
1641 zlog_err ("%s [FSM] Update packet received under status %s",
1642 peer->host, LOOKUP (bgp_status_msg, peer->status));
1643 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1644 return -1;
1645 }
1646
1647 /* Set initial values. */
1648 memset (&attr, 0, sizeof (struct attr));
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001649 memset (&extra, 0, sizeof (struct attr_extra));
Paul Jakma518a4b72016-02-04 13:27:04 +00001650 memset (&nlris, 0, sizeof nlris);
Paul Jakma3b847ef2016-04-22 12:48:49 +01001651
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001652 attr.extra = &extra;
paul718e3742002-12-13 20:15:29 +00001653
1654 s = peer->ibuf;
1655 end = stream_pnt (s) + size;
1656
1657 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1658 Length is too large (i.e., if Unfeasible Routes Length + Total
1659 Attribute Length + 23 exceeds the message Length), then the Error
1660 Subcode is set to Malformed Attribute List. */
1661 if (stream_pnt (s) + 2 > end)
1662 {
1663 zlog_err ("%s [Error] Update packet error"
1664 " (packet length is short for unfeasible length)",
1665 peer->host);
1666 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1667 BGP_NOTIFY_UPDATE_MAL_ATTR);
1668 return -1;
1669 }
1670
1671 /* Unfeasible Route Length. */
1672 withdraw_len = stream_getw (s);
1673
1674 /* Unfeasible Route Length check. */
1675 if (stream_pnt (s) + withdraw_len > end)
1676 {
1677 zlog_err ("%s [Error] Update packet error"
1678 " (packet unfeasible length overflow %d)",
1679 peer->host, withdraw_len);
1680 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1681 BGP_NOTIFY_UPDATE_MAL_ATTR);
1682 return -1;
1683 }
1684
1685 /* Unfeasible Route packet format check. */
1686 if (withdraw_len > 0)
1687 {
Paul Jakma518a4b72016-02-04 13:27:04 +00001688 nlris[NLRI_WITHDRAW].afi = AFI_IP;
1689 nlris[NLRI_WITHDRAW].safi = SAFI_UNICAST;
1690 nlris[NLRI_WITHDRAW].nlri = stream_pnt (s);
1691 nlris[NLRI_WITHDRAW].length = withdraw_len;
1692
paul718e3742002-12-13 20:15:29 +00001693 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001694 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001695
paul9985f832005-02-09 15:51:56 +00001696 stream_forward_getp (s, withdraw_len);
paul718e3742002-12-13 20:15:29 +00001697 }
1698
1699 /* Attribute total length check. */
1700 if (stream_pnt (s) + 2 > end)
1701 {
1702 zlog_warn ("%s [Error] Packet Error"
1703 " (update packet is short for attribute length)",
1704 peer->host);
1705 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1706 BGP_NOTIFY_UPDATE_MAL_ATTR);
1707 return -1;
1708 }
1709
1710 /* Fetch attribute total length. */
1711 attribute_len = stream_getw (s);
1712
1713 /* Attribute length check. */
1714 if (stream_pnt (s) + attribute_len > end)
1715 {
1716 zlog_warn ("%s [Error] Packet Error"
1717 " (update packet attribute length overflow %d)",
1718 peer->host, attribute_len);
1719 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1720 BGP_NOTIFY_UPDATE_MAL_ATTR);
1721 return -1;
1722 }
Paul Jakmab881c702010-11-23 16:35:42 +00001723
1724 /* Certain attribute parsing errors should not be considered bad enough
1725 * to reset the session for, most particularly any partial/optional
1726 * attributes that have 'tunneled' over speakers that don't understand
1727 * them. Instead we withdraw only the prefix concerned.
1728 *
1729 * Complicates the flow a little though..
1730 */
1731 bgp_attr_parse_ret_t attr_parse_ret = BGP_ATTR_PARSE_PROCEED;
1732 /* This define morphs the update case into a withdraw when lower levels
1733 * have signalled an error condition where this is best.
1734 */
1735#define NLRI_ATTR_ARG (attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : NULL)
paul718e3742002-12-13 20:15:29 +00001736
1737 /* Parse attribute when it exists. */
1738 if (attribute_len)
1739 {
Paul Jakmab881c702010-11-23 16:35:42 +00001740 attr_parse_ret = bgp_attr_parse (peer, &attr, attribute_len,
Paul Jakma518a4b72016-02-04 13:27:04 +00001741 &nlris[NLRI_MP_UPDATE], &nlris[NLRI_MP_WITHDRAW]);
Paul Jakmab881c702010-11-23 16:35:42 +00001742 if (attr_parse_ret == BGP_ATTR_PARSE_ERROR)
David Lamparterf80f8382014-06-04 01:00:51 +02001743 {
1744 bgp_attr_unintern_sub (&attr);
Lou Berger050defe2016-01-12 13:41:59 -05001745 bgp_attr_flush (&attr);
David Lamparterf80f8382014-06-04 01:00:51 +02001746 return -1;
1747 }
paul718e3742002-12-13 20:15:29 +00001748 }
Paul Jakmab881c702010-11-23 16:35:42 +00001749
paul718e3742002-12-13 20:15:29 +00001750 /* Logging the attribute. */
Paul Jakmab881c702010-11-23 16:35:42 +00001751 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW
1752 || BGP_DEBUG (update, UPDATE_IN))
paul718e3742002-12-13 20:15:29 +00001753 {
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +00001754 char attrstr[BUFSIZ];
1755 attrstr[0] = '\0';
1756
paule01f9cb2004-07-09 17:48:53 +00001757 ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
Paul Jakmab881c702010-11-23 16:35:42 +00001758 int lvl = (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1759 ? LOG_ERR : LOG_DEBUG;
1760
1761 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1762 zlog (peer->log, LOG_ERR,
1763 "%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
1764 peer->host);
paule01f9cb2004-07-09 17:48:53 +00001765
1766 if (ret)
Paul Jakmab881c702010-11-23 16:35:42 +00001767 zlog (peer->log, lvl, "%s rcvd UPDATE w/ attr: %s",
paule01f9cb2004-07-09 17:48:53 +00001768 peer->host, attrstr);
paul718e3742002-12-13 20:15:29 +00001769 }
Paul Jakmab881c702010-11-23 16:35:42 +00001770
paul718e3742002-12-13 20:15:29 +00001771 /* Network Layer Reachability Information. */
1772 update_len = end - stream_pnt (s);
1773
1774 if (update_len)
1775 {
Paul Jakma18ab08b2016-01-27 16:37:33 +00001776 /* Set NLRI portion to structure. */
Paul Jakma518a4b72016-02-04 13:27:04 +00001777 nlris[NLRI_UPDATE].afi = AFI_IP;
1778 nlris[NLRI_UPDATE].safi = SAFI_UNICAST;
1779 nlris[NLRI_UPDATE].nlri = stream_pnt (s);
1780 nlris[NLRI_UPDATE].length = update_len;
Paul Jakma18ab08b2016-01-27 16:37:33 +00001781
paul9985f832005-02-09 15:51:56 +00001782 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001783 }
Paul Jakma518a4b72016-02-04 13:27:04 +00001784
1785 /* Parse any given NLRIs */
1786 for (i = NLRI_UPDATE; i < NLRI_TYPE_MAX; i++)
paul718e3742002-12-13 20:15:29 +00001787 {
Paul Jakma3b847ef2016-04-22 12:48:49 +01001788 if (!nlris[i].nlri) continue;
1789
Paul Jakma518a4b72016-02-04 13:27:04 +00001790 /* We use afi and safi as indices into tables and what not. It would
1791 * be impossible, at this time, to support unknown afi/safis. And
1792 * anyway, the peer needs to be configured to enable the afi/safi
1793 * explicitly which requires UI support.
1794 *
1795 * Ignore unknown afi/safi NLRIs.
1796 *
1797 * Note: this means nlri[x].afi/safi still can not be trusted for
1798 * indexing later in this function!
1799 *
1800 * Note2: This will also remap the wire code-point for VPN safi to the
1801 * internal safi_t point, as needs be.
1802 */
1803 if (!bgp_afi_safi_valid_indices (nlris[i].afi, &nlris[i].safi))
1804 {
1805 plog_info (peer->log,
1806 "%s [Info] UPDATE with unsupported AFI/SAFI %u/%u",
1807 peer->host, nlris[i].afi, nlris[i].safi);
1808 continue;
1809 }
1810
1811 /* NLRI is processed only when the peer is configured specific
1812 Address Family and Subsequent Address Family. */
1813 if (!peer->afc[nlris[i].afi][nlris[i].safi])
1814 {
1815 plog_info (peer->log,
1816 "%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u",
1817 peer->host, nlris[i].afi, nlris[i].safi);
1818 continue;
1819 }
1820
1821 /* EoR handled later */
1822 if (nlris[i].length == 0)
1823 continue;
1824
1825 switch (i)
1826 {
1827 case NLRI_UPDATE:
1828 case NLRI_MP_UPDATE:
1829 nlri_ret = bgp_nlri_parse (peer, NLRI_ATTR_ARG, &nlris[i]);
1830 break;
1831 case NLRI_WITHDRAW:
1832 case NLRI_MP_WITHDRAW:
1833 nlri_ret = bgp_nlri_parse (peer, NULL, &nlris[i]);
1834 }
1835
1836 if (nlri_ret < 0)
1837 {
1838 plog_err (peer->log,
1839 "%s [Error] Error parsing NLRI", peer->host);
1840 if (peer->status == Established)
1841 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1842 i <= NLRI_WITHDRAW
1843 ? BGP_NOTIFY_UPDATE_INVAL_NETWORK
1844 : BGP_NOTIFY_UPDATE_OPT_ATTR_ERR);
1845 bgp_attr_unintern_sub (&attr);
1846 return -1;
1847 }
1848 }
1849
1850 /* EoR checks.
1851 *
1852 * Non-MP IPv4/Unicast EoR is a completely empty UPDATE
1853 * and MP EoR should have only an empty MP_UNREACH
1854 */
1855 if (!update_len && !withdraw_len
1856 && nlris[NLRI_MP_UPDATE].length == 0)
1857 {
1858 afi_t afi = 0;
1859 safi_t safi;
1860
1861 /* Non-MP IPv4/Unicast is a completely empty UPDATE - already
1862 * checked update and withdraw NLRI lengths are 0.
1863 */
1864 if (!attribute_len)
1865 {
1866 afi = AFI_IP;
1867 safi = SAFI_UNICAST;
1868 }
1869 /* otherwise MP AFI/SAFI is an empty update, other than an empty
1870 * MP_UNREACH_NLRI attr (with an AFI/SAFI we recognise).
1871 */
1872 else if (attr.flag == BGP_ATTR_MP_UNREACH_NLRI
1873 && nlris[NLRI_MP_WITHDRAW].length == 0
1874 && bgp_afi_safi_valid_indices (nlris[NLRI_MP_WITHDRAW].afi,
1875 &nlris[NLRI_MP_WITHDRAW].safi))
1876 {
1877 afi = nlris[NLRI_MP_WITHDRAW].afi;
1878 safi = nlris[NLRI_MP_WITHDRAW].safi;
1879 }
1880
1881 if (afi && peer->afc[afi][safi])
1882 {
paule01f9cb2004-07-09 17:48:53 +00001883 /* End-of-RIB received */
Paul Jakma518a4b72016-02-04 13:27:04 +00001884 SET_FLAG (peer->af_sflags[afi][safi],
hasso93406d82005-02-02 14:40:33 +00001885 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001886
hasso93406d82005-02-02 14:40:33 +00001887 /* NSF delete stale route */
Paul Jakma518a4b72016-02-04 13:27:04 +00001888 if (peer->nsf[afi][safi])
1889 bgp_clear_stale_route (peer, afi, safi);
hasso93406d82005-02-02 14:40:33 +00001890
1891 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma518a4b72016-02-04 13:27:04 +00001892 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for %s from %s",
1893 peer->host, afi_safi_print (afi, safi));
1894 }
paul718e3742002-12-13 20:15:29 +00001895 }
Paul Jakma518a4b72016-02-04 13:27:04 +00001896
paul718e3742002-12-13 20:15:29 +00001897 /* Everything is done. We unintern temporary structures which
1898 interned in bgp_attr_parse(). */
Paul Jakmab881c702010-11-23 16:35:42 +00001899 bgp_attr_unintern_sub (&attr);
Lou Berger050defe2016-01-12 13:41:59 -05001900 bgp_attr_flush (&attr);
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001901
paul718e3742002-12-13 20:15:29 +00001902 /* If peering is stopped due to some reason, do not generate BGP
1903 event. */
1904 if (peer->status != Established)
1905 return 0;
1906
1907 /* Increment packet counter. */
1908 peer->update_in++;
Stephen Hemminger65957882010-01-15 16:22:10 +03001909 peer->update_time = bgp_clock ();
paul718e3742002-12-13 20:15:29 +00001910
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02001911 /* Rearm holdtime timer */
Jorge Boncompte [DTI2]6a4677b2012-05-07 16:53:07 +00001912 BGP_TIMER_OFF (peer->t_holdtime);
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02001913 bgp_timer_set (peer);
paul718e3742002-12-13 20:15:29 +00001914
1915 return 0;
1916}
1917
1918/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00001919static void
paul718e3742002-12-13 20:15:29 +00001920bgp_notify_receive (struct peer *peer, bgp_size_t size)
1921{
1922 struct bgp_notify bgp_notify;
1923
1924 if (peer->notify.data)
1925 {
1926 XFREE (MTYPE_TMP, peer->notify.data);
1927 peer->notify.data = NULL;
1928 peer->notify.length = 0;
1929 }
1930
1931 bgp_notify.code = stream_getc (peer->ibuf);
1932 bgp_notify.subcode = stream_getc (peer->ibuf);
1933 bgp_notify.length = size - 2;
1934 bgp_notify.data = NULL;
1935
1936 /* Preserv notify code and sub code. */
1937 peer->notify.code = bgp_notify.code;
1938 peer->notify.subcode = bgp_notify.subcode;
1939 /* For further diagnostic record returned Data. */
1940 if (bgp_notify.length)
1941 {
1942 peer->notify.length = size - 2;
1943 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
1944 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
1945 }
1946
1947 /* For debug */
1948 {
1949 int i;
1950 int first = 0;
1951 char c[4];
1952
1953 if (bgp_notify.length)
1954 {
1955 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
1956 for (i = 0; i < bgp_notify.length; i++)
1957 if (first)
1958 {
1959 sprintf (c, " %02x", stream_getc (peer->ibuf));
1960 strcat (bgp_notify.data, c);
1961 }
1962 else
1963 {
1964 first = 1;
1965 sprintf (c, "%02x", stream_getc (peer->ibuf));
1966 strcpy (bgp_notify.data, c);
1967 }
1968 }
1969
1970 bgp_notify_print(peer, &bgp_notify, "received");
1971 if (bgp_notify.data)
Daniel Walton363c9032015-10-21 06:42:54 -07001972 {
1973 XFREE (MTYPE_TMP, bgp_notify.data);
1974 bgp_notify.data = NULL;
1975 bgp_notify.length = 0;
1976 }
paul718e3742002-12-13 20:15:29 +00001977 }
1978
1979 /* peer count update */
1980 peer->notify_in++;
1981
hassoe0701b72004-05-20 09:19:34 +00001982 if (peer->status == Established)
1983 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
1984
paul718e3742002-12-13 20:15:29 +00001985 /* We have to check for Notify with Unsupported Optional Parameter.
1986 in that case we fallback to open without the capability option.
1987 But this done in bgp_stop. We just mark it here to avoid changing
1988 the fsm tables. */
1989 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
1990 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
1991 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1992
paul718e3742002-12-13 20:15:29 +00001993 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
1994}
1995
1996/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00001997static void
paul718e3742002-12-13 20:15:29 +00001998bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
1999{
2000 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00002001 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00002002
2003 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
2004}
2005
2006/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00002007static void
paul718e3742002-12-13 20:15:29 +00002008bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
2009{
2010 afi_t afi;
2011 safi_t safi;
paul718e3742002-12-13 20:15:29 +00002012 struct stream *s;
2013
2014 /* If peer does not have the capability, send notification. */
2015 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
2016 {
2017 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
2018 peer->host);
2019 bgp_notify_send (peer,
2020 BGP_NOTIFY_HEADER_ERR,
2021 BGP_NOTIFY_HEADER_BAD_MESTYPE);
2022 return;
2023 }
2024
2025 /* Status must be Established. */
2026 if (peer->status != Established)
2027 {
2028 plog_err (peer->log,
2029 "%s [Error] Route refresh packet received under status %s",
2030 peer->host, LOOKUP (bgp_status_msg, peer->status));
2031 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
2032 return;
2033 }
2034
2035 s = peer->ibuf;
2036
2037 /* Parse packet. */
2038 afi = stream_getw (s);
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002039 /* reserved byte */
2040 stream_getc (s);
paul718e3742002-12-13 20:15:29 +00002041 safi = stream_getc (s);
2042
2043 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002044 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00002045 peer->host, afi, safi);
2046
2047 /* Check AFI and SAFI. */
2048 if ((afi != AFI_IP && afi != AFI_IP6)
2049 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
Denis Ovsienko42e6d742011-07-14 12:36:19 +04002050 && safi != SAFI_MPLS_LABELED_VPN))
paul718e3742002-12-13 20:15:29 +00002051 {
2052 if (BGP_DEBUG (normal, NORMAL))
2053 {
ajs6b514742004-12-08 21:03:23 +00002054 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00002055 peer->host, afi, safi);
2056 }
2057 return;
2058 }
2059
2060 /* Adjust safi code. */
Denis Ovsienko42e6d742011-07-14 12:36:19 +04002061 if (safi == SAFI_MPLS_LABELED_VPN)
paul718e3742002-12-13 20:15:29 +00002062 safi = SAFI_MPLS_VPN;
2063
2064 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
2065 {
2066 u_char *end;
2067 u_char when_to_refresh;
2068 u_char orf_type;
2069 u_int16_t orf_len;
2070
2071 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
2072 {
2073 zlog_info ("%s ORF route refresh length error", peer->host);
2074 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2075 return;
2076 }
2077
2078 when_to_refresh = stream_getc (s);
2079 end = stream_pnt (s) + (size - 5);
2080
Paul Jakma370b64a2007-12-22 16:49:52 +00002081 while ((stream_pnt (s) + 2) < end)
paul718e3742002-12-13 20:15:29 +00002082 {
2083 orf_type = stream_getc (s);
2084 orf_len = stream_getw (s);
Paul Jakma370b64a2007-12-22 16:49:52 +00002085
2086 /* orf_len in bounds? */
2087 if ((stream_pnt (s) + orf_len) > end)
2088 break; /* XXX: Notify instead?? */
paul718e3742002-12-13 20:15:29 +00002089 if (orf_type == ORF_TYPE_PREFIX
2090 || orf_type == ORF_TYPE_PREFIX_OLD)
2091 {
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002092 uint8_t *p_pnt = stream_pnt (s);
2093 uint8_t *p_end = stream_pnt (s) + orf_len;
paul718e3742002-12-13 20:15:29 +00002094 struct orf_prefix orfp;
2095 u_char common = 0;
2096 u_int32_t seq;
2097 int psize;
2098 char name[BUFSIZ];
paul718e3742002-12-13 20:15:29 +00002099 int ret;
2100
2101 if (BGP_DEBUG (normal, NORMAL))
2102 {
ajs6b514742004-12-08 21:03:23 +00002103 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00002104 peer->host, orf_type, orf_len);
2105 }
2106
Paul Jakma370b64a2007-12-22 16:49:52 +00002107 /* we're going to read at least 1 byte of common ORF header,
2108 * and 7 bytes of ORF Address-filter entry from the stream
2109 */
2110 if (orf_len < 7)
2111 break;
2112
paul718e3742002-12-13 20:15:29 +00002113 /* ORF prefix-list name */
2114 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
2115
2116 while (p_pnt < p_end)
2117 {
Chris Halld64379e2010-05-14 16:38:39 +04002118 /* If the ORF entry is malformed, want to read as much of it
2119 * as possible without going beyond the bounds of the entry,
2120 * to maximise debug information.
2121 */
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002122 int ok;
paul718e3742002-12-13 20:15:29 +00002123 memset (&orfp, 0, sizeof (struct orf_prefix));
2124 common = *p_pnt++;
Chris Halld64379e2010-05-14 16:38:39 +04002125 /* after ++: p_pnt <= p_end */
paul718e3742002-12-13 20:15:29 +00002126 if (common & ORF_COMMON_PART_REMOVE_ALL)
2127 {
2128 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002129 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
David Lamparterc9c06d02015-04-13 10:21:35 +02002130 prefix_bgp_orf_remove_all (afi, name);
paul718e3742002-12-13 20:15:29 +00002131 break;
2132 }
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002133 ok = ((size_t)(p_end - p_pnt) >= sizeof(u_int32_t)) ;
Denis Ovsienkobb915f52011-12-13 21:11:39 +04002134 if (ok)
Chris Halld64379e2010-05-14 16:38:39 +04002135 {
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002136 memcpy (&seq, p_pnt, sizeof (u_int32_t));
2137 p_pnt += sizeof (u_int32_t);
2138 orfp.seq = ntohl (seq);
Chris Halld64379e2010-05-14 16:38:39 +04002139 }
2140 else
2141 p_pnt = p_end ;
2142
2143 if ((ok = (p_pnt < p_end)))
2144 orfp.ge = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2145 if ((ok = (p_pnt < p_end)))
2146 orfp.le = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2147 if ((ok = (p_pnt < p_end)))
2148 orfp.p.prefixlen = *p_pnt++ ;
2149 orfp.p.family = afi2family (afi); /* afi checked already */
2150
2151 psize = PSIZE (orfp.p.prefixlen); /* 0 if not ok */
2152 if (psize > prefix_blen(&orfp.p)) /* valid for family ? */
2153 {
2154 ok = 0 ;
2155 psize = prefix_blen(&orfp.p) ;
2156 }
2157 if (psize > (p_end - p_pnt)) /* valid for packet ? */
2158 {
2159 ok = 0 ;
2160 psize = p_end - p_pnt ;
2161 }
2162
2163 if (psize > 0)
2164 memcpy (&orfp.p.u.prefix, p_pnt, psize);
paul718e3742002-12-13 20:15:29 +00002165 p_pnt += psize;
2166
2167 if (BGP_DEBUG (normal, NORMAL))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +00002168 {
2169 char buf[INET6_BUFSIZ];
2170
2171 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
2172 peer->host,
2173 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
2174 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
2175 orfp.seq,
2176 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, INET6_BUFSIZ),
2177 orfp.p.prefixlen, orfp.ge, orfp.le,
2178 ok ? "" : " MALFORMED");
2179 }
2180
Chris Halld64379e2010-05-14 16:38:39 +04002181 if (ok)
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002182 ret = prefix_bgp_orf_set (name, afi, &orfp,
2183 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
2184 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002185
2186 if (!ok || (ok && ret != CMD_SUCCESS))
paul718e3742002-12-13 20:15:29 +00002187 {
2188 if (BGP_DEBUG (normal, NORMAL))
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002189 zlog_debug ("%s Received misformatted prefixlist ORF."
2190 " Remove All pfxlist", peer->host);
David Lamparterc9c06d02015-04-13 10:21:35 +02002191 prefix_bgp_orf_remove_all (afi, name);
paul718e3742002-12-13 20:15:29 +00002192 break;
2193 }
2194 }
2195 peer->orf_plist[afi][safi] =
David Lamparterc9c06d02015-04-13 10:21:35 +02002196 prefix_bgp_orf_lookup (afi, name);
paul718e3742002-12-13 20:15:29 +00002197 }
paul9985f832005-02-09 15:51:56 +00002198 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00002199 }
2200 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002201 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00002202 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
2203 if (when_to_refresh == REFRESH_DEFER)
2204 return;
2205 }
2206
2207 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2208 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
2209 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
2210
2211 /* Perform route refreshment to the peer */
2212 bgp_announce_route (peer, afi, safi);
2213}
2214
paul94f2b392005-06-28 12:44:16 +00002215static int
paul718e3742002-12-13 20:15:29 +00002216bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
2217{
2218 u_char *end;
Paul Jakma6d582722007-08-06 15:21:45 +00002219 struct capability_mp_data mpc;
2220 struct capability_header *hdr;
paul718e3742002-12-13 20:15:29 +00002221 u_char action;
paul718e3742002-12-13 20:15:29 +00002222 afi_t afi;
2223 safi_t safi;
2224
paul718e3742002-12-13 20:15:29 +00002225 end = pnt + length;
2226
2227 while (pnt < end)
Paul Jakma6d582722007-08-06 15:21:45 +00002228 {
paul718e3742002-12-13 20:15:29 +00002229 /* We need at least action, capability code and capability length. */
2230 if (pnt + 3 > end)
2231 {
2232 zlog_info ("%s Capability length error", peer->host);
2233 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2234 return -1;
2235 }
paul718e3742002-12-13 20:15:29 +00002236 action = *pnt;
Paul Jakma6d582722007-08-06 15:21:45 +00002237 hdr = (struct capability_header *)(pnt + 1);
2238
paul718e3742002-12-13 20:15:29 +00002239 /* Action value check. */
2240 if (action != CAPABILITY_ACTION_SET
2241 && action != CAPABILITY_ACTION_UNSET)
2242 {
2243 zlog_info ("%s Capability Action Value error %d",
2244 peer->host, action);
2245 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2246 return -1;
2247 }
2248
2249 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002250 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
Paul Jakma6d582722007-08-06 15:21:45 +00002251 peer->host, action, hdr->code, hdr->length);
paul718e3742002-12-13 20:15:29 +00002252
2253 /* Capability length check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002254 if ((pnt + hdr->length + 3) > end)
paul718e3742002-12-13 20:15:29 +00002255 {
2256 zlog_info ("%s Capability length error", peer->host);
2257 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2258 return -1;
2259 }
2260
Paul Jakma6d582722007-08-06 15:21:45 +00002261 /* Fetch structure to the byte stream. */
2262 memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
2263
paul718e3742002-12-13 20:15:29 +00002264 /* We know MP Capability Code. */
Paul Jakma6d582722007-08-06 15:21:45 +00002265 if (hdr->code == CAPABILITY_CODE_MP)
paul718e3742002-12-13 20:15:29 +00002266 {
Paul Jakma6d582722007-08-06 15:21:45 +00002267 afi = ntohs (mpc.afi);
2268 safi = mpc.safi;
paul718e3742002-12-13 20:15:29 +00002269
2270 /* Ignore capability when override-capability is set. */
2271 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2272 continue;
Paul Jakma6d582722007-08-06 15:21:45 +00002273
2274 if (!bgp_afi_safi_valid_indices (afi, &safi))
2275 {
2276 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002277 zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
2278 "(%u/%u)", peer->host, afi, safi);
Paul Jakma6d582722007-08-06 15:21:45 +00002279 continue;
2280 }
2281
paul718e3742002-12-13 20:15:29 +00002282 /* Address family check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002283 if (BGP_DEBUG (normal, NORMAL))
2284 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2285 peer->host,
2286 action == CAPABILITY_ACTION_SET
2287 ? "Advertising" : "Removing",
2288 ntohs(mpc.afi) , mpc.safi);
2289
2290 if (action == CAPABILITY_ACTION_SET)
2291 {
2292 peer->afc_recv[afi][safi] = 1;
2293 if (peer->afc[afi][safi])
2294 {
2295 peer->afc_nego[afi][safi] = 1;
2296 bgp_announce_route (peer, afi, safi);
2297 }
2298 }
2299 else
2300 {
2301 peer->afc_recv[afi][safi] = 0;
2302 peer->afc_nego[afi][safi] = 0;
paul718e3742002-12-13 20:15:29 +00002303
Paul Jakma6d582722007-08-06 15:21:45 +00002304 if (peer_active_nego (peer))
Chris Caputo228da422009-07-18 05:44:03 +00002305 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
Paul Jakma6d582722007-08-06 15:21:45 +00002306 else
2307 BGP_EVENT_ADD (peer, BGP_Stop);
2308 }
paul718e3742002-12-13 20:15:29 +00002309 }
paul718e3742002-12-13 20:15:29 +00002310 else
2311 {
2312 zlog_warn ("%s unrecognized capability code: %d - ignored",
Paul Jakma6d582722007-08-06 15:21:45 +00002313 peer->host, hdr->code);
paul718e3742002-12-13 20:15:29 +00002314 }
Paul Jakma6d582722007-08-06 15:21:45 +00002315 pnt += hdr->length + 3;
paul718e3742002-12-13 20:15:29 +00002316 }
2317 return 0;
2318}
2319
Paul Jakma01b7ce22009-06-18 12:34:43 +01002320/* Dynamic Capability is received.
2321 *
2322 * This is exported for unit-test purposes
2323 */
Paul Jakma6d582722007-08-06 15:21:45 +00002324int
paul718e3742002-12-13 20:15:29 +00002325bgp_capability_receive (struct peer *peer, bgp_size_t size)
2326{
2327 u_char *pnt;
paul718e3742002-12-13 20:15:29 +00002328
2329 /* Fetch pointer. */
2330 pnt = stream_pnt (peer->ibuf);
2331
2332 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002333 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002334
2335 /* If peer does not have the capability, send notification. */
2336 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2337 {
2338 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2339 peer->host);
2340 bgp_notify_send (peer,
2341 BGP_NOTIFY_HEADER_ERR,
2342 BGP_NOTIFY_HEADER_BAD_MESTYPE);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002343 return -1;
paul718e3742002-12-13 20:15:29 +00002344 }
2345
2346 /* Status must be Established. */
2347 if (peer->status != Established)
2348 {
2349 plog_err (peer->log,
2350 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2351 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002352 return -1;
paul718e3742002-12-13 20:15:29 +00002353 }
2354
2355 /* Parse packet. */
Paul Jakma6d582722007-08-06 15:21:45 +00002356 return bgp_capability_msg_parse (peer, pnt, size);
paul718e3742002-12-13 20:15:29 +00002357}
David Lamparter6b0655a2014-06-04 06:53:35 +02002358
paul718e3742002-12-13 20:15:29 +00002359/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002360static int
paul718e3742002-12-13 20:15:29 +00002361bgp_read_packet (struct peer *peer)
2362{
2363 int nbytes;
2364 int readsize;
2365
paul9985f832005-02-09 15:51:56 +00002366 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002367
2368 /* If size is zero then return. */
2369 if (! readsize)
2370 return 0;
2371
2372 /* Read packet from fd. */
Stephen Hemminger35398582010-08-05 10:26:23 -07002373 nbytes = stream_read_try (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002374
2375 /* If read byte is smaller than zero then error occured. */
2376 if (nbytes < 0)
2377 {
Stephen Hemminger35398582010-08-05 10:26:23 -07002378 /* Transient error should retry */
2379 if (nbytes == -2)
paul718e3742002-12-13 20:15:29 +00002380 return -1;
2381
2382 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002383 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002384
2385 if (peer->status == Established)
2386 {
2387 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2388 {
2389 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2390 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2391 }
2392 else
2393 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2394 }
2395
paul718e3742002-12-13 20:15:29 +00002396 BGP_EVENT_ADD (peer, TCP_fatal_error);
2397 return -1;
2398 }
2399
2400 /* When read byte is zero : clear bgp peer and return */
2401 if (nbytes == 0)
2402 {
2403 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002404 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002405 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002406
2407 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002408 {
2409 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2410 {
2411 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2412 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2413 }
2414 else
2415 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2416 }
hassoe0701b72004-05-20 09:19:34 +00002417
paul718e3742002-12-13 20:15:29 +00002418 BGP_EVENT_ADD (peer, TCP_connection_closed);
2419 return -1;
2420 }
2421
2422 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002423 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002424 return -1;
2425
2426 return 0;
2427}
2428
2429/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002430static int
paul718e3742002-12-13 20:15:29 +00002431bgp_marker_all_one (struct stream *s, int length)
2432{
2433 int i;
2434
2435 for (i = 0; i < length; i++)
2436 if (s->data[i] != 0xff)
2437 return 0;
2438
2439 return 1;
2440}
2441
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002442/* Recent thread time.
2443 On same clock base as bgp_clock (MONOTONIC)
2444 but can be time of last context switch to bgp_read thread. */
2445static time_t
2446bgp_recent_clock (void)
2447{
2448 return recent_relative_time().tv_sec;
2449}
2450
paul718e3742002-12-13 20:15:29 +00002451/* Starting point of packet process function. */
2452int
2453bgp_read (struct thread *thread)
2454{
2455 int ret;
2456 u_char type = 0;
2457 struct peer *peer;
2458 bgp_size_t size;
2459 char notify_data_length[2];
2460
2461 /* Yes first of all get peer pointer. */
2462 peer = THREAD_ARG (thread);
2463 peer->t_read = NULL;
2464
2465 /* For non-blocking IO check. */
2466 if (peer->status == Connect)
2467 {
2468 bgp_connect_check (peer);
2469 goto done;
2470 }
2471 else
2472 {
pauleb821182004-05-01 08:44:08 +00002473 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002474 {
pauleb821182004-05-01 08:44:08 +00002475 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002476 return -1;
2477 }
pauleb821182004-05-01 08:44:08 +00002478 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002479 }
2480
2481 /* Read packet header to determine type of the packet */
2482 if (peer->packet_size == 0)
2483 peer->packet_size = BGP_HEADER_SIZE;
2484
paul9985f832005-02-09 15:51:56 +00002485 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002486 {
2487 ret = bgp_read_packet (peer);
2488
2489 /* Header read error or partial read packet. */
2490 if (ret < 0)
2491 goto done;
2492
2493 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002494 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002495 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2496 size = stream_getw (peer->ibuf);
2497 type = stream_getc (peer->ibuf);
2498
2499 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002500 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002501 peer->host, type, size - BGP_HEADER_SIZE);
2502
2503 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002504 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002505 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2506 {
2507 bgp_notify_send (peer,
2508 BGP_NOTIFY_HEADER_ERR,
2509 BGP_NOTIFY_HEADER_NOT_SYNC);
2510 goto done;
2511 }
2512
2513 /* BGP type check. */
2514 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2515 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2516 && type != BGP_MSG_ROUTE_REFRESH_NEW
2517 && type != BGP_MSG_ROUTE_REFRESH_OLD
2518 && type != BGP_MSG_CAPABILITY)
2519 {
2520 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002521 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002522 "%s unknown message type 0x%02x",
2523 peer->host, type);
2524 bgp_notify_send_with_data (peer,
2525 BGP_NOTIFY_HEADER_ERR,
2526 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2527 &type, 1);
2528 goto done;
2529 }
2530 /* Mimimum packet length check. */
2531 if ((size < BGP_HEADER_SIZE)
2532 || (size > BGP_MAX_PACKET_SIZE)
2533 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2534 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2535 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2536 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2537 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2538 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2539 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2540 {
2541 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002542 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002543 "%s bad message length - %d for %s",
2544 peer->host, size,
2545 type == 128 ? "ROUTE-REFRESH" :
2546 bgp_type_str[(int) type]);
2547 bgp_notify_send_with_data (peer,
2548 BGP_NOTIFY_HEADER_ERR,
2549 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002550 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002551 goto done;
2552 }
2553
2554 /* Adjust size to message length. */
2555 peer->packet_size = size;
2556 }
2557
2558 ret = bgp_read_packet (peer);
2559 if (ret < 0)
2560 goto done;
2561
2562 /* Get size and type again. */
2563 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2564 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2565
2566 /* BGP packet dump function. */
2567 bgp_dump_packet (peer, type, peer->ibuf);
2568
2569 size = (peer->packet_size - BGP_HEADER_SIZE);
2570
2571 /* Read rest of the packet and call each sort of packet routine */
2572 switch (type)
2573 {
2574 case BGP_MSG_OPEN:
2575 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002576 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002577 break;
2578 case BGP_MSG_UPDATE:
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002579 peer->readtime = bgp_recent_clock ();
paul718e3742002-12-13 20:15:29 +00002580 bgp_update_receive (peer, size);
2581 break;
2582 case BGP_MSG_NOTIFY:
2583 bgp_notify_receive (peer, size);
2584 break;
2585 case BGP_MSG_KEEPALIVE:
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002586 peer->readtime = bgp_recent_clock ();
paul718e3742002-12-13 20:15:29 +00002587 bgp_keepalive_receive (peer, size);
2588 break;
2589 case BGP_MSG_ROUTE_REFRESH_NEW:
2590 case BGP_MSG_ROUTE_REFRESH_OLD:
2591 peer->refresh_in++;
2592 bgp_route_refresh_receive (peer, size);
2593 break;
2594 case BGP_MSG_CAPABILITY:
2595 peer->dynamic_cap_in++;
2596 bgp_capability_receive (peer, size);
2597 break;
2598 }
2599
2600 /* Clear input buffer. */
2601 peer->packet_size = 0;
2602 if (peer->ibuf)
2603 stream_reset (peer->ibuf);
2604
2605 done:
2606 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2607 {
2608 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002609 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002610 peer_delete (peer);
paul718e3742002-12-13 20:15:29 +00002611 }
2612 return 0;
2613}