Merge pull request #13227 from mjstapp/ospf_sock_bufsizes

ospfd: support configuration of socket buffer sizes
This commit is contained in:
Russ White 2023-04-11 08:55:47 -04:00 committed by GitHub
commit e80c797a1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 147 additions and 4 deletions

View File

@ -310,6 +310,11 @@ To start OSPF process you have to specify the OSPF router.
of packets to process before returning. The defult value of this parameter
is 20.
.. clicmd:: socket buffer <send | recv | all> (1-4000000000)
This command controls the ospf instance's socket buffer sizes. The
'no' form resets one or both values to the default.
.. _ospf-area:
Areas

View File

@ -111,7 +111,7 @@ int ospf_if_drop_alldrouters(struct ospf *top, struct prefix *p,
"can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %pI4, ifindex %u, AllDRouters): %s",
top->fd, &p->u.prefix4, ifindex,
safe_strerror(errno));
else
else if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
"interface %pI4 [%u] leave AllDRouters Multicast group.",
&p->u.prefix4, ifindex);
@ -159,7 +159,6 @@ int ospf_sock_init(struct ospf *ospf)
{
int ospf_sock;
int ret, hincl = 1;
int bufsize = (8 * 1024 * 1024);
/* silently ignore. already done */
if (ospf->fd > 0)
@ -213,9 +212,28 @@ int ospf_sock_init(struct ospf *ospf)
ospf_sock);
}
setsockopt_so_sendbuf(ospf_sock, bufsize);
setsockopt_so_recvbuf(ospf_sock, bufsize);
/* Update socket buffer sizes */
ospf_sock_bufsize_update(ospf, ospf_sock, OSPF_SOCK_BOTH);
ospf->fd = ospf_sock;
return ret;
}
/*
* Update a socket bufsize(s), based on its ospf instance
*/
void ospf_sock_bufsize_update(const struct ospf *ospf, int sock,
enum ospf_sock_type_e type)
{
int bufsize;
if (type == OSPF_SOCK_BOTH || type == OSPF_SOCK_RECV) {
bufsize = ospf->recv_sock_bufsize;
setsockopt_so_recvbuf(sock, bufsize);
}
if (type == OSPF_SOCK_BOTH || type == OSPF_SOCK_SEND) {
bufsize = ospf->send_sock_bufsize;
setsockopt_so_sendbuf(sock, bufsize);
}
}

View File

@ -16,4 +16,14 @@ extern int ospf_if_drop_alldrouters(struct ospf *, struct prefix *, ifindex_t);
extern int ospf_if_ipmulticast(struct ospf *, struct prefix *, ifindex_t);
extern int ospf_sock_init(struct ospf *ospf);
enum ospf_sock_type_e {
OSPF_SOCK_NONE = 0,
OSPF_SOCK_RECV,
OSPF_SOCK_SEND,
OSPF_SOCK_BOTH
};
void ospf_sock_bufsize_update(const struct ospf *ospf, int sock,
enum ospf_sock_type_e type);
#endif /* _ZEBRA_OSPF_NETWORK_H */

View File

