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 of packets to process before returning. The defult value of this parameter
is 20. 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: .. _ospf-area:
Areas 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", "can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %pI4, ifindex %u, AllDRouters): %s",
top->fd, &p->u.prefix4, ifindex, top->fd, &p->u.prefix4, ifindex,
safe_strerror(errno)); safe_strerror(errno));
else else if (IS_DEBUG_OSPF_EVENT)
zlog_debug( zlog_debug(
"interface %pI4 [%u] leave AllDRouters Multicast group.", "interface %pI4 [%u] leave AllDRouters Multicast group.",
&p->u.prefix4, ifindex); &p->u.prefix4, ifindex);
@ -159,7 +159,6 @@ int ospf_sock_init(struct ospf *ospf)
{ {
int ospf_sock; int ospf_sock;
int ret, hincl = 1; int ret, hincl = 1;
int bufsize = (8 * 1024 * 1024);
/* silently ignore. already done */ /* silently ignore. already done */
if (ospf->fd > 0) if (ospf->fd > 0)
@ -213,9 +212,28 @@ int ospf_sock_init(struct ospf *ospf)
ospf_sock); ospf_sock);
} }
setsockopt_so_sendbuf(ospf_sock, bufsize); /* Update socket buffer sizes */
setsockopt_so_recvbuf(ospf_sock, bufsize); ospf_sock_bufsize_update(ospf, ospf_sock, OSPF_SOCK_BOTH);
ospf->fd = ospf_sock; ospf->fd = ospf_sock;
return ret; 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_if_ipmulticast(struct ospf *, struct prefix *, ifindex_t);
extern int ospf_sock_init(struct ospf *ospf); 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 */ #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 */ /* show LDP-Sync status */
ospf_ldp_sync_show_info(vty, ospf, json_vrf, json ? 1 : 0); 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. */ /* Show each area status. */
for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area))
show_ip_ospf_area(vty, area, json_areas, json ? 1 : 0); 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 */ /* LDP-Sync print */
ospf_ldp_sync_write_config(vty, ospf); 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"); vty_out(vty, "exit\n");
write++; write++;
@ -13006,6 +13039,42 @@ DEFPY(no_flood_reduction_area, no_flood_reduction_area_cmd,
return CMD_SUCCESS; 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) void ospf_vty_clear_init(void)
{ {
install_element(ENABLE_NODE, &clear_ip_ospf_interface_cmd); 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, &flood_reduction_area_cmd);
install_element(OSPF_NODE, &no_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. */ /* Init interface related vty commands. */
ospf_vty_if_init(); 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->fd = -1;
new->recv_sock_bufsize = OSPF_DEFAULT_SOCK_BUFSIZE;
new->send_sock_bufsize = OSPF_DEFAULT_SOCK_BUFSIZE;
return new; return new;
} }
@ -2180,6 +2183,32 @@ int ospf_nbr_nbma_poll_interval_unset(struct ospf *ospf, struct in_addr addr)
return 1; 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) void ospf_master_init(struct event_loop *master)
{ {
memset(&ospf_master, 0, sizeof(ospf_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_SHIFT (60 * 15)
#define OSPF_LS_REFRESH_JITTER 60 #define OSPF_LS_REFRESH_JITTER 60
/* Default socket buffer size */
#define OSPF_DEFAULT_SOCK_BUFSIZE (8 * 1024 * 1024)
struct ospf_external { struct ospf_external {
unsigned short instance; unsigned short instance;
struct route_table *external_info; struct route_table *external_info;
@ -424,6 +427,10 @@ struct ospf {
/* Flood Reduction configuration state */ /* Flood Reduction configuration state */
bool fr_configured; bool fr_configured;
/* Socket buffer sizes */
uint32_t recv_sock_bufsize;
uint32_t send_sock_bufsize;
QOBJ_FIELDS; QOBJ_FIELDS;
}; };
DECLARE_QOBJ_TYPE(ospf); 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); const char *ospf_get_name(const struct ospf *ospf);
extern struct ospf_interface *add_ospf_interface(struct connected *co, extern struct ospf_interface *add_ospf_interface(struct connected *co,
struct ospf_area *area); 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, extern int p_spaces_compare_func(const struct p_space *a,
const struct p_space *b); const struct p_space *b);