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