@ -3403,6 +3403,23 @@ static int show_ip_ospf_common(struct vty *vty, struct ospf *ospf,
/* show LDP-Sync status */
ospf_ldp_sync_show_info(vty, ospf, json_vrf, json ? 1 : 0);
/* Socket buffer sizes */
if (json) {
if (ospf->recv_sock_bufsize != OSPF_DEFAULT_SOCK_BUFSIZE)
json_object_int_add(json_vrf, "recvSockBufsize",
ospf->recv_sock_bufsize);
if (ospf->send_sock_bufsize != OSPF_DEFAULT_SOCK_BUFSIZE)
json_object_int_add(json_vrf, "sendSockBufsize",
ospf->send_sock_bufsize);
} else {
if (ospf->recv_sock_bufsize != OSPF_DEFAULT_SOCK_BUFSIZE)
vty_out(vty, " Receive socket bufsize: %u\n",
ospf->recv_sock_bufsize);
if (ospf->send_sock_bufsize != OSPF_DEFAULT_SOCK_BUFSIZE)
vty_out(vty, " Send socket bufsize: %u\n",
ospf->send_sock_bufsize);
}
/* Show each area status. */
for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area))
show_ip_ospf_area(vty, area, json_areas, json ? 1 : 0);
@ -12550,6 +12567,22 @@ static int ospf_config_write_one(struct vty *vty, struct ospf *ospf)
/* LDP-Sync print */
ospf_ldp_sync_write_config(vty, ospf);
/* Socket buffer sizes */
if (ospf->recv_sock_bufsize != OSPF_DEFAULT_SOCK_BUFSIZE) {
if (ospf->send_sock_bufsize == ospf->recv_sock_bufsize)
vty_out(vty, " socket buffer all %u\n",
ospf->recv_sock_bufsize);
else
vty_out(vty, " socket buffer recv %u\n",
ospf->recv_sock_bufsize);
}
if (ospf->send_sock_bufsize != OSPF_DEFAULT_SOCK_BUFSIZE &&
ospf->send_sock_bufsize != ospf->recv_sock_bufsize)
vty_out(vty, " socket buffer send %u\n",
ospf->send_sock_bufsize);
vty_out(vty, "exit\n");
write++;
@ -13006,6 +13039,42 @@ DEFPY(no_flood_reduction_area, no_flood_reduction_area_cmd,
return CMD_SUCCESS;
}
DEFPY(ospf_socket_bufsizes,
ospf_socket_bufsizes_cmd,
"[no] socket buffer <send$send_val | recv$recv_val | all$all_val> \
![(1-4000000000)$bufsize]",
NO_STR
"Socket parameters\n"
"Buffer size configuration\n"
"Send buffer size\n"
"Receive buffer size\n"
"Both send and receive buffer sizes\n"
"Buffer size, in bytes\n")
{
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
uint32_t recvsz, sendsz;
if (no)
bufsize = OSPF_DEFAULT_SOCK_BUFSIZE;
if (all_val) {
recvsz = bufsize;
sendsz = bufsize;
} else if (send_val) {
sendsz = bufsize;
recvsz = ospf->recv_sock_bufsize;
} else if (recv_val) {
recvsz = bufsize;
sendsz = ospf->send_sock_bufsize;
} else
return CMD_SUCCESS;
/* React to a change by modifying existing sockets */
ospf_update_bufsize(ospf, recvsz, sendsz);
return CMD_SUCCESS;
}
void ospf_vty_clear_init(void)
{
install_element(ENABLE_NODE, &clear_ip_ospf_interface_cmd);
@ -13169,6 +13238,8 @@ void ospf_vty_init(void)
install_element(OSPF_NODE, &flood_reduction_area_cmd);
install_element(OSPF_NODE, &no_flood_reduction_area_cmd);
install_element(OSPF_NODE, &ospf_socket_bufsizes_cmd);
/* Init interface related vty commands. */
ospf_vty_if_init();

View File

@ -420,6 +420,9 @@ struct ospf *ospf_new_alloc(unsigned short instance, const char *name)
new->fd = -1;
new->recv_sock_bufsize = OSPF_DEFAULT_SOCK_BUFSIZE;
new->send_sock_bufsize = OSPF_DEFAULT_SOCK_BUFSIZE;
return new;
}
@ -2180,6 +2183,32 @@ int ospf_nbr_nbma_poll_interval_unset(struct ospf *ospf, struct in_addr addr)
return 1;
}
/*
* Update socket bufsize(s), usually after config change
*/
void ospf_update_bufsize(struct ospf *ospf, uint32_t recvsize,
uint32_t sendsize)
{
enum ospf_sock_type_e type = OSPF_SOCK_NONE;
/* Figure out whether there's been a change */
if (recvsize != ospf->recv_sock_bufsize) {
type = OSPF_SOCK_RECV;
ospf->recv_sock_bufsize = recvsize;
if (sendsize != ospf->send_sock_bufsize) {
type = OSPF_SOCK_BOTH;
ospf->send_sock_bufsize = sendsize;
}
} else if (sendsize != ospf->send_sock_bufsize) {
type = OSPF_SOCK_SEND;
ospf->send_sock_bufsize = sendsize;
}
if (type != OSPF_SOCK_NONE)
ospf_sock_bufsize_update(ospf, ospf->fd, type);
}
void ospf_master_init(struct event_loop *master)
{
memset(&ospf_master, 0, sizeof(ospf_master));

View File

@ -67,6 +67,9 @@
#define OSPF_LS_REFRESH_SHIFT (60 * 15)
#define OSPF_LS_REFRESH_JITTER 60
/* Default socket buffer size */
#define OSPF_DEFAULT_SOCK_BUFSIZE (8 * 1024 * 1024)
struct ospf_external {
unsigned short instance;
struct route_table *external_info;
@ -424,6 +427,10 @@ struct ospf {
/* Flood Reduction configuration state */
bool fr_configured;
/* Socket buffer sizes */
uint32_t recv_sock_bufsize;
uint32_t send_sock_bufsize;
QOBJ_FIELDS;
};
DECLARE_QOBJ_TYPE(ospf);
@ -793,6 +800,9 @@ int ospf_area_nssa_no_summary_set(struct ospf *ospf, struct in_addr area_id);
const char *ospf_get_name(const struct ospf *ospf);
extern struct ospf_interface *add_ospf_interface(struct connected *co,
struct ospf_area *area);
/* Update socket bufsize(s), after config change */
void ospf_update_bufsize(struct ospf *ospf, uint32_t recvsize,
uint32_t sendsize);
extern int p_spaces_compare_func(const struct p_space *a,
const struct p_space *b);