]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_network.c
*: remove the configuration lock from all daemons
[mirror_frr.git] / bgpd / bgp_network.c
index 5b830a23acd8c6c5abb659392f644f97b61f02d0..e15b8f4ec38c356d7a418872e23fdc0d3d81bf47 100644 (file)
@@ -36,6 +36,7 @@
 #include "filter.h"
 #include "ns.h"
 #include "lib_errors.h"
+#include "nexthop.h"
 
 #include "bgpd/bgpd.h"
 #include "bgpd/bgp_open.h"
@@ -44,6 +45,7 @@
 #include "bgpd/bgp_debug.h"
 #include "bgpd/bgp_errors.h"
 #include "bgpd/bgp_network.h"
+#include "bgpd/bgp_zebra.h"
 
 extern struct zebra_privs_t bgpd_privs;
 
@@ -84,7 +86,8 @@ static int bgp_md5_set_socket(int socket, union sockunion *su,
 #endif /* HAVE_TCP_MD5SIG */
 
        if (ret < 0)
-               zlog_warn("can't set TCP_MD5SIG option on socket %d: %s",
+               flog_warn(EC_BGP_NO_TCP_MD5,
+                         "can't set TCP_MD5SIG option on socket %d: %s",
                          socket, safe_strerror(en));
 
        return ret;
@@ -97,17 +100,9 @@ static int bgp_md5_set_connect(int socket, union sockunion *su,
        int ret = -1;
 
 #if HAVE_DECL_TCP_MD5SIG
-       if (bgpd_privs.change(ZPRIVS_RAISE)) {
-               zlog_ferr(LIB_ERR_PRIVILEGES, "%s: could not raise privs",
-                         __func__);
-               return ret;
+       frr_elevate_privs(&bgpd_privs) {
+               ret = bgp_md5_set_socket(socket, su, password);
        }
-
-       ret = bgp_md5_set_socket(socket, su, password);
-
-       if (bgpd_privs.change(ZPRIVS_LOWER))
-               zlog_ferr(LIB_ERR_PRIVILEGES, "%s: could not lower privs",
-                         __func__);
 #endif /* HAVE_TCP_MD5SIG */
 
        return ret;
@@ -119,27 +114,18 @@ static int bgp_md5_set_password(struct peer *peer, const char *password)
        int ret = 0;
        struct bgp_listener *listener;
 
-       if (bgpd_privs.change(ZPRIVS_RAISE)) {
-               zlog_ferr(LIB_ERR_PRIVILEGES, "%s: could not raise privs",
-                         __func__);
-               return -1;
-       }
-
+       frr_elevate_privs(&bgpd_privs) {
        /* Set or unset the password on the listen socket(s). Outbound
-        * connections
-        * are taken care of in bgp_connect() below.
+        * connections are taken care of in bgp_connect() below.
         */
-       for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, listener))
-               if (listener->su.sa.sa_family == peer->su.sa.sa_family) {
-                       ret = bgp_md5_set_socket(listener->fd, &peer->su,
-                                                password);
-                       break;
-               }
-
-       if (bgpd_privs.change(ZPRIVS_LOWER))
-               zlog_ferr(LIB_ERR_PRIVILEGES, "%s: could not lower privs",
-                         __func__);
-
+               for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, listener))
+                       if (listener->su.sa.sa_family
+                           == peer->su.sa.sa_family) {
+                               ret = bgp_md5_set_socket(listener->fd,
+                                                        &peer->su, password);
+                               break;
+                       }
+       }
        return ret;
 }
 
