tdef: Introduce min_val and max_val fields

This is useful for timers expected to have a range of valid or expected
values.

Validation is done at runtime when timer values are set by the app or by
the user through the VTY.

Related: OS#4190
Change-Id: I4661ac41c29a009a1d5fc57d87aaee6041c7d1b2
This commit is contained in:
Pau Espin 2019-09-17 13:13:52 +02:00 committed by pespin
parent 4ad3cb1044
commit 0cbe8f0100
8 changed files with 175 additions and 13 deletions

View File

@ -8,3 +8,4 @@
# If any interfaces have been removed or changed since the last public release: c:r:0. # If any interfaces have been removed or changed since the last public release: c:r:0.
#library what description / commit summary line #library what description / commit summary line
core osmo_tdef_get() change val_if_not_present arg from unsigned long to long to allow passing -1 core osmo_tdef_get() change val_if_not_present arg from unsigned long to long to allow passing -1
core struct osmo_tdef fields min_val,max_val added, ABI break (arrays of structs used in programs)

View File

@ -77,6 +77,10 @@ struct osmo_tdef {
/*! Currently active timeout value, e.g. set by user config. This is the only mutable member: a user may /*! Currently active timeout value, e.g. set by user config. This is the only mutable member: a user may
* configure the timeout value, but neither unit nor any other field. */ * configure the timeout value, but neither unit nor any other field. */
unsigned long val; unsigned long val;
/*! Minimum timer value (in this tdef unit), checked if set (not zero). */
unsigned long min_val;
/*! Maximum timer value (in this tdef unit), checked if set (not zero). */
unsigned long max_val;
}; };
/*! Iterate an array of struct osmo_tdef, the last item should be fully zero, i.e. "{}". /*! Iterate an array of struct osmo_tdef, the last item should be fully zero, i.e. "{}".
@ -98,6 +102,8 @@ unsigned long osmo_tdef_get(const struct osmo_tdef *tdefs, int T, enum osmo_tdef
long val_if_not_present); long val_if_not_present);
struct osmo_tdef *osmo_tdef_get_entry(struct osmo_tdef *tdefs, int T); struct osmo_tdef *osmo_tdef_get_entry(struct osmo_tdef *tdefs, int T);
int osmo_tdef_set(struct osmo_tdef *tdefs, int T, unsigned long val, enum osmo_tdef_unit val_unit); int osmo_tdef_set(struct osmo_tdef *tdefs, int T, unsigned long val, enum osmo_tdef_unit val_unit);
bool osmo_tdef_val_in_range(struct osmo_tdef *tdef, unsigned long new_val);
int osmo_tdef_range_str_buf(char *buf, size_t buf_len, struct osmo_tdef *t);
/*! Using osmo_tdef for osmo_fsm_inst: array entry for a mapping of state numbers to timeout definitions. /*! Using osmo_tdef for osmo_fsm_inst: array entry for a mapping of state numbers to timeout definitions.
* For a usage example, see osmo_tdef_get_state_timeout() and test_tdef_state_timeout() in tdef_test.c. */ * For a usage example, see osmo_tdef_get_state_timeout() and test_tdef_state_timeout() in tdef_test.c. */

View File

