1 /* BGP network related fucntions
2 Copyright (C) 1999 Kunihiro Ishiguro
4 This file is part of GNU Zebra.
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
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.
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
24 #include "sockunion.h"
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"
43 extern struct zebra_privs_t bgpd_privs
;
45 static int bgp_bind(struct peer
*);
47 /* BGP listening socket. */
52 struct thread
*thread
;
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.
60 bgp_md5_set_socket (int socket
, union sockunion
*su
, const char *password
)
67 #if HAVE_DECL_TCP_MD5SIG
68 ret
= sockopt_tcp_signature (socket
, su
, password
);
70 #endif /* HAVE_TCP_MD5SIG */
73 zlog_warn ("can't set TCP_MD5SIG option on socket %d: %s", socket
, safe_strerror (en
));
78 /* Helper for bgp_connect */
80 bgp_md5_set_connect (int socket
, union sockunion
*su
, const char *password
)
84 #if HAVE_DECL_TCP_MD5SIG
85 if ( bgpd_privs
.change (ZPRIVS_RAISE
) )
87 zlog_err ("%s: could not raise privs", __func__
);
91 ret
= bgp_md5_set_socket (socket
, su
, password
);
93 if (bgpd_privs
.change (ZPRIVS_LOWER
) )
94 zlog_err ("%s: could not lower privs", __func__
);
95 #endif /* HAVE_TCP_MD5SIG */
101 bgp_md5_set (struct peer
*peer
)
103 struct listnode
*node
;
105 struct bgp_listener
*listener
;
107 if ( bgpd_privs
.change (ZPRIVS_RAISE
) )
109 zlog_err ("%s: could not raise privs", __func__
);
113 /* Just set the password on the listen socket(s). Outbound connections
114 * are taken care of in bgp_connect() below.
116 for (ALL_LIST_ELEMENTS_RO(bm
->listen_sockets
, node
, listener
))
117 if (listener
->su
.sa
.sa_family
== peer
->su
.sa
.sa_family
)
119 ret
= bgp_md5_set_socket (listener
->fd
, &peer
->su
, peer
->password
);
123 if (bgpd_privs
.change (ZPRIVS_LOWER
) )
124 zlog_err ("%s: could not lower privs", __func__
);
129 /* Update BGP socket send buffer size */
131 bgp_update_sock_send_buffer_size (int fd
)
133 int size
= BGP_SOCKET_SNDBUF_SIZE
;
135 socklen_t optlen
= sizeof(optval
);
137 if (getsockopt(fd
, SOL_SOCKET
, SO_SNDBUF
, &optval
, &optlen
) < 0)
139 zlog_err("getsockopt of SO_SNDBUF failed %s\n", safe_strerror(errno
));
144 if (setsockopt(fd
, SOL_SOCKET
, SO_SNDBUF
, &size
, sizeof(size
)) < 0)
146 zlog_err("Couldn't increase send buffer: %s\n", safe_strerror(errno
));
152 bgp_set_socket_ttl (struct peer
*peer
, int bgp_sock
)
154 char buf
[INET_ADDRSTRLEN
];
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
))
160 ret
= sockopt_ttl (peer
->su
.sa
.sa_family
, bgp_sock
, peer
->ttl
);
163 zlog_err ("%s: Can't set TxTTL on peer (rtrid %s) socket, err = %d",
165 inet_ntop (AF_INET
, &peer
->remote_id
, buf
, sizeof(buf
)),
169 else if (peer
->gtsm_hops
)
171 /* On Linux, setting minttl without setting ttl seems to mess with the
172 outgoing ttl. Therefore setting both.
174 ret
= sockopt_ttl (peer
->su
.sa
.sa_family
, bgp_sock
, MAXTTL
);
177 zlog_err ("%s: Can't set TxTTL on peer (rtrid %s) socket, err = %d",
179 inet_ntop (AF_INET
, &peer
->remote_id
, buf
, sizeof(buf
)),
182 ret
= sockopt_minttl (peer
->su
.sa
.sa_family
, bgp_sock
,
183 MAXTTL
+ 1 - peer
->gtsm_hops
);
186 zlog_err ("%s: Can't set MinTTL on peer (rtrid %s) socket, err = %d",
188 inet_ntop (AF_INET
, &peer
->remote_id
, buf
, sizeof(buf
)),
194 /* Accept bgp connection. */
196 bgp_accept (struct thread
*thread
)
201 struct bgp_listener
*listener
= THREAD_ARG(thread
);
204 char buf
[SU_ADDRSTRLEN
];
206 /* Register accept thread. */
207 accept_sock
= THREAD_FD (thread
);
210 zlog_err ("accept_sock is nevative value %d", accept_sock
);
213 listener
->thread
= thread_add_read (master
, bgp_accept
, listener
, accept_sock
);
215 /* Accept client connection. */
216 bgp_sock
= sockunion_accept (accept_sock
, &su
);
219 zlog_err ("[Error] BGP socket accept failed (%s)", safe_strerror (errno
));
222 set_nonblocking (bgp_sock
);
224 /* Set socket send buffer size */
225 bgp_update_sock_send_buffer_size(bgp_sock
);
227 /* Check remote IP address */
228 peer1
= peer_lookup (NULL
, &su
);
232 peer1
= peer_lookup_dynamic_neighbor (NULL
, &su
);
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() */
240 if (peer_active (peer1
))
241 BGP_EVENT_ADD (peer1
, TCP_connection_open
);
249 if (bgp_debug_neighbor_events(NULL
))
251 zlog_debug ("[Event] %s connection rejected - not configured"
252 " and not valid for dynamic",
253 inet_sutop (&su
, buf
));
259 if (CHECK_FLAG(peer1
->flags
, PEER_FLAG_SHUTDOWN
))
261 if (bgp_debug_neighbor_events(peer1
))
262 zlog_debug ("[Event] connection from %s rejected due to admin shutdown",
263 inet_sutop (&su
, buf
));
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.
274 if (peer1
->status
== Clearing
|| peer1
->status
== Deleted
)
276 struct bgp
*bgp
= peer1
->bgp
;
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
);
285 /* Check that at least one AF is activated for the peer. */
286 if (!peer_active (peer1
))
288 if (bgp_debug_neighbor_events(peer1
))
289 zlog_debug ("%s - incoming conn rejected - no AF activated for peer",
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
);
299 if (peer1
->doppelganger
)
301 /* We have an existing connection. Kill the existing one and run
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
);
310 bgp_set_socket_ttl (peer1
, bgp_sock
);
312 peer
= peer_create (&su
, peer1
->conf_if
, peer1
->bgp
, peer1
->local_as
,
313 peer1
->as
, peer1
->as_type
, 0, 0);
315 peer_xfer_config(peer
, peer1
);
316 UNSET_FLAG (peer
->flags
, PEER_FLAG_CONFIG_NODE
);
318 peer
->doppelganger
= peer1
;
319 peer1
->doppelganger
= peer
;
322 bgp_fsm_change_status(peer
, Active
);
323 BGP_TIMER_OFF(peer
->t_start
); /* created in peer_create() */
325 SET_FLAG (peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
327 /* Make dummy peer until read Open packet. */
328 if (peer1
->status
== Established
&&
329 CHECK_FLAG (peer1
->sflags
, PEER_STATUS_NSF_MODE
))
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.
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
);
340 if (peer_active (peer
))
342 BGP_EVENT_ADD (peer
, TCP_connection_open
);
348 /* BGP socket bind. */
350 bgp_bind (struct peer
*peer
)
352 #ifdef SO_BINDTODEVICE
356 if (! peer
->ifname
&& !peer
->conf_if
)
359 name
= (peer
->conf_if
? peer
->conf_if
: peer
->ifname
);
361 if ( bgpd_privs
.change (ZPRIVS_RAISE
) )
362 zlog_err ("bgp_bind: could not raise privs");
364 ret
= setsockopt (peer
->fd
, SOL_SOCKET
, SO_BINDTODEVICE
,
367 if (bgpd_privs
.change (ZPRIVS_LOWER
) )
368 zlog_err ("bgp_bind: could not lower privs");
372 zlog_info ("bind to interface %s failed", name
);
375 #endif /* SO_BINDTODEVICE */
380 bgp_update_address (struct interface
*ifp
, const union sockunion
*dst
,
381 union sockunion
*addr
)
383 struct prefix
*p
, *sel
, *d
;
384 struct connected
*connected
;
385 struct listnode
*node
;
388 d
= sockunion2hostprefix (dst
);
392 for (ALL_LIST_ELEMENTS_RO (ifp
->connected
, node
, connected
))
394 p
= connected
->address
;
395 if (p
->family
!= d
->family
)
397 if (prefix_common_bits (p
, d
) > common
)
400 common
= prefix_common_bits (sel
, d
);
408 prefix2sockunion (sel
, addr
);
412 /* Update source selection. */
414 bgp_update_source (struct peer
*peer
)
416 struct interface
*ifp
;
417 union sockunion addr
;
419 /* Source is specified with interface name. */
422 ifp
= if_lookup_by_name (peer
->update_if
);
426 if (bgp_update_address (ifp
, &peer
->su
, &addr
))
429 sockunion_bind (peer
->fd
, &addr
, 0, &addr
);
432 /* Source is specified with IP address. */
433 if (peer
->update_source
)
434 sockunion_bind (peer
->fd
, peer
->update_source
, 0, peer
->update_source
);
437 /* BGP try to connect to the peer. */
439 bgp_connect (struct peer
*peer
)
441 unsigned int ifindex
= 0;
443 if (peer
->conf_if
&& BGP_PEER_SU_UNSPEC(peer
))
445 zlog_debug("Peer address not learnt: Returning from connect");
448 /* Make socket for the peer. */
449 peer
->fd
= sockunion_socket (&peer
->su
);
453 set_nonblocking (peer
->fd
);
455 /* Set socket send buffer size */
456 bgp_update_sock_send_buffer_size(peer
->fd
);
458 bgp_set_socket_ttl (peer
, peer
->fd
);
460 sockopt_reuseaddr (peer
->fd
);
461 sockopt_reuseport (peer
->fd
);
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
);
469 else if (sockunion_family (&peer
->su
) == AF_INET6
)
470 setsockopt_ipv6_tclass (peer
->fd
, IPTOS_PREC_INTERNETCONTROL
);
472 if (bgpd_privs
.change (ZPRIVS_LOWER
))
473 zlog_err ("%s: could not lower privs", __func__
);
477 bgp_md5_set_connect (peer
->fd
, &peer
->su
, peer
->password
);
482 /* Update source bind. */
483 bgp_update_source (peer
);
486 if (peer
->conf_if
|| peer
->ifname
)
487 ifindex
= if_nametoindex (peer
->conf_if
? peer
->conf_if
: peer
->ifname
);
488 #endif /* HAVE_IPV6 */
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
);
494 /* Connect to the remote peer. */
495 return sockunion_connect (peer
->fd
, &peer
->su
, htons (peer
->port
), ifindex
);
498 /* After TCP connection is established. Get local address and port. */
500 bgp_getsockname (struct peer
*peer
)
504 sockunion_free (peer
->su_local
);
505 peer
->su_local
= NULL
;
510 sockunion_free (peer
->su_remote
);
511 peer
->su_remote
= NULL
;
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;
519 bgp_nexthop_set (peer
->su_local
, peer
->su_remote
, &peer
->nexthop
, peer
);
526 bgp_listener (int sock
, struct sockaddr
*sa
, socklen_t salen
)
528 struct bgp_listener
*listener
;
531 sockopt_reuseaddr (sock
);
532 sockopt_reuseport (sock
);
534 if (bgpd_privs
.change (ZPRIVS_RAISE
))
535 zlog_err ("%s: could not raise privs", __func__
);
537 #ifdef IPTOS_PREC_INTERNETCONTROL
538 if (sa
->sa_family
== AF_INET
)
539 setsockopt_ipv4_tos (sock
, IPTOS_PREC_INTERNETCONTROL
);
541 else if (sa
->sa_family
== AF_INET6
)
542 setsockopt_ipv6_tclass (sock
, IPTOS_PREC_INTERNETCONTROL
);
546 sockopt_v6only (sa
->sa_family
, sock
);
548 ret
= bind (sock
, sa
, salen
);
550 if (bgpd_privs
.change (ZPRIVS_LOWER
))
551 zlog_err ("%s: could not lower privs", __func__
);
555 zlog_err ("bind: %s", safe_strerror (en
));
559 ret
= listen (sock
, 3);
562 zlog_err ("listen: %s", safe_strerror (errno
));
566 listener
= XMALLOC (MTYPE_BGP_LISTENER
, sizeof(*listener
));
568 memcpy(&listener
->su
, sa
, salen
);
569 listener
->thread
= thread_add_read (master
, bgp_accept
, listener
, sock
);
570 listnode_add (bm
->listen_sockets
, listener
);
575 /* IPv6 supported version of BGP server socket setup. */
576 #if defined (HAVE_IPV6) && ! defined (NRL)
578 bgp_socket (unsigned short port
, const char *address
)
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
,
588 char port_str
[BUFSIZ
];
590 snprintf (port_str
, sizeof(port_str
), "%d", port
);
591 port_str
[sizeof (port_str
) - 1] = '\0';
593 ret
= getaddrinfo (address
, port_str
, &req
, &ainfo_save
);
596 zlog_err ("getaddrinfo: %s", gai_strerror (ret
));
601 for (ainfo
= ainfo_save
; ainfo
; ainfo
= ainfo
->ai_next
)
605 if (ainfo
->ai_family
!= AF_INET
&& ainfo
->ai_family
!= AF_INET6
)
608 sock
= socket (ainfo
->ai_family
, ainfo
->ai_socktype
, ainfo
->ai_protocol
);
611 zlog_err ("socket: %s", safe_strerror (errno
));
615 /* if we intend to implement ttl-security, this socket needs ttl=255 */
616 sockopt_ttl (ainfo
->ai_family
, sock
, MAXTTL
);
618 ret
= bgp_listener (sock
, ainfo
->ai_addr
, ainfo
->ai_addrlen
);
624 freeaddrinfo (ainfo_save
);
627 zlog_err ("%s: no usable addresses", __func__
);
634 /* Traditional IPv4 only version. */
636 bgp_socket (unsigned short port
, const char *address
)
640 struct sockaddr_in sin
;
643 sock
= socket (AF_INET
, SOCK_STREAM
, 0);
646 zlog_err ("socket: %s", safe_strerror (errno
));
650 /* if we intend to implement ttl-security, this socket needs ttl=255 */
651 sockopt_ttl (AF_INET
, sock
, MAXTTL
);
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
);
658 if (address
&& ((ret
= inet_aton(address
, &sin
.sin_addr
)) < 1))
660 zlog_err("bgp_socket: could not parse ip address %s: %s",
661 address
, safe_strerror (errno
));
664 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
665 sin
.sin_len
= socklen
;
666 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
668 ret
= bgp_listener (sock
, (struct sockaddr
*) &sin
, socklen
);
676 #endif /* HAVE_IPV6 && !NRL */
681 struct listnode
*node
, *next
;
682 struct bgp_listener
*listener
;
684 if (bm
->listen_sockets
== NULL
)
687 for (ALL_LIST_ELEMENTS (bm
->listen_sockets
, node
, next
, listener
))
689 thread_cancel (listener
->thread
);
690 close (listener
->fd
);
691 listnode_delete (bm
->listen_sockets
, listener
);
692 XFREE (MTYPE_BGP_LISTENER
, listener
);