@@ -164,8 +150,8 @@ int bgp_set_socket_ttl(struct peer *peer, int bgp_sock)
        if (!peer->gtsm_hops && (peer_sort(peer) == BGP_PEER_EBGP)) {
                ret = sockopt_ttl(peer->su.sa.sa_family, bgp_sock, peer->ttl);
                if (ret) {
-                       zlog_ferr(
-                               LIB_ERR_SOCKET,
+                       flog_err(
+                               EC_LIB_SOCKET,
                                "%s: Can't set TxTTL on peer (rtrid %s) socket, err = %d",
                                __func__,
                                inet_ntop(AF_INET, &peer->remote_id, buf,
@@ -180,8 +166,8 @@ int bgp_set_socket_ttl(struct peer *peer, int bgp_sock)
                */
                ret = sockopt_ttl(peer->su.sa.sa_family, bgp_sock, MAXTTL);
                if (ret) {
-                       zlog_ferr(
-                               LIB_ERR_SOCKET,
+                       flog_err(
+                               EC_LIB_SOCKET,
                                "%s: Can't set TxTTL on peer (rtrid %s) socket, err = %d",
                                __func__,
                                inet_ntop(AF_INET, &peer->remote_id, buf,
@@ -192,8 +178,8 @@ int bgp_set_socket_ttl(struct peer *peer, int bgp_sock)
                ret = sockopt_minttl(peer->su.sa.sa_family, bgp_sock,
                                     MAXTTL + 1 - peer->gtsm_hops);
                if (ret) {
-                       zlog_ferr(
-                               LIB_ERR_SOCKET,
+                       flog_err(
+                               EC_LIB_SOCKET,
                                "%s: Can't set MinTTL on peer (rtrid %s) socket, err = %d",
                                __func__,
                                inet_ntop(AF_INET, &peer->remote_id, buf,
@@ -238,10 +224,9 @@ static int bgp_get_instance_for_inc_conn(int sock, struct bgp **bgp_inst)
        rc = getsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, name, &name_len);
        if (rc != 0) {
 #if defined(HAVE_CUMULUS)
-               zlog_ferr(
-                       LIB_ERR_SOCKET,
-                       "[Error] BGP SO_BINDTODEVICE get failed (%s), sock %d",
-                       safe_strerror(errno), sock);
+               flog_err(EC_LIB_SOCKET,
+                        "[Error] BGP SO_BINDTODEVICE get failed (%s), sock %d",
+                        safe_strerror(errno), sock);
                return -1;
 #endif
        }
@@ -296,8 +281,8 @@ static int bgp_accept(struct thread *thread)
        /* Register accept thread. */
        accept_sock = THREAD_FD(thread);
        if (accept_sock < 0) {
-               zlog_ferr(LIB_ERR_SOCKET, "accept_sock is nevative value %d",
-                         accept_sock);
+               flog_err_sys(EC_LIB_SOCKET, "accept_sock is nevative value %d",
+                            accept_sock);
                return -1;
        }
        listener->thread = NULL;
@@ -308,9 +293,9 @@ static int bgp_accept(struct thread *thread)
        /* Accept client connection. */
        bgp_sock = sockunion_accept(accept_sock, &su);
        if (bgp_sock < 0) {
-               zlog_ferr(LIB_ERR_SOCKET,
-                         "[Error] BGP socket accept failed (%s)",
-                         safe_strerror(errno));
+               flog_err_sys(EC_LIB_SOCKET,
+                            "[Error] BGP socket accept failed (%s)",
+                            safe_strerror(errno));
                return -1;
        }
        set_nonblocking(bgp_sock);
@@ -421,7 +406,6 @@ static int bgp_accept(struct thread *thread)
 
        peer = peer_create(&su, peer1->conf_if, peer1->bgp, peer1->local_as,
                           peer1->as, peer1->as_type, 0, 0, NULL);
-       peer->su = su;
        hash_release(peer->bgp->peerhash, peer);
        hash_get(peer->bgp->peerhash, peer, hash_alloc_intern);
 
@@ -559,13 +543,11 @@ int bgp_connect(struct peer *peer)
                zlog_debug("Peer address not learnt: Returning from connect");
                return 0;
        }
-       if (bgpd_privs.change(ZPRIVS_RAISE))
-               zlog_ferr(LIB_ERR_PRIVILEGES, "Can't raise privileges");
+       frr_elevate_privs(&bgpd_privs) {
        /* Make socket for the peer. */
-       peer->fd = vrf_sockunion_socket(&peer->su, peer->bgp->vrf_id,
-                                       bgp_get_bound_name(peer));
-       if (bgpd_privs.change(ZPRIVS_LOWER))
-               zlog_ferr(LIB_ERR_PRIVILEGES, "Can't lower privileges");
+               peer->fd = vrf_sockunion_socket(&peer->su, peer->bgp->vrf_id,
+                                               bgp_get_bound_name(peer));
+       }
        if (peer->fd < 0)
                return -1;
 
@@ -580,20 +562,19 @@ int bgp_connect(struct peer *peer)
        sockopt_reuseaddr(peer->fd);
        sockopt_reuseport(peer->fd);
        if (sockopt_mark_default(peer->fd, DATAPLANE_MARK, &bgpd_privs) < 0)
-               zlog_warn("Unable to set mark on FD for peer %s, err=%s",
+               flog_warn(EC_BGP_NO_SOCKOPT_MARK,
+                         "Unable to set mark on FD for peer %s, err=%s",
                          peer->host, safe_strerror(errno));
 
 #ifdef IPTOS_PREC_INTERNETCONTROL
-       if (bgpd_privs.change(ZPRIVS_RAISE))
-               zlog_ferr(LIB_ERR_PRIVILEGES, "%s: could not raise privs",
-                         __func__);
-       if (sockunion_family(&peer->su) == AF_INET)
-               setsockopt_ipv4_tos(peer->fd, IPTOS_PREC_INTERNETCONTROL);
-       else if (sockunion_family(&peer->su) == AF_INET6)
-               setsockopt_ipv6_tclass(peer->fd, IPTOS_PREC_INTERNETCONTROL);
-       if (bgpd_privs.change(ZPRIVS_LOWER))
-               zlog_ferr(LIB_ERR_PRIVILEGES, "%s: could not lower privs",
-                         __func__);
+       frr_elevate_privs(&bgpd_privs) {
+               if (sockunion_family(&peer->su) == AF_INET)
+                       setsockopt_ipv4_tos(peer->fd,
+                                           IPTOS_PREC_INTERNETCONTROL);
+               else if (sockunion_family(&peer->su) == AF_INET6)
+                       setsockopt_ipv6_tclass(peer->fd,
+                                              IPTOS_PREC_INTERNETCONTROL);
+       }
 #endif
 
        if (peer->password)
@@ -638,15 +619,12 @@ int bgp_getsockname(struct peer *peer)
        if (!peer->su_remote)
                return -1;
 
-       if (bgp_nexthop_set(peer->su_local, peer->su_remote, &peer->nexthop,
-                           peer)) {
-#if defined(HAVE_CUMULUS)
-               zlog_ferr(
-                       BGP_ERR_NH_UPD,
-                       "%s: nexthop_set failed, resetting connection - intf %p",
-                       peer->host, peer->nexthop.ifp);
+       if (!bgp_zebra_nexthop_set(peer->su_local, peer->su_remote,
+                                  &peer->nexthop, peer)) {
+               flog_err(EC_BGP_NH_UPD,
+                        "%s: nexthop_set failed, resetting connection - intf %p",
+                        peer->host, peer->nexthop.ifp);
                return -1;
-#endif
        }
        return 0;
 }
@@ -661,33 +639,30 @@ static int bgp_listener(int sock, struct sockaddr *sa, socklen_t salen,
        sockopt_reuseaddr(sock);
        sockopt_reuseport(sock);
 
-       if (bgpd_privs.change(ZPRIVS_RAISE))
-               zlog_ferr(LIB_ERR_PRIVILEGES, "%s: could not raise privs",
-                         __func__);
+       frr_elevate_privs(&bgpd_privs) {
 
 #ifdef IPTOS_PREC_INTERNETCONTROL
-       if (sa->sa_family == AF_INET)
-               setsockopt_ipv4_tos(sock, IPTOS_PREC_INTERNETCONTROL);
-       else if (sa->sa_family == AF_INET6)
-               setsockopt_ipv6_tclass(sock, IPTOS_PREC_INTERNETCONTROL);
+               if (sa->sa_family == AF_INET)
+                       setsockopt_ipv4_tos(sock, IPTOS_PREC_INTERNETCONTROL);
+               else if (sa->sa_family == AF_INET6)
+                       setsockopt_ipv6_tclass(sock,
+                                              IPTOS_PREC_INTERNETCONTROL);
 #endif
 
-       sockopt_v6only(sa->sa_family, sock);
+               sockopt_v6only(sa->sa_family, sock);
 
-       ret = bind(sock, sa, salen);
-       en = errno;
-       if (bgpd_privs.change(ZPRIVS_LOWER))
-               zlog_ferr(LIB_ERR_PRIVILEGES, "%s: could not lower privs",
-                         __func__);
+               ret = bind(sock, sa, salen);
+               en = errno;
+       }
 
        if (ret < 0) {
-               zlog_ferr(LIB_ERR_SOCKET, "bind: %s", safe_strerror(en));
+               flog_err_sys(EC_LIB_SOCKET, "bind: %s", safe_strerror(en));
                return ret;
        }
 
        ret = listen(sock, SOMAXCONN);
        if (ret < 0) {
-               zlog_ferr(LIB_ERR_SOCKET, "listen: %s", safe_strerror(errno));
+               flog_err_sys(EC_LIB_SOCKET, "listen: %s", safe_strerror(errno));
                return ret;
        }
 
@@ -695,7 +670,8 @@ static int bgp_listener(int sock, struct sockaddr *sa, socklen_t salen,
        listener->fd = sock;
 
        /* this socket needs a change of ns. record bgp back pointer */
-       if (bgp->vrf_id != VRF_DEFAULT && vrf_is_mapped_on_netns(bgp->vrf_id))
+       if (bgp->vrf_id != VRF_DEFAULT && vrf_is_mapped_on_netns(
+                                               vrf_lookup_by_id(bgp->vrf_id)))
                listener->bgp = bgp;
 
        memcpy(&listener->su, sa, salen);
@@ -723,17 +699,20 @@ int bgp_socket(struct bgp *bgp, unsigned short port, const char *address)
        snprintf(port_str, sizeof(port_str), "%d", port);
        port_str[sizeof(port_str) - 1] = '\0';
 
-       if (bgpd_privs.change(ZPRIVS_RAISE))
-               zlog_ferr(LIB_ERR_PRIVILEGES, "Can't raise privileges");
-       ret = vrf_getaddrinfo(address, port_str, &req, &ainfo_save,
-                             bgp->vrf_id);
-       if (bgpd_privs.change(ZPRIVS_LOWER))
-               zlog_ferr(LIB_ERR_PRIVILEGES, "Can't lower privileges");
+       frr_elevate_privs(&bgpd_privs) {
+               ret = vrf_getaddrinfo(address, port_str, &req, &ainfo_save,
+                                     bgp->vrf_id);
+       }
        if (ret != 0) {
-               zlog_ferr(LIB_ERR_SOCKET, "getaddrinfo: %s", gai_strerror(ret));
+               flog_err_sys(EC_LIB_SOCKET, "getaddrinfo: %s",
+                            gai_strerror(ret));
+               return -1;
+       }
+       if (bgp_option_check(BGP_OPT_NO_ZEBRA) &&
+           bgp->vrf_id != VRF_DEFAULT) {
+               freeaddrinfo(ainfo_save);
                return -1;
        }
-
        count = 0;
        for (ainfo = ainfo_save; ainfo; ainfo = ainfo->ai_next) {
                int sock;
@@ -741,17 +720,17 @@ int bgp_socket(struct bgp *bgp, unsigned short port, const char *address)
                if (ainfo->ai_family != AF_INET && ainfo->ai_family != AF_INET6)
                        continue;
 
-               if (bgpd_privs.change(ZPRIVS_RAISE))
-                       zlog_ferr(LIB_ERR_PRIVILEGES, "Can't raise privileges");
-               sock = vrf_socket(ainfo->ai_family, ainfo->ai_socktype,
-                                 ainfo->ai_protocol, bgp->vrf_id,
-                                 (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ?
-                                  bgp->name : NULL));
-               if (bgpd_privs.change(ZPRIVS_LOWER))
-                       zlog_ferr(LIB_ERR_PRIVILEGES, "Can't lower privileges");
+               frr_elevate_privs(&bgpd_privs) {
+                       sock = vrf_socket(ainfo->ai_family,
+                                         ainfo->ai_socktype,
+                                         ainfo->ai_protocol, bgp->vrf_id,
+                                         (bgp->inst_type
+                                          == BGP_INSTANCE_TYPE_VRF
+                                          ? bgp->name : NULL));
+               }
                if (sock < 0) {
-                       zlog_ferr(LIB_ERR_SOCKET, "socket: %s",
-                                 safe_strerror(errno));
+                       flog_err_sys(EC_LIB_SOCKET, "socket: %s",
+                                    safe_strerror(errno));
                        continue;
                }
 
@@ -768,12 +747,12 @@ int bgp_socket(struct bgp *bgp, unsigned short port, const char *address)
        }
        freeaddrinfo(ainfo_save);
        if (count == 0 && bgp->inst_type != BGP_INSTANCE_TYPE_VRF) {
-               zlog_ferr(
-                       LIB_ERR_SOCKET,
+               flog_err(
+                       EC_LIB_SOCKET,
                        "%s: no usable addresses please check other programs usage of specified port %d",
                        __func__, port);
-               zlog_ferr(LIB_ERR_SOCKET, "%s: Program cannot continue",
-                         __func__);
+               flog_err_sys(EC_LIB_SOCKET, "%s: Program cannot continue",
+                            __func__);
                exit(-1);
        }