Merge pull request #5108 from donaldsharp/sendbuffer_size_bgp

Sendbuffer size bgp
This commit is contained in:
Donatas Abraitis 2019-10-20 12:09:42 +03:00 committed by GitHub
commit acf061a9ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 132 additions and 15 deletions

View File

@ -75,6 +75,7 @@ static const struct option longopts[] = {
{"ecmp", required_argument, NULL, 'e'}, {"ecmp", required_argument, NULL, 'e'},
{"int_num", required_argument, NULL, 'I'}, {"int_num", required_argument, NULL, 'I'},
{"no_zebra", no_argument, NULL, 'Z'}, {"no_zebra", no_argument, NULL, 'Z'},
{"socket_size", required_argument, NULL, 's'},
{0}}; {0}};
/* signal definitions */ /* signal definitions */
@ -386,17 +387,19 @@ int main(int argc, char **argv)
int no_zebra_flag = 0; int no_zebra_flag = 0;
int skip_runas = 0; int skip_runas = 0;
int instance = 0; int instance = 0;
int buffer_size = BGP_SOCKET_SNDBUF_SIZE;
frr_preinit(&bgpd_di, argc, argv); frr_preinit(&bgpd_di, argc, argv);
frr_opt_add( frr_opt_add(
"p:l:SnZe:I:" DEPRECATED_OPTIONS, longopts, "p:l:SnZe:I:s:" DEPRECATED_OPTIONS, longopts,
" -p, --bgp_port Set BGP listen port number (0 means do not listen).\n" " -p, --bgp_port Set BGP listen port number (0 means do not listen).\n"
" -l, --listenon Listen on specified address (implies -n)\n" " -l, --listenon Listen on specified address (implies -n)\n"
" -n, --no_kernel Do not install route to kernel.\n" " -n, --no_kernel Do not install route to kernel.\n"
" -Z, --no_zebra Do not communicate with Zebra.\n" " -Z, --no_zebra Do not communicate with Zebra.\n"
" -S, --skip_runas Skip capabilities checks, and changing user and group IDs.\n" " -S, --skip_runas Skip capabilities checks, and changing user and group IDs.\n"
" -e, --ecmp Specify ECMP to use.\n" " -e, --ecmp Specify ECMP to use.\n"
" -I, --int_num Set instance number (label-manager)\n"); " -I, --int_num Set instance number (label-manager)\n"
" -s, --socket_size Set BGP peer socket send buffer size\n");
/* Command line argument treatment. */ /* Command line argument treatment. */
while (1) { while (1) {
@ -452,6 +455,9 @@ int main(int argc, char **argv)
zlog_err("Instance %i out of range (0..%u)", zlog_err("Instance %i out of range (0..%u)",
instance, (unsigned short)-1); instance, (unsigned short)-1);
break; break;
case 's':
buffer_size = atoi(optarg);
break;
default: default:
frr_help_exit(1); frr_help_exit(1);
break; break;
@ -461,7 +467,7 @@ int main(int argc, char **argv)
memset(&bgpd_privs, 0, sizeof(bgpd_privs)); memset(&bgpd_privs, 0, sizeof(bgpd_privs));
/* BGP master init. */ /* BGP master init. */
bgp_master_init(frr_init()); bgp_master_init(frr_init(), buffer_size);
bm->port = bgp_port; bm->port = bgp_port;
if (bgp_port == 0) if (bgp_port == 0)
bgp_option_set(BGP_OPT_NO_LISTEN); bgp_option_set(BGP_OPT_NO_LISTEN);

View File

@ -320,6 +320,14 @@ static int bgp_get_instance_for_inc_conn(int sock, struct bgp **bgp_inst)
#endif #endif
} }
static void bgp_socket_set_buffer_size(const int fd)
{
if (getsockopt_so_sendbuf(fd) < (int)bm->socket_buffer)
setsockopt_so_sendbuf(fd, bm->socket_buffer);
if (getsockopt_so_recvbuf(fd) < (int)bm->socket_buffer)
setsockopt_so_recvbuf(fd, bm->socket_buffer);
}
/* Accept bgp connection. */ /* Accept bgp connection. */
static int bgp_accept(struct thread *thread) static int bgp_accept(struct thread *thread)
{ {
@ -371,8 +379,7 @@ static int bgp_accept(struct thread *thread)
return -1; return -1;
} }
/* Set socket send buffer size */ bgp_socket_set_buffer_size(bgp_sock);
setsockopt_so_sendbuf(bgp_sock, BGP_SOCKET_SNDBUF_SIZE);
/* Check remote IP address */ /* Check remote IP address */
peer1 = peer_lookup(bgp, &su); peer1 = peer_lookup(bgp, &su);
@ -621,8 +628,7 @@ int bgp_connect(struct peer *peer)
set_nonblocking(peer->fd); set_nonblocking(peer->fd);
/* Set socket send buffer size */ bgp_socket_set_buffer_size(peer->fd);
setsockopt_so_sendbuf(peer->fd, BGP_SOCKET_SNDBUF_SIZE);
if (bgp_set_socket_ttl(peer, peer->fd) < 0) if (bgp_set_socket_ttl(peer, peer->fd) < 0)
return -1; return -1;

