tcp: socket option to get stack alias name

TCP stack sysctl nodes are currently inserted using the stack
name alias. Allow the user to get the current stack's alias to
allow for programatic sysctl access.

Obtained from:	Netflix
This commit is contained in:
Peter Lei 2021-10-25 20:08:54 -07:00 committed by Gleb Smirnoff
parent 71f31d784e
commit e28330832b
4 changed files with 44 additions and 4 deletions

View File

@ -210,6 +210,7 @@ struct tcphdr {
#define TCP_PCAP_OUT 2048 /* number of output packets to keep */
#define TCP_PCAP_IN 4096 /* number of input packets to keep */
#define TCP_FUNCTION_BLK 8192 /* Set the tcp function pointers to the specified stack */
#define TCP_FUNCTION_ALIAS 8193 /* Get the current tcp function pointer name alias */
/* Options for Rack and BBR */
#define TCP_REUSPORT_LB_NUMA 1026 /* set listen socket numa domain */
#define TCP_RACK_MBUF_QUEUE 1050 /* Do we allow mbuf queuing if supported */

View File

@ -473,6 +473,37 @@ find_and_ref_tcp_fb(struct tcp_function_block *blk)
return(rblk);
}
/* Find a matching alias for the given tcp_function_block. */
int
find_tcp_function_alias(struct tcp_function_block *blk,
struct tcp_function_set *fs)
{
struct tcp_function *f;
int found;
found = 0;
rw_rlock(&tcp_function_lock);
TAILQ_FOREACH(f, &t_functions, tf_next) {
if ((f->tf_fb == blk) &&
(strncmp(f->tf_name, blk->tfb_tcp_block_name,
TCP_FUNCTION_NAME_LEN_MAX) != 0)) {
/* Matching function block with different name. */
strncpy(fs->function_set_name, f->tf_name,
TCP_FUNCTION_NAME_LEN_MAX);
found = 1;
break;
}
}
/* Null terminate the string appropriately. */
if (found) {
fs->function_set_name[TCP_FUNCTION_NAME_LEN_MAX - 1] = '\0';
} else {
fs->function_set_name[0] = '\0';
}
rw_runlock(&tcp_function_lock);
return (found);
}
static struct tcp_function_block *
find_and_ref_tcp_default_fb(void)
{

View File

@ -1894,10 +1894,17 @@ tcp_ctloutput(struct socket *so, struct sockopt *sopt)
INP_WUNLOCK(inp);
return (error);
} else if ((sopt->sopt_dir == SOPT_GET) &&
(sopt->sopt_name == TCP_FUNCTION_BLK)) {
strncpy(fsn.function_set_name, tp->t_fb->tfb_tcp_block_name,
TCP_FUNCTION_NAME_LEN_MAX);
fsn.function_set_name[TCP_FUNCTION_NAME_LEN_MAX - 1] = '\0';
((sopt->sopt_name == TCP_FUNCTION_BLK) ||
(sopt->sopt_name == TCP_FUNCTION_ALIAS))) {
if (sopt->sopt_name == TCP_FUNCTION_ALIAS) {
memset(&fsn, 0, sizeof(fsn));
find_tcp_function_alias(tp->t_fb, &fsn);
} else {
strncpy(fsn.function_set_name,
tp->t_fb->tfb_tcp_block_name,
TCP_FUNCTION_NAME_LEN_MAX);
fsn.function_set_name[TCP_FUNCTION_NAME_LEN_MAX - 1] = '\0';
}
fsn.pcbcnt = tp->t_fb->tfb_refcnt;
INP_WUNLOCK(inp);
error = sooptcopyout(sopt, &fsn, sizeof fsn);

View File

@ -1020,6 +1020,7 @@ int register_tcp_functions_as_name(struct tcp_function_block *blk,
int deregister_tcp_functions(struct tcp_function_block *blk, bool quiesce,
bool force);
struct tcp_function_block *find_and_ref_tcp_functions(struct tcp_function_set *fs);
int find_tcp_function_alias(struct tcp_function_block *blk, struct tcp_function_set *fs);
void tcp_switch_back_to_default(struct tcpcb *tp);
struct tcp_function_block *
find_and_ref_tcp_fb(struct tcp_function_block *fs);