blob: 26e4d8ffc962beaa64d2d37a394d630267aa647a [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* BGP packet management routine.
2 Copyright (C) 1999 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include <zebra.h>
22
23#include "thread.h"
24#include "stream.h"
25#include "network.h"
26#include "prefix.h"
27#include "command.h"
28#include "log.h"
29#include "memory.h"
30#include "sockunion.h" /* for inet_ntop () */
Timo Teräsef757702015-04-29 09:43:04 +030031#include "sockopt.h"
paul718e3742002-12-13 20:15:29 +000032#include "linklist.h"
33#include "plist.h"
Donald Sharp04907292016-01-07 10:03:01 -050034#include "filter.h"
paul718e3742002-12-13 20:15:29 +000035
36#include "bgpd/bgpd.h"
37#include "bgpd/bgp_table.h"
38#include "bgpd/bgp_dump.h"
39#include "bgpd/bgp_attr.h"
40#include "bgpd/bgp_debug.h"
41#include "bgpd/bgp_fsm.h"
42#include "bgpd/bgp_route.h"
43#include "bgpd/bgp_packet.h"
44#include "bgpd/bgp_open.h"
45#include "bgpd/bgp_aspath.h"
46#include "bgpd/bgp_community.h"
47#include "bgpd/bgp_ecommunity.h"
48#include "bgpd/bgp_network.h"
49#include "bgpd/bgp_mplsvpn.h"
Lou Berger298cc2f2016-01-12 13:42:02 -050050#include "bgpd/bgp_encap.h"
paul718e3742002-12-13 20:15:29 +000051#include "bgpd/bgp_advertise.h"
hasso93406d82005-02-02 14:40:33 +000052#include "bgpd/bgp_vty.h"
paul718e3742002-12-13 20:15:29 +000053
54int stream_put_prefix (struct stream *, struct prefix *);
David Lamparter6b0655a2014-06-04 06:53:35 +020055
paul718e3742002-12-13 20:15:29 +000056/* Set up BGP packet marker and packet type. */
57static int
58bgp_packet_set_marker (struct stream *s, u_char type)
59{
60 int i;
61
62 /* Fill in marker. */
63 for (i = 0; i < BGP_MARKER_SIZE; i++)
64 stream_putc (s, 0xff);
65
66 /* Dummy total length. This field is should be filled in later on. */
67 stream_putw (s, 0);
68
69 /* BGP packet type. */
70 stream_putc (s, type);
71
72 /* Return current stream size. */
paul9985f832005-02-09 15:51:56 +000073 return stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +000074}
75
76/* Set BGP packet header size entry. If size is zero then use current
77 stream size. */
78static int
79bgp_packet_set_size (struct stream *s)
80{
81 int cp;
82
83 /* Preserve current pointer. */
paul9985f832005-02-09 15:51:56 +000084 cp = stream_get_endp (s);
85 stream_putw_at (s, BGP_MARKER_SIZE, cp);
paul718e3742002-12-13 20:15:29 +000086
87 return cp;
88}
89
90/* Add new packet to the peer. */
paul94f2b392005-06-28 12:44:16 +000091static void
paul718e3742002-12-13 20:15:29 +000092bgp_packet_add (struct peer *peer, struct stream *s)
93{
94 /* Add packet to the end of list. */
95 stream_fifo_push (peer->obuf, s);
96}
97
98/* Free first packet. */
paul94f2b392005-06-28 12:44:16 +000099static void
paul718e3742002-12-13 20:15:29 +0000100bgp_packet_delete (struct peer *peer)
101{
102 stream_free (stream_fifo_pop (peer->obuf));
103}
104
paul718e3742002-12-13 20:15:29 +0000105/* Check file descriptor whether connect is established. */
106static void
107bgp_connect_check (struct peer *peer)
108{
109 int status;
paul5228ad22004-06-04 17:58:18 +0000110 socklen_t slen;
paul718e3742002-12-13 20:15:29 +0000111 int ret;
112
113 /* Anyway I have to reset read and write thread. */
114 BGP_READ_OFF (peer->t_read);
115 BGP_WRITE_OFF (peer->t_write);
116
117 /* Check file descriptor. */
118 slen = sizeof (status);
pauleb821182004-05-01 08:44:08 +0000119 ret = getsockopt(peer->fd, SOL_SOCKET, SO_ERROR, (void *) &status, &slen);
paul718e3742002-12-13 20:15:29 +0000120
121 /* If getsockopt is fail, this is fatal error. */
122 if (ret < 0)
123 {
124 zlog (peer->log, LOG_INFO, "can't get sockopt for nonblocking connect");
125 BGP_EVENT_ADD (peer, TCP_fatal_error);
126 return;
127 }
128
129 /* When status is 0 then TCP connection is established. */
130 if (status == 0)
131 {
132 BGP_EVENT_ADD (peer, TCP_connection_open);
133 }
134 else
135 {
136 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +0000137 plog_debug (peer->log, "%s [Event] Connect failed (%s)",
ajs6099b3b2004-11-20 02:06:59 +0000138 peer->host, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000139 BGP_EVENT_ADD (peer, TCP_connection_open_failed);
140 }
141}
142
143/* Make BGP update packet. */
paul94f2b392005-06-28 12:44:16 +0000144static struct stream *
paul718e3742002-12-13 20:15:29 +0000145bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi)
146{
147 struct stream *s;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000148 struct stream *snlri;
paul718e3742002-12-13 20:15:29 +0000149 struct bgp_adj_out *adj;
150 struct bgp_advertise *adv;
151 struct stream *packet;
152 struct bgp_node *rn = NULL;
153 struct bgp_info *binfo = NULL;
154 bgp_size_t total_attr_len = 0;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000155 unsigned long attrlen_pos = 0;
156 size_t mpattrlen_pos = 0;
157 size_t mpattr_pos = 0;
paul718e3742002-12-13 20:15:29 +0000158
159 s = peer->work;
160 stream_reset (s);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000161 snlri = peer->scratch;
162 stream_reset (snlri);
paul718e3742002-12-13 20:15:29 +0000163
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100164 adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update);
paul718e3742002-12-13 20:15:29 +0000165
166 while (adv)
167 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000168 assert (adv->rn);
169 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000170 adj = adv->adj;
171 if (adv->binfo)
172 binfo = adv->binfo;
paul718e3742002-12-13 20:15:29 +0000173
174 /* When remaining space can't include NLRI and it's length. */
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000175 if (STREAM_CONCAT_REMAIN (s, snlri, STREAM_SIZE(s)) <=
Lou Berger050defe2016-01-12 13:41:59 -0500176 (BGP_NLRI_LENGTH + bgp_packet_mpattr_prefix_size(afi,safi,&rn->p)))
paul718e3742002-12-13 20:15:29 +0000177 break;
178
179 /* If packet is empty, set attribute. */
180 if (stream_empty (s))
181 {
Lou Berger050defe2016-01-12 13:41:59 -0500182 struct prefix_rd *prd = NULL;
183 u_char *tag = NULL;
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000184 struct peer *from = NULL;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000185
Lou Berger050defe2016-01-12 13:41:59 -0500186 if (rn->prn)
187 prd = (struct prefix_rd *) &rn->prn->p;
Greg Troxeld3ddb222010-09-17 10:47:49 -0400188 if (binfo)
Lou Berger050defe2016-01-12 13:41:59 -0500189 {
190 from = binfo->peer;
191 if (binfo->extra)
192 tag = binfo->extra->tag;
193 }
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000194
195 /* 1: Write the BGP message header - 16 bytes marker, 2 bytes length,
196 * one byte message type.
197 */
paul718e3742002-12-13 20:15:29 +0000198 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000199
200 /* 2: withdrawn routes length */
paul718e3742002-12-13 20:15:29 +0000201 stream_putw (s, 0);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000202
203 /* 3: total attributes length - attrlen_pos stores the position */
204 attrlen_pos = stream_get_endp (s);
205 stream_putw (s, 0);
206
207 /* 4: if there is MP_REACH_NLRI attribute, that should be the first
208 * attribute, according to draft-ietf-idr-error-handling. Save the
209 * position.
210 */
211 mpattr_pos = stream_get_endp(s);
212
213 /* 5: Encode all the attributes, except MP_REACH_NLRI attr. */
214 total_attr_len = bgp_packet_attribute (NULL, peer, s,
paul5228ad22004-06-04 17:58:18 +0000215 adv->baa->attr,
Lou Berger298cc2f2016-01-12 13:42:02 -0500216 ((afi == AFI_IP && safi == SAFI_UNICAST) ?
217 &rn->p : NULL),
218 afi, safi,
Lou Berger050defe2016-01-12 13:41:59 -0500219 from, prd, tag);
paul718e3742002-12-13 20:15:29 +0000220 }
221
222 if (afi == AFI_IP && safi == SAFI_UNICAST)
223 stream_put_prefix (s, &rn->p);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000224 else
225 {
226 /* Encode the prefix in MP_REACH_NLRI attribute */
227 struct prefix_rd *prd = NULL;
228 u_char *tag = NULL;
229
230 if (rn->prn)
231 prd = (struct prefix_rd *) &rn->prn->p;
232 if (binfo && binfo->extra)
233 tag = binfo->extra->tag;
234
235 if (stream_empty(snlri))
236 mpattrlen_pos = bgp_packet_mpattr_start(snlri, afi, safi,
237 adv->baa->attr);
238 bgp_packet_mpattr_prefix(snlri, afi, safi, &rn->p, prd, tag);
239 }
paul718e3742002-12-13 20:15:29 +0000240 if (BGP_DEBUG (update, UPDATE_OUT))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000241 {
242 char buf[INET6_BUFSIZ];
243
244 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d",
245 peer->host,
246 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, INET6_BUFSIZ),
247 rn->p.prefixlen);
248 }
paul718e3742002-12-13 20:15:29 +0000249
250 /* Synchnorize attribute. */
251 if (adj->attr)
Paul Jakmaf6f434b2010-11-23 21:28:03 +0000252 bgp_attr_unintern (&adj->attr);
paul718e3742002-12-13 20:15:29 +0000253 else
254 peer->scount[afi][safi]++;
255
256 adj->attr = bgp_attr_intern (adv->baa->attr);
257
258 adv = bgp_advertise_clean (peer, adj, afi, safi);
paul718e3742002-12-13 20:15:29 +0000259 }
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000260
paul718e3742002-12-13 20:15:29 +0000261 if (! stream_empty (s))
262 {
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000263 if (!stream_empty(snlri))
264 {
265 bgp_packet_mpattr_end(snlri, mpattrlen_pos);
266 total_attr_len += stream_get_endp(snlri);
267 }
268
269 /* set the total attribute length correctly */
270 stream_putw_at (s, attrlen_pos, total_attr_len);
271
272 if (!stream_empty(snlri))
273 packet = stream_dupcat(s, snlri, mpattr_pos);
274 else
275 packet = stream_dup (s);
276 bgp_packet_set_size (packet);
paul718e3742002-12-13 20:15:29 +0000277 bgp_packet_add (peer, packet);
pauleb821182004-05-01 08:44:08 +0000278 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000279 stream_reset (s);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000280 stream_reset (snlri);
paul718e3742002-12-13 20:15:29 +0000281 return packet;
282 }
283 return NULL;
hasso93406d82005-02-02 14:40:33 +0000284}
paul718e3742002-12-13 20:15:29 +0000285
paul94f2b392005-06-28 12:44:16 +0000286static struct stream *
hasso93406d82005-02-02 14:40:33 +0000287bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
288{
289 struct stream *s;
hasso93406d82005-02-02 14:40:33 +0000290
Paul Jakma750e8142008-07-22 21:11:48 +0000291 if (DISABLE_BGP_ANNOUNCE)
292 return NULL;
hasso93406d82005-02-02 14:40:33 +0000293
294 if (BGP_DEBUG (normal, NORMAL))
295 zlog_debug ("send End-of-RIB for %s to %s", afi_safi_print (afi, safi), peer->host);
296
297 s = stream_new (BGP_MAX_PACKET_SIZE);
298
299 /* Make BGP update packet. */
300 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
301
302 /* Unfeasible Routes Length */
303 stream_putw (s, 0);
304
305 if (afi == AFI_IP && safi == SAFI_UNICAST)
306 {
307 /* Total Path Attribute Length */
308 stream_putw (s, 0);
309 }
310 else
311 {
312 /* Total Path Attribute Length */
313 stream_putw (s, 6);
314 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
315 stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
316 stream_putc (s, 3);
317 stream_putw (s, afi);
318 stream_putc (s, safi);
319 }
320
321 bgp_packet_set_size (s);
Donald Sharpa752c3b2015-08-18 08:48:53 -0400322 bgp_packet_add (peer, s);
323 return s;
paul718e3742002-12-13 20:15:29 +0000324}
325
326/* Make BGP withdraw packet. */
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000327/* For ipv4 unicast:
328 16-octet marker | 2-octet length | 1-octet type |
329 2-octet withdrawn route length | withdrawn prefixes | 2-octet attrlen (=0)
330*/
331/* For other afi/safis:
332 16-octet marker | 2-octet length | 1-octet type |
333 2-octet withdrawn route length (=0) | 2-octet attrlen |
334 mp_unreach attr type | attr len | afi | safi | withdrawn prefixes
335*/
paul94f2b392005-06-28 12:44:16 +0000336static struct stream *
paul718e3742002-12-13 20:15:29 +0000337bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi)
338{
339 struct stream *s;
340 struct stream *packet;
341 struct bgp_adj_out *adj;
342 struct bgp_advertise *adv;
343 struct bgp_node *rn;
paul718e3742002-12-13 20:15:29 +0000344 bgp_size_t unfeasible_len;
345 bgp_size_t total_attr_len;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000346 size_t mp_start = 0;
347 size_t attrlen_pos = 0;
348 size_t mplen_pos = 0;
349 u_char first_time = 1;
paul718e3742002-12-13 20:15:29 +0000350
351 s = peer->work;
352 stream_reset (s);
353
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100354 while ((adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL)
paul718e3742002-12-13 20:15:29 +0000355 {
Paul Jakmaed3ebfa2006-10-15 23:50:16 +0000356 assert (adv->rn);
paul718e3742002-12-13 20:15:29 +0000357 adj = adv->adj;
358 rn = adv->rn;
paul718e3742002-12-13 20:15:29 +0000359
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000360 if (STREAM_REMAIN (s)
hasso4372df72004-05-20 10:20:02 +0000361 < (BGP_NLRI_LENGTH + BGP_TOTAL_ATTR_LEN + PSIZE (rn->p.prefixlen)))
paul718e3742002-12-13 20:15:29 +0000362 break;
363
364 if (stream_empty (s))
365 {
366 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000367 stream_putw (s, 0); /* unfeasible routes length */
paul718e3742002-12-13 20:15:29 +0000368 }
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000369 else
370 first_time = 0;
paul718e3742002-12-13 20:15:29 +0000371
372 if (afi == AFI_IP && safi == SAFI_UNICAST)
373 stream_put_prefix (s, &rn->p);
374 else
375 {
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000376 struct prefix_rd *prd = NULL;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000377
Paul Jakmaa3b6ea52006-05-04 07:52:12 +0000378 if (rn->prn)
379 prd = (struct prefix_rd *) &rn->prn->p;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000380
381 /* If first time, format the MP_UNREACH header */
382 if (first_time)
383 {
384 attrlen_pos = stream_get_endp (s);
385 /* total attr length = 0 for now. reevaluate later */
386 stream_putw (s, 0);
387 mp_start = stream_get_endp (s);
388 mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
389 }
390
391 bgp_packet_mpunreach_prefix(s, &rn->p, afi, safi, prd, NULL);
paul718e3742002-12-13 20:15:29 +0000392 }
393
394 if (BGP_DEBUG (update, UPDATE_OUT))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000395 {
396 char buf[INET6_BUFSIZ];
397
398 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
399 peer->host,
400 inet_ntop (rn->p.family, &(rn->p.u.prefix), buf, INET6_BUFSIZ),
401 rn->p.prefixlen);
402 }
paul718e3742002-12-13 20:15:29 +0000403
404 peer->scount[afi][safi]--;
405
406 bgp_adj_out_remove (rn, adj, peer, afi, safi);
407 bgp_unlock_node (rn);
paul718e3742002-12-13 20:15:29 +0000408 }
409
410 if (! stream_empty (s))
411 {
412 if (afi == AFI_IP && safi == SAFI_UNICAST)
413 {
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000414 unfeasible_len
paul9985f832005-02-09 15:51:56 +0000415 = stream_get_endp (s) - BGP_HEADER_SIZE - BGP_UNFEASIBLE_LEN;
paul718e3742002-12-13 20:15:29 +0000416 stream_putw_at (s, BGP_HEADER_SIZE, unfeasible_len);
417 stream_putw (s, 0);
418 }
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000419 else
420 {
421 /* Set the mp_unreach attr's length */
422 bgp_packet_mpunreach_end(s, mplen_pos);
423
424 /* Set total path attribute length. */
425 total_attr_len = stream_get_endp(s) - mp_start;
426 stream_putw_at (s, attrlen_pos, total_attr_len);
427 }
paul718e3742002-12-13 20:15:29 +0000428 bgp_packet_set_size (s);
paule83e2082005-05-19 02:12:25 +0000429 packet = stream_dup (s);
paul718e3742002-12-13 20:15:29 +0000430 bgp_packet_add (peer, packet);
431 stream_reset (s);
432 return packet;
433 }
434
435 return NULL;
436}
437
438void
439bgp_default_update_send (struct peer *peer, struct attr *attr,
440 afi_t afi, safi_t safi, struct peer *from)
441{
442 struct stream *s;
paul718e3742002-12-13 20:15:29 +0000443 struct prefix p;
444 unsigned long pos;
445 bgp_size_t total_attr_len;
paul718e3742002-12-13 20:15:29 +0000446
Paul Jakma750e8142008-07-22 21:11:48 +0000447 if (DISABLE_BGP_ANNOUNCE)
448 return;
paul718e3742002-12-13 20:15:29 +0000449
450 if (afi == AFI_IP)
451 str2prefix ("0.0.0.0/0", &p);
paul718e3742002-12-13 20:15:29 +0000452 else
453 str2prefix ("::/0", &p);
paul718e3742002-12-13 20:15:29 +0000454
455 /* Logging the attribute. */
456 if (BGP_DEBUG (update, UPDATE_OUT))
457 {
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000458 char attrstr[BUFSIZ];
459 char buf[INET6_BUFSIZ];
460 attrstr[0] = '\0';
461
paul718e3742002-12-13 20:15:29 +0000462 bgp_dump_attr (peer, attr, attrstr, BUFSIZ);
ajs6b514742004-12-08 21:03:23 +0000463 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d %s",
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000464 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, INET6_BUFSIZ),
paul718e3742002-12-13 20:15:29 +0000465 p.prefixlen, attrstr);
466 }
467
468 s = stream_new (BGP_MAX_PACKET_SIZE);
469
470 /* Make BGP update packet. */
471 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
472
473 /* Unfeasible Routes Length. */
474 stream_putw (s, 0);
475
476 /* Make place for total attribute length. */
paul9985f832005-02-09 15:51:56 +0000477 pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000478 stream_putw (s, 0);
479 total_attr_len = bgp_packet_attribute (NULL, peer, s, attr, &p, afi, safi, from, NULL, NULL);
480
481 /* Set Total Path Attribute Length. */
482 stream_putw_at (s, pos, total_attr_len);
483
484 /* NLRI set. */
485 if (p.family == AF_INET && safi == SAFI_UNICAST)
486 stream_put_prefix (s, &p);
487
488 /* Set size. */
489 bgp_packet_set_size (s);
490
paul718e3742002-12-13 20:15:29 +0000491 /* Dump packet if debug option is set. */
492#ifdef DEBUG
jardin2d74db52005-10-01 00:07:50 +0000493 /* bgp_packet_dump (packet); */
paul718e3742002-12-13 20:15:29 +0000494#endif /* DEBUG */
495
496 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -0400497 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +0000498
pauleb821182004-05-01 08:44:08 +0000499 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000500}
501
502void
503bgp_default_withdraw_send (struct peer *peer, afi_t afi, safi_t safi)
504{
505 struct stream *s;
paul718e3742002-12-13 20:15:29 +0000506 struct prefix p;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000507 unsigned long attrlen_pos = 0;
paul718e3742002-12-13 20:15:29 +0000508 unsigned long cp;
509 bgp_size_t unfeasible_len;
510 bgp_size_t total_attr_len;
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000511 size_t mp_start = 0;
512 size_t mplen_pos = 0;
paul718e3742002-12-13 20:15:29 +0000513
Paul Jakma750e8142008-07-22 21:11:48 +0000514 if (DISABLE_BGP_ANNOUNCE)
515 return;
paul718e3742002-12-13 20:15:29 +0000516
517 if (afi == AFI_IP)
518 str2prefix ("0.0.0.0/0", &p);
paul718e3742002-12-13 20:15:29 +0000519 else
520 str2prefix ("::/0", &p);
paul718e3742002-12-13 20:15:29 +0000521
522 total_attr_len = 0;
paul718e3742002-12-13 20:15:29 +0000523
524 if (BGP_DEBUG (update, UPDATE_OUT))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +0000525 {
526 char buf[INET6_BUFSIZ];
527
528 zlog (peer->log, LOG_DEBUG, "%s send UPDATE %s/%d -- unreachable",
529 peer->host, inet_ntop(p.family, &(p.u.prefix), buf, INET6_BUFSIZ),
530 p.prefixlen);
531 }
paul718e3742002-12-13 20:15:29 +0000532
533 s = stream_new (BGP_MAX_PACKET_SIZE);
534
535 /* Make BGP update packet. */
536 bgp_packet_set_marker (s, BGP_MSG_UPDATE);
537
538 /* Unfeasible Routes Length. */;
paul9985f832005-02-09 15:51:56 +0000539 cp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000540 stream_putw (s, 0);
541
542 /* Withdrawn Routes. */
543 if (p.family == AF_INET && safi == SAFI_UNICAST)
544 {
545 stream_put_prefix (s, &p);
546
paul9985f832005-02-09 15:51:56 +0000547 unfeasible_len = stream_get_endp (s) - cp - 2;
paul718e3742002-12-13 20:15:29 +0000548
549 /* Set unfeasible len. */
550 stream_putw_at (s, cp, unfeasible_len);
551
552 /* Set total path attribute length. */
553 stream_putw (s, 0);
554 }
555 else
556 {
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000557 attrlen_pos = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000558 stream_putw (s, 0);
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000559 mp_start = stream_get_endp (s);
560 mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
561 bgp_packet_mpunreach_prefix(s, &p, afi, safi, NULL, NULL);
562
563 /* Set the mp_unreach attr's length */
564 bgp_packet_mpunreach_end(s, mplen_pos);
paul718e3742002-12-13 20:15:29 +0000565
566 /* Set total path attribute length. */
Pradosh Mohapatra8c71e482014-01-15 06:57:57 +0000567 total_attr_len = stream_get_endp(s) - mp_start;
568 stream_putw_at (s, attrlen_pos, total_attr_len);
paul718e3742002-12-13 20:15:29 +0000569 }
570
571 bgp_packet_set_size (s);
572
paul718e3742002-12-13 20:15:29 +0000573 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -0400574 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +0000575
pauleb821182004-05-01 08:44:08 +0000576 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000577}
578
579/* Get next packet to be written. */
paul94f2b392005-06-28 12:44:16 +0000580static struct stream *
paul718e3742002-12-13 20:15:29 +0000581bgp_write_packet (struct peer *peer)
582{
583 afi_t afi;
584 safi_t safi;
585 struct stream *s = NULL;
586 struct bgp_advertise *adv;
587
588 s = stream_fifo_head (peer->obuf);
589 if (s)
590 return s;
591
592 for (afi = AFI_IP; afi < AFI_MAX; afi++)
593 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
594 {
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100595 adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->withdraw);
paul718e3742002-12-13 20:15:29 +0000596 if (adv)
597 {
598 s = bgp_withdraw_packet (peer, afi, safi);
599 if (s)
600 return s;
601 }
602 }
603
604 for (afi = AFI_IP; afi < AFI_MAX; afi++)
605 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
606 {
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100607 adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update);
paul718e3742002-12-13 20:15:29 +0000608 if (adv)
609 {
610 if (adv->binfo && adv->binfo->uptime < peer->synctime)
hasso93406d82005-02-02 14:40:33 +0000611 {
612 if (CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_RCV)
613 && CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_ADV)
Vipin Kumardd49eb12014-09-30 14:36:38 -0700614 && ! (CHECK_FLAG (adv->binfo->peer->cap,
615 PEER_CAP_RESTART_BIT_RCV) &&
616 CHECK_FLAG (adv->binfo->peer->cap,
617 PEER_CAP_RESTART_BIT_ADV))
hasso93406d82005-02-02 14:40:33 +0000618 && ! CHECK_FLAG (adv->binfo->flags, BGP_INFO_STALE)
619 && safi != SAFI_MPLS_VPN)
620 {
621 if (CHECK_FLAG (adv->binfo->peer->af_sflags[afi][safi],
622 PEER_STATUS_EOR_RECEIVED))
623 s = bgp_update_packet (peer, afi, safi);
624 }
625 else
626 s = bgp_update_packet (peer, afi, safi);
627 }
paul718e3742002-12-13 20:15:29 +0000628
629 if (s)
630 return s;
631 }
hasso93406d82005-02-02 14:40:33 +0000632
633 if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV))
634 {
635 if (peer->afc_nego[afi][safi] && peer->synctime
636 && ! CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND)
637 && safi != SAFI_MPLS_VPN)
638 {
639 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND);
640 return bgp_update_packet_eor (peer, afi, safi);
641 }
642 }
paul718e3742002-12-13 20:15:29 +0000643 }
644
645 return NULL;
646}
647
648/* Is there partially written packet or updates we can send right
649 now. */
paul94f2b392005-06-28 12:44:16 +0000650static int
paul718e3742002-12-13 20:15:29 +0000651bgp_write_proceed (struct peer *peer)
652{
653 afi_t afi;
654 safi_t safi;
655 struct bgp_advertise *adv;
656
657 if (stream_fifo_head (peer->obuf))
658 return 1;
659
660 for (afi = AFI_IP; afi < AFI_MAX; afi++)
661 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
662 if (FIFO_HEAD (&peer->sync[afi][safi]->withdraw))
663 return 1;
664
665 for (afi = AFI_IP; afi < AFI_MAX; afi++)
666 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
Paul Jakma7aa9dce2014-09-19 14:42:23 +0100667 if ((adv = BGP_ADV_FIFO_HEAD (&peer->sync[afi][safi]->update)) != NULL)
paul718e3742002-12-13 20:15:29 +0000668 if (adv->binfo->uptime < peer->synctime)
669 return 1;
670
671 return 0;
672}
673
674/* Write packet to the peer. */
675int
676bgp_write (struct thread *thread)
677{
678 struct peer *peer;
679 u_char type;
680 struct stream *s;
681 int num;
paulfd79ac92004-10-13 05:06:08 +0000682 unsigned int count = 0;
paul718e3742002-12-13 20:15:29 +0000683
684 /* Yes first of all get peer pointer. */
685 peer = THREAD_ARG (thread);
686 peer->t_write = NULL;
687
688 /* For non-blocking IO check. */
689 if (peer->status == Connect)
690 {
691 bgp_connect_check (peer);
692 return 0;
693 }
694
Stephen Hemmingereac57022010-08-05 10:26:25 -0700695 s = bgp_write_packet (peer);
696 if (!s)
697 return 0; /* nothing to send */
698
699 sockopt_cork (peer->fd, 1);
700
701 /* Nonblocking write until TCP output buffer is full. */
702 do
paul718e3742002-12-13 20:15:29 +0000703 {
704 int writenum;
paul718e3742002-12-13 20:15:29 +0000705
706 /* Number of bytes to be sent. */
707 writenum = stream_get_endp (s) - stream_get_getp (s);
708
709 /* Call write() system call. */
pauleb821182004-05-01 08:44:08 +0000710 num = write (peer->fd, STREAM_PNT (s), writenum);
Stephen Hemminger35398582010-08-05 10:26:23 -0700711 if (num < 0)
paul718e3742002-12-13 20:15:29 +0000712 {
Stephen Hemmingereac57022010-08-05 10:26:25 -0700713 /* write failed either retry needed or error */
714 if (ERRNO_IO_RETRY(errno))
715 break;
716
717 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000718 return 0;
719 }
Stephen Hemminger35398582010-08-05 10:26:23 -0700720
paul718e3742002-12-13 20:15:29 +0000721 if (num != writenum)
722 {
Stephen Hemminger35398582010-08-05 10:26:23 -0700723 /* Partial write */
paul9985f832005-02-09 15:51:56 +0000724 stream_forward_getp (s, num);
Stephen Hemmingereac57022010-08-05 10:26:25 -0700725 break;
paul718e3742002-12-13 20:15:29 +0000726 }
727
728 /* Retrieve BGP packet type. */
729 stream_set_getp (s, BGP_MARKER_SIZE + 2);
730 type = stream_getc (s);
731
732 switch (type)
733 {
734 case BGP_MSG_OPEN:
735 peer->open_out++;
736 break;
737 case BGP_MSG_UPDATE:
738 peer->update_out++;
739 break;
740 case BGP_MSG_NOTIFY:
741 peer->notify_out++;
742 /* Double start timer. */
743 peer->v_start *= 2;
744
745 /* Overflow check. */
746 if (peer->v_start >= (60 * 2))
747 peer->v_start = (60 * 2);
748
Paul Jakmaca058a32006-09-14 02:58:49 +0000749 /* Flush any existing events */
Paul Jakmadcdf3992006-10-15 23:39:59 +0000750 BGP_EVENT_ADD (peer, BGP_Stop);
Stephen Hemminger3a69f742013-01-11 18:27:23 +0000751 goto done;
752
paul718e3742002-12-13 20:15:29 +0000753 case BGP_MSG_KEEPALIVE:
754 peer->keepalive_out++;
755 break;
756 case BGP_MSG_ROUTE_REFRESH_NEW:
757 case BGP_MSG_ROUTE_REFRESH_OLD:
758 peer->refresh_out++;
759 break;
760 case BGP_MSG_CAPABILITY:
761 peer->dynamic_cap_out++;
762 break;
763 }
764
765 /* OK we send packet so delete it. */
766 bgp_packet_delete (peer);
paul718e3742002-12-13 20:15:29 +0000767 }
Stephen Hemmingereac57022010-08-05 10:26:25 -0700768 while (++count < BGP_WRITE_PACKET_MAX &&
769 (s = bgp_write_packet (peer)) != NULL);
paul718e3742002-12-13 20:15:29 +0000770
771 if (bgp_write_proceed (peer))
pauleb821182004-05-01 08:44:08 +0000772 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
Stephen Hemminger3a69f742013-01-11 18:27:23 +0000773
774 done:
775 sockopt_cork (peer->fd, 0);
paul718e3742002-12-13 20:15:29 +0000776 return 0;
777}
778
779/* This is only for sending NOTIFICATION message to neighbor. */
paul94f2b392005-06-28 12:44:16 +0000780static int
paul718e3742002-12-13 20:15:29 +0000781bgp_write_notify (struct peer *peer)
782{
Stephen Hemminger35398582010-08-05 10:26:23 -0700783 int ret, val;
paul718e3742002-12-13 20:15:29 +0000784 u_char type;
785 struct stream *s;
786
787 /* There should be at least one packet. */
788 s = stream_fifo_head (peer->obuf);
789 if (!s)
790 return 0;
791 assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
792
Leonid Rosenboim86998bc2012-12-14 19:12:17 +0000793 /* Stop collecting data within the socket */
794 sockopt_cork (peer->fd, 0);
795
David Lamparter8ff202e2013-07-31 14:39:41 +0200796 /* socket is in nonblocking mode, if we can't deliver the NOTIFY, well,
797 * we only care about getting a clean shutdown at this point. */
Leonid Rosenboim86998bc2012-12-14 19:12:17 +0000798 ret = write (peer->fd, STREAM_DATA (s), stream_get_endp (s));
David Lamparter8ff202e2013-07-31 14:39:41 +0200799
800 /* only connection reset/close gets counted as TCP_fatal_error, failure
801 * to write the entire NOTIFY doesn't get different FSM treatment */
paul718e3742002-12-13 20:15:29 +0000802 if (ret <= 0)
803 {
Paul Jakmadcdf3992006-10-15 23:39:59 +0000804 BGP_EVENT_ADD (peer, TCP_fatal_error);
paul718e3742002-12-13 20:15:29 +0000805 return 0;
806 }
807
Leonid Rosenboim86998bc2012-12-14 19:12:17 +0000808 /* Disable Nagle, make NOTIFY packet go out right away */
809 val = 1;
810 (void) setsockopt (peer->fd, IPPROTO_TCP, TCP_NODELAY,
811 (char *) &val, sizeof (val));
812
paul718e3742002-12-13 20:15:29 +0000813 /* Retrieve BGP packet type. */
814 stream_set_getp (s, BGP_MARKER_SIZE + 2);
815 type = stream_getc (s);
816
817 assert (type == BGP_MSG_NOTIFY);
818
819 /* Type should be notify. */
820 peer->notify_out++;
821
822 /* Double start timer. */
823 peer->v_start *= 2;
824
825 /* Overflow check. */
826 if (peer->v_start >= (60 * 2))
827 peer->v_start = (60 * 2);
828
Paul Jakmadcdf3992006-10-15 23:39:59 +0000829 BGP_EVENT_ADD (peer, BGP_Stop);
paul718e3742002-12-13 20:15:29 +0000830
831 return 0;
832}
833
834/* Make keepalive packet and send it to the peer. */
835void
836bgp_keepalive_send (struct peer *peer)
837{
838 struct stream *s;
839 int length;
840
841 s = stream_new (BGP_MAX_PACKET_SIZE);
842
843 /* Make keepalive packet. */
844 bgp_packet_set_marker (s, BGP_MSG_KEEPALIVE);
845
846 /* Set packet size. */
847 length = bgp_packet_set_size (s);
848
849 /* Dump packet if debug option is set. */
850 /* bgp_packet_dump (s); */
851
852 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +0000853 zlog_debug ("%s sending KEEPALIVE", peer->host);
paul718e3742002-12-13 20:15:29 +0000854 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000855 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000856 peer->host, BGP_MSG_KEEPALIVE, length);
857
858 /* Add packet to the peer. */
859 bgp_packet_add (peer, s);
860
pauleb821182004-05-01 08:44:08 +0000861 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000862}
863
864/* Make open packet and send it to the peer. */
865void
866bgp_open_send (struct peer *peer)
867{
868 struct stream *s;
869 int length;
870 u_int16_t send_holdtime;
871 as_t local_as;
872
873 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
874 send_holdtime = peer->holdtime;
875 else
876 send_holdtime = peer->bgp->default_holdtime;
877
878 /* local-as Change */
879 if (peer->change_local_as)
880 local_as = peer->change_local_as;
881 else
882 local_as = peer->local_as;
883
884 s = stream_new (BGP_MAX_PACKET_SIZE);
885
886 /* Make open packet. */
887 bgp_packet_set_marker (s, BGP_MSG_OPEN);
888
889 /* Set open packet values. */
890 stream_putc (s, BGP_VERSION_4); /* BGP version */
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000891 stream_putw (s, (local_as <= BGP_AS_MAX) ? (u_int16_t) local_as
892 : BGP_AS_TRANS);
paul718e3742002-12-13 20:15:29 +0000893 stream_putw (s, send_holdtime); /* Hold Time */
894 stream_put_in_addr (s, &peer->local_id); /* BGP Identifier */
895
896 /* Set capability code. */
897 bgp_open_capability (s, peer);
898
899 /* Set BGP packet length. */
900 length = bgp_packet_set_size (s);
901
902 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +0400903 zlog_debug ("%s sending OPEN, version %d, my as %u, holdtime %d, id %s",
paul718e3742002-12-13 20:15:29 +0000904 peer->host, BGP_VERSION_4, local_as,
905 send_holdtime, inet_ntoa (peer->local_id));
906
907 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000908 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000909 peer->host, BGP_MSG_OPEN, length);
910
911 /* Dump packet if debug option is set. */
912 /* bgp_packet_dump (s); */
913
914 /* Add packet to the peer. */
915 bgp_packet_add (peer, s);
916
pauleb821182004-05-01 08:44:08 +0000917 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +0000918}
919
920/* Send BGP notify packet with data potion. */
921void
922bgp_notify_send_with_data (struct peer *peer, u_char code, u_char sub_code,
923 u_char *data, size_t datalen)
924{
925 struct stream *s;
926 int length;
927
928 /* Allocate new stream. */
929 s = stream_new (BGP_MAX_PACKET_SIZE);
930
931 /* Make nitify packet. */
932 bgp_packet_set_marker (s, BGP_MSG_NOTIFY);
933
934 /* Set notify packet values. */
935 stream_putc (s, code); /* BGP notify code */
936 stream_putc (s, sub_code); /* BGP notify sub_code */
937
938 /* If notify data is present. */
939 if (data)
940 stream_write (s, data, datalen);
941
942 /* Set BGP packet length. */
943 length = bgp_packet_set_size (s);
944
945 /* Add packet to the peer. */
946 stream_fifo_clean (peer->obuf);
947 bgp_packet_add (peer, s);
948
949 /* For debug */
950 {
951 struct bgp_notify bgp_notify;
952 int first = 0;
953 int i;
954 char c[4];
955
956 bgp_notify.code = code;
957 bgp_notify.subcode = sub_code;
958 bgp_notify.data = NULL;
959 bgp_notify.length = length - BGP_MSG_NOTIFY_MIN_SIZE;
960
961 if (bgp_notify.length)
962 {
963 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
964 for (i = 0; i < bgp_notify.length; i++)
965 if (first)
966 {
967 sprintf (c, " %02x", data[i]);
968 strcat (bgp_notify.data, c);
969 }
970 else
971 {
972 first = 1;
973 sprintf (c, "%02x", data[i]);
974 strcpy (bgp_notify.data, c);
975 }
976 }
977 bgp_notify_print (peer, &bgp_notify, "sending");
Daniel Walton363c9032015-10-21 06:42:54 -0700978
paul718e3742002-12-13 20:15:29 +0000979 if (bgp_notify.data)
Daniel Walton363c9032015-10-21 06:42:54 -0700980 {
981 XFREE (MTYPE_TMP, bgp_notify.data);
982 bgp_notify.data = NULL;
983 bgp_notify.length = 0;
984 }
paul718e3742002-12-13 20:15:29 +0000985 }
986
987 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +0000988 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +0000989 peer->host, BGP_MSG_NOTIFY, length);
990
hassoe0701b72004-05-20 09:19:34 +0000991 /* peer reset cause */
992 if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
993 {
994 if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
heasley1212dc12011-09-12 13:27:52 +0400995 {
996 peer->last_reset = PEER_DOWN_USER_RESET;
997 zlog_info ("Notification sent to neighbor %s: User reset", peer->host);
998 }
hassoe0701b72004-05-20 09:19:34 +0000999 else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
heasley1212dc12011-09-12 13:27:52 +04001000 {
1001 peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
1002 zlog_info ("Notification sent to neighbor %s: shutdown", peer->host);
1003 }
hassoe0701b72004-05-20 09:19:34 +00001004 else
heasley1212dc12011-09-12 13:27:52 +04001005 {
1006 peer->last_reset = PEER_DOWN_NOTIFY_SEND;
1007 zlog_info ("Notification sent to neighbor %s: type %u/%u",
1008 peer->host, code, sub_code);
1009 }
hassoe0701b72004-05-20 09:19:34 +00001010 }
heasley1212dc12011-09-12 13:27:52 +04001011 else
1012 zlog_info ("Notification sent to neighbor %s: configuration change",
1013 peer->host);
hassoe0701b72004-05-20 09:19:34 +00001014
Denis Ovsienko7ccf5e52011-09-10 16:53:30 +04001015 /* Call immediately. */
paul718e3742002-12-13 20:15:29 +00001016 BGP_WRITE_OFF (peer->t_write);
1017
1018 bgp_write_notify (peer);
1019}
1020
1021/* Send BGP notify packet. */
1022void
1023bgp_notify_send (struct peer *peer, u_char code, u_char sub_code)
1024{
1025 bgp_notify_send_with_data (peer, code, sub_code, NULL, 0);
1026}
1027
paul718e3742002-12-13 20:15:29 +00001028/* Send route refresh message to the peer. */
1029void
1030bgp_route_refresh_send (struct peer *peer, afi_t afi, safi_t safi,
1031 u_char orf_type, u_char when_to_refresh, int remove)
1032{
1033 struct stream *s;
paul718e3742002-12-13 20:15:29 +00001034 int length;
1035 struct bgp_filter *filter;
1036 int orf_refresh = 0;
1037
Paul Jakma750e8142008-07-22 21:11:48 +00001038 if (DISABLE_BGP_ANNOUNCE)
1039 return;
paul718e3742002-12-13 20:15:29 +00001040
1041 filter = &peer->filter[afi][safi];
1042
1043 /* Adjust safi code. */
1044 if (safi == SAFI_MPLS_VPN)
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001045 safi = SAFI_MPLS_LABELED_VPN;
paul718e3742002-12-13 20:15:29 +00001046
1047 s = stream_new (BGP_MAX_PACKET_SIZE);
1048
1049 /* Make BGP update packet. */
1050 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
1051 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_NEW);
1052 else
1053 bgp_packet_set_marker (s, BGP_MSG_ROUTE_REFRESH_OLD);
1054
1055 /* Encode Route Refresh message. */
1056 stream_putw (s, afi);
1057 stream_putc (s, 0);
1058 stream_putc (s, safi);
1059
1060 if (orf_type == ORF_TYPE_PREFIX
1061 || orf_type == ORF_TYPE_PREFIX_OLD)
1062 if (remove || filter->plist[FILTER_IN].plist)
1063 {
1064 u_int16_t orf_len;
1065 unsigned long orfp;
1066
1067 orf_refresh = 1;
1068 stream_putc (s, when_to_refresh);
1069 stream_putc (s, orf_type);
paul9985f832005-02-09 15:51:56 +00001070 orfp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00001071 stream_putw (s, 0);
1072
1073 if (remove)
1074 {
1075 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1076 stream_putc (s, ORF_COMMON_PART_REMOVE_ALL);
1077 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001078 zlog_debug ("%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001079 peer->host, orf_type,
1080 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1081 afi, safi);
1082 }
1083 else
1084 {
1085 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND);
1086 prefix_bgp_orf_entry (s, filter->plist[FILTER_IN].plist,
1087 ORF_COMMON_PART_ADD, ORF_COMMON_PART_PERMIT,
1088 ORF_COMMON_PART_DENY);
1089 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001090 zlog_debug ("%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001091 peer->host, orf_type,
1092 (when_to_refresh == REFRESH_DEFER ? "defer" : "immediate"),
1093 afi, safi);
1094 }
1095
1096 /* Total ORF Entry Len. */
paul9985f832005-02-09 15:51:56 +00001097 orf_len = stream_get_endp (s) - orfp - 2;
paul718e3742002-12-13 20:15:29 +00001098 stream_putw_at (s, orfp, orf_len);
1099 }
1100
1101 /* Set packet size. */
1102 length = bgp_packet_set_size (s);
1103
1104 if (BGP_DEBUG (normal, NORMAL))
1105 {
1106 if (! orf_refresh)
ajs6b514742004-12-08 21:03:23 +00001107 zlog_debug ("%s sending REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001108 peer->host, afi, safi);
ajs6b514742004-12-08 21:03:23 +00001109 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001110 peer->host, CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV) ?
1111 BGP_MSG_ROUTE_REFRESH_NEW : BGP_MSG_ROUTE_REFRESH_OLD, length);
1112 }
1113
paul718e3742002-12-13 20:15:29 +00001114 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -04001115 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +00001116
pauleb821182004-05-01 08:44:08 +00001117 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001118}
1119
1120/* Send capability message to the peer. */
1121void
1122bgp_capability_send (struct peer *peer, afi_t afi, safi_t safi,
1123 int capability_code, int action)
1124{
1125 struct stream *s;
paul718e3742002-12-13 20:15:29 +00001126 int length;
1127
1128 /* Adjust safi code. */
1129 if (safi == SAFI_MPLS_VPN)
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001130 safi = SAFI_MPLS_LABELED_VPN;
paul718e3742002-12-13 20:15:29 +00001131
1132 s = stream_new (BGP_MAX_PACKET_SIZE);
1133
1134 /* Make BGP update packet. */
1135 bgp_packet_set_marker (s, BGP_MSG_CAPABILITY);
1136
1137 /* Encode MP_EXT capability. */
1138 if (capability_code == CAPABILITY_CODE_MP)
1139 {
1140 stream_putc (s, action);
1141 stream_putc (s, CAPABILITY_CODE_MP);
1142 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1143 stream_putw (s, afi);
1144 stream_putc (s, 0);
1145 stream_putc (s, safi);
1146
1147 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001148 zlog_debug ("%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00001149 peer->host, action == CAPABILITY_ACTION_SET ?
1150 "Advertising" : "Removing", afi, safi);
1151 }
1152
paul718e3742002-12-13 20:15:29 +00001153 /* Set packet size. */
1154 length = bgp_packet_set_size (s);
1155
paul718e3742002-12-13 20:15:29 +00001156
1157 /* Add packet to the peer. */
Donald Sharpa752c3b2015-08-18 08:48:53 -04001158 bgp_packet_add (peer, s);
paul718e3742002-12-13 20:15:29 +00001159
1160 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001161 zlog_debug ("%s send message type %d, length (incl. header) %d",
paul718e3742002-12-13 20:15:29 +00001162 peer->host, BGP_MSG_CAPABILITY, length);
1163
pauleb821182004-05-01 08:44:08 +00001164 BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
paul718e3742002-12-13 20:15:29 +00001165}
David Lamparter6b0655a2014-06-04 06:53:35 +02001166
paul718e3742002-12-13 20:15:29 +00001167/* RFC1771 6.8 Connection collision detection. */
paul94f2b392005-06-28 12:44:16 +00001168static int
pauleb821182004-05-01 08:44:08 +00001169bgp_collision_detect (struct peer *new, struct in_addr remote_id)
paul718e3742002-12-13 20:15:29 +00001170{
pauleb821182004-05-01 08:44:08 +00001171 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +00001172 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001173 struct bgp *bgp;
1174
1175 bgp = bgp_get_default ();
1176 if (! bgp)
1177 return 0;
1178
1179 /* Upon receipt of an OPEN message, the local system must examine
1180 all of its connections that are in the OpenConfirm state. A BGP
1181 speaker may also examine connections in an OpenSent state if it
1182 knows the BGP Identifier of the peer by means outside of the
1183 protocol. If among these connections there is a connection to a
1184 remote BGP speaker whose BGP Identifier equals the one in the
1185 OPEN message, then the local system performs the following
1186 collision resolution procedure: */
1187
paul1eb8ef22005-04-07 07:30:20 +00001188 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00001189 {
1190 /* Under OpenConfirm status, local peer structure already hold
1191 remote router ID. */
pauleb821182004-05-01 08:44:08 +00001192
1193 if (peer != new
1194 && (peer->status == OpenConfirm || peer->status == OpenSent)
1195 && sockunion_same (&peer->su, &new->su))
1196 {
paul718e3742002-12-13 20:15:29 +00001197 /* 1. The BGP Identifier of the local system is compared to
1198 the BGP Identifier of the remote system (as specified in
1199 the OPEN message). */
1200
1201 if (ntohl (peer->local_id.s_addr) < ntohl (remote_id.s_addr))
1202 {
1203 /* 2. If the value of the local BGP Identifier is less
1204 than the remote one, the local system closes BGP
1205 connection that already exists (the one that is
1206 already in the OpenConfirm state), and accepts BGP
1207 connection initiated by the remote system. */
1208
pauleb821182004-05-01 08:44:08 +00001209 if (peer->fd >= 0)
hassoe0701b72004-05-20 09:19:34 +00001210 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001211 return 1;
1212 }
1213 else
1214 {
1215 /* 3. Otherwise, the local system closes newly created
1216 BGP connection (the one associated with the newly
1217 received OPEN message), and continues to use the
1218 existing one (the one that is already in the
1219 OpenConfirm state). */
1220
pauleb821182004-05-01 08:44:08 +00001221 if (new->fd >= 0)
paulf5ba3872004-07-09 12:11:31 +00001222 bgp_notify_send (new, BGP_NOTIFY_CEASE,
1223 BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
paul718e3742002-12-13 20:15:29 +00001224 return -1;
1225 }
pauleb821182004-05-01 08:44:08 +00001226 }
1227 }
paul718e3742002-12-13 20:15:29 +00001228 return 0;
1229}
1230
paul94f2b392005-06-28 12:44:16 +00001231static int
paul718e3742002-12-13 20:15:29 +00001232bgp_open_receive (struct peer *peer, bgp_size_t size)
1233{
1234 int ret;
1235 u_char version;
1236 u_char optlen;
1237 u_int16_t holdtime;
1238 u_int16_t send_holdtime;
1239 as_t remote_as;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001240 as_t as4 = 0;
paul718e3742002-12-13 20:15:29 +00001241 struct peer *realpeer;
1242 struct in_addr remote_id;
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001243 int mp_capability;
paul5228ad22004-06-04 17:58:18 +00001244 u_int8_t notify_data_remote_as[2];
1245 u_int8_t notify_data_remote_id[4];
paul718e3742002-12-13 20:15:29 +00001246
1247 realpeer = NULL;
1248
1249 /* Parse open packet. */
1250 version = stream_getc (peer->ibuf);
1251 memcpy (notify_data_remote_as, stream_pnt (peer->ibuf), 2);
1252 remote_as = stream_getw (peer->ibuf);
1253 holdtime = stream_getw (peer->ibuf);
1254 memcpy (notify_data_remote_id, stream_pnt (peer->ibuf), 4);
1255 remote_id.s_addr = stream_get_ipv4 (peer->ibuf);
1256
1257 /* Receive OPEN message log */
1258 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001259 zlog_debug ("%s rcv OPEN, version %d, remote-as (in open) %u,"
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001260 " holdtime %d, id %s",
1261 peer->host, version, remote_as, holdtime,
1262 inet_ntoa (remote_id));
1263
1264 /* BEGIN to read the capability here, but dont do it yet */
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001265 mp_capability = 0;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001266 optlen = stream_getc (peer->ibuf);
1267
1268 if (optlen != 0)
1269 {
1270 /* We need the as4 capability value *right now* because
1271 * if it is there, we have not got the remote_as yet, and without
1272 * that we do not know which peer is connecting to us now.
1273 */
1274 as4 = peek_for_as4_capability (peer, optlen);
1275 }
1276
1277 /* Just in case we have a silly peer who sends AS4 capability set to 0 */
1278 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV) && !as4)
1279 {
1280 zlog_err ("%s bad OPEN, got AS4 capability, but AS4 set to 0",
1281 peer->host);
1282 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1283 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1284 return -1;
1285 }
1286
1287 if (remote_as == BGP_AS_TRANS)
1288 {
1289 /* Take the AS4 from the capability. We must have received the
1290 * capability now! Otherwise we have a asn16 peer who uses
1291 * BGP_AS_TRANS, for some unknown reason.
1292 */
1293 if (as4 == BGP_AS_TRANS)
1294 {
1295 zlog_err ("%s [AS4] NEW speaker using AS_TRANS for AS4, not allowed",
1296 peer->host);
1297 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1298 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1299 return -1;
1300 }
1301
1302 if (!as4 && BGP_DEBUG (as4, AS4))
1303 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but no AS4."
1304 " Odd, but proceeding.", peer->host);
1305 else if (as4 < BGP_AS_MAX && BGP_DEBUG (as4, AS4))
Paul Jakma0df7c912008-07-21 21:02:49 +00001306 zlog_debug ("%s [AS4] OPEN remote_as is AS_TRANS, but AS4 (%u) fits "
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001307 "in 2-bytes, very odd peer.", peer->host, as4);
1308 if (as4)
1309 remote_as = as4;
1310 }
1311 else
1312 {
1313 /* We may have a partner with AS4 who has an asno < BGP_AS_MAX */
1314 /* If we have got the capability, peer->as4cap must match remote_as */
1315 if (CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)
1316 && as4 != remote_as)
1317 {
1318 /* raise error, log this, close session */
1319 zlog_err ("%s bad OPEN, got AS4 capability, but remote_as %u"
1320 " mismatch with 16bit 'myasn' %u in open",
1321 peer->host, as4, remote_as);
1322 bgp_notify_send (peer, BGP_NOTIFY_OPEN_ERR,
1323 BGP_NOTIFY_OPEN_BAD_PEER_AS);
1324 return -1;
1325 }
1326 }
1327
paul718e3742002-12-13 20:15:29 +00001328 /* Lookup peer from Open packet. */
1329 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1330 {
1331 int as = 0;
1332
1333 realpeer = peer_lookup_with_open (&peer->su, remote_as, &remote_id, &as);
1334
1335 if (! realpeer)
1336 {
1337 /* Peer's source IP address is check in bgp_accept(), so this
1338 must be AS number mismatch or remote-id configuration
1339 mismatch. */
1340 if (as)
1341 {
1342 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001343 zlog_debug ("%s bad OPEN, wrong router identifier %s",
1344 peer->host, inet_ntoa (remote_id));
1345 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1346 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1347 notify_data_remote_id, 4);
paul718e3742002-12-13 20:15:29 +00001348 }
1349 else
1350 {
1351 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001352 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
ajs6b514742004-12-08 21:03:23 +00001353 peer->host, remote_as, peer->as);
1354 bgp_notify_send_with_data (peer, BGP_NOTIFY_OPEN_ERR,
1355 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1356 notify_data_remote_as, 2);
paul718e3742002-12-13 20:15:29 +00001357 }
1358 return -1;
1359 }
1360 }
1361
1362 /* When collision is detected and this peer is closed. Retrun
1363 immidiately. */
1364 ret = bgp_collision_detect (peer, remote_id);
1365 if (ret < 0)
1366 return ret;
1367
pauleb821182004-05-01 08:44:08 +00001368 /* Hack part. */
1369 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
1370 {
hasso93406d82005-02-02 14:40:33 +00001371 if (realpeer->status == Established
1372 && CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
1373 {
1374 realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
1375 SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
1376 }
1377 else if (ret == 0 && realpeer->status != Active
1378 && realpeer->status != OpenSent
Paul Jakma6e199262008-09-09 17:14:33 +01001379 && realpeer->status != OpenConfirm
1380 && realpeer->status != Connect)
pauleb821182004-05-01 08:44:08 +00001381 {
Paul Jakma2b2fc562008-09-06 13:09:35 +01001382 /* XXX: This is an awful problem..
1383 *
1384 * According to the RFC we should just let this connection (of the
1385 * accepted 'peer') continue on to Established if the other
1386 * connection (the 'realpeer' one) is in state Connect, and deal
1387 * with the more larval FSM as/when it gets far enough to receive
1388 * an Open. We don't do that though, we instead close the (more
1389 * developed) accepted connection.
1390 *
1391 * This means there's a race, which if hit, can loop:
1392 *
1393 * FSM for A FSM for B
1394 * realpeer accept-peer realpeer accept-peer
1395 *
1396 * Connect Connect
1397 * Active
1398 * OpenSent OpenSent
1399 * <arrive here,
1400 * Notify, delete>
1401 * Idle Active
1402 * OpenSent OpenSent
1403 * <arrive here,
1404 * Notify, delete>
1405 * Idle
1406 * <wait> <wait>
1407 * Connect Connect
1408 *
1409 *
1410 * If both sides are Quagga, they're almost certain to wait for
1411 * the same amount of time of course (which doesn't preclude other
1412 * implementations also waiting for same time). The race is
1413 * exacerbated by high-latency (in bgpd and/or the network).
1414 *
1415 * The reason we do this is because our FSM is tied to our peer
1416 * structure, which carries our configuration information, etc.
1417 * I.e. we can't let the accepted-peer FSM continue on as it is,
1418 * cause it's not associated with any actual peer configuration -
1419 * it's just a dummy.
1420 *
1421 * It's possible we could hack-fix this by just bgp_stop'ing the
1422 * realpeer and continueing on with the 'transfer FSM' below.
1423 * Ideally, we need to seperate FSMs from struct peer.
1424 *
1425 * Setting one side to passive avoids the race, as a workaround.
1426 */
pauleb821182004-05-01 08:44:08 +00001427 if (BGP_DEBUG (events, EVENTS))
hasso93406d82005-02-02 14:40:33 +00001428 zlog_debug ("%s peer status is %s close connection",
1429 realpeer->host, LOOKUP (bgp_status_msg,
1430 realpeer->status));
1431 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1432 BGP_NOTIFY_CEASE_CONNECT_REJECT);
1433
pauleb821182004-05-01 08:44:08 +00001434 return -1;
1435 }
1436
1437 if (BGP_DEBUG (events, EVENTS))
Paul Jakma6e199262008-09-09 17:14:33 +01001438 zlog_debug ("%s [Event] Transfer accept BGP peer to real (state %s)",
1439 peer->host,
1440 LOOKUP (bgp_status_msg, realpeer->status));
pauleb821182004-05-01 08:44:08 +00001441
1442 bgp_stop (realpeer);
1443
1444 /* Transfer file descriptor. */
1445 realpeer->fd = peer->fd;
1446 peer->fd = -1;
1447
1448 /* Transfer input buffer. */
1449 stream_free (realpeer->ibuf);
1450 realpeer->ibuf = peer->ibuf;
1451 realpeer->packet_size = peer->packet_size;
1452 peer->ibuf = NULL;
1453
1454 /* Transfer status. */
1455 realpeer->status = peer->status;
1456 bgp_stop (peer);
paul200df112005-06-01 11:17:05 +00001457
pauleb821182004-05-01 08:44:08 +00001458 /* peer pointer change. Open packet send to neighbor. */
1459 peer = realpeer;
1460 bgp_open_send (peer);
1461 if (peer->fd < 0)
1462 {
1463 zlog_err ("bgp_open_receive peer's fd is negative value %d",
1464 peer->fd);
1465 return -1;
1466 }
1467 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
1468 }
1469
paul718e3742002-12-13 20:15:29 +00001470 /* remote router-id check. */
1471 if (remote_id.s_addr == 0
Denis Ovsienko733cd9e2011-12-17 19:39:30 +04001472 || IPV4_CLASS_DE (ntohl (remote_id.s_addr))
paul718e3742002-12-13 20:15:29 +00001473 || ntohl (peer->local_id.s_addr) == ntohl (remote_id.s_addr))
1474 {
1475 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001476 zlog_debug ("%s bad OPEN, wrong router identifier %s",
paul718e3742002-12-13 20:15:29 +00001477 peer->host, inet_ntoa (remote_id));
1478 bgp_notify_send_with_data (peer,
1479 BGP_NOTIFY_OPEN_ERR,
1480 BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
1481 notify_data_remote_id, 4);
1482 return -1;
1483 }
1484
1485 /* Set remote router-id */
1486 peer->remote_id = remote_id;
1487
1488 /* Peer BGP version check. */
1489 if (version != BGP_VERSION_4)
1490 {
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001491 u_int16_t maxver = htons(BGP_VERSION_4);
1492 /* XXX this reply may not be correct if version < 4 XXX */
paul718e3742002-12-13 20:15:29 +00001493 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001494 zlog_debug ("%s bad protocol version, remote requested %d, local request %d",
paul718e3742002-12-13 20:15:29 +00001495 peer->host, version, BGP_VERSION_4);
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001496 /* Data must be in network byte order here */
paul718e3742002-12-13 20:15:29 +00001497 bgp_notify_send_with_data (peer,
1498 BGP_NOTIFY_OPEN_ERR,
1499 BGP_NOTIFY_OPEN_UNSUP_VERSION,
Leonid Rosenboima689e6a2012-12-07 21:25:00 +00001500 (u_int8_t *) &maxver, 2);
paul718e3742002-12-13 20:15:29 +00001501 return -1;
1502 }
1503
1504 /* Check neighbor as number. */
1505 if (remote_as != peer->as)
1506 {
1507 if (BGP_DEBUG (normal, NORMAL))
Denis Ovsienkoaea339f2009-04-30 17:16:22 +04001508 zlog_debug ("%s bad OPEN, remote AS is %u, expected %u",
paul718e3742002-12-13 20:15:29 +00001509 peer->host, remote_as, peer->as);
1510 bgp_notify_send_with_data (peer,
1511 BGP_NOTIFY_OPEN_ERR,
1512 BGP_NOTIFY_OPEN_BAD_PEER_AS,
1513 notify_data_remote_as, 2);
1514 return -1;
1515 }
1516
1517 /* From the rfc: Upon receipt of an OPEN message, a BGP speaker MUST
1518 calculate the value of the Hold Timer by using the smaller of its
1519 configured Hold Time and the Hold Time received in the OPEN message.
1520 The Hold Time MUST be either zero or at least three seconds. An
1521 implementation may reject connections on the basis of the Hold Time. */
1522
1523 if (holdtime < 3 && holdtime != 0)
1524 {
1525 bgp_notify_send (peer,
1526 BGP_NOTIFY_OPEN_ERR,
1527 BGP_NOTIFY_OPEN_UNACEP_HOLDTIME);
1528 return -1;
1529 }
1530
1531 /* From the rfc: A reasonable maximum time between KEEPALIVE messages
1532 would be one third of the Hold Time interval. KEEPALIVE messages
1533 MUST NOT be sent more frequently than one per second. An
1534 implementation MAY adjust the rate at which it sends KEEPALIVE
1535 messages as a function of the Hold Time interval. */
1536
1537 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
1538 send_holdtime = peer->holdtime;
1539 else
1540 send_holdtime = peer->bgp->default_holdtime;
1541
1542 if (holdtime < send_holdtime)
1543 peer->v_holdtime = holdtime;
1544 else
1545 peer->v_holdtime = send_holdtime;
1546
1547 peer->v_keepalive = peer->v_holdtime / 3;
1548
1549 /* Open option part parse. */
paul718e3742002-12-13 20:15:29 +00001550 if (optlen != 0)
1551 {
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001552 if ((ret = bgp_open_option_parse (peer, optlen, &mp_capability)) < 0)
Paul Jakma58617392012-01-09 20:59:26 +00001553 {
1554 bgp_notify_send (peer,
1555 BGP_NOTIFY_OPEN_ERR,
Paul Jakma68ec4242015-11-25 17:14:34 +00001556 BGP_NOTIFY_OPEN_UNSPECIFIC);
Paul Jakma58617392012-01-09 20:59:26 +00001557 return ret;
1558 }
paul718e3742002-12-13 20:15:29 +00001559 }
1560 else
1561 {
1562 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001563 zlog_debug ("%s rcvd OPEN w/ OPTION parameter len: 0",
paul718e3742002-12-13 20:15:29 +00001564 peer->host);
1565 }
1566
Avneesh Sachdev3b381c32012-02-19 10:19:52 -08001567 /*
1568 * Assume that the peer supports the locally configured set of
1569 * AFI/SAFIs if the peer did not send us any Mulitiprotocol
1570 * capabilities, or if 'override-capability' is configured.
1571 */
1572 if (! mp_capability ||
1573 CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
paul718e3742002-12-13 20:15:29 +00001574 {
1575 peer->afc_nego[AFI_IP][SAFI_UNICAST] = peer->afc[AFI_IP][SAFI_UNICAST];
1576 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = peer->afc[AFI_IP][SAFI_MULTICAST];
1577 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = peer->afc[AFI_IP6][SAFI_UNICAST];
1578 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = peer->afc[AFI_IP6][SAFI_MULTICAST];
1579 }
1580
1581 /* Get sockname. */
1582 bgp_getsockname (peer);
Timo Teräs0edba8b2015-10-22 11:35:17 +03001583 peer->rtt = sockopt_tcp_rtt (peer->fd);
paul718e3742002-12-13 20:15:29 +00001584
1585 BGP_EVENT_ADD (peer, Receive_OPEN_message);
1586
1587 peer->packet_size = 0;
1588 if (peer->ibuf)
1589 stream_reset (peer->ibuf);
1590
1591 return 0;
1592}
1593
1594/* Parse BGP Update packet and make attribute object. */
paul94f2b392005-06-28 12:44:16 +00001595static int
paul718e3742002-12-13 20:15:29 +00001596bgp_update_receive (struct peer *peer, bgp_size_t size)
1597{
1598 int ret;
1599 u_char *end;
1600 struct stream *s;
1601 struct attr attr;
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001602 struct attr_extra extra;
paul718e3742002-12-13 20:15:29 +00001603 bgp_size_t attribute_len;
1604 bgp_size_t update_len;
1605 bgp_size_t withdraw_len;
1606 struct bgp_nlri update;
1607 struct bgp_nlri withdraw;
1608 struct bgp_nlri mp_update;
1609 struct bgp_nlri mp_withdraw;
paul718e3742002-12-13 20:15:29 +00001610
1611 /* Status must be Established. */
1612 if (peer->status != Established)
1613 {
1614 zlog_err ("%s [FSM] Update packet received under status %s",
1615 peer->host, LOOKUP (bgp_status_msg, peer->status));
1616 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
1617 return -1;
1618 }
1619
1620 /* Set initial values. */
1621 memset (&attr, 0, sizeof (struct attr));
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001622 memset (&extra, 0, sizeof (struct attr_extra));
paul718e3742002-12-13 20:15:29 +00001623 memset (&update, 0, sizeof (struct bgp_nlri));
1624 memset (&withdraw, 0, sizeof (struct bgp_nlri));
1625 memset (&mp_update, 0, sizeof (struct bgp_nlri));
1626 memset (&mp_withdraw, 0, sizeof (struct bgp_nlri));
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001627 attr.extra = &extra;
paul718e3742002-12-13 20:15:29 +00001628
1629 s = peer->ibuf;
1630 end = stream_pnt (s) + size;
1631
1632 /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute
1633 Length is too large (i.e., if Unfeasible Routes Length + Total
1634 Attribute Length + 23 exceeds the message Length), then the Error
1635 Subcode is set to Malformed Attribute List. */
1636 if (stream_pnt (s) + 2 > end)
1637 {
1638 zlog_err ("%s [Error] Update packet error"
1639 " (packet length is short for unfeasible length)",
1640 peer->host);
1641 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1642 BGP_NOTIFY_UPDATE_MAL_ATTR);
1643 return -1;
1644 }
1645
1646 /* Unfeasible Route Length. */
1647 withdraw_len = stream_getw (s);
1648
1649 /* Unfeasible Route Length check. */
1650 if (stream_pnt (s) + withdraw_len > end)
1651 {
1652 zlog_err ("%s [Error] Update packet error"
1653 " (packet unfeasible length overflow %d)",
1654 peer->host, withdraw_len);
1655 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1656 BGP_NOTIFY_UPDATE_MAL_ATTR);
1657 return -1;
1658 }
1659
1660 /* Unfeasible Route packet format check. */
1661 if (withdraw_len > 0)
1662 {
Lou Berger050defe2016-01-12 13:41:59 -05001663 ret = bgp_nlri_sanity_check (peer, AFI_IP, SAFI_UNICAST, stream_pnt (s), withdraw_len);
paul718e3742002-12-13 20:15:29 +00001664 if (ret < 0)
1665 return -1;
1666
1667 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001668 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001669
1670 withdraw.afi = AFI_IP;
1671 withdraw.safi = SAFI_UNICAST;
1672 withdraw.nlri = stream_pnt (s);
1673 withdraw.length = withdraw_len;
paul9985f832005-02-09 15:51:56 +00001674 stream_forward_getp (s, withdraw_len);
paul718e3742002-12-13 20:15:29 +00001675 }
1676
1677 /* Attribute total length check. */
1678 if (stream_pnt (s) + 2 > end)
1679 {
1680 zlog_warn ("%s [Error] Packet Error"
1681 " (update packet is short for attribute length)",
1682 peer->host);
1683 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1684 BGP_NOTIFY_UPDATE_MAL_ATTR);
1685 return -1;
1686 }
1687
1688 /* Fetch attribute total length. */
1689 attribute_len = stream_getw (s);
1690
1691 /* Attribute length check. */
1692 if (stream_pnt (s) + attribute_len > end)
1693 {
1694 zlog_warn ("%s [Error] Packet Error"
1695 " (update packet attribute length overflow %d)",
1696 peer->host, attribute_len);
1697 bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
1698 BGP_NOTIFY_UPDATE_MAL_ATTR);
1699 return -1;
1700 }
Paul Jakmab881c702010-11-23 16:35:42 +00001701
1702 /* Certain attribute parsing errors should not be considered bad enough
1703 * to reset the session for, most particularly any partial/optional
1704 * attributes that have 'tunneled' over speakers that don't understand
1705 * them. Instead we withdraw only the prefix concerned.
1706 *
1707 * Complicates the flow a little though..
1708 */
1709 bgp_attr_parse_ret_t attr_parse_ret = BGP_ATTR_PARSE_PROCEED;
1710 /* This define morphs the update case into a withdraw when lower levels
1711 * have signalled an error condition where this is best.
1712 */
1713#define NLRI_ATTR_ARG (attr_parse_ret != BGP_ATTR_PARSE_WITHDRAW ? &attr : NULL)
paul718e3742002-12-13 20:15:29 +00001714
1715 /* Parse attribute when it exists. */
1716 if (attribute_len)
1717 {
Paul Jakmab881c702010-11-23 16:35:42 +00001718 attr_parse_ret = bgp_attr_parse (peer, &attr, attribute_len,
paul718e3742002-12-13 20:15:29 +00001719 &mp_update, &mp_withdraw);
Paul Jakmab881c702010-11-23 16:35:42 +00001720 if (attr_parse_ret == BGP_ATTR_PARSE_ERROR)
David Lamparterf80f8382014-06-04 01:00:51 +02001721 {
1722 bgp_attr_unintern_sub (&attr);
Lou Berger050defe2016-01-12 13:41:59 -05001723 bgp_attr_flush (&attr);
David Lamparterf80f8382014-06-04 01:00:51 +02001724 return -1;
1725 }
paul718e3742002-12-13 20:15:29 +00001726 }
Paul Jakmab881c702010-11-23 16:35:42 +00001727
paul718e3742002-12-13 20:15:29 +00001728 /* Logging the attribute. */
Paul Jakmab881c702010-11-23 16:35:42 +00001729 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW
1730 || BGP_DEBUG (update, UPDATE_IN))
paul718e3742002-12-13 20:15:29 +00001731 {
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +00001732 char attrstr[BUFSIZ];
1733 attrstr[0] = '\0';
1734
paule01f9cb2004-07-09 17:48:53 +00001735 ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);
Paul Jakmab881c702010-11-23 16:35:42 +00001736 int lvl = (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1737 ? LOG_ERR : LOG_DEBUG;
1738
1739 if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW)
1740 zlog (peer->log, LOG_ERR,
1741 "%s rcvd UPDATE with errors in attr(s)!! Withdrawing route.",
1742 peer->host);
paule01f9cb2004-07-09 17:48:53 +00001743
1744 if (ret)
Paul Jakmab881c702010-11-23 16:35:42 +00001745 zlog (peer->log, lvl, "%s rcvd UPDATE w/ attr: %s",
paule01f9cb2004-07-09 17:48:53 +00001746 peer->host, attrstr);
paul718e3742002-12-13 20:15:29 +00001747 }
Paul Jakmab881c702010-11-23 16:35:42 +00001748
paul718e3742002-12-13 20:15:29 +00001749 /* Network Layer Reachability Information. */
1750 update_len = end - stream_pnt (s);
1751
1752 if (update_len)
1753 {
1754 /* Check NLRI packet format and prefix length. */
Lou Berger050defe2016-01-12 13:41:59 -05001755 ret = bgp_nlri_sanity_check (peer, AFI_IP, SAFI_UNICAST, stream_pnt (s), update_len);
paul718e3742002-12-13 20:15:29 +00001756 if (ret < 0)
Paul Jakmab881c702010-11-23 16:35:42 +00001757 {
1758 bgp_attr_unintern_sub (&attr);
Lou Berger050defe2016-01-12 13:41:59 -05001759 bgp_attr_flush (&attr);
Paul Jakmab881c702010-11-23 16:35:42 +00001760 return -1;
1761 }
paul718e3742002-12-13 20:15:29 +00001762
1763 /* Set NLRI portion to structure. */
1764 update.afi = AFI_IP;
1765 update.safi = SAFI_UNICAST;
1766 update.nlri = stream_pnt (s);
1767 update.length = update_len;
paul9985f832005-02-09 15:51:56 +00001768 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001769 }
1770
1771 /* NLRI is processed only when the peer is configured specific
1772 Address Family and Subsequent Address Family. */
1773 if (peer->afc[AFI_IP][SAFI_UNICAST])
1774 {
1775 if (withdraw.length)
1776 bgp_nlri_parse (peer, NULL, &withdraw);
1777
1778 if (update.length)
Paul Jakmab881c702010-11-23 16:35:42 +00001779 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &update);
paule01f9cb2004-07-09 17:48:53 +00001780
hassof4184462005-02-01 20:13:16 +00001781 if (mp_update.length
1782 && mp_update.afi == AFI_IP
1783 && mp_update.safi == SAFI_UNICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001784 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
hassof4184462005-02-01 20:13:16 +00001785
1786 if (mp_withdraw.length
1787 && mp_withdraw.afi == AFI_IP
1788 && mp_withdraw.safi == SAFI_UNICAST)
1789 bgp_nlri_parse (peer, NULL, &mp_withdraw);
1790
paule01f9cb2004-07-09 17:48:53 +00001791 if (! attribute_len && ! withdraw_len)
1792 {
1793 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001794 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],
1795 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001796
hasso93406d82005-02-02 14:40:33 +00001797 /* NSF delete stale route */
1798 if (peer->nsf[AFI_IP][SAFI_UNICAST])
1799 bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);
1800
1801 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001802 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001803 peer->host);
1804 }
paul718e3742002-12-13 20:15:29 +00001805 }
1806 if (peer->afc[AFI_IP][SAFI_MULTICAST])
1807 {
1808 if (mp_update.length
Lou Berger9da04bc2016-01-12 13:41:55 -05001809 && mp_update.afi == AFI_IP
paul718e3742002-12-13 20:15:29 +00001810 && mp_update.safi == SAFI_MULTICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001811 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001812
1813 if (mp_withdraw.length
Lou Berger9da04bc2016-01-12 13:41:55 -05001814 && mp_withdraw.afi == AFI_IP
paul718e3742002-12-13 20:15:29 +00001815 && mp_withdraw.safi == SAFI_MULTICAST)
1816 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001817
hasso93406d82005-02-02 14:40:33 +00001818 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001819 && mp_withdraw.afi == AFI_IP
1820 && mp_withdraw.safi == SAFI_MULTICAST
1821 && mp_withdraw.length == 0)
1822 {
1823 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001824 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
1825 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001826
hasso93406d82005-02-02 14:40:33 +00001827 /* NSF delete stale route */
1828 if (peer->nsf[AFI_IP][SAFI_MULTICAST])
1829 bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);
1830
1831 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001832 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001833 peer->host);
1834 }
paul718e3742002-12-13 20:15:29 +00001835 }
1836 if (peer->afc[AFI_IP6][SAFI_UNICAST])
1837 {
1838 if (mp_update.length
1839 && mp_update.afi == AFI_IP6
1840 && mp_update.safi == SAFI_UNICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001841 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001842
1843 if (mp_withdraw.length
1844 && mp_withdraw.afi == AFI_IP6
1845 && mp_withdraw.safi == SAFI_UNICAST)
1846 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001847
hasso93406d82005-02-02 14:40:33 +00001848 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001849 && mp_withdraw.afi == AFI_IP6
1850 && mp_withdraw.safi == SAFI_UNICAST
1851 && mp_withdraw.length == 0)
1852 {
1853 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001854 SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001855
hasso93406d82005-02-02 14:40:33 +00001856 /* NSF delete stale route */
1857 if (peer->nsf[AFI_IP6][SAFI_UNICAST])
1858 bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST);
1859
1860 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001861 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001862 peer->host);
1863 }
paul718e3742002-12-13 20:15:29 +00001864 }
1865 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
1866 {
1867 if (mp_update.length
1868 && mp_update.afi == AFI_IP6
1869 && mp_update.safi == SAFI_MULTICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001870 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001871
1872 if (mp_withdraw.length
1873 && mp_withdraw.afi == AFI_IP6
1874 && mp_withdraw.safi == SAFI_MULTICAST)
1875 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001876
hasso93406d82005-02-02 14:40:33 +00001877 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001878 && mp_withdraw.afi == AFI_IP6
1879 && mp_withdraw.safi == SAFI_MULTICAST
1880 && mp_withdraw.length == 0)
1881 {
1882 /* End-of-RIB received */
1883
hasso93406d82005-02-02 14:40:33 +00001884 /* NSF delete stale route */
1885 if (peer->nsf[AFI_IP6][SAFI_MULTICAST])
1886 bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST);
1887
paule01f9cb2004-07-09 17:48:53 +00001888 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001889 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001890 peer->host);
1891 }
paul718e3742002-12-13 20:15:29 +00001892 }
1893 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
1894 {
1895 if (mp_update.length
1896 && mp_update.afi == AFI_IP
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001897 && mp_update.safi == SAFI_MPLS_LABELED_VPN)
Lou Berger9da04bc2016-01-12 13:41:55 -05001898 bgp_nlri_parse_vpn (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001899
1900 if (mp_withdraw.length
1901 && mp_withdraw.afi == AFI_IP
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001902 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN)
Lou Berger9da04bc2016-01-12 13:41:55 -05001903 bgp_nlri_parse_vpn (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001904
hasso93406d82005-02-02 14:40:33 +00001905 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001906 && mp_withdraw.afi == AFI_IP
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001907 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN
paule01f9cb2004-07-09 17:48:53 +00001908 && mp_withdraw.length == 0)
1909 {
1910 /* End-of-RIB received */
1911
1912 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001913 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001914 peer->host);
1915 }
paul718e3742002-12-13 20:15:29 +00001916 }
Lou Berger9da04bc2016-01-12 13:41:55 -05001917 if (peer->afc[AFI_IP6][SAFI_MPLS_VPN])
1918 {
1919 if (mp_update.length
1920 && mp_update.afi == AFI_IP6
1921 && mp_update.safi == SAFI_MPLS_LABELED_VPN)
1922 bgp_nlri_parse_vpn (peer, NLRI_ATTR_ARG, &mp_update);
1923
1924 if (mp_withdraw.length
1925 && mp_withdraw.afi == AFI_IP6
1926 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN)
1927 bgp_nlri_parse_vpn (peer, NULL, &mp_withdraw);
1928
1929 if (! withdraw_len
1930 && mp_withdraw.afi == AFI_IP6
1931 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN
1932 && mp_withdraw.length == 0)
1933 {
1934 /* End-of-RIB received */
1935
1936 if (BGP_DEBUG (update, UPDATE_IN))
1937 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s",
1938 peer->host);
1939 }
1940 }
Lou Berger298cc2f2016-01-12 13:42:02 -05001941 if (peer->afc[AFI_IP][SAFI_ENCAP])
1942 {
1943 if (mp_update.length
1944 && mp_update.afi == AFI_IP
1945 && mp_update.safi == SAFI_ENCAP)
1946 bgp_nlri_parse_encap (mp_update.afi, peer, &attr, &mp_update, 0);
1947
1948 if (mp_withdraw.length
1949 && mp_withdraw.afi == AFI_IP
1950 && mp_withdraw.safi == SAFI_ENCAP)
1951 bgp_nlri_parse_encap (mp_withdraw.afi, peer, &attr, &mp_withdraw, 1);
1952
1953 if (! withdraw_len
1954 && mp_withdraw.afi == AFI_IP
1955 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN
1956 && mp_withdraw.length == 0)
1957 {
1958 /* End-of-RIB received */
1959
1960 if (BGP_DEBUG (update, UPDATE_IN))
1961 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for Encap Unicast from %s",
1962 peer->host);
1963 }
1964 }
1965 if (peer->afc[AFI_IP6][SAFI_ENCAP])
1966 {
1967 if (mp_update.length
1968 && mp_update.afi == AFI_IP6
1969 && mp_update.safi == SAFI_ENCAP)
1970 bgp_nlri_parse_encap (mp_update.afi, peer, &attr, &mp_update, 0);
1971
1972 if (mp_withdraw.length
1973 && mp_withdraw.afi == AFI_IP6
1974 && mp_withdraw.safi == SAFI_ENCAP)
1975 bgp_nlri_parse_encap (mp_withdraw.afi, peer, &attr, &mp_withdraw, 1);
1976
1977 if (! withdraw_len
1978 && mp_withdraw.afi == AFI_IP6
1979 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN
1980 && mp_withdraw.length == 0)
1981 {
1982 /* End-of-RIB received */
1983
1984 if (BGP_DEBUG (update, UPDATE_IN))
1985 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for Encap Unicast from %s",
1986 peer->host);
1987 }
1988 }
paul718e3742002-12-13 20:15:29 +00001989
1990 /* Everything is done. We unintern temporary structures which
1991 interned in bgp_attr_parse(). */
Paul Jakmab881c702010-11-23 16:35:42 +00001992 bgp_attr_unintern_sub (&attr);
Lou Berger050defe2016-01-12 13:41:59 -05001993 bgp_attr_flush (&attr);
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001994
paul718e3742002-12-13 20:15:29 +00001995 /* If peering is stopped due to some reason, do not generate BGP
1996 event. */
1997 if (peer->status != Established)
1998 return 0;
1999
2000 /* Increment packet counter. */
2001 peer->update_in++;
Stephen Hemminger65957882010-01-15 16:22:10 +03002002 peer->update_time = bgp_clock ();
paul718e3742002-12-13 20:15:29 +00002003
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02002004 /* Rearm holdtime timer */
Jorge Boncompte [DTI2]6a4677b2012-05-07 16:53:07 +00002005 BGP_TIMER_OFF (peer->t_holdtime);
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02002006 bgp_timer_set (peer);
paul718e3742002-12-13 20:15:29 +00002007
2008 return 0;
2009}
2010
2011/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00002012static void
paul718e3742002-12-13 20:15:29 +00002013bgp_notify_receive (struct peer *peer, bgp_size_t size)
2014{
2015 struct bgp_notify bgp_notify;
2016
2017 if (peer->notify.data)
2018 {
2019 XFREE (MTYPE_TMP, peer->notify.data);
2020 peer->notify.data = NULL;
2021 peer->notify.length = 0;
2022 }
2023
2024 bgp_notify.code = stream_getc (peer->ibuf);
2025 bgp_notify.subcode = stream_getc (peer->ibuf);
2026 bgp_notify.length = size - 2;
2027 bgp_notify.data = NULL;
2028
2029 /* Preserv notify code and sub code. */
2030 peer->notify.code = bgp_notify.code;
2031 peer->notify.subcode = bgp_notify.subcode;
2032 /* For further diagnostic record returned Data. */
2033 if (bgp_notify.length)
2034 {
2035 peer->notify.length = size - 2;
2036 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
2037 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
2038 }
2039
2040 /* For debug */
2041 {
2042 int i;
2043 int first = 0;
2044 char c[4];
2045
2046 if (bgp_notify.length)
2047 {
2048 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
2049 for (i = 0; i < bgp_notify.length; i++)
2050 if (first)
2051 {
2052 sprintf (c, " %02x", stream_getc (peer->ibuf));
2053 strcat (bgp_notify.data, c);
2054 }
2055 else
2056 {
2057 first = 1;
2058 sprintf (c, "%02x", stream_getc (peer->ibuf));
2059 strcpy (bgp_notify.data, c);
2060 }
2061 }
2062
2063 bgp_notify_print(peer, &bgp_notify, "received");
2064 if (bgp_notify.data)
Daniel Walton363c9032015-10-21 06:42:54 -07002065 {
2066 XFREE (MTYPE_TMP, bgp_notify.data);
2067 bgp_notify.data = NULL;
2068 bgp_notify.length = 0;
2069 }
paul718e3742002-12-13 20:15:29 +00002070 }
2071
2072 /* peer count update */
2073 peer->notify_in++;
2074
hassoe0701b72004-05-20 09:19:34 +00002075 if (peer->status == Established)
2076 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
2077
paul718e3742002-12-13 20:15:29 +00002078 /* We have to check for Notify with Unsupported Optional Parameter.
2079 in that case we fallback to open without the capability option.
2080 But this done in bgp_stop. We just mark it here to avoid changing
2081 the fsm tables. */
2082 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
2083 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
2084 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
2085
paul718e3742002-12-13 20:15:29 +00002086 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
2087}
2088
2089/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00002090static void
paul718e3742002-12-13 20:15:29 +00002091bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
2092{
2093 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00002094 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00002095
2096 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
2097}
2098
2099/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00002100static void
paul718e3742002-12-13 20:15:29 +00002101bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
2102{
2103 afi_t afi;
2104 safi_t safi;
paul718e3742002-12-13 20:15:29 +00002105 struct stream *s;
2106
2107 /* If peer does not have the capability, send notification. */
2108 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
2109 {
2110 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
2111 peer->host);
2112 bgp_notify_send (peer,
2113 BGP_NOTIFY_HEADER_ERR,
2114 BGP_NOTIFY_HEADER_BAD_MESTYPE);
2115 return;
2116 }
2117
2118 /* Status must be Established. */
2119 if (peer->status != Established)
2120 {
2121 plog_err (peer->log,
2122 "%s [Error] Route refresh packet received under status %s",
2123 peer->host, LOOKUP (bgp_status_msg, peer->status));
2124 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
2125 return;
2126 }
2127
2128 s = peer->ibuf;
2129
2130 /* Parse packet. */
2131 afi = stream_getw (s);
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002132 /* reserved byte */
2133 stream_getc (s);
paul718e3742002-12-13 20:15:29 +00002134 safi = stream_getc (s);
2135
2136 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002137 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00002138 peer->host, afi, safi);
2139
2140 /* Check AFI and SAFI. */
2141 if ((afi != AFI_IP && afi != AFI_IP6)
2142 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
Denis Ovsienko42e6d742011-07-14 12:36:19 +04002143 && safi != SAFI_MPLS_LABELED_VPN))
paul718e3742002-12-13 20:15:29 +00002144 {
2145 if (BGP_DEBUG (normal, NORMAL))
2146 {
ajs6b514742004-12-08 21:03:23 +00002147 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00002148 peer->host, afi, safi);
2149 }
2150 return;
2151 }
2152
2153 /* Adjust safi code. */
Denis Ovsienko42e6d742011-07-14 12:36:19 +04002154 if (safi == SAFI_MPLS_LABELED_VPN)
paul718e3742002-12-13 20:15:29 +00002155 safi = SAFI_MPLS_VPN;
2156
2157 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
2158 {
2159 u_char *end;
2160 u_char when_to_refresh;
2161 u_char orf_type;
2162 u_int16_t orf_len;
2163
2164 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
2165 {
2166 zlog_info ("%s ORF route refresh length error", peer->host);
2167 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2168 return;
2169 }
2170
2171 when_to_refresh = stream_getc (s);
2172 end = stream_pnt (s) + (size - 5);
2173
Paul Jakma370b64a2007-12-22 16:49:52 +00002174 while ((stream_pnt (s) + 2) < end)
paul718e3742002-12-13 20:15:29 +00002175 {
2176 orf_type = stream_getc (s);
2177 orf_len = stream_getw (s);
Paul Jakma370b64a2007-12-22 16:49:52 +00002178
2179 /* orf_len in bounds? */
2180 if ((stream_pnt (s) + orf_len) > end)
2181 break; /* XXX: Notify instead?? */
paul718e3742002-12-13 20:15:29 +00002182 if (orf_type == ORF_TYPE_PREFIX
2183 || orf_type == ORF_TYPE_PREFIX_OLD)
2184 {
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002185 uint8_t *p_pnt = stream_pnt (s);
2186 uint8_t *p_end = stream_pnt (s) + orf_len;
paul718e3742002-12-13 20:15:29 +00002187 struct orf_prefix orfp;
2188 u_char common = 0;
2189 u_int32_t seq;
2190 int psize;
2191 char name[BUFSIZ];
paul718e3742002-12-13 20:15:29 +00002192 int ret;
2193
2194 if (BGP_DEBUG (normal, NORMAL))
2195 {
ajs6b514742004-12-08 21:03:23 +00002196 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00002197 peer->host, orf_type, orf_len);
2198 }
2199
Paul Jakma370b64a2007-12-22 16:49:52 +00002200 /* we're going to read at least 1 byte of common ORF header,
2201 * and 7 bytes of ORF Address-filter entry from the stream
2202 */
2203 if (orf_len < 7)
2204 break;
2205
paul718e3742002-12-13 20:15:29 +00002206 /* ORF prefix-list name */
2207 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
2208
2209 while (p_pnt < p_end)
2210 {
Chris Halld64379e2010-05-14 16:38:39 +04002211 /* If the ORF entry is malformed, want to read as much of it
2212 * as possible without going beyond the bounds of the entry,
2213 * to maximise debug information.
2214 */
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002215 int ok;
paul718e3742002-12-13 20:15:29 +00002216 memset (&orfp, 0, sizeof (struct orf_prefix));
2217 common = *p_pnt++;
Chris Halld64379e2010-05-14 16:38:39 +04002218 /* after ++: p_pnt <= p_end */
paul718e3742002-12-13 20:15:29 +00002219 if (common & ORF_COMMON_PART_REMOVE_ALL)
2220 {
2221 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002222 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
David Lamparterc9c06d02015-04-13 10:21:35 +02002223 prefix_bgp_orf_remove_all (afi, name);
paul718e3742002-12-13 20:15:29 +00002224 break;
2225 }
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002226 ok = ((size_t)(p_end - p_pnt) >= sizeof(u_int32_t)) ;
Denis Ovsienkobb915f52011-12-13 21:11:39 +04002227 if (ok)
Chris Halld64379e2010-05-14 16:38:39 +04002228 {
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002229 memcpy (&seq, p_pnt, sizeof (u_int32_t));
2230 p_pnt += sizeof (u_int32_t);
2231 orfp.seq = ntohl (seq);
Chris Halld64379e2010-05-14 16:38:39 +04002232 }
2233 else
2234 p_pnt = p_end ;
2235
2236 if ((ok = (p_pnt < p_end)))
2237 orfp.ge = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2238 if ((ok = (p_pnt < p_end)))
2239 orfp.le = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2240 if ((ok = (p_pnt < p_end)))
2241 orfp.p.prefixlen = *p_pnt++ ;
2242 orfp.p.family = afi2family (afi); /* afi checked already */
2243
2244 psize = PSIZE (orfp.p.prefixlen); /* 0 if not ok */
2245 if (psize > prefix_blen(&orfp.p)) /* valid for family ? */
2246 {
2247 ok = 0 ;
2248 psize = prefix_blen(&orfp.p) ;
2249 }
2250 if (psize > (p_end - p_pnt)) /* valid for packet ? */
2251 {
2252 ok = 0 ;
2253 psize = p_end - p_pnt ;
2254 }
2255
2256 if (psize > 0)
2257 memcpy (&orfp.p.u.prefix, p_pnt, psize);
paul718e3742002-12-13 20:15:29 +00002258 p_pnt += psize;
2259
2260 if (BGP_DEBUG (normal, NORMAL))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +00002261 {
2262 char buf[INET6_BUFSIZ];
2263
2264 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
2265 peer->host,
2266 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
2267 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
2268 orfp.seq,
2269 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, INET6_BUFSIZ),
2270 orfp.p.prefixlen, orfp.ge, orfp.le,
2271 ok ? "" : " MALFORMED");
2272 }
2273
Chris Halld64379e2010-05-14 16:38:39 +04002274 if (ok)
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002275 ret = prefix_bgp_orf_set (name, afi, &orfp,
2276 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
2277 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002278
2279 if (!ok || (ok && ret != CMD_SUCCESS))
paul718e3742002-12-13 20:15:29 +00002280 {
2281 if (BGP_DEBUG (normal, NORMAL))
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002282 zlog_debug ("%s Received misformatted prefixlist ORF."
2283 " Remove All pfxlist", peer->host);
David Lamparterc9c06d02015-04-13 10:21:35 +02002284 prefix_bgp_orf_remove_all (afi, name);
paul718e3742002-12-13 20:15:29 +00002285 break;
2286 }
2287 }
2288 peer->orf_plist[afi][safi] =
David Lamparterc9c06d02015-04-13 10:21:35 +02002289 prefix_bgp_orf_lookup (afi, name);
paul718e3742002-12-13 20:15:29 +00002290 }
paul9985f832005-02-09 15:51:56 +00002291 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00002292 }
2293 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002294 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00002295 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
2296 if (when_to_refresh == REFRESH_DEFER)
2297 return;
2298 }
2299
2300 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2301 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
2302 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
2303
2304 /* Perform route refreshment to the peer */
2305 bgp_announce_route (peer, afi, safi);
2306}
2307
paul94f2b392005-06-28 12:44:16 +00002308static int
paul718e3742002-12-13 20:15:29 +00002309bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
2310{
2311 u_char *end;
Paul Jakma6d582722007-08-06 15:21:45 +00002312 struct capability_mp_data mpc;
2313 struct capability_header *hdr;
paul718e3742002-12-13 20:15:29 +00002314 u_char action;
paul718e3742002-12-13 20:15:29 +00002315 afi_t afi;
2316 safi_t safi;
2317
paul718e3742002-12-13 20:15:29 +00002318 end = pnt + length;
2319
2320 while (pnt < end)
Paul Jakma6d582722007-08-06 15:21:45 +00002321 {
paul718e3742002-12-13 20:15:29 +00002322 /* We need at least action, capability code and capability length. */
2323 if (pnt + 3 > end)
2324 {
2325 zlog_info ("%s Capability length error", peer->host);
2326 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2327 return -1;
2328 }
paul718e3742002-12-13 20:15:29 +00002329 action = *pnt;
Paul Jakma6d582722007-08-06 15:21:45 +00002330 hdr = (struct capability_header *)(pnt + 1);
2331
paul718e3742002-12-13 20:15:29 +00002332 /* Action value check. */
2333 if (action != CAPABILITY_ACTION_SET
2334 && action != CAPABILITY_ACTION_UNSET)
2335 {
2336 zlog_info ("%s Capability Action Value error %d",
2337 peer->host, action);
2338 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2339 return -1;
2340 }
2341
2342 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002343 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
Paul Jakma6d582722007-08-06 15:21:45 +00002344 peer->host, action, hdr->code, hdr->length);
paul718e3742002-12-13 20:15:29 +00002345
2346 /* Capability length check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002347 if ((pnt + hdr->length + 3) > end)
paul718e3742002-12-13 20:15:29 +00002348 {
2349 zlog_info ("%s Capability length error", peer->host);
2350 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2351 return -1;
2352 }
2353
Paul Jakma6d582722007-08-06 15:21:45 +00002354 /* Fetch structure to the byte stream. */
2355 memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
2356
paul718e3742002-12-13 20:15:29 +00002357 /* We know MP Capability Code. */
Paul Jakma6d582722007-08-06 15:21:45 +00002358 if (hdr->code == CAPABILITY_CODE_MP)
paul718e3742002-12-13 20:15:29 +00002359 {
Paul Jakma6d582722007-08-06 15:21:45 +00002360 afi = ntohs (mpc.afi);
2361 safi = mpc.safi;
paul718e3742002-12-13 20:15:29 +00002362
2363 /* Ignore capability when override-capability is set. */
2364 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2365 continue;
Paul Jakma6d582722007-08-06 15:21:45 +00002366
2367 if (!bgp_afi_safi_valid_indices (afi, &safi))
2368 {
2369 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002370 zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
2371 "(%u/%u)", peer->host, afi, safi);
Paul Jakma6d582722007-08-06 15:21:45 +00002372 continue;
2373 }
2374
paul718e3742002-12-13 20:15:29 +00002375 /* Address family check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002376 if (BGP_DEBUG (normal, NORMAL))
2377 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2378 peer->host,
2379 action == CAPABILITY_ACTION_SET
2380 ? "Advertising" : "Removing",
2381 ntohs(mpc.afi) , mpc.safi);
2382
2383 if (action == CAPABILITY_ACTION_SET)
2384 {
2385 peer->afc_recv[afi][safi] = 1;
2386 if (peer->afc[afi][safi])
2387 {
2388 peer->afc_nego[afi][safi] = 1;
2389 bgp_announce_route (peer, afi, safi);
2390 }
2391 }
2392 else
2393 {
2394 peer->afc_recv[afi][safi] = 0;
2395 peer->afc_nego[afi][safi] = 0;
paul718e3742002-12-13 20:15:29 +00002396
Paul Jakma6d582722007-08-06 15:21:45 +00002397 if (peer_active_nego (peer))
Chris Caputo228da422009-07-18 05:44:03 +00002398 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
Paul Jakma6d582722007-08-06 15:21:45 +00002399 else
2400 BGP_EVENT_ADD (peer, BGP_Stop);
2401 }
paul718e3742002-12-13 20:15:29 +00002402 }
paul718e3742002-12-13 20:15:29 +00002403 else
2404 {
2405 zlog_warn ("%s unrecognized capability code: %d - ignored",
Paul Jakma6d582722007-08-06 15:21:45 +00002406 peer->host, hdr->code);
paul718e3742002-12-13 20:15:29 +00002407 }
Paul Jakma6d582722007-08-06 15:21:45 +00002408 pnt += hdr->length + 3;
paul718e3742002-12-13 20:15:29 +00002409 }
2410 return 0;
2411}
2412
Paul Jakma01b7ce22009-06-18 12:34:43 +01002413/* Dynamic Capability is received.
2414 *
2415 * This is exported for unit-test purposes
2416 */
Paul Jakma6d582722007-08-06 15:21:45 +00002417int
paul718e3742002-12-13 20:15:29 +00002418bgp_capability_receive (struct peer *peer, bgp_size_t size)
2419{
2420 u_char *pnt;
paul718e3742002-12-13 20:15:29 +00002421
2422 /* Fetch pointer. */
2423 pnt = stream_pnt (peer->ibuf);
2424
2425 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002426 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002427
2428 /* If peer does not have the capability, send notification. */
2429 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2430 {
2431 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2432 peer->host);
2433 bgp_notify_send (peer,
2434 BGP_NOTIFY_HEADER_ERR,
2435 BGP_NOTIFY_HEADER_BAD_MESTYPE);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002436 return -1;
paul718e3742002-12-13 20:15:29 +00002437 }
2438
2439 /* Status must be Established. */
2440 if (peer->status != Established)
2441 {
2442 plog_err (peer->log,
2443 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2444 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002445 return -1;
paul718e3742002-12-13 20:15:29 +00002446 }
2447
2448 /* Parse packet. */
Paul Jakma6d582722007-08-06 15:21:45 +00002449 return bgp_capability_msg_parse (peer, pnt, size);
paul718e3742002-12-13 20:15:29 +00002450}
David Lamparter6b0655a2014-06-04 06:53:35 +02002451
paul718e3742002-12-13 20:15:29 +00002452/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002453static int
paul718e3742002-12-13 20:15:29 +00002454bgp_read_packet (struct peer *peer)
2455{
2456 int nbytes;
2457 int readsize;
2458
paul9985f832005-02-09 15:51:56 +00002459 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002460
2461 /* If size is zero then return. */
2462 if (! readsize)
2463 return 0;
2464
2465 /* Read packet from fd. */
Stephen Hemminger35398582010-08-05 10:26:23 -07002466 nbytes = stream_read_try (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002467
2468 /* If read byte is smaller than zero then error occured. */
2469 if (nbytes < 0)
2470 {
Stephen Hemminger35398582010-08-05 10:26:23 -07002471 /* Transient error should retry */
2472 if (nbytes == -2)
paul718e3742002-12-13 20:15:29 +00002473 return -1;
2474
2475 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002476 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002477
2478 if (peer->status == Established)
2479 {
2480 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2481 {
2482 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2483 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2484 }
2485 else
2486 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2487 }
2488
paul718e3742002-12-13 20:15:29 +00002489 BGP_EVENT_ADD (peer, TCP_fatal_error);
2490 return -1;
2491 }
2492
2493 /* When read byte is zero : clear bgp peer and return */
2494 if (nbytes == 0)
2495 {
2496 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002497 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002498 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002499
2500 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002501 {
2502 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2503 {
2504 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2505 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2506 }
2507 else
2508 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2509 }
hassoe0701b72004-05-20 09:19:34 +00002510
paul718e3742002-12-13 20:15:29 +00002511 BGP_EVENT_ADD (peer, TCP_connection_closed);
2512 return -1;
2513 }
2514
2515 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002516 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002517 return -1;
2518
2519 return 0;
2520}
2521
2522/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002523static int
paul718e3742002-12-13 20:15:29 +00002524bgp_marker_all_one (struct stream *s, int length)
2525{
2526 int i;
2527
2528 for (i = 0; i < length; i++)
2529 if (s->data[i] != 0xff)
2530 return 0;
2531
2532 return 1;
2533}
2534
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002535/* Recent thread time.
2536 On same clock base as bgp_clock (MONOTONIC)
2537 but can be time of last context switch to bgp_read thread. */
2538static time_t
2539bgp_recent_clock (void)
2540{
2541 return recent_relative_time().tv_sec;
2542}
2543
paul718e3742002-12-13 20:15:29 +00002544/* Starting point of packet process function. */
2545int
2546bgp_read (struct thread *thread)
2547{
2548 int ret;
2549 u_char type = 0;
2550 struct peer *peer;
2551 bgp_size_t size;
2552 char notify_data_length[2];
2553
2554 /* Yes first of all get peer pointer. */
2555 peer = THREAD_ARG (thread);
2556 peer->t_read = NULL;
2557
2558 /* For non-blocking IO check. */
2559 if (peer->status == Connect)
2560 {
2561 bgp_connect_check (peer);
2562 goto done;
2563 }
2564 else
2565 {
pauleb821182004-05-01 08:44:08 +00002566 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002567 {
pauleb821182004-05-01 08:44:08 +00002568 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002569 return -1;
2570 }
pauleb821182004-05-01 08:44:08 +00002571 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002572 }
2573
2574 /* Read packet header to determine type of the packet */
2575 if (peer->packet_size == 0)
2576 peer->packet_size = BGP_HEADER_SIZE;
2577
paul9985f832005-02-09 15:51:56 +00002578 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002579 {
2580 ret = bgp_read_packet (peer);
2581
2582 /* Header read error or partial read packet. */
2583 if (ret < 0)
2584 goto done;
2585
2586 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002587 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002588 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2589 size = stream_getw (peer->ibuf);
2590 type = stream_getc (peer->ibuf);
2591
2592 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002593 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002594 peer->host, type, size - BGP_HEADER_SIZE);
2595
2596 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002597 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002598 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2599 {
2600 bgp_notify_send (peer,
2601 BGP_NOTIFY_HEADER_ERR,
2602 BGP_NOTIFY_HEADER_NOT_SYNC);
2603 goto done;
2604 }
2605
2606 /* BGP type check. */
2607 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2608 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2609 && type != BGP_MSG_ROUTE_REFRESH_NEW
2610 && type != BGP_MSG_ROUTE_REFRESH_OLD
2611 && type != BGP_MSG_CAPABILITY)
2612 {
2613 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002614 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002615 "%s unknown message type 0x%02x",
2616 peer->host, type);
2617 bgp_notify_send_with_data (peer,
2618 BGP_NOTIFY_HEADER_ERR,
2619 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2620 &type, 1);
2621 goto done;
2622 }
2623 /* Mimimum packet length check. */
2624 if ((size < BGP_HEADER_SIZE)
2625 || (size > BGP_MAX_PACKET_SIZE)
2626 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2627 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2628 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2629 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2630 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2631 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2632 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2633 {
2634 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002635 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002636 "%s bad message length - %d for %s",
2637 peer->host, size,
2638 type == 128 ? "ROUTE-REFRESH" :
2639 bgp_type_str[(int) type]);
2640 bgp_notify_send_with_data (peer,
2641 BGP_NOTIFY_HEADER_ERR,
2642 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002643 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002644 goto done;
2645 }
2646
2647 /* Adjust size to message length. */
2648 peer->packet_size = size;
2649 }
2650
2651 ret = bgp_read_packet (peer);
2652 if (ret < 0)
2653 goto done;
2654
2655 /* Get size and type again. */
2656 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2657 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2658
2659 /* BGP packet dump function. */
2660 bgp_dump_packet (peer, type, peer->ibuf);
2661
2662 size = (peer->packet_size - BGP_HEADER_SIZE);
2663
2664 /* Read rest of the packet and call each sort of packet routine */
2665 switch (type)
2666 {
2667 case BGP_MSG_OPEN:
2668 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002669 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002670 break;
2671 case BGP_MSG_UPDATE:
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002672 peer->readtime = bgp_recent_clock ();
paul718e3742002-12-13 20:15:29 +00002673 bgp_update_receive (peer, size);
2674 break;
2675 case BGP_MSG_NOTIFY:
2676 bgp_notify_receive (peer, size);
2677 break;
2678 case BGP_MSG_KEEPALIVE:
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002679 peer->readtime = bgp_recent_clock ();
paul718e3742002-12-13 20:15:29 +00002680 bgp_keepalive_receive (peer, size);
2681 break;
2682 case BGP_MSG_ROUTE_REFRESH_NEW:
2683 case BGP_MSG_ROUTE_REFRESH_OLD:
2684 peer->refresh_in++;
2685 bgp_route_refresh_receive (peer, size);
2686 break;
2687 case BGP_MSG_CAPABILITY:
2688 peer->dynamic_cap_in++;
2689 bgp_capability_receive (peer, size);
2690 break;
2691 }
2692
2693 /* Clear input buffer. */
2694 peer->packet_size = 0;
2695 if (peer->ibuf)
2696 stream_reset (peer->ibuf);
2697
2698 done:
2699 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2700 {
2701 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002702 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002703 peer_delete (peer);
paul718e3742002-12-13 20:15:29 +00002704 }
2705 return 0;
2706}