I have a problem with VTY validation. When there is wrong command formatting,
we exit VTY parsing in error, which leads to a program exit in error.
However, if the format matches but the value is wrong in a way that the VTY
format description is unable to detect, the way to escalate an error up
the VTY call chain is a bit weird.
The concrete item in question is the SCCP address point code. The format is
like A.B.C, while ranges are variable depending on configuration.
point-code 0.0.1
If I write 'point-code 0.0.99', it exceeds the range and I want to immediately
abort the program, indicating the VTY config error.
If I return CMD_WARNING, it is merely ignored.
There are various CMD_ERR_* values to return, but there is no plain error like
CMD_ERR_INVALID_VALUE.
I can for example return CMD_ERR_AMBIGUOUS; then the code will try to parse the
same line a second time, to see whether the command succeeds on a child of the
parent node (we had this before, about implicit node 'exit').
DLSS7 <002d> ../../src/osmo_ss7.c:244 1: Error parsing Pointcode
'0.42.99'
DLSS7 <002d> ../../src/osmo_ss7.c:244 1: Error parsing Pointcode
'0.42.99'
There is no such command.
Error occurred during reading below line:
point-code 0.42.99
% Power 21 dB is not an even value
Invalid point code (0.42.99)
Invalid point code (0.42.99)
This result is rather curious.
I would like to have a CMD_ERROR return value that immediately exits VTY
parsing with a clear error return code.
(We can't abort with an assertion, because that would cause the program to exit
in case someone enters a wrong value on the telnet VTY.)
This is the function in question:
int config_from_file(struct vty *vty, FILE * fp)
{
int ret;
vector vline;
while (fgets(vty->buf, VTY_BUFSIZ, fp)) {
vline = cmd_make_strvec(vty->buf);
/* In case of comment line */
if (vline == NULL)
continue;
/* Execute configuration command : this is strict match */
ret = cmd_execute_command_strict(vline, vty, NULL);
// I would insert something like this:
// if (ret == CMD_ERROR)
// return ret;
/* Try again with setting node to CONFIG_NODE */
while (ret != CMD_SUCCESS && ret != CMD_WARNING
&& ret != CMD_ERR_NOTHING_TODO
&& is_config_child(vty)) {
vty_go_parent(vty);
ret = cmd_execute_command_strict(vline, vty, NULL);
// same here
}
cmd_free_strvec(vline);
if (ret != CMD_SUCCESS && ret != CMD_WARNING
&& ret != CMD_ERR_NOTHING_TODO)
return ret;
}
return CMD_SUCCESS;
}
Am I on the right track here, have I missed something?
~N
Show replies by date