blob: d40c24c2cf75fb2238f5d36614fe1decec1de85e [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 {
Paul Jakma18ab08b2016-01-27 16:37:33 +00001663 withdraw.afi = AFI_IP;
1664 withdraw.safi = SAFI_UNICAST;
1665 withdraw.nlri = stream_pnt (s);
1666 withdraw.length = withdraw_len;
1667 ret = bgp_nlri_sanity_check (peer, &withdraw);
paul718e3742002-12-13 20:15:29 +00001668 if (ret < 0)
1669 return -1;
1670
1671 if (BGP_DEBUG (packet, PACKET_RECV))
ajs6b514742004-12-08 21:03:23 +00001672 zlog_debug ("%s [Update:RECV] Unfeasible NLRI received", peer->host);
paul718e3742002-12-13 20:15:29 +00001673
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 {
Paul Jakma18ab08b2016-01-27 16:37:33 +00001754 /* Set NLRI portion to structure. */
1755 update.afi = AFI_IP;
1756 update.safi = SAFI_UNICAST;
1757 update.nlri = stream_pnt (s);
1758 update.length = update_len;
1759
paul718e3742002-12-13 20:15:29 +00001760 /* Check NLRI packet format and prefix length. */
Paul Jakma18ab08b2016-01-27 16:37:33 +00001761 ret = bgp_nlri_sanity_check (peer, &update);
paul718e3742002-12-13 20:15:29 +00001762 if (ret < 0)
Paul Jakmab881c702010-11-23 16:35:42 +00001763 {
1764 bgp_attr_unintern_sub (&attr);
Lou Berger050defe2016-01-12 13:41:59 -05001765 bgp_attr_flush (&attr);
Paul Jakmab881c702010-11-23 16:35:42 +00001766 return -1;
1767 }
paul718e3742002-12-13 20:15:29 +00001768
paul9985f832005-02-09 15:51:56 +00001769 stream_forward_getp (s, update_len);
paul718e3742002-12-13 20:15:29 +00001770 }
1771
1772 /* NLRI is processed only when the peer is configured specific
1773 Address Family and Subsequent Address Family. */
1774 if (peer->afc[AFI_IP][SAFI_UNICAST])
1775 {
1776 if (withdraw.length)
1777 bgp_nlri_parse (peer, NULL, &withdraw);
1778
1779 if (update.length)
Paul Jakmab881c702010-11-23 16:35:42 +00001780 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &update);
paule01f9cb2004-07-09 17:48:53 +00001781
hassof4184462005-02-01 20:13:16 +00001782 if (mp_update.length
1783 && mp_update.afi == AFI_IP
1784 && mp_update.safi == SAFI_UNICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001785 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
hassof4184462005-02-01 20:13:16 +00001786
1787 if (mp_withdraw.length
1788 && mp_withdraw.afi == AFI_IP
1789 && mp_withdraw.safi == SAFI_UNICAST)
1790 bgp_nlri_parse (peer, NULL, &mp_withdraw);
1791
paule01f9cb2004-07-09 17:48:53 +00001792 if (! attribute_len && ! withdraw_len)
1793 {
1794 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001795 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],
1796 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001797
hasso93406d82005-02-02 14:40:33 +00001798 /* NSF delete stale route */
1799 if (peer->nsf[AFI_IP][SAFI_UNICAST])
1800 bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);
1801
1802 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001803 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001804 peer->host);
1805 }
paul718e3742002-12-13 20:15:29 +00001806 }
1807 if (peer->afc[AFI_IP][SAFI_MULTICAST])
1808 {
1809 if (mp_update.length
Lou Berger9da04bc2016-01-12 13:41:55 -05001810 && mp_update.afi == AFI_IP
paul718e3742002-12-13 20:15:29 +00001811 && mp_update.safi == SAFI_MULTICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001812 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001813
1814 if (mp_withdraw.length
Lou Berger9da04bc2016-01-12 13:41:55 -05001815 && mp_withdraw.afi == AFI_IP
paul718e3742002-12-13 20:15:29 +00001816 && mp_withdraw.safi == SAFI_MULTICAST)
1817 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001818
hasso93406d82005-02-02 14:40:33 +00001819 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001820 && mp_withdraw.afi == AFI_IP
1821 && mp_withdraw.safi == SAFI_MULTICAST
1822 && mp_withdraw.length == 0)
1823 {
1824 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001825 SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
1826 PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001827
hasso93406d82005-02-02 14:40:33 +00001828 /* NSF delete stale route */
1829 if (peer->nsf[AFI_IP][SAFI_MULTICAST])
1830 bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);
1831
1832 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001833 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001834 peer->host);
1835 }
paul718e3742002-12-13 20:15:29 +00001836 }
1837 if (peer->afc[AFI_IP6][SAFI_UNICAST])
1838 {
1839 if (mp_update.length
1840 && mp_update.afi == AFI_IP6
1841 && mp_update.safi == SAFI_UNICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001842 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001843
1844 if (mp_withdraw.length
1845 && mp_withdraw.afi == AFI_IP6
1846 && mp_withdraw.safi == SAFI_UNICAST)
1847 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001848
hasso93406d82005-02-02 14:40:33 +00001849 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001850 && mp_withdraw.afi == AFI_IP6
1851 && mp_withdraw.safi == SAFI_UNICAST
1852 && mp_withdraw.length == 0)
1853 {
1854 /* End-of-RIB received */
hasso93406d82005-02-02 14:40:33 +00001855 SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);
paule01f9cb2004-07-09 17:48:53 +00001856
hasso93406d82005-02-02 14:40:33 +00001857 /* NSF delete stale route */
1858 if (peer->nsf[AFI_IP6][SAFI_UNICAST])
1859 bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST);
1860
1861 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00001862 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001863 peer->host);
1864 }
paul718e3742002-12-13 20:15:29 +00001865 }
1866 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
1867 {
1868 if (mp_update.length
1869 && mp_update.afi == AFI_IP6
1870 && mp_update.safi == SAFI_MULTICAST)
Paul Jakmab881c702010-11-23 16:35:42 +00001871 bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001872
1873 if (mp_withdraw.length
1874 && mp_withdraw.afi == AFI_IP6
1875 && mp_withdraw.safi == SAFI_MULTICAST)
1876 bgp_nlri_parse (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001877
hasso93406d82005-02-02 14:40:33 +00001878 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001879 && mp_withdraw.afi == AFI_IP6
1880 && mp_withdraw.safi == SAFI_MULTICAST
1881 && mp_withdraw.length == 0)
1882 {
1883 /* End-of-RIB received */
1884
hasso93406d82005-02-02 14:40:33 +00001885 /* NSF delete stale route */
1886 if (peer->nsf[AFI_IP6][SAFI_MULTICAST])
1887 bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST);
1888
paule01f9cb2004-07-09 17:48:53 +00001889 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001890 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Multicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001891 peer->host);
1892 }
paul718e3742002-12-13 20:15:29 +00001893 }
1894 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
1895 {
1896 if (mp_update.length
1897 && mp_update.afi == AFI_IP
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001898 && mp_update.safi == SAFI_MPLS_LABELED_VPN)
Lou Berger9da04bc2016-01-12 13:41:55 -05001899 bgp_nlri_parse_vpn (peer, NLRI_ATTR_ARG, &mp_update);
paul718e3742002-12-13 20:15:29 +00001900
1901 if (mp_withdraw.length
1902 && mp_withdraw.afi == AFI_IP
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001903 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN)
Lou Berger9da04bc2016-01-12 13:41:55 -05001904 bgp_nlri_parse_vpn (peer, NULL, &mp_withdraw);
paule01f9cb2004-07-09 17:48:53 +00001905
hasso93406d82005-02-02 14:40:33 +00001906 if (! withdraw_len
paule01f9cb2004-07-09 17:48:53 +00001907 && mp_withdraw.afi == AFI_IP
Denis Ovsienko42e6d742011-07-14 12:36:19 +04001908 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN
paule01f9cb2004-07-09 17:48:53 +00001909 && mp_withdraw.length == 0)
1910 {
1911 /* End-of-RIB received */
1912
1913 if (BGP_DEBUG (update, UPDATE_IN))
ajs6b514742004-12-08 21:03:23 +00001914 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s",
paule01f9cb2004-07-09 17:48:53 +00001915 peer->host);
1916 }
paul718e3742002-12-13 20:15:29 +00001917 }
Lou Berger9da04bc2016-01-12 13:41:55 -05001918 if (peer->afc[AFI_IP6][SAFI_MPLS_VPN])
1919 {
1920 if (mp_update.length
1921 && mp_update.afi == AFI_IP6
1922 && mp_update.safi == SAFI_MPLS_LABELED_VPN)
1923 bgp_nlri_parse_vpn (peer, NLRI_ATTR_ARG, &mp_update);
1924
1925 if (mp_withdraw.length
1926 && mp_withdraw.afi == AFI_IP6
1927 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN)
1928 bgp_nlri_parse_vpn (peer, NULL, &mp_withdraw);
1929
1930 if (! withdraw_len
1931 && mp_withdraw.afi == AFI_IP6
1932 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN
1933 && mp_withdraw.length == 0)
1934 {
1935 /* End-of-RIB received */
1936
1937 if (BGP_DEBUG (update, UPDATE_IN))
1938 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for VPNv4 Unicast from %s",
1939 peer->host);
1940 }
1941 }
Lou Berger298cc2f2016-01-12 13:42:02 -05001942 if (peer->afc[AFI_IP][SAFI_ENCAP])
1943 {
1944 if (mp_update.length
1945 && mp_update.afi == AFI_IP
1946 && mp_update.safi == SAFI_ENCAP)
Paul Jakmac49a2742016-02-05 14:57:17 +00001947 bgp_nlri_parse_encap (peer, NLRI_ATTR_ARG, &mp_update);
Lou Berger298cc2f2016-01-12 13:42:02 -05001948
1949 if (mp_withdraw.length
1950 && mp_withdraw.afi == AFI_IP
1951 && mp_withdraw.safi == SAFI_ENCAP)
Paul Jakmac49a2742016-02-05 14:57:17 +00001952 bgp_nlri_parse_encap (peer, NULL, &mp_withdraw);
Lou Berger298cc2f2016-01-12 13:42:02 -05001953
1954 if (! withdraw_len
1955 && mp_withdraw.afi == AFI_IP
1956 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN
1957 && mp_withdraw.length == 0)
1958 {
1959 /* End-of-RIB received */
1960
1961 if (BGP_DEBUG (update, UPDATE_IN))
1962 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for Encap Unicast from %s",
1963 peer->host);
1964 }
1965 }
1966 if (peer->afc[AFI_IP6][SAFI_ENCAP])
1967 {
1968 if (mp_update.length
1969 && mp_update.afi == AFI_IP6
1970 && mp_update.safi == SAFI_ENCAP)
Paul Jakmac49a2742016-02-05 14:57:17 +00001971 bgp_nlri_parse_encap (peer, NLRI_ATTR_ARG, &mp_update);
Lou Berger298cc2f2016-01-12 13:42:02 -05001972
1973 if (mp_withdraw.length
1974 && mp_withdraw.afi == AFI_IP6
1975 && mp_withdraw.safi == SAFI_ENCAP)
Paul Jakmac49a2742016-02-05 14:57:17 +00001976 bgp_nlri_parse_encap (peer, NULL, &mp_withdraw);
Lou Berger298cc2f2016-01-12 13:42:02 -05001977
1978 if (! withdraw_len
1979 && mp_withdraw.afi == AFI_IP6
1980 && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN
1981 && mp_withdraw.length == 0)
1982 {
1983 /* End-of-RIB received */
1984
1985 if (BGP_DEBUG (update, UPDATE_IN))
1986 zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for Encap Unicast from %s",
1987 peer->host);
1988 }
1989 }
paul718e3742002-12-13 20:15:29 +00001990
1991 /* Everything is done. We unintern temporary structures which
1992 interned in bgp_attr_parse(). */
Paul Jakmab881c702010-11-23 16:35:42 +00001993 bgp_attr_unintern_sub (&attr);
Lou Berger050defe2016-01-12 13:41:59 -05001994 bgp_attr_flush (&attr);
Jorge Boncompte [DTI2]489d0052012-05-07 16:53:03 +00001995
paul718e3742002-12-13 20:15:29 +00001996 /* If peering is stopped due to some reason, do not generate BGP
1997 event. */
1998 if (peer->status != Established)
1999 return 0;
2000
2001 /* Increment packet counter. */
2002 peer->update_in++;
Stephen Hemminger65957882010-01-15 16:22:10 +03002003 peer->update_time = bgp_clock ();
paul718e3742002-12-13 20:15:29 +00002004
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02002005 /* Rearm holdtime timer */
Jorge Boncompte [DTI2]6a4677b2012-05-07 16:53:07 +00002006 BGP_TIMER_OFF (peer->t_holdtime);
Jorge Boncompte [DTI2]e2c38e62012-06-20 17:45:50 +02002007 bgp_timer_set (peer);
paul718e3742002-12-13 20:15:29 +00002008
2009 return 0;
2010}
2011
2012/* Notify message treatment function. */
paul94f2b392005-06-28 12:44:16 +00002013static void
paul718e3742002-12-13 20:15:29 +00002014bgp_notify_receive (struct peer *peer, bgp_size_t size)
2015{
2016 struct bgp_notify bgp_notify;
2017
2018 if (peer->notify.data)
2019 {
2020 XFREE (MTYPE_TMP, peer->notify.data);
2021 peer->notify.data = NULL;
2022 peer->notify.length = 0;
2023 }
2024
2025 bgp_notify.code = stream_getc (peer->ibuf);
2026 bgp_notify.subcode = stream_getc (peer->ibuf);
2027 bgp_notify.length = size - 2;
2028 bgp_notify.data = NULL;
2029
2030 /* Preserv notify code and sub code. */
2031 peer->notify.code = bgp_notify.code;
2032 peer->notify.subcode = bgp_notify.subcode;
2033 /* For further diagnostic record returned Data. */
2034 if (bgp_notify.length)
2035 {
2036 peer->notify.length = size - 2;
2037 peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);
2038 memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);
2039 }
2040
2041 /* For debug */
2042 {
2043 int i;
2044 int first = 0;
2045 char c[4];
2046
2047 if (bgp_notify.length)
2048 {
2049 bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);
2050 for (i = 0; i < bgp_notify.length; i++)
2051 if (first)
2052 {
2053 sprintf (c, " %02x", stream_getc (peer->ibuf));
2054 strcat (bgp_notify.data, c);
2055 }
2056 else
2057 {
2058 first = 1;
2059 sprintf (c, "%02x", stream_getc (peer->ibuf));
2060 strcpy (bgp_notify.data, c);
2061 }
2062 }
2063
2064 bgp_notify_print(peer, &bgp_notify, "received");
2065 if (bgp_notify.data)
Daniel Walton363c9032015-10-21 06:42:54 -07002066 {
2067 XFREE (MTYPE_TMP, bgp_notify.data);
2068 bgp_notify.data = NULL;
2069 bgp_notify.length = 0;
2070 }
paul718e3742002-12-13 20:15:29 +00002071 }
2072
2073 /* peer count update */
2074 peer->notify_in++;
2075
hassoe0701b72004-05-20 09:19:34 +00002076 if (peer->status == Established)
2077 peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
2078
paul718e3742002-12-13 20:15:29 +00002079 /* We have to check for Notify with Unsupported Optional Parameter.
2080 in that case we fallback to open without the capability option.
2081 But this done in bgp_stop. We just mark it here to avoid changing
2082 the fsm tables. */
2083 if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&
2084 bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )
2085 UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
2086
paul718e3742002-12-13 20:15:29 +00002087 BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);
2088}
2089
2090/* Keepalive treatment function -- get keepalive send keepalive */
paul94f2b392005-06-28 12:44:16 +00002091static void
paul718e3742002-12-13 20:15:29 +00002092bgp_keepalive_receive (struct peer *peer, bgp_size_t size)
2093{
2094 if (BGP_DEBUG (keepalive, KEEPALIVE))
ajs6b514742004-12-08 21:03:23 +00002095 zlog_debug ("%s KEEPALIVE rcvd", peer->host);
paul718e3742002-12-13 20:15:29 +00002096
2097 BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);
2098}
2099
2100/* Route refresh message is received. */
paul94f2b392005-06-28 12:44:16 +00002101static void
paul718e3742002-12-13 20:15:29 +00002102bgp_route_refresh_receive (struct peer *peer, bgp_size_t size)
2103{
2104 afi_t afi;
2105 safi_t safi;
paul718e3742002-12-13 20:15:29 +00002106 struct stream *s;
2107
2108 /* If peer does not have the capability, send notification. */
2109 if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))
2110 {
2111 plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",
2112 peer->host);
2113 bgp_notify_send (peer,
2114 BGP_NOTIFY_HEADER_ERR,
2115 BGP_NOTIFY_HEADER_BAD_MESTYPE);
2116 return;
2117 }
2118
2119 /* Status must be Established. */
2120 if (peer->status != Established)
2121 {
2122 plog_err (peer->log,
2123 "%s [Error] Route refresh packet received under status %s",
2124 peer->host, LOOKUP (bgp_status_msg, peer->status));
2125 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
2126 return;
2127 }
2128
2129 s = peer->ibuf;
2130
2131 /* Parse packet. */
2132 afi = stream_getw (s);
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002133 /* reserved byte */
2134 stream_getc (s);
paul718e3742002-12-13 20:15:29 +00002135 safi = stream_getc (s);
2136
2137 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002138 zlog_debug ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +00002139 peer->host, afi, safi);
2140
2141 /* Check AFI and SAFI. */
2142 if ((afi != AFI_IP && afi != AFI_IP6)
2143 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
Denis Ovsienko42e6d742011-07-14 12:36:19 +04002144 && safi != SAFI_MPLS_LABELED_VPN))
paul718e3742002-12-13 20:15:29 +00002145 {
2146 if (BGP_DEBUG (normal, NORMAL))
2147 {
ajs6b514742004-12-08 21:03:23 +00002148 zlog_debug ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",
paul718e3742002-12-13 20:15:29 +00002149 peer->host, afi, safi);
2150 }
2151 return;
2152 }
2153
2154 /* Adjust safi code. */
Denis Ovsienko42e6d742011-07-14 12:36:19 +04002155 if (safi == SAFI_MPLS_LABELED_VPN)
paul718e3742002-12-13 20:15:29 +00002156 safi = SAFI_MPLS_VPN;
2157
2158 if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)
2159 {
2160 u_char *end;
2161 u_char when_to_refresh;
2162 u_char orf_type;
2163 u_int16_t orf_len;
2164
2165 if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)
2166 {
2167 zlog_info ("%s ORF route refresh length error", peer->host);
2168 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2169 return;
2170 }
2171
2172 when_to_refresh = stream_getc (s);
2173 end = stream_pnt (s) + (size - 5);
2174
Paul Jakma370b64a2007-12-22 16:49:52 +00002175 while ((stream_pnt (s) + 2) < end)
paul718e3742002-12-13 20:15:29 +00002176 {
2177 orf_type = stream_getc (s);
2178 orf_len = stream_getw (s);
Paul Jakma370b64a2007-12-22 16:49:52 +00002179
2180 /* orf_len in bounds? */
2181 if ((stream_pnt (s) + orf_len) > end)
2182 break; /* XXX: Notify instead?? */
paul718e3742002-12-13 20:15:29 +00002183 if (orf_type == ORF_TYPE_PREFIX
2184 || orf_type == ORF_TYPE_PREFIX_OLD)
2185 {
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002186 uint8_t *p_pnt = stream_pnt (s);
2187 uint8_t *p_end = stream_pnt (s) + orf_len;
paul718e3742002-12-13 20:15:29 +00002188 struct orf_prefix orfp;
2189 u_char common = 0;
2190 u_int32_t seq;
2191 int psize;
2192 char name[BUFSIZ];
paul718e3742002-12-13 20:15:29 +00002193 int ret;
2194
2195 if (BGP_DEBUG (normal, NORMAL))
2196 {
ajs6b514742004-12-08 21:03:23 +00002197 zlog_debug ("%s rcvd Prefixlist ORF(%d) length %d",
paul718e3742002-12-13 20:15:29 +00002198 peer->host, orf_type, orf_len);
2199 }
2200
Paul Jakma370b64a2007-12-22 16:49:52 +00002201 /* we're going to read at least 1 byte of common ORF header,
2202 * and 7 bytes of ORF Address-filter entry from the stream
2203 */
2204 if (orf_len < 7)
2205 break;
2206
paul718e3742002-12-13 20:15:29 +00002207 /* ORF prefix-list name */
2208 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
2209
2210 while (p_pnt < p_end)
2211 {
Chris Halld64379e2010-05-14 16:38:39 +04002212 /* If the ORF entry is malformed, want to read as much of it
2213 * as possible without going beyond the bounds of the entry,
2214 * to maximise debug information.
2215 */
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002216 int ok;
paul718e3742002-12-13 20:15:29 +00002217 memset (&orfp, 0, sizeof (struct orf_prefix));
2218 common = *p_pnt++;
Chris Halld64379e2010-05-14 16:38:39 +04002219 /* after ++: p_pnt <= p_end */
paul718e3742002-12-13 20:15:29 +00002220 if (common & ORF_COMMON_PART_REMOVE_ALL)
2221 {
2222 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002223 zlog_debug ("%s rcvd Remove-All pfxlist ORF request", peer->host);
David Lamparterc9c06d02015-04-13 10:21:35 +02002224 prefix_bgp_orf_remove_all (afi, name);
paul718e3742002-12-13 20:15:29 +00002225 break;
2226 }
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002227 ok = ((size_t)(p_end - p_pnt) >= sizeof(u_int32_t)) ;
Denis Ovsienkobb915f52011-12-13 21:11:39 +04002228 if (ok)
Chris Halld64379e2010-05-14 16:38:39 +04002229 {
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002230 memcpy (&seq, p_pnt, sizeof (u_int32_t));
2231 p_pnt += sizeof (u_int32_t);
2232 orfp.seq = ntohl (seq);
Chris Halld64379e2010-05-14 16:38:39 +04002233 }
2234 else
2235 p_pnt = p_end ;
2236
2237 if ((ok = (p_pnt < p_end)))
2238 orfp.ge = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2239 if ((ok = (p_pnt < p_end)))
2240 orfp.le = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */
2241 if ((ok = (p_pnt < p_end)))
2242 orfp.p.prefixlen = *p_pnt++ ;
2243 orfp.p.family = afi2family (afi); /* afi checked already */
2244
2245 psize = PSIZE (orfp.p.prefixlen); /* 0 if not ok */
2246 if (psize > prefix_blen(&orfp.p)) /* valid for family ? */
2247 {
2248 ok = 0 ;
2249 psize = prefix_blen(&orfp.p) ;
2250 }
2251 if (psize > (p_end - p_pnt)) /* valid for packet ? */
2252 {
2253 ok = 0 ;
2254 psize = p_end - p_pnt ;
2255 }
2256
2257 if (psize > 0)
2258 memcpy (&orfp.p.u.prefix, p_pnt, psize);
paul718e3742002-12-13 20:15:29 +00002259 p_pnt += psize;
2260
2261 if (BGP_DEBUG (normal, NORMAL))
Jorge Boncompte [DTI2]14542f32012-05-07 16:52:53 +00002262 {
2263 char buf[INET6_BUFSIZ];
2264
2265 zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d%s",
2266 peer->host,
2267 (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"),
2268 (common & ORF_COMMON_PART_DENY ? "deny" : "permit"),
2269 orfp.seq,
2270 inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, INET6_BUFSIZ),
2271 orfp.p.prefixlen, orfp.ge, orfp.le,
2272 ok ? "" : " MALFORMED");
2273 }
2274
Chris Halld64379e2010-05-14 16:38:39 +04002275 if (ok)
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002276 ret = prefix_bgp_orf_set (name, afi, &orfp,
2277 (common & ORF_COMMON_PART_DENY ? 0 : 1 ),
2278 (common & ORF_COMMON_PART_REMOVE ? 0 : 1));
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002279
2280 if (!ok || (ok && ret != CMD_SUCCESS))
paul718e3742002-12-13 20:15:29 +00002281 {
2282 if (BGP_DEBUG (normal, NORMAL))
Paul Jakmafdbc8e72011-04-11 16:31:43 +01002283 zlog_debug ("%s Received misformatted prefixlist ORF."
2284 " Remove All pfxlist", peer->host);
David Lamparterc9c06d02015-04-13 10:21:35 +02002285 prefix_bgp_orf_remove_all (afi, name);
paul718e3742002-12-13 20:15:29 +00002286 break;
2287 }
2288 }
2289 peer->orf_plist[afi][safi] =
David Lamparterc9c06d02015-04-13 10:21:35 +02002290 prefix_bgp_orf_lookup (afi, name);
paul718e3742002-12-13 20:15:29 +00002291 }
paul9985f832005-02-09 15:51:56 +00002292 stream_forward_getp (s, orf_len);
paul718e3742002-12-13 20:15:29 +00002293 }
2294 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002295 zlog_debug ("%s rcvd Refresh %s ORF request", peer->host,
paul718e3742002-12-13 20:15:29 +00002296 when_to_refresh == REFRESH_DEFER ? "Defer" : "Immediate");
2297 if (when_to_refresh == REFRESH_DEFER)
2298 return;
2299 }
2300
2301 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2302 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
2303 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH);
2304
2305 /* Perform route refreshment to the peer */
2306 bgp_announce_route (peer, afi, safi);
2307}
2308
paul94f2b392005-06-28 12:44:16 +00002309static int
paul718e3742002-12-13 20:15:29 +00002310bgp_capability_msg_parse (struct peer *peer, u_char *pnt, bgp_size_t length)
2311{
2312 u_char *end;
Paul Jakma6d582722007-08-06 15:21:45 +00002313 struct capability_mp_data mpc;
2314 struct capability_header *hdr;
paul718e3742002-12-13 20:15:29 +00002315 u_char action;
paul718e3742002-12-13 20:15:29 +00002316 afi_t afi;
2317 safi_t safi;
2318
paul718e3742002-12-13 20:15:29 +00002319 end = pnt + length;
2320
2321 while (pnt < end)
Paul Jakma6d582722007-08-06 15:21:45 +00002322 {
paul718e3742002-12-13 20:15:29 +00002323 /* We need at least action, capability code and capability length. */
2324 if (pnt + 3 > end)
2325 {
2326 zlog_info ("%s Capability length error", peer->host);
2327 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2328 return -1;
2329 }
paul718e3742002-12-13 20:15:29 +00002330 action = *pnt;
Paul Jakma6d582722007-08-06 15:21:45 +00002331 hdr = (struct capability_header *)(pnt + 1);
2332
paul718e3742002-12-13 20:15:29 +00002333 /* Action value check. */
2334 if (action != CAPABILITY_ACTION_SET
2335 && action != CAPABILITY_ACTION_UNSET)
2336 {
2337 zlog_info ("%s Capability Action Value error %d",
2338 peer->host, action);
2339 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2340 return -1;
2341 }
2342
2343 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002344 zlog_debug ("%s CAPABILITY has action: %d, code: %u, length %u",
Paul Jakma6d582722007-08-06 15:21:45 +00002345 peer->host, action, hdr->code, hdr->length);
paul718e3742002-12-13 20:15:29 +00002346
2347 /* Capability length check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002348 if ((pnt + hdr->length + 3) > end)
paul718e3742002-12-13 20:15:29 +00002349 {
2350 zlog_info ("%s Capability length error", peer->host);
2351 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
2352 return -1;
2353 }
2354
Paul Jakma6d582722007-08-06 15:21:45 +00002355 /* Fetch structure to the byte stream. */
2356 memcpy (&mpc, pnt + 3, sizeof (struct capability_mp_data));
2357
paul718e3742002-12-13 20:15:29 +00002358 /* We know MP Capability Code. */
Paul Jakma6d582722007-08-06 15:21:45 +00002359 if (hdr->code == CAPABILITY_CODE_MP)
paul718e3742002-12-13 20:15:29 +00002360 {
Paul Jakma6d582722007-08-06 15:21:45 +00002361 afi = ntohs (mpc.afi);
2362 safi = mpc.safi;
paul718e3742002-12-13 20:15:29 +00002363
2364 /* Ignore capability when override-capability is set. */
2365 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
2366 continue;
Paul Jakma6d582722007-08-06 15:21:45 +00002367
2368 if (!bgp_afi_safi_valid_indices (afi, &safi))
2369 {
2370 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002371 zlog_debug ("%s Dynamic Capability MP_EXT afi/safi invalid "
2372 "(%u/%u)", peer->host, afi, safi);
Paul Jakma6d582722007-08-06 15:21:45 +00002373 continue;
2374 }
2375
paul718e3742002-12-13 20:15:29 +00002376 /* Address family check. */
Paul Jakma6d582722007-08-06 15:21:45 +00002377 if (BGP_DEBUG (normal, NORMAL))
2378 zlog_debug ("%s CAPABILITY has %s MP_EXT CAP for afi/safi: %u/%u",
2379 peer->host,
2380 action == CAPABILITY_ACTION_SET
2381 ? "Advertising" : "Removing",
2382 ntohs(mpc.afi) , mpc.safi);
2383
2384 if (action == CAPABILITY_ACTION_SET)
2385 {
2386 peer->afc_recv[afi][safi] = 1;
2387 if (peer->afc[afi][safi])
2388 {
2389 peer->afc_nego[afi][safi] = 1;
2390 bgp_announce_route (peer, afi, safi);
2391 }
2392 }
2393 else
2394 {
2395 peer->afc_recv[afi][safi] = 0;
2396 peer->afc_nego[afi][safi] = 0;
paul718e3742002-12-13 20:15:29 +00002397
Paul Jakma6d582722007-08-06 15:21:45 +00002398 if (peer_active_nego (peer))
Chris Caputo228da422009-07-18 05:44:03 +00002399 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
Paul Jakma6d582722007-08-06 15:21:45 +00002400 else
2401 BGP_EVENT_ADD (peer, BGP_Stop);
2402 }
paul718e3742002-12-13 20:15:29 +00002403 }
paul718e3742002-12-13 20:15:29 +00002404 else
2405 {
2406 zlog_warn ("%s unrecognized capability code: %d - ignored",
Paul Jakma6d582722007-08-06 15:21:45 +00002407 peer->host, hdr->code);
paul718e3742002-12-13 20:15:29 +00002408 }
Paul Jakma6d582722007-08-06 15:21:45 +00002409 pnt += hdr->length + 3;
paul718e3742002-12-13 20:15:29 +00002410 }
2411 return 0;
2412}
2413
Paul Jakma01b7ce22009-06-18 12:34:43 +01002414/* Dynamic Capability is received.
2415 *
2416 * This is exported for unit-test purposes
2417 */
Paul Jakma6d582722007-08-06 15:21:45 +00002418int
paul718e3742002-12-13 20:15:29 +00002419bgp_capability_receive (struct peer *peer, bgp_size_t size)
2420{
2421 u_char *pnt;
paul718e3742002-12-13 20:15:29 +00002422
2423 /* Fetch pointer. */
2424 pnt = stream_pnt (peer->ibuf);
2425
2426 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002427 zlog_debug ("%s rcv CAPABILITY", peer->host);
paul718e3742002-12-13 20:15:29 +00002428
2429 /* If peer does not have the capability, send notification. */
2430 if (! CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV))
2431 {
2432 plog_err (peer->log, "%s [Error] BGP dynamic capability is not enabled",
2433 peer->host);
2434 bgp_notify_send (peer,
2435 BGP_NOTIFY_HEADER_ERR,
2436 BGP_NOTIFY_HEADER_BAD_MESTYPE);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002437 return -1;
paul718e3742002-12-13 20:15:29 +00002438 }
2439
2440 /* Status must be Established. */
2441 if (peer->status != Established)
2442 {
2443 plog_err (peer->log,
2444 "%s [Error] Dynamic capability packet received under status %s", peer->host, LOOKUP (bgp_status_msg, peer->status));
2445 bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00002446 return -1;
paul718e3742002-12-13 20:15:29 +00002447 }
2448
2449 /* Parse packet. */
Paul Jakma6d582722007-08-06 15:21:45 +00002450 return bgp_capability_msg_parse (peer, pnt, size);
paul718e3742002-12-13 20:15:29 +00002451}
David Lamparter6b0655a2014-06-04 06:53:35 +02002452
paul718e3742002-12-13 20:15:29 +00002453/* BGP read utility function. */
paul94f2b392005-06-28 12:44:16 +00002454static int
paul718e3742002-12-13 20:15:29 +00002455bgp_read_packet (struct peer *peer)
2456{
2457 int nbytes;
2458 int readsize;
2459
paul9985f832005-02-09 15:51:56 +00002460 readsize = peer->packet_size - stream_get_endp (peer->ibuf);
paul718e3742002-12-13 20:15:29 +00002461
2462 /* If size is zero then return. */
2463 if (! readsize)
2464 return 0;
2465
2466 /* Read packet from fd. */
Stephen Hemminger35398582010-08-05 10:26:23 -07002467 nbytes = stream_read_try (peer->ibuf, peer->fd, readsize);
paul718e3742002-12-13 20:15:29 +00002468
2469 /* If read byte is smaller than zero then error occured. */
2470 if (nbytes < 0)
2471 {
Stephen Hemminger35398582010-08-05 10:26:23 -07002472 /* Transient error should retry */
2473 if (nbytes == -2)
paul718e3742002-12-13 20:15:29 +00002474 return -1;
2475
2476 plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
ajs6099b3b2004-11-20 02:06:59 +00002477 peer->host, safe_strerror (errno));
hasso93406d82005-02-02 14:40:33 +00002478
2479 if (peer->status == Established)
2480 {
2481 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2482 {
2483 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2484 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2485 }
2486 else
2487 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2488 }
2489
paul718e3742002-12-13 20:15:29 +00002490 BGP_EVENT_ADD (peer, TCP_fatal_error);
2491 return -1;
2492 }
2493
2494 /* When read byte is zero : clear bgp peer and return */
2495 if (nbytes == 0)
2496 {
2497 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002498 plog_debug (peer->log, "%s [Event] BGP connection closed fd %d",
pauleb821182004-05-01 08:44:08 +00002499 peer->host, peer->fd);
hassoe0701b72004-05-20 09:19:34 +00002500
2501 if (peer->status == Established)
hasso93406d82005-02-02 14:40:33 +00002502 {
2503 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
2504 {
2505 peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
2506 SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
2507 }
2508 else
2509 peer->last_reset = PEER_DOWN_CLOSE_SESSION;
2510 }
hassoe0701b72004-05-20 09:19:34 +00002511
paul718e3742002-12-13 20:15:29 +00002512 BGP_EVENT_ADD (peer, TCP_connection_closed);
2513 return -1;
2514 }
2515
2516 /* We read partial packet. */
paul9985f832005-02-09 15:51:56 +00002517 if (stream_get_endp (peer->ibuf) != peer->packet_size)
paul718e3742002-12-13 20:15:29 +00002518 return -1;
2519
2520 return 0;
2521}
2522
2523/* Marker check. */
paul94f2b392005-06-28 12:44:16 +00002524static int
paul718e3742002-12-13 20:15:29 +00002525bgp_marker_all_one (struct stream *s, int length)
2526{
2527 int i;
2528
2529 for (i = 0; i < length; i++)
2530 if (s->data[i] != 0xff)
2531 return 0;
2532
2533 return 1;
2534}
2535
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002536/* Recent thread time.
2537 On same clock base as bgp_clock (MONOTONIC)
2538 but can be time of last context switch to bgp_read thread. */
2539static time_t
2540bgp_recent_clock (void)
2541{
2542 return recent_relative_time().tv_sec;
2543}
2544
paul718e3742002-12-13 20:15:29 +00002545/* Starting point of packet process function. */
2546int
2547bgp_read (struct thread *thread)
2548{
2549 int ret;
2550 u_char type = 0;
2551 struct peer *peer;
2552 bgp_size_t size;
2553 char notify_data_length[2];
2554
2555 /* Yes first of all get peer pointer. */
2556 peer = THREAD_ARG (thread);
2557 peer->t_read = NULL;
2558
2559 /* For non-blocking IO check. */
2560 if (peer->status == Connect)
2561 {
2562 bgp_connect_check (peer);
2563 goto done;
2564 }
2565 else
2566 {
pauleb821182004-05-01 08:44:08 +00002567 if (peer->fd < 0)
paul718e3742002-12-13 20:15:29 +00002568 {
pauleb821182004-05-01 08:44:08 +00002569 zlog_err ("bgp_read peer's fd is negative value %d", peer->fd);
paul718e3742002-12-13 20:15:29 +00002570 return -1;
2571 }
pauleb821182004-05-01 08:44:08 +00002572 BGP_READ_ON (peer->t_read, bgp_read, peer->fd);
paul718e3742002-12-13 20:15:29 +00002573 }
2574
2575 /* Read packet header to determine type of the packet */
2576 if (peer->packet_size == 0)
2577 peer->packet_size = BGP_HEADER_SIZE;
2578
paul9985f832005-02-09 15:51:56 +00002579 if (stream_get_endp (peer->ibuf) < BGP_HEADER_SIZE)
paul718e3742002-12-13 20:15:29 +00002580 {
2581 ret = bgp_read_packet (peer);
2582
2583 /* Header read error or partial read packet. */
2584 if (ret < 0)
2585 goto done;
2586
2587 /* Get size and type. */
paul9985f832005-02-09 15:51:56 +00002588 stream_forward_getp (peer->ibuf, BGP_MARKER_SIZE);
paul718e3742002-12-13 20:15:29 +00002589 memcpy (notify_data_length, stream_pnt (peer->ibuf), 2);
2590 size = stream_getw (peer->ibuf);
2591 type = stream_getc (peer->ibuf);
2592
2593 if (BGP_DEBUG (normal, NORMAL) && type != 2 && type != 0)
ajs6b514742004-12-08 21:03:23 +00002594 zlog_debug ("%s rcv message type %d, length (excl. header) %d",
paul718e3742002-12-13 20:15:29 +00002595 peer->host, type, size - BGP_HEADER_SIZE);
2596
2597 /* Marker check */
paulf5ba3872004-07-09 12:11:31 +00002598 if (((type == BGP_MSG_OPEN) || (type == BGP_MSG_KEEPALIVE))
paul718e3742002-12-13 20:15:29 +00002599 && ! bgp_marker_all_one (peer->ibuf, BGP_MARKER_SIZE))
2600 {
2601 bgp_notify_send (peer,
2602 BGP_NOTIFY_HEADER_ERR,
2603 BGP_NOTIFY_HEADER_NOT_SYNC);
2604 goto done;
2605 }
2606
2607 /* BGP type check. */
2608 if (type != BGP_MSG_OPEN && type != BGP_MSG_UPDATE
2609 && type != BGP_MSG_NOTIFY && type != BGP_MSG_KEEPALIVE
2610 && type != BGP_MSG_ROUTE_REFRESH_NEW
2611 && type != BGP_MSG_ROUTE_REFRESH_OLD
2612 && type != BGP_MSG_CAPABILITY)
2613 {
2614 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002615 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002616 "%s unknown message type 0x%02x",
2617 peer->host, type);
2618 bgp_notify_send_with_data (peer,
2619 BGP_NOTIFY_HEADER_ERR,
2620 BGP_NOTIFY_HEADER_BAD_MESTYPE,
2621 &type, 1);
2622 goto done;
2623 }
2624 /* Mimimum packet length check. */
2625 if ((size < BGP_HEADER_SIZE)
2626 || (size > BGP_MAX_PACKET_SIZE)
2627 || (type == BGP_MSG_OPEN && size < BGP_MSG_OPEN_MIN_SIZE)
2628 || (type == BGP_MSG_UPDATE && size < BGP_MSG_UPDATE_MIN_SIZE)
2629 || (type == BGP_MSG_NOTIFY && size < BGP_MSG_NOTIFY_MIN_SIZE)
2630 || (type == BGP_MSG_KEEPALIVE && size != BGP_MSG_KEEPALIVE_MIN_SIZE)
2631 || (type == BGP_MSG_ROUTE_REFRESH_NEW && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2632 || (type == BGP_MSG_ROUTE_REFRESH_OLD && size < BGP_MSG_ROUTE_REFRESH_MIN_SIZE)
2633 || (type == BGP_MSG_CAPABILITY && size < BGP_MSG_CAPABILITY_MIN_SIZE))
2634 {
2635 if (BGP_DEBUG (normal, NORMAL))
ajs6b514742004-12-08 21:03:23 +00002636 plog_debug (peer->log,
paul718e3742002-12-13 20:15:29 +00002637 "%s bad message length - %d for %s",
2638 peer->host, size,
2639 type == 128 ? "ROUTE-REFRESH" :
2640 bgp_type_str[(int) type]);
2641 bgp_notify_send_with_data (peer,
2642 BGP_NOTIFY_HEADER_ERR,
2643 BGP_NOTIFY_HEADER_BAD_MESLEN,
hassoc9e52be2004-09-26 16:09:34 +00002644 (u_char *) notify_data_length, 2);
paul718e3742002-12-13 20:15:29 +00002645 goto done;
2646 }
2647
2648 /* Adjust size to message length. */
2649 peer->packet_size = size;
2650 }
2651
2652 ret = bgp_read_packet (peer);
2653 if (ret < 0)
2654 goto done;
2655
2656 /* Get size and type again. */
2657 size = stream_getw_from (peer->ibuf, BGP_MARKER_SIZE);
2658 type = stream_getc_from (peer->ibuf, BGP_MARKER_SIZE + 2);
2659
2660 /* BGP packet dump function. */
2661 bgp_dump_packet (peer, type, peer->ibuf);
2662
2663 size = (peer->packet_size - BGP_HEADER_SIZE);
2664
2665 /* Read rest of the packet and call each sort of packet routine */
2666 switch (type)
2667 {
2668 case BGP_MSG_OPEN:
2669 peer->open_in++;
paulf5ba3872004-07-09 12:11:31 +00002670 bgp_open_receive (peer, size); /* XXX return value ignored! */
paul718e3742002-12-13 20:15:29 +00002671 break;
2672 case BGP_MSG_UPDATE:
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002673 peer->readtime = bgp_recent_clock ();
paul718e3742002-12-13 20:15:29 +00002674 bgp_update_receive (peer, size);
2675 break;
2676 case BGP_MSG_NOTIFY:
2677 bgp_notify_receive (peer, size);
2678 break;
2679 case BGP_MSG_KEEPALIVE:
Stephen Hemmingerd61c1bb2013-01-04 22:29:23 +00002680 peer->readtime = bgp_recent_clock ();
paul718e3742002-12-13 20:15:29 +00002681 bgp_keepalive_receive (peer, size);
2682 break;
2683 case BGP_MSG_ROUTE_REFRESH_NEW:
2684 case BGP_MSG_ROUTE_REFRESH_OLD:
2685 peer->refresh_in++;
2686 bgp_route_refresh_receive (peer, size);
2687 break;
2688 case BGP_MSG_CAPABILITY:
2689 peer->dynamic_cap_in++;
2690 bgp_capability_receive (peer, size);
2691 break;
2692 }
2693
2694 /* Clear input buffer. */
2695 peer->packet_size = 0;
2696 if (peer->ibuf)
2697 stream_reset (peer->ibuf);
2698
2699 done:
2700 if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2701 {
2702 if (BGP_DEBUG (events, EVENTS))
ajs6b514742004-12-08 21:03:23 +00002703 zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host);
paul718e3742002-12-13 20:15:29 +00002704 peer_delete (peer);
paul718e3742002-12-13 20:15:29 +00002705 }
2706 return 0;
2707}