View File

@ -7823,7 +7823,7 @@ int bgp_config_write(struct vty *vty)
return 0; return 0;
} }
void bgp_master_init(struct thread_master *master) void bgp_master_init(struct thread_master *master, const int buffer_size)
{ {
qobj_init(); qobj_init();
@ -7838,6 +7838,7 @@ void bgp_master_init(struct thread_master *master)
bm->t_rmap_update = NULL; bm->t_rmap_update = NULL;
bm->rmap_update_timer = RMAP_DEFAULT_UPDATE_TIMER; bm->rmap_update_timer = RMAP_DEFAULT_UPDATE_TIMER;
bm->terminating = false; bm->terminating = false;
bm->socket_buffer = buffer_size;
bgp_process_queue_init(); bgp_process_queue_init();

View File

@ -156,6 +156,9 @@ struct bgp_master {
/* BGP-EVPN VRF ID. Defaults to default VRF (if any) */ /* BGP-EVPN VRF ID. Defaults to default VRF (if any) */
struct bgp* bgp_evpn; struct bgp* bgp_evpn;
/* How big should we set the socket buffer size */
uint32_t socket_buffer;
bool terminating; /* global flag that sigint terminate seen */ bool terminating; /* global flag that sigint terminate seen */
QOBJ_FIELDS QOBJ_FIELDS
}; };
@ -1575,7 +1578,8 @@ extern char *peer_uptime(time_t uptime2, char *buf, size_t len, bool use_json,
extern int bgp_config_write(struct vty *); extern int bgp_config_write(struct vty *);
extern void bgp_master_init(struct thread_master *master); extern void bgp_master_init(struct thread_master *master,
const int buffer_size);
extern void bgp_init(unsigned short instance); extern void bgp_init(unsigned short instance);
extern void bgp_pthreads_run(void); extern void bgp_pthreads_run(void);

View File

@ -21,6 +21,48 @@ OPTIONS available for the |DAEMON| command:
.. include:: common-options.rst .. include:: common-options.rst
.. option:: -p, --bgp_port <port>
Set the bgp protocol's port number. When port number is 0, that means do not
listen bgp port.
.. option:: -l, --listenon
Specify a specific IP address for bgpd to listen on, rather than its default
of ``0.0.0.0`` / ``::``. This can be useful to constrain bgpd to an internal
address, or to run multiple bgpd processes on one host.
.. option:: -n, --no_kernel
Do not install learned routes into the linux kernel. This option is useful
for a route-reflector environment or if you are running multiple bgp
processes in the same namespace. This option is different than the --no_zebra
option in that a ZAPI connection is made.
.. option:: -S, --skip_runas
Skip the normal process of checking capabilities and changing user and group
information.
.. option:: -e, --ecmp
Run BGP with a limited ecmp capability, that is different than what BGP
was compiled with. The value specified must be greater than 0 and less
than or equal to the MULTIPATH_NUM specified on compilation.
.. option:: -Z, --no_zebra
Do not communicate with zebra at all. This is different than the --no_kernel
option in that we do not even open a ZAPI connection to the zebra process.
.. option:: -s, --socket_size
When opening tcp connections to our peers, set the socket send buffer
size that the kernel will use for the peers socket. This option
is only really useful at a very large scale. Experimentation should
be done to see if this is helping or not at the scale you are running
at.
LABEL MANAGER LABEL MANAGER
------------- -------------

View File

@ -35,6 +35,44 @@ be specified (:ref:`common-invocation-options`).
of ``0.0.0.0`` / ``::``. This can be useful to constrain bgpd to an internal of ``0.0.0.0`` / ``::``. This can be useful to constrain bgpd to an internal
address, or to run multiple bgpd processes on one host. address, or to run multiple bgpd processes on one host.
.. option:: -n, --no_kernel
Do not install learned routes into the linux kernel. This option is useful
for a route-reflector environment or if you are running multiple bgp
processes in the same namespace. This option is different than the --no_zebra
option in that a ZAPI connection is made.
.. option:: -S, --skip_runas
Skip the normal process of checking capabilities and changing user and group
information.
.. option:: -e, --ecmp
Run BGP with a limited ecmp capability, that is different than what BGP
was compiled with. The value specified must be greater than 0 and less
than or equal to the MULTIPATH_NUM specified on compilation.
.. option:: -Z, --no_zebra
Do not communicate with zebra at all. This is different than the --no_kernel
option in that we do not even open a ZAPI connection to the zebra process.
.. option:: -s, --socket_size
When opening tcp connections to our peers, set the socket send buffer
size that the kernel will use for the peers socket. This option
is only really useful at a very large scale. Experimentation should
be done to see if this is helping or not at the scale you are running
at.
LABEL MANAGER
-------------
.. option:: -I, --int_num
Set zclient id. This is required when using Zebra label manager in proxy mode.
.. _bgp-basic-concepts: .. _bgp-basic-concepts:
Basic Concepts Basic Concepts

View File

@ -72,6 +72,21 @@ int getsockopt_so_sendbuf(const int sock)
return optval; return optval;
} }
int getsockopt_so_recvbuf(const int sock)
{
uint32_t optval;
socklen_t optlen = sizeof(optval);
int ret = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&optval,
&optlen);
if (ret < 0) {
flog_err_sys(EC_LIB_SYSTEM_CALL,
"fd %d: can't getsockopt SO_RCVBUF: %d (%s)", sock,
errno, safe_strerror(errno));
return ret;
}
return optval;
}
static void *getsockopt_cmsg_data(struct msghdr *msgh, int level, int type) static void *getsockopt_cmsg_data(struct msghdr *msgh, int level, int type)
{ {
struct cmsghdr *cmsg; struct cmsghdr *cmsg;

View File

@ -30,6 +30,7 @@ extern "C" {
extern void setsockopt_so_recvbuf(int sock, int size); extern void setsockopt_so_recvbuf(int sock, int size);
extern void setsockopt_so_sendbuf(const int sock, int size); extern void setsockopt_so_sendbuf(const int sock, int size);
extern int getsockopt_so_sendbuf(const int sock); extern int getsockopt_so_sendbuf(const int sock);
extern int getsockopt_so_recvbuf(const int sock);
extern int setsockopt_ipv6_pktinfo(int, int); extern int setsockopt_ipv6_pktinfo(int, int);
extern int setsockopt_ipv6_checksum(int, int); extern int setsockopt_ipv6_checksum(int, int);

View File

@ -1339,7 +1339,7 @@ int main(void)
{ {
int i = 0; int i = 0;
qobj_init(); qobj_init();
bgp_master_init(thread_master_create(NULL)); bgp_master_init(thread_master_create(NULL), BGP_SOCKET_SNDBUF_SIZE);
master = bm->master; master = bm->master;
bgp_option_set(BGP_OPT_NO_LISTEN); bgp_option_set(BGP_OPT_NO_LISTEN);
bgp_attr_init(); bgp_attr_init();

View File

@ -912,7 +912,7 @@ int main(void)
qobj_init(); qobj_init();
master = thread_master_create(NULL); master = thread_master_create(NULL);
bgp_master_init(master); bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE);
vrf_init(NULL, NULL, NULL, NULL, NULL); vrf_init(NULL, NULL, NULL, NULL, NULL);
bgp_option_set(BGP_OPT_NO_LISTEN); bgp_option_set(BGP_OPT_NO_LISTEN);

View File

@ -37,6 +37,7 @@
#include "bgpd/bgp_mplsvpn.h" #include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_nexthop.h" #include "bgpd/bgp_nexthop.h"
#include "bgpd/bgp_vty.h" #include "bgpd/bgp_vty.h"
#include "bgpd/bgp_network.h"
#define VT100_RESET "\x1b[0m" #define VT100_RESET "\x1b[0m"
#define VT100_RED "\x1b[31m" #define VT100_RED "\x1b[31m"
@ -1078,7 +1079,7 @@ int main(void)
cmd_init(0); cmd_init(0);
bgp_vty_init(); bgp_vty_init();
master = thread_master_create("test mp attr"); master = thread_master_create("test mp attr");
bgp_master_init(master); bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE);
vrf_init(NULL, NULL, NULL, NULL, NULL); vrf_init(NULL, NULL, NULL, NULL, NULL);
bgp_option_set(BGP_OPT_NO_LISTEN); bgp_option_set(BGP_OPT_NO_LISTEN);
bgp_attr_init(); bgp_attr_init();

View File

@ -38,6 +38,7 @@
#include "bgpd/bgp_nexthop.h" #include "bgpd/bgp_nexthop.h"
#include "bgpd/bgp_mpath.h" #include "bgpd/bgp_mpath.h"
#include "bgpd/bgp_evpn.h" #include "bgpd/bgp_evpn.h"
#include "bgpd/bgp_network.h"
#define VT100_RESET "\x1b[0m" #define VT100_RESET "\x1b[0m"
#define VT100_RED "\x1b[31m" #define VT100_RED "\x1b[31m"
@ -379,7 +380,7 @@ static int global_test_init(void)
qobj_init(); qobj_init();
master = thread_master_create(NULL); master = thread_master_create(NULL);
zclient = zclient_new(master, &zclient_options_default); zclient = zclient_new(master, &zclient_options_default);
bgp_master_init(master); bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE);
vrf_init(NULL, NULL, NULL, NULL, NULL); vrf_init(NULL, NULL, NULL, NULL, NULL);
bgp_option_set(BGP_OPT_NO_LISTEN); bgp_option_set(BGP_OPT_NO_LISTEN);

View File

@ -34,6 +34,7 @@
#include "bgpd/bgp_debug.h" #include "bgpd/bgp_debug.h"
#include "bgpd/bgp_packet.h" #include "bgpd/bgp_packet.h"
#include "bgpd/bgp_aspath.h" #include "bgpd/bgp_aspath.h"
#include "bgpd/bgp_network.h"
/* need these to link in libbgp */ /* need these to link in libbgp */
struct zebra_privs_t *bgpd_privs = NULL; struct zebra_privs_t *bgpd_privs = NULL;
@ -58,7 +59,7 @@ int main(int argc, char *argv[])
qobj_init(); qobj_init();
bgp_attr_init(); bgp_attr_init();
master = thread_master_create(NULL); master = thread_master_create(NULL);
bgp_master_init(master); bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE);
vrf_init(NULL, NULL, NULL, NULL, NULL); vrf_init(NULL, NULL, NULL, NULL, NULL);
bgp_option_set(BGP_OPT_NO_LISTEN); bgp_option_set(BGP_OPT_NO_LISTEN);

View File

@ -29,6 +29,7 @@
#include "bgpd/bgp_route.h" #include "bgpd/bgp_route.h"
#include "bgpd/bgp_vty.h" #include "bgpd/bgp_vty.h"
#include "bgpd/bgp_zebra.h" #include "bgpd/bgp_zebra.h"
#include "bgpd/bgp_network.h"
#ifdef ENABLE_BGP_VNC #ifdef ENABLE_BGP_VNC
#include "bgpd/rfapi/rfapi_backend.h" #include "bgpd/rfapi/rfapi_backend.h"
@ -1388,7 +1389,7 @@ static void bgp_startup(void)
master = thread_master_create(NULL); master = thread_master_create(NULL);
yang_init(); yang_init();
nb_init(master, NULL, 0); nb_init(master, NULL, 0);
bgp_master_init(master); bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE);
bgp_option_set(BGP_OPT_NO_LISTEN); bgp_option_set(BGP_OPT_NO_LISTEN);
vrf_init(NULL, NULL, NULL, NULL, NULL); vrf_init(NULL, NULL, NULL, NULL, NULL);
frr_pthread_init(); frr_pthread_init();