]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_network.c
zebra: zebra-warnings.patch
[mirror_frr.git] / bgpd / bgp_network.c
1 /* BGP network related fucntions
2 Copyright (C) 1999 Kunihiro Ishiguro
3
4 This file is part of GNU Zebra.
5
6 GNU Zebra is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 GNU Zebra is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Zebra; see the file COPYING. If not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
20
21 #include <zebra.h>
22
23 #include "thread.h"
24 #include "sockunion.h"
25 #include "sockopt.h"
26 #include "memory.h"
27 #include "log.h"
28 #include "if.h"
29 #include "prefix.h"
30 #include "command.h"
31 #include "privs.h"
32 #include "linklist.h"
33 #include "network.h"
34 #include "queue.h"
35
36 #include "bgpd/bgpd.h"
37 #include "bgpd/bgp_open.h"
38 #include "bgpd/bgp_fsm.h"
39 #include "bgpd/bgp_attr.h"
40 #include "bgpd/bgp_debug.h"
41 #include "bgpd/bgp_network.h"
42
43 extern struct zebra_privs_t bgpd_privs;
44
45 static int bgp_bind(struct peer *);
46
47 /* BGP listening socket. */
48 struct bgp_listener
49 {
50 int fd;
51 union sockunion su;
52 struct thread *thread;
53 };
54
55 /*
56 * Set MD5 key for the socket, for the given IPv4 peer address.
57 * If the password is NULL or zero-length, the option will be disabled.
58 */
59 static int
60 bgp_md5_set_socket (int socket, union sockunion *su, const char *password)
61 {
62 int ret = -1;
63 int en = ENOSYS;
64
65 assert (socket >= 0);
66
67 #if HAVE_DECL_TCP_MD5SIG
68 ret = sockopt_tcp_signature (socket, su, password);
69 en = errno;
70 #endif /* HAVE_TCP_MD5SIG */
71
72 if (ret < 0)
73 zlog_warn ("can't set TCP_MD5SIG option on socket %d: %s", socket, safe_strerror (en));
74
75 return ret;
76 }
77
78 /* Helper for bgp_connect */
79 static int
80 bgp_md5_set_connect (int socket, union sockunion *su, const char *password)
81 {
82 int ret = -1;
83
84 #if HAVE_DECL_TCP_MD5SIG
85 if ( bgpd_privs.change (ZPRIVS_RAISE) )
86 {
87 zlog_err ("%s: could not raise privs", __func__);
88 return ret;
89 }
90
91 ret = bgp_md5_set_socket (socket, su, password);
92
93 if (bgpd_privs.change (ZPRIVS_LOWER) )
94 zlog_err ("%s: could not lower privs", __func__);
95 #endif /* HAVE_TCP_MD5SIG */
96
97 return ret;
98 }
99
100 int
101 bgp_md5_set (struct peer *peer)
102 {
103 struct listnode *node;
104 int ret = 0;
105 struct bgp_listener *listener;
106
107 if ( bgpd_privs.change (ZPRIVS_RAISE) )
108 {
109 zlog_err ("%s: could not raise privs", __func__);
110 return -1;
111 }
112
113 /* Just set the password on the listen socket(s). Outbound connections
114 * are taken care of in bgp_connect() below.
115 */
116 for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, listener))
117 if (listener->su.sa.sa_family == peer->su.sa.sa_family)
118 {
119 ret = bgp_md5_set_socket (listener->fd, &peer->su, peer->password);
120 break;
121 }
122
123 if (bgpd_privs.change (ZPRIVS_LOWER) )
124 zlog_err ("%s: could not lower privs", __func__);
125
126 return ret;
127 }
128
129 /* Update BGP socket send buffer size */
130 static void
131 bgp_update_sock_send_buffer_size (int fd)
132 {
133 int size = BGP_SOCKET_SNDBUF_SIZE;
134 int optval;
135 socklen_t optlen = sizeof(optval);
136
137 if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &optval, &optlen) < 0)
138 {
139 zlog_err("getsockopt of SO_SNDBUF failed %s\n", safe_strerror(errno));
140 return;
141 }
142 if (optval < size)
143 {
144 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)) < 0)
145 {
146 zlog_err("Couldn't increase send buffer: %s\n", safe_strerror(errno));
147 }
148 }
149 }
150
151 static void
152 bgp_set_socket_ttl (struct peer *peer, int bgp_sock)
153 {
154 char buf[INET_ADDRSTRLEN];
155 int ret = 0;
156
157 /* In case of peer is EBGP, we should set TTL for this connection. */
158 if (!peer->gtsm_hops && (peer_sort (peer) == BGP_PEER_EBGP))
159 {
160 ret = sockopt_ttl (peer->su.sa.sa_family, bgp_sock, peer->ttl);
161 if (ret)
162 {
163 zlog_err ("%s: Can't set TxTTL on peer (rtrid %s) socket, err = %d",
164 __func__,
165 inet_ntop (AF_INET, &peer->remote_id, buf, sizeof(buf)),
166 errno);
167 }
168 }
169 else if (peer->gtsm_hops)
170 {
171 /* On Linux, setting minttl without setting ttl seems to mess with the
172 outgoing ttl. Therefore setting both.
173 */
174 ret = sockopt_ttl (peer->su.sa.sa_family, bgp_sock, MAXTTL);
175 if (ret)
176 {
177 zlog_err ("%s: Can't set TxTTL on peer (rtrid %s) socket, err = %d",
178 __func__,
179 inet_ntop (AF_INET, &peer->remote_id, buf, sizeof(buf)),
180 errno);
181 }
182 ret = sockopt_minttl (peer->su.sa.sa_family, bgp_sock,
183 MAXTTL + 1 - peer->gtsm_hops);
184 if (ret)
185 {
186 zlog_err ("%s: Can't set MinTTL on peer (rtrid %s) socket, err = %d",
187 __func__,
188 inet_ntop (AF_INET, &peer->remote_id, buf, sizeof(buf)),
189 errno);
190 }
191 }
192 }
193
194 /* Accept bgp connection. */
195 static int
196 bgp_accept (struct thread *thread)
197 {
198 int bgp_sock;
199 int accept_sock;
200 union sockunion su;
201 struct bgp_listener *listener = THREAD_ARG(thread);
202 struct peer *peer;
203 struct peer *peer1;
204 char buf[SU_ADDRSTRLEN];
205
206 /* Register accept thread. */
207 accept_sock = THREAD_FD (thread);
208 if (accept_sock < 0)
209 {
210 zlog_err ("accept_sock is nevative value %d", accept_sock);
211 return -1;
212 }
213 listener->thread = thread_add_read (master, bgp_accept, listener, accept_sock);
214
215 /* Accept client connection. */
216 bgp_sock = sockunion_accept (accept_sock, &su);
217 if (bgp_sock < 0)
218 {
219 zlog_err ("[Error] BGP socket accept failed (%s)", safe_strerror (errno));
220 return -1;
221 }
222 set_nonblocking (bgp_sock);
223
224 /* Set socket send buffer size */
225 bgp_update_sock_send_buffer_size(bgp_sock);
226
227 /* Check remote IP address */
228 peer1 = peer_lookup (NULL, &su);
229
230 if (! peer1)
231 {
232 peer1 = peer_lookup_dynamic_neighbor (NULL, &su);
233 if (peer1)
234 {
235 /* Dynamic neighbor has been created, let it proceed */
236 peer1->fd = bgp_sock;
237 bgp_fsm_change_status(peer1, Active);
238 BGP_TIMER_OFF(peer1->t_start); /* created in peer_create() */
239
240 if (peer_active (peer1))
241 BGP_EVENT_ADD (peer1, TCP_connection_open);
242
243 return 0;
244 }
245 }
246
247 if (! peer1)
248 {
249 if (bgp_debug_neighbor_events(NULL))
250 {
251 zlog_debug ("[Event] %s connection rejected - not configured"
252 " and not valid for dynamic",
253 inet_sutop (&su, buf));
254 }
255 close (bgp_sock);
256 return -1;
257 }
258
259 if (CHECK_FLAG(peer1->flags, PEER_FLAG_SHUTDOWN))
260 {
261 if (bgp_debug_neighbor_events(peer1))
262 zlog_debug ("[Event] connection from %s rejected due to admin shutdown",
263 inet_sutop (&su, buf));
264 close (bgp_sock);
265 return -1;
266 }
267
268 /*
269 * Do not accept incoming connections in Clearing state. This can result
270 * in incorect state transitions - e.g., the connection goes back to
271 * Established and then the Clearing_Completed event is generated. Also,
272 * block incoming connection in Deleted state.
273 */
274 if (peer1->status == Clearing || peer1->status == Deleted)
275 {
276 struct bgp *bgp = peer1->bgp;
277
278 if (bgp_debug_neighbor_events(peer1))
279 zlog_debug("[Event] Closing incoming conn for %s (0x%x) state %d",
280 peer1->host, peer1, peer1->status);
281 close (bgp_sock);
282 return -1;
283 }
284
285 /* Check that at least one AF is activated for the peer. */
286 if (!peer_active (peer1))
287 {
288 if (bgp_debug_neighbor_events(peer1))
289 zlog_debug ("%s - incoming conn rejected - no AF activated for peer",
290 peer1->host);
291 close (bgp_sock);
292 return -1;
293 }
294
295 if (bgp_debug_neighbor_events(peer1))
296 zlog_debug ("[Event] BGP connection from host %s fd %d",
297 inet_sutop (&su, buf), bgp_sock);
298
299 if (peer1->doppelganger)
300 {
301 /* We have an existing connection. Kill the existing one and run
302 with this one.
303 */
304 if (bgp_debug_neighbor_events(peer1))
305 zlog_debug ("[Event] New active connection from peer %s, Killing"
306 " previous active connection", peer1->host);
307 peer_delete(peer1->doppelganger);
308 }
309
310 bgp_set_socket_ttl (peer1, bgp_sock);
311
312 peer = peer_create (&su, peer1->conf_if, peer1->bgp, peer1->local_as,
313 peer1->as, peer1->as_type, 0, 0);
314
315 peer_xfer_config(peer, peer1);
316 UNSET_FLAG (peer->flags, PEER_FLAG_CONFIG_NODE);
317
318 peer->doppelganger = peer1;
319 peer1->doppelganger = peer;
320 peer->fd = bgp_sock;
321 bgp_bind(peer);
322 bgp_fsm_change_status(peer, Active);
323 BGP_TIMER_OFF(peer->t_start); /* created in peer_create() */
324
325 SET_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER);
326
327 /* Make dummy peer until read Open packet. */
328 if (peer1->status == Established &&
329 CHECK_FLAG (peer1->sflags, PEER_STATUS_NSF_MODE))
330 {
331 /* If we have an existing established connection with graceful restart
332 * capability announced with one or more address families, then drop
333 * existing established connection and move state to connect.
334 */
335 peer1->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
336 SET_FLAG (peer1->sflags, PEER_STATUS_NSF_WAIT);
337 bgp_event_update(peer1, TCP_connection_closed);
338 }
339
340 if (peer_active (peer))
341 {
342 BGP_EVENT_ADD (peer, TCP_connection_open);
343 }
344
345 return 0;
346 }
347
348 /* BGP socket bind. */
349 static int
350 bgp_bind (struct peer *peer)
351 {
352 #ifdef SO_BINDTODEVICE
353 int ret;
354 char *name;
355
356 if (! peer->ifname && !peer->conf_if)
357 return 0;
358
359 name = (peer->conf_if ? peer->conf_if : peer->ifname);
360
361 if ( bgpd_privs.change (ZPRIVS_RAISE) )
362 zlog_err ("bgp_bind: could not raise privs");
363
364 ret = setsockopt (peer->fd, SOL_SOCKET, SO_BINDTODEVICE,
365 name, strlen(name));
366
367 if (bgpd_privs.change (ZPRIVS_LOWER) )
368 zlog_err ("bgp_bind: could not lower privs");
369
370 if (ret < 0)
371 {
372 zlog_info ("bind to interface %s failed", name);
373 return ret;
374 }
375 #endif /* SO_BINDTODEVICE */
376 return 0;
377 }
378
379 static int
380 bgp_update_address (struct interface *ifp, const union sockunion *dst,
381 union sockunion *addr)
382 {
383 struct prefix *p, *sel, *d;
384 struct connected *connected;
385 struct listnode *node;
386 int common;
387
388 d = sockunion2hostprefix (dst);
389 sel = NULL;
390 common = -1;
391
392 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
393 {
394 p = connected->address;
395 if (p->family != d->family)
396 continue;
397 if (prefix_common_bits (p, d) > common)
398 {
399 sel = p;
400 common = prefix_common_bits (sel, d);
401 }
402 }
403
404 prefix_free (d);
405 if (!sel)
406 return 1;
407
408 prefix2sockunion (sel, addr);
409 return 0;
410 }
411
412 /* Update source selection. */
413 static void
414 bgp_update_source (struct peer *peer)
415 {
416 struct interface *ifp;
417 union sockunion addr;
418
419 /* Source is specified with interface name. */
420 if (peer->update_if)
421 {
422 ifp = if_lookup_by_name (peer->update_if);
423 if (! ifp)
424 return;
425
426 if (bgp_update_address (ifp, &peer->su, &addr))
427 return;
428
429 sockunion_bind (peer->fd, &addr, 0, &addr);
430 }
431
432 /* Source is specified with IP address. */
433 if (peer->update_source)
434 sockunion_bind (peer->fd, peer->update_source, 0, peer->update_source);
435 }
436
437 /* BGP try to connect to the peer. */
438 int
439 bgp_connect (struct peer *peer)
440 {
441 unsigned int ifindex = 0;
442
443 if (peer->conf_if && BGP_PEER_SU_UNSPEC(peer))
444 {
445 zlog_debug("Peer address not learnt: Returning from connect");
446 return 0;
447 }
448 /* Make socket for the peer. */
449 peer->fd = sockunion_socket (&peer->su);
450 if (peer->fd < 0)
451 return -1;
452
453 set_nonblocking (peer->fd);
454
455 /* Set socket send buffer size */
456 bgp_update_sock_send_buffer_size(peer->fd);
457
458 bgp_set_socket_ttl (peer, peer->fd);
459
460 sockopt_reuseaddr (peer->fd);
461 sockopt_reuseport (peer->fd);
462
463 #ifdef IPTOS_PREC_INTERNETCONTROL
464 if (bgpd_privs.change (ZPRIVS_RAISE))
465 zlog_err ("%s: could not raise privs", __func__);
466 if (sockunion_family (&peer->su) == AF_INET)
467 setsockopt_ipv4_tos (peer->fd, IPTOS_PREC_INTERNETCONTROL);
468 # ifdef HAVE_IPV6
469 else if (sockunion_family (&peer->su) == AF_INET6)
470 setsockopt_ipv6_tclass (peer->fd, IPTOS_PREC_INTERNETCONTROL);
471 # endif
472 if (bgpd_privs.change (ZPRIVS_LOWER))
473 zlog_err ("%s: could not lower privs", __func__);
474 #endif
475
476 if (peer->password)
477 bgp_md5_set_connect (peer->fd, &peer->su, peer->password);
478
479 /* Bind socket. */
480 bgp_bind (peer);
481
482 /* Update source bind. */
483 bgp_update_source (peer);
484
485 #ifdef HAVE_IPV6
486 if (peer->conf_if || peer->ifname)
487 ifindex = if_nametoindex (peer->conf_if ? peer->conf_if : peer->ifname);
488 #endif /* HAVE_IPV6 */
489
490 if (bgp_debug_neighbor_events(peer))
491 zlog_debug ("%s [Event] Connect start to %s fd %d",
492 peer->host, peer->host, peer->fd);
493
494 /* Connect to the remote peer. */
495 return sockunion_connect (peer->fd, &peer->su, htons (peer->port), ifindex);
496 }
497
498 /* After TCP connection is established. Get local address and port. */
499 int
500 bgp_getsockname (struct peer *peer)
501 {
502 if (peer->su_local)
503 {
504 sockunion_free (peer->su_local);
505 peer->su_local = NULL;
506 }
507
508 if (peer->su_remote)
509 {
510 sockunion_free (peer->su_remote);
511 peer->su_remote = NULL;
512 }
513
514 peer->su_local = sockunion_getsockname (peer->fd);
515 if (!peer->su_local) return -1;
516 peer->su_remote = sockunion_getpeername (peer->fd);
517 if (!peer->su_remote) return -1;
518
519 bgp_nexthop_set (peer->su_local, peer->su_remote, &peer->nexthop, peer);
520
521 return 0;
522 }
523
524
525 static int
526 bgp_listener (int sock, struct sockaddr *sa, socklen_t salen)
527 {
528 struct bgp_listener *listener;
529 int ret, en;
530
531 sockopt_reuseaddr (sock);
532 sockopt_reuseport (sock);
533
534 if (bgpd_privs.change (ZPRIVS_RAISE))
535 zlog_err ("%s: could not raise privs", __func__);
536
537 #ifdef IPTOS_PREC_INTERNETCONTROL
538 if (sa->sa_family == AF_INET)
539 setsockopt_ipv4_tos (sock, IPTOS_PREC_INTERNETCONTROL);
540 # ifdef HAVE_IPV6
541 else if (sa->sa_family == AF_INET6)
542 setsockopt_ipv6_tclass (sock, IPTOS_PREC_INTERNETCONTROL);
543 # endif
544 #endif
545
546 sockopt_v6only (sa->sa_family, sock);
547
548 ret = bind (sock, sa, salen);
549 en = errno;
550 if (bgpd_privs.change (ZPRIVS_LOWER))
551 zlog_err ("%s: could not lower privs", __func__);
552
553 if (ret < 0)
554 {
555 zlog_err ("bind: %s", safe_strerror (en));
556 return ret;
557 }
558
559 ret = listen (sock, 3);
560 if (ret < 0)
561 {
562 zlog_err ("listen: %s", safe_strerror (errno));
563 return ret;
564 }
565
566 listener = XMALLOC (MTYPE_BGP_LISTENER, sizeof(*listener));
567 listener->fd = sock;
568 memcpy(&listener->su, sa, salen);
569 listener->thread = thread_add_read (master, bgp_accept, listener, sock);
570 listnode_add (bm->listen_sockets, listener);
571
572 return 0;
573 }
574
575 /* IPv6 supported version of BGP server socket setup. */
576 #if defined (HAVE_IPV6) && ! defined (NRL)
577 int
578 bgp_socket (unsigned short port, const char *address)
579 {
580 struct addrinfo *ainfo;
581 struct addrinfo *ainfo_save;
582 static const struct addrinfo req = {
583 .ai_family = AF_UNSPEC,
584 .ai_flags = AI_PASSIVE,
585 .ai_socktype = SOCK_STREAM,
586 };
587 int ret, count;
588 char port_str[BUFSIZ];
589
590 snprintf (port_str, sizeof(port_str), "%d", port);
591 port_str[sizeof (port_str) - 1] = '\0';
592
593 ret = getaddrinfo (address, port_str, &req, &ainfo_save);
594 if (ret != 0)
595 {
596 zlog_err ("getaddrinfo: %s", gai_strerror (ret));
597 return -1;
598 }
599
600 count = 0;
601 for (ainfo = ainfo_save; ainfo; ainfo = ainfo->ai_next)
602 {
603 int sock;
604
605 if (ainfo->ai_family != AF_INET && ainfo->ai_family != AF_INET6)
606 continue;
607
608 sock = socket (ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol);
609 if (sock < 0)
610 {
611 zlog_err ("socket: %s", safe_strerror (errno));
612 continue;
613 }
614
615 /* if we intend to implement ttl-security, this socket needs ttl=255 */
616 sockopt_ttl (ainfo->ai_family, sock, MAXTTL);
617
618 ret = bgp_listener (sock, ainfo->ai_addr, ainfo->ai_addrlen);
619 if (ret == 0)
620 ++count;
621 else
622 close(sock);
623 }
624 freeaddrinfo (ainfo_save);
625 if (count == 0)
626 {
627 zlog_err ("%s: no usable addresses", __func__);
628 return -1;
629 }
630
631 return 0;
632 }
633 #else
634 /* Traditional IPv4 only version. */
635 int
636 bgp_socket (unsigned short port, const char *address)
637 {
638 int sock;
639 int socklen;
640 struct sockaddr_in sin;
641 int ret, en;
642
643 sock = socket (AF_INET, SOCK_STREAM, 0);
644 if (sock < 0)
645 {
646 zlog_err ("socket: %s", safe_strerror (errno));
647 return sock;
648 }
649
650 /* if we intend to implement ttl-security, this socket needs ttl=255 */
651 sockopt_ttl (AF_INET, sock, MAXTTL);
652
653 memset (&sin, 0, sizeof (struct sockaddr_in));
654 sin.sin_family = AF_INET;
655 sin.sin_port = htons (port);
656 socklen = sizeof (struct sockaddr_in);
657
658 if (address && ((ret = inet_aton(address, &sin.sin_addr)) < 1))
659 {
660 zlog_err("bgp_socket: could not parse ip address %s: %s",
661 address, safe_strerror (errno));
662 return ret;
663 }
664 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
665 sin.sin_len = socklen;
666 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
667
668 ret = bgp_listener (sock, (struct sockaddr *) &sin, socklen);
669 if (ret < 0)
670 {
671 close (sock);
672 return ret;
673 }
674 return sock;
675 }
676 #endif /* HAVE_IPV6 && !NRL */
677
678 void
679 bgp_close (void)
680 {
681 struct listnode *node, *next;
682 struct bgp_listener *listener;
683
684 if (bm->listen_sockets == NULL)
685 return;
686
687 for (ALL_LIST_ELEMENTS (bm->listen_sockets, node, next, listener))
688 {
689 thread_cancel (listener->thread);
690 close (listener->fd);
691 listnode_delete (bm->listen_sockets, listener);
692 XFREE (MTYPE_BGP_LISTENER, listener);
693 }
694 }