@ -136,14 +136,22 @@ static unsigned long osmo_tdef_round(unsigned long val, enum osmo_tdef_unit from
/*! Set all osmo_tdef values to the default_val. /*! Set all osmo_tdef values to the default_val.
* It is convenient to define a tdefs array by setting only the default_val, and calling osmo_tdefs_reset() once for * It is convenient to define a tdefs array by setting only the default_val, and calling osmo_tdefs_reset() once for
* program startup. (See also osmo_tdef_vty_init()) * program startup. (See also osmo_tdef_vty_init()).
* During call to this function, default values are verified to be inside valid range; process is aborted otherwise.
* \param[in] tdefs Array of timer definitions, last entry being fully zero. * \param[in] tdefs Array of timer definitions, last entry being fully zero.
*/ */
void osmo_tdefs_reset(struct osmo_tdef *tdefs) void osmo_tdefs_reset(struct osmo_tdef *tdefs)
{ {
struct osmo_tdef *t; struct osmo_tdef *t;
osmo_tdef_for_each(t, tdefs) osmo_tdef_for_each(t, tdefs) {
if (!osmo_tdef_val_in_range(t, t->default_val)) {
char range_str[64];
osmo_tdef_range_str_buf(range_str, sizeof(range_str), t);
osmo_panic("%s:%d Timer " OSMO_T_FMT " contains default value %lu not in range %s\n",
__FILE__, __LINE__, OSMO_T_FMT_ARGS(t->T), t->default_val, range_str);
}
t->val = t->default_val; t->val = t->default_val;
}
} }
/*! Return the value of a T timer from a list of osmo_tdef, in the given unit. /*! Return the value of a T timer from a list of osmo_tdef, in the given unit.
@ -221,13 +229,55 @@ struct osmo_tdef *osmo_tdef_get_entry(struct osmo_tdef *tdefs, int T)
*/ */
int osmo_tdef_set(struct osmo_tdef *tdefs, int T, unsigned long val, enum osmo_tdef_unit val_unit) int osmo_tdef_set(struct osmo_tdef *tdefs, int T, unsigned long val, enum osmo_tdef_unit val_unit)
{ {
unsigned long new_val;
struct osmo_tdef *t = osmo_tdef_get_entry(tdefs, T); struct osmo_tdef *t = osmo_tdef_get_entry(tdefs, T);
if (!t) if (!t)
return -EEXIST; return -EEXIST;
t->val = osmo_tdef_round(val, val_unit, t->unit);
new_val = osmo_tdef_round(val, val_unit, t->unit);
if (!osmo_tdef_val_in_range(t, new_val))
return -ERANGE;
t->val = new_val;
return 0; return 0;
} }
/*! Check if value new_val is in range of valid possible values for timer entry tdef.
* \param[in] tdef Timer entry from a timer definition table.
* \param[in] new_val The value whose validity to check, in units as per this timer entry.
* \return true if inside range, false otherwise.
*/
bool osmo_tdef_val_in_range(struct osmo_tdef *tdef, unsigned long new_val)
{
return new_val >= tdef->min_val && (!tdef->max_val || new_val <= tdef->max_val);
}
/*! Write string representation of osmo_tdef range into buf.
* \param[in] buf The buffer where the string representation is stored.
* \param[in] buf_len Length of buffer in bytes.
* \param[in] tdef Timer entry from a timer definition table.
* \return The number of characters printed on success, negative on error. See snprintf().
*/
int osmo_tdef_range_str_buf(char *buf, size_t buf_len, struct osmo_tdef *t)
{
int ret, len = 0, offset = 0, rem = buf_len;
buf[0] = '\0';
ret = snprintf(buf + offset, rem, "[%lu .. ", t->min_val);
if (ret < 0)
return ret;
OSMO_SNPRINTF_RET(ret, rem, offset, len);
if (t->max_val)
ret = snprintf(buf + offset, rem, "%lu]", t->max_val);
else
ret = snprintf(buf + offset, rem, "inf]");
if (ret < 0)
return ret;
OSMO_SNPRINTF_RET(ret, rem, offset, len);
return ret;
}
/*! Using osmo_tdef for osmo_fsm_inst: find a given state's osmo_tdef_state_timeout entry. /*! Using osmo_tdef for osmo_fsm_inst: find a given state's osmo_tdef_state_timeout entry.
* *
* The timeouts_array shall contain exactly 32 elements, regardless whether only some of them are actually populated * The timeouts_array shall contain exactly 32 elements, regardless whether only some of them are actually populated

View File

@ -115,12 +115,22 @@ unsigned long osmo_tdef_vty_parse_val_arg(const char *val_arg, unsigned long def
*/ */
int osmo_tdef_vty_set_cmd(struct vty *vty, struct osmo_tdef *tdefs, const char **args) int osmo_tdef_vty_set_cmd(struct vty *vty, struct osmo_tdef *tdefs, const char **args)
{ {
unsigned long new_val;
const char *T_arg = args[0]; const char *T_arg = args[0];
const char *val_arg = args[1]; const char *val_arg = args[1];
struct osmo_tdef *t = osmo_tdef_vty_parse_T_arg(vty, tdefs, T_arg); struct osmo_tdef *t = osmo_tdef_vty_parse_T_arg(vty, tdefs, T_arg);
if (!t) if (!t)
return CMD_WARNING; return CMD_WARNING;
t->val = osmo_tdef_vty_parse_val_arg(val_arg, t->default_val); new_val = osmo_tdef_vty_parse_val_arg(val_arg, t->default_val);
if (!osmo_tdef_val_in_range(t, new_val)) {
char range_str[64];
osmo_tdef_range_str_buf(range_str, sizeof(range_str), t);
vty_out(vty, "%% Timer " OSMO_T_FMT " value %lu is out of range %s%s",
OSMO_T_FMT_ARGS(t->T), new_val, range_str, VTY_NEWLINE);
return CMD_WARNING;
}
t->val = new_val;
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -161,18 +171,29 @@ int osmo_tdef_vty_show_cmd(struct vty *vty, struct osmo_tdef *tdefs, const char
*/ */
void osmo_tdef_vty_out_one_va(struct vty *vty, struct osmo_tdef *t, const char *prefix_fmt, va_list va) void osmo_tdef_vty_out_one_va(struct vty *vty, struct osmo_tdef *t, const char *prefix_fmt, va_list va)
{ {
char range_str[64];
if (!t) { if (!t) {
vty_out(vty, "%% Error: no such timer%s", VTY_NEWLINE); vty_out(vty, "%% Error: no such timer%s", VTY_NEWLINE);
return; return;
} }
if (prefix_fmt) if (prefix_fmt)
vty_out_va(vty, prefix_fmt, va); vty_out_va(vty, prefix_fmt, va);
vty_out(vty, OSMO_T_FMT " = %lu%s%s\t%s (default: %lu%s%s)%s",
OSMO_T_FMT_ARGS(t->T), t->val, vty_out(vty, OSMO_T_FMT " = %lu", OSMO_T_FMT_ARGS(t->T), t->val);
t->unit == OSMO_TDEF_CUSTOM ? "" : " ", t->unit == OSMO_TDEF_CUSTOM ? "" : osmo_tdef_unit_name(t->unit), if (t->unit != OSMO_TDEF_CUSTOM)
t->desc, t->default_val, vty_out(vty, " %s", osmo_tdef_unit_name(t->unit));
t->unit == OSMO_TDEF_CUSTOM ? "" : " ", t->unit == OSMO_TDEF_CUSTOM ? "" : osmo_tdef_unit_name(t->unit),
VTY_NEWLINE); vty_out(vty, "\t%s (default: %lu", t->desc, t->default_val);
if (t->unit != OSMO_TDEF_CUSTOM)
vty_out(vty, " %s", osmo_tdef_unit_name(t->unit));
if (t->min_val || t->max_val) {
osmo_tdef_range_str_buf(range_str, sizeof(range_str), t);
vty_out(vty, ", range: %s", range_str);
}
vty_out(vty, ")%s", VTY_NEWLINE);
} }
/*! Write to VTY the current status of one timer. /*! Write to VTY the current status of one timer.

View File

@ -41,7 +41,7 @@ static struct osmo_tdef tdefs[] = {
{ .T=3, .default_val=100, .unit=OSMO_TDEF_M, .desc="100m" }, { .T=3, .default_val=100, .unit=OSMO_TDEF_M, .desc="100m" },
{ .T=4, .default_val=100, .unit=OSMO_TDEF_CUSTOM, .desc="100 potatoes" }, { .T=4, .default_val=100, .unit=OSMO_TDEF_CUSTOM, .desc="100 potatoes" },
{ .T=7, .default_val=50, .desc="Water Boiling Timeout" }, // default is .unit=OSMO_TDEF_S == 0 { .T=7, .default_val=50, .desc="Water Boiling Timeout", .min_val=20, .max_val=800 }, // default is .unit=OSMO_TDEF_S == 0
{ .T=8, .default_val=300, .desc="Tea brewing" }, { .T=8, .default_val=300, .desc="Tea brewing" },
{ .T=9, .default_val=5, .unit=OSMO_TDEF_M, .desc="Let tea cool down before drinking" }, { .T=9, .default_val=5, .unit=OSMO_TDEF_M, .desc="Let tea cool down before drinking" },
{ .T=10, .default_val=20, .unit=OSMO_TDEF_M, .desc="Forgot to drink tea while it's warm" }, { .T=10, .default_val=20, .unit=OSMO_TDEF_M, .desc="Forgot to drink tea while it's warm" },
@ -143,8 +143,9 @@ static void test_tdef_set_and_get()
struct osmo_tdef *t; struct osmo_tdef *t;
printf("\n%s()\n", __func__); printf("\n%s()\n", __func__);
t = osmo_tdef_get_entry(tdefs, 7);
printf("setting 7 = 42\n"); printf("setting 7 = 42\n");
t = osmo_tdef_get_entry(tdefs, 7);
OSMO_ASSERT(osmo_tdef_val_in_range(t, 42));
t->val = 42; t->val = 42;
print_tdef_info(7); print_tdef_info(7);
print_tdef_get_short(tdefs, 7, OSMO_TDEF_MS); print_tdef_get_short(tdefs, 7, OSMO_TDEF_MS);
@ -153,7 +154,25 @@ static void test_tdef_set_and_get()
print_tdef_get_short(tdefs, 7, OSMO_TDEF_CUSTOM); print_tdef_get_short(tdefs, 7, OSMO_TDEF_CUSTOM);
printf("setting 7 = 420\n"); printf("setting 7 = 420\n");
t->val = 420; OSMO_ASSERT(osmo_tdef_set(tdefs, 7, 420, OSMO_TDEF_S) == 0);
print_tdef_info(7);
print_tdef_get_short(tdefs, 7, OSMO_TDEF_MS);
print_tdef_get_short(tdefs, 7, OSMO_TDEF_S);
print_tdef_get_short(tdefs, 7, OSMO_TDEF_M);
print_tdef_get_short(tdefs, 7, OSMO_TDEF_CUSTOM);
printf("setting 7 = 10 (ERANGE)\n");
OSMO_ASSERT(!osmo_tdef_val_in_range(t, 10));
OSMO_ASSERT(osmo_tdef_set(tdefs, 7, 10, OSMO_TDEF_S) == -ERANGE);
print_tdef_info(7);
print_tdef_get_short(tdefs, 7, OSMO_TDEF_MS);
print_tdef_get_short(tdefs, 7, OSMO_TDEF_S);
print_tdef_get_short(tdefs, 7, OSMO_TDEF_M);
print_tdef_get_short(tdefs, 7, OSMO_TDEF_CUSTOM);
printf("setting 7 = 900 (ERANGE)\n");
OSMO_ASSERT(!osmo_tdef_val_in_range(t, 900));
OSMO_ASSERT(osmo_tdef_set(tdefs, 7, 900, OSMO_TDEF_S) == -ERANGE);
print_tdef_info(7); print_tdef_info(7);
print_tdef_get_short(tdefs, 7, OSMO_TDEF_MS); print_tdef_get_short(tdefs, 7, OSMO_TDEF_MS);
print_tdef_get_short(tdefs, 7, OSMO_TDEF_S); print_tdef_get_short(tdefs, 7, OSMO_TDEF_S);

View File

@ -105,6 +105,18 @@ osmo_tdef_get(7, ms) = 420000
osmo_tdef_get(7, s) = 420 osmo_tdef_get(7, s) = 420
osmo_tdef_get(7, m) = 7 osmo_tdef_get(7, m) = 7
osmo_tdef_get(7, custom-unit) = 420 osmo_tdef_get(7, custom-unit) = 420
setting 7 = 10 (ERANGE)
T7=420s(def=50)
osmo_tdef_get(7, ms) = 420000
osmo_tdef_get(7, s) = 420
osmo_tdef_get(7, m) = 7
osmo_tdef_get(7, custom-unit) = 420
setting 7 = 900 (ERANGE)
T7=420s(def=50)
osmo_tdef_get(7, ms) = 420000
osmo_tdef_get(7, s) = 420
osmo_tdef_get(7, m) = 7
osmo_tdef_get(7, custom-unit) = 420
resetting resetting
T7=50s T7=50s
osmo_tdef_get(7, s) = 50 osmo_tdef_get(7, s) = 50

View File

@ -55,6 +55,9 @@ static struct osmo_tdef tdefs_test[] = {
{ .T=4, .default_val=100, .unit=OSMO_TDEF_CUSTOM, .desc="Testing a hundred potatoes" }, { .T=4, .default_val=100, .unit=OSMO_TDEF_CUSTOM, .desc="Testing a hundred potatoes" },
{ .T=0x7fffffff, .default_val=0xffffffff, .unit=OSMO_TDEF_M, .desc="Very large" }, { .T=0x7fffffff, .default_val=0xffffffff, .unit=OSMO_TDEF_M, .desc="Very large" },
{ .T=-23, .default_val=239471, .desc="Negative T number" }, { .T=-23, .default_val=239471, .desc="Negative T number" },
{ .T=30, .default_val=50, .desc="Testing range min", .min_val=20 },
{ .T=31, .default_val=50, .desc="Testing range max", .max_val=52 },
{ .T=32, .default_val=50, .desc="Testing range both", .min_val=20, .max_val=52 },
{} // <-- important! last entry shall be zero {} // <-- important! last entry shall be zero
}; };

View File

@ -22,6 +22,9 @@ test: T3 = 100 m Testing a hundred minutes (default: 100 m)
test: T4 = 100 Testing a hundred potatoes (default: 100) test: T4 = 100 Testing a hundred potatoes (default: 100)
test: T2147483647 = 4294967295 m Very large (default: 4294967295 m) test: T2147483647 = 4294967295 m Very large (default: 4294967295 m)
test: X23 = 239471 s Negative T number (default: 239471 s) test: X23 = 239471 s Negative T number (default: 239471 s)
test: T30 = 50 s Testing range min (default: 50 s, range: [20 .. inf])
test: T31 = 50 s Testing range max (default: 50 s, range: [0 .. 52])
test: T32 = 50 s Testing range both (default: 50 s, range: [20 .. 52])
software: T1 = 30 m Write code (default: 30 m) software: T1 = 30 m Write code (default: 30 m)
software: T2 = 20 ms Hit segfault (default: 20 ms) software: T2 = 20 ms Hit segfault (default: 20 ms)
software: T3 = 480 m Fix bugs (default: 480 m) software: T3 = 480 m Fix bugs (default: 480 m)
@ -38,6 +41,9 @@ test: T3 = 100 m Testing a hundred minutes (default: 100 m)
test: T4 = 100 Testing a hundred potatoes (default: 100) test: T4 = 100 Testing a hundred potatoes (default: 100)
test: T2147483647 = 4294967295 m Very large (default: 4294967295 m) test: T2147483647 = 4294967295 m Very large (default: 4294967295 m)
test: X23 = 239471 s Negative T number (default: 239471 s) test: X23 = 239471 s Negative T number (default: 239471 s)
test: T30 = 50 s Testing range min (default: 50 s, range: [20 .. inf])
test: T31 = 50 s Testing range max (default: 50 s, range: [0 .. 52])
test: T32 = 50 s Testing range both (default: 50 s, range: [20 .. 52])
software: T1 = 30 m Write code (default: 30 m) software: T1 = 30 m Write code (default: 30 m)
software: T2 = 20 ms Hit segfault (default: 20 ms) software: T2 = 20 ms Hit segfault (default: 20 ms)
software: T3 = 480 m Fix bugs (default: 480 m) software: T3 = 480 m Fix bugs (default: 480 m)
@ -83,6 +89,9 @@ test: T3 = 100 m Testing a hundred minutes (default: 100 m)
test: T4 = 100 Testing a hundred potatoes (default: 100) test: T4 = 100 Testing a hundred potatoes (default: 100)
test: T2147483647 = 4294967295 m Very large (default: 4294967295 m) test: T2147483647 = 4294967295 m Very large (default: 4294967295 m)
test: X23 = 239471 s Negative T number (default: 239471 s) test: X23 = 239471 s Negative T number (default: 239471 s)
test: T30 = 50 s Testing range min (default: 50 s, range: [20 .. inf])
test: T31 = 50 s Testing range max (default: 50 s, range: [0 .. 52])
test: T32 = 50 s Testing range both (default: 50 s, range: [20 .. 52])
software: T1 = 30 m Write code (default: 30 m) software: T1 = 30 m Write code (default: 30 m)
software: T2 = 20 ms Hit segfault (default: 20 ms) software: T2 = 20 ms Hit segfault (default: 20 ms)
software: T3 = 480 m Fix bugs (default: 480 m) software: T3 = 480 m Fix bugs (default: 480 m)
@ -167,6 +176,32 @@ tdef_vty_test(config)# timer tes T2 100
tdef_vty_test(config)# timer te T2 100 tdef_vty_test(config)# timer te T2 100
% Ambiguous command. % Ambiguous command.
tdef_vty_test(config)# timer test 30 40
tdef_vty_test(config)# timer test 30 60
tdef_vty_test(config)# timer test 30 10
% Timer T30 value 10 is out of range [20 .. inf]
tdef_vty_test(config)# timer test 31 40
tdef_vty_test(config)# timer test 31 60
% Timer T31 value 60 is out of range [0 .. 52]
tdef_vty_test(config)# timer test 31 10
tdef_vty_test(config)# timer test 32 40
tdef_vty_test(config)# timer test 32 60
% Timer T32 value 60 is out of range [20 .. 52]
tdef_vty_test(config)# timer test 32 10
% Timer T32 value 10 is out of range [20 .. 52]
tdef_vty_test(config)# timer test
test: T1 = 100 s Testing a hundred seconds (default: 100 s)
test: T2 = 100 ms Testing a hundred milliseconds (default: 100 ms)
test: T3 = 100 m Testing a hundred minutes (default: 100 m)
test: T4 = 100 Testing a hundred potatoes (default: 100)
test: T2147483647 = 4294967295 m Very large (default: 4294967295 m)
test: X23 = 239471 s Negative T number (default: 239471 s)
test: T30 = 60 s Testing range min (default: 50 s, range: [20 .. inf])
test: T31 = 10 s Testing range max (default: 50 s, range: [0 .. 52])
test: T32 = 40 s Testing range both (default: 50 s, range: [20 .. 52])
tdef_vty_test(config)# do show timer software tdef_vty_test(config)# do show timer software
software: T1 = 30 m Write code (default: 30 m) software: T1 = 30 m Write code (default: 30 m)
@ -230,6 +265,9 @@ test: T3 = 100 m Testing a hundred minutes (default: 100 m)
test: T4 = 100 Testing a hundred potatoes (default: 100) test: T4 = 100 Testing a hundred potatoes (default: 100)
test: T2147483647 = 4294967295 m Very large (default: 4294967295 m) test: T2147483647 = 4294967295 m Very large (default: 4294967295 m)
test: X23 = 239471 s Negative T number (default: 239471 s) test: X23 = 239471 s Negative T number (default: 239471 s)
test: T30 = 60 s Testing range min (default: 50 s, range: [20 .. inf])
test: T31 = 10 s Testing range max (default: 50 s, range: [0 .. 52])
test: T32 = 40 s Testing range both (default: 50 s, range: [20 .. 52])
software: T1 = 13 m Write code (default: 30 m) software: T1 = 13 m Write code (default: 30 m)
software: T2 = 0 ms Hit segfault (default: 20 ms) software: T2 = 0 ms Hit segfault (default: 20 ms)
software: T3 = 23 m Fix bugs (default: 480 m) software: T3 = 23 m Fix bugs (default: 480 m)
@ -245,6 +283,9 @@ test: T3 = 100 m Testing a hundred minutes (default: 100 m)
test: T4 = 100 Testing a hundred potatoes (default: 100) test: T4 = 100 Testing a hundred potatoes (default: 100)
test: T2147483647 = 4294967295 m Very large (default: 4294967295 m) test: T2147483647 = 4294967295 m Very large (default: 4294967295 m)
test: X23 = 239471 s Negative T number (default: 239471 s) test: X23 = 239471 s Negative T number (default: 239471 s)
test: T30 = 60 s Testing range min (default: 50 s, range: [20 .. inf])
test: T31 = 10 s Testing range max (default: 50 s, range: [0 .. 52])
test: T32 = 40 s Testing range both (default: 50 s, range: [20 .. 52])
software: T1 = 13 m Write code (default: 30 m) software: T1 = 13 m Write code (default: 30 m)
software: T2 = 0 ms Hit segfault (default: 20 ms) software: T2 = 0 ms Hit segfault (default: 20 ms)
software: T3 = 23 m Fix bugs (default: 480 m) software: T3 = 23 m Fix bugs (default: 480 m)
@ -252,6 +293,9 @@ software: T3 = 23 m Fix bugs (default: 480 m)
tdef_vty_test(config)# show running-config tdef_vty_test(config)# show running-config
... !timer ... !timer
timer tea T3 32 timer tea T3 32
timer test T30 60
timer test T31 10
timer test T32 40
timer software T1 13 timer software T1 13
timer software T2 0 timer software T2 0
timer software T3 23 timer software T3 23
@ -261,6 +305,9 @@ tdef_vty_test(config)# timer tea T3 default
tdef_vty_test(config)# timer software T1 default tdef_vty_test(config)# timer software T1 default
tdef_vty_test(config)# show running-config tdef_vty_test(config)# show running-config
... !timer ... !timer
timer test T30 60
timer test T31 10
timer test T32 40
timer software T2 0 timer software T2 0
timer software T3 23 timer software T3 23
... !timer ... !timer
@ -269,5 +316,8 @@ tdef_vty_test(config)# timer softw 2 default
tdef_vty_test(config)# timer software 2 default tdef_vty_test(config)# timer software 2 default
tdef_vty_test(config)# show running-config tdef_vty_test(config)# show running-config
... !timer ... !timer
timer test T30 60
timer test T31 10
timer test T32 40
timer software T3 23 timer software T3 23
... !timer ... !timer