* Document internal commands.

* Do not require/set default table type if algo name is specified.
* Add TA_FLAG_READONLY option for algorithms.
This commit is contained in:
Alexander V. Chernikov 2014-08-14 17:31:04 +00:00
parent 98eff10e84
commit fd0869d547
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/ipfw/; revision=269988
5 changed files with 88 additions and 36 deletions

View File

@ -113,6 +113,11 @@ in-kernel NAT.
.Oc
.Oc
.Ar pathname
.Ss INTERNAL DIAGNOSTICS
.Nm
.Cm internal iflist
.Nm
.Cm internal talist
.Sh DESCRIPTION
The
.Nm
@ -3181,6 +3186,22 @@ Controls whether bridged packets are passed to
.Nm .
Default is no.
.El
.Sh INTERNAL DIAGNOSTICS
There are some commands that may be useful to understand current state
of certain subsystems inside kernel module.
These commands provide debugging output which may change without notice.
.Pp
Currently the following commands are available as
.Cm internal
sub-options:
.Bl -tag -width indent
.It Cm iflist
Lists all interface which are currently tracked by
.Nm
with their in-kernel status.
.It Cm talist
List all table lookup algorithms currently available.
.El
.Sh EXAMPLES
There are far too many possible uses of
.Nm

View File

@ -391,10 +391,6 @@ table_create(ipfw_obj_header *oh, int ac, char *av[])
sz = sizeof(tbuf);
memset(&xi, 0, sizeof(xi));
/* Set some defaults to preserve compability */
xi.type = IPFW_TABLE_CIDR;
xi.vtype = IPFW_VTYPE_U32;
while (ac > 0) {
tcmd = get_token(tablenewcmds, *av, "option");
ac--; av++;
@ -464,6 +460,12 @@ table_create(ipfw_obj_header *oh, int ac, char *av[])
}
}
/* Set some defaults to preserve compability */
if (xi.algoname[0] == '\0' && xi.type == 0)
xi.type = IPFW_TABLE_CIDR;
if (xi.vtype == 0)
xi.vtype = IPFW_VTYPE_U32;
if ((error = table_do_create(oh, &xi)) != 0)
err(EX_OSERR, "Table creation failed");
}

View File

@ -667,6 +667,9 @@ check_table_space(struct ip_fw_chain *ch, struct table_config *tc,
error = 0;
ta = tc->ta;
if (ta->need_modify == NULL)
return (0);
/* Acquire reference not to loose @tc between locks/unlocks */
tc->no.refcnt++;
@ -1051,6 +1054,11 @@ flush_table(struct ip_fw_chain *ch, struct tid_info *ti)
return (ESRCH);
}
ta = tc->ta;
/* Do not flush readonly tables */
if ((ta->flags & TA_FLAG_READONLY) != 0) {
IPFW_UH_WUNLOCK(ch);
return (EACCES);
}
tc->no.refcnt++;
/* Save startup algo parameters */
if (ta->print_config != NULL) {
@ -1206,6 +1214,12 @@ swap_tables(struct ip_fw_chain *ch, struct tid_info *a,
return (EFBIG);
}
/* Check if one of the tables is readonly */
if (((tc_a->ta->flags | tc_b->ta->flags) & TA_FLAG_READONLY) != 0) {
IPFW_UH_WUNLOCK(ch);
return (EACCES);
}
/* Everything is fine, prepare to swap */
tablestate = (struct table_info *)ch->tablestate;
ti = tablestate[tc_a->no.kidx];
@ -1622,6 +1636,13 @@ ipfw_modify_table(struct ip_fw_chain *ch, ip_fw3_opheader *op3,
IPFW_UH_WUNLOCK(ch);
return (ESRCH);
}
/* Do not support any modifications for readonly tables */
if ((tc->ta->flags & TA_FLAG_READONLY) != 0) {
IPFW_UH_WUNLOCK(ch);
return (EACCES);
}
if ((i->mflags & IPFW_TMFLAGS_FTYPE) != 0)
tc->vftype = i->vftype;
if ((i->mflags & IPFW_TMFLAGS_LIMIT) != 0)
@ -1720,7 +1741,10 @@ create_table_internal(struct ip_fw_chain *ch, struct tid_info *ti,
tc->vftype = i->vftype;
tc->limit = i->limit;
tc->locked = (i->flags & IPFW_TGFLAGS_LOCKED) != 0;
if (ta->flags & TA_FLAG_READONLY)
tc->locked = 1;
else
tc->locked = (i->flags & IPFW_TGFLAGS_LOCKED) != 0;
IPFW_UH_WLOCK(ch);
@ -2311,32 +2335,36 @@ find_table_algo(struct tables_config *tcfg, struct tid_info *ti, char *name)
return (tcfg->algo[ti->atype]);
}
/* Search by name if supplied */
if (name != NULL) {
/* TODO: better search */
for (i = 1; i <= tcfg->algo_count; i++) {
ta = tcfg->algo[i];
/*
* One can supply additional algorithm
* parameters so we compare only the first word
* of supplied name:
* 'hash_cidr hsize=32'
* '^^^^^^^^^'
*
*/
l = strlen(ta->name);
if (strncmp(name, ta->name, l) == 0) {
if (name[l] == '\0' || name[l] == ' ')
return (ta);
}
}
return (NULL);
if (name == NULL) {
/* Return default algorithm for given type if set */
return (tcfg->def_algo[ti->type]);
}
/* Return default algorithm for given type if set */
return (tcfg->def_algo[ti->type]);
/* Search by name */
/* TODO: better search */
for (i = 1; i <= tcfg->algo_count; i++) {
ta = tcfg->algo[i];
/*
* One can supply additional algorithm
* parameters so we compare only the first word
* of supplied name:
* 'hash_cidr hsize=32'
* '^^^^^^^^^'
*
*/
l = strlen(ta->name);
if (strncmp(name, ta->name, l) != 0)
continue;
if (name[l] != '\0' && name[l] != ' ')
continue;
/* Check if we're requesting proper table type */
if (ti->type != 0 && ti->type != ta->type)
return (NULL);
return (ta);
}
return (NULL);
}
/*
@ -2704,7 +2732,7 @@ alloc_table_config(struct ip_fw_chain *ch, struct tid_info *ti,
tc = malloc(sizeof(struct table_config), M_IPFW, M_WAITOK | M_ZERO);
tc->no.name = tc->tablename;
tc->no.type = ti->type;
tc->no.type = ta->type;
tc->no.set = set;
tc->tflags = tflags;
tc->ta = ta;

View File

@ -132,7 +132,8 @@ struct table_algo {
ta_print_config *print_config;
ta_dump_tinfo *dump_tinfo;
};
#define TA_FLAG_DEFAULT 0x01 /* Algorithm is default for given type */
#define TA_FLAG_DEFAULT 0x01 /* Algo is default for given type */
#define TA_FLAG_READONLY 0x02 /* Algo does not support modifications*/
int ipfw_add_table_algo(struct ip_fw_chain *ch, struct table_algo *ta,
size_t size, int *idx);

View File

@ -179,7 +179,7 @@ __FBSDID("$FreeBSD: projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c 267384 2014-06-
* -need_modify: checks if @ti has enough space to hold another @count items.
* typedef int (ta_need_modify)(void *ta_state, struct table_info *ti,
* uint32_t count, uint64_t *pflags);
* MANDATORY, locked (UH). (M_NOWAIT). Returns 0 if has.
* OPTIONAL, locked (UH). (M_NOWAIT). Returns 0 if has.
*
* Checks if given table has enough space to add @count items without
* resize. Caller may use @pflags to store desired modification data.
@ -188,7 +188,7 @@ __FBSDID("$FreeBSD: projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c 267384 2014-06-
*
* -prepare_mod: allocate structures for table modification.
* typedef int (ta_prepare_mod)(void *ta_buf, uint64_t *pflags);
* MANDATORY, unlocked. (M_WAITOK). Returns 0 on success.
* OPTIONAL(need_modify), unlocked. (M_WAITOK). Returns 0 on success.
*
* Allocate all needed state for table modification. Caller
* should use `struct mod_item` to store new state in @ta_buf.
@ -199,7 +199,7 @@ __FBSDID("$FreeBSD: projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c 267384 2014-06-
* -fill_mod: copy some data to new state/
* typedef int (ta_fill_mod)(void *ta_state, struct table_info *ti,
* void *ta_buf, uint64_t *pflags);
* MANDATORY, locked (UH). (M_NOWAIT). Returns 0 on success.
* OPTIONAL(need_modify), locked (UH). (M_NOWAIT). Returns 0 on success.
*
* Copy as much data as we can to minimize changes under WLOCK.
* For example, array can be merged inside this callback.
@ -209,7 +209,7 @@ __FBSDID("$FreeBSD: projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c 267384 2014-06-
* -modify: perform final modification.
* typedef void (ta_modify)(void *ta_state, struct table_info *ti,
* void *ta_buf, uint64_t pflags);
* MANDATORY, locked (UH+WLOCK). (M_NOWAIT).
* OPTIONAL(need_modify), locked (UH+WLOCK). (M_NOWAIT).
*
* Performs all changes necessary to switch to new structures.
* * Caller should save old pointers to @ta_buf storage.
@ -218,7 +218,7 @@ __FBSDID("$FreeBSD: projects/ipfw/sys/netpfil/ipfw/ip_fw_table.c 267384 2014-06-
*
* -flush_mod: flush table modification state.
* typedef void (ta_flush_mod)(void *ta_buf);
* MANDATORY, unlocked. (M_WAITOK).
* OPTIONAL(need_modify), unlocked. (M_WAITOK).
*
* Performs flush for the following:
* - prepare_mod (modification was not necessary)