diff options
Diffstat (limited to 'vnet')
-rw-r--r-- | vnet/vnet/interface.c | 1 | ||||
-rw-r--r-- | vnet/vnet/interface_cli.c | 67 | ||||
-rw-r--r-- | vnet/vnet/interface_funcs.h | 38 | ||||
-rw-r--r-- | vnet/vnet/vnet.h | 2 |
4 files changed, 107 insertions, 1 deletions
diff --git a/vnet/vnet/interface.c b/vnet/vnet/interface.c index e552733e58b..6e3d7f291b7 100644 --- a/vnet/vnet/interface.c +++ b/vnet/vnet/interface.c @@ -1202,6 +1202,7 @@ vnet_interface_init (vlib_main_t * vm) return error; } + vnm->interface_tag_by_sw_if_index = hash_create (0, sizeof (uword)); } VLIB_INIT_FUNCTION (vnet_interface_init); diff --git a/vnet/vnet/interface_cli.c b/vnet/vnet/interface_cli.c index 1c15eb18028..7dbee867ded 100644 --- a/vnet/vnet/interface_cli.c +++ b/vnet/vnet/interface_cli.c @@ -228,6 +228,7 @@ show_sw_interfaces (vlib_main_t * vm, u32 sw_if_index = ~(u32) 0; u8 show_addresses = 0; u8 show_features = 0; + u8 show_tag = 0; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { @@ -242,6 +243,8 @@ show_sw_interfaces (vlib_main_t * vm, show_addresses = 1; else if (unformat (input, "features") || unformat (input, "feat")) show_features = 1; + else if (unformat (input, "tag")) + show_tag = 1; else { error = clib_error_return (0, "unknown input `%U'", @@ -250,14 +253,26 @@ show_sw_interfaces (vlib_main_t * vm, } } - if (show_features) + if (show_features || show_tag) { if (sw_if_index == ~(u32) 0) return clib_error_return (0, "Interface not specified..."); + } + if (show_features) + { vnet_interface_features_show (vm, sw_if_index); return 0; } + if (show_tag) + { + u8 *tag; + tag = vnet_get_sw_interface_tag (vnm, sw_if_index); + vlib_cli_output (vm, "%U: %s", + format_vnet_sw_if_index_name, vnm, sw_if_index, + tag ? (char *) tag : "(none)"); + return 0; + } if (!show_addresses) vlib_cli_output (vm, "%U\n", format_vnet_sw_interface, vnm, 0); @@ -1091,6 +1106,56 @@ VLIB_CLI_COMMAND (set_interface_mac_address_cmd, static) = { }; /* *INDENT-ON* */ +static clib_error_t * +set_tag (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) +{ + vnet_main_t *vnm = vnet_get_main (); + u32 sw_if_index = ~0; + u8 *tag = 0; + + if (!unformat (input, "%U %s", unformat_vnet_sw_interface, + vnm, &sw_if_index, &tag)) + return clib_error_return (0, "unknown input `%U'", + format_unformat_error, input); + + vnet_set_sw_interface_tag (vnm, tag, sw_if_index); + + return 0; +} + +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (set_tag_command, static) = { + .path = "set interface tag", + .short_help = "set interface tag <intfc> <tag>", + .function = set_tag, +}; +/* *INDENT-ON* */ + +static clib_error_t * +clear_tag (vlib_main_t * vm, unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + vnet_main_t *vnm = vnet_get_main (); + u32 sw_if_index = ~0; + + if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index)) + return clib_error_return (0, "unknown input `%U'", + format_unformat_error, input); + + vnet_clear_sw_interface_tag (vnm, sw_if_index); + + return 0; +} + +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (clear_tag_command, static) = { + .path = "clear interface tag", + .short_help = "clear interface tag <intfc>", + .function = clear_tag, +}; +/* *INDENT-ON* */ + + /* * fd.io coding-style-patch-verification: ON * diff --git a/vnet/vnet/interface_funcs.h b/vnet/vnet/interface_funcs.h index 17c677f07b6..a488599cff0 100644 --- a/vnet/vnet/interface_funcs.h +++ b/vnet/vnet/interface_funcs.h @@ -92,6 +92,44 @@ vnet_get_device_class (vnet_main_t * vnm, u32 dev_class_index) dev_class_index); } +static inline u8 * +vnet_get_sw_interface_tag (vnet_main_t * vnm, u32 sw_if_index) +{ + uword *p; + p = hash_get (vnm->interface_tag_by_sw_if_index, sw_if_index); + if (p) + return ((u8 *) p[0]); + return 0; +} + +static inline void +vnet_set_sw_interface_tag (vnet_main_t * vnm, u8 * tag, u32 sw_if_index) +{ + uword *p; + p = hash_get (vnm->interface_tag_by_sw_if_index, sw_if_index); + if (p) + { + u8 *oldtag = (u8 *) p[0]; + hash_unset (vnm->interface_tag_by_sw_if_index, sw_if_index); + vec_free (oldtag); + } + + hash_set (vnm->interface_tag_by_sw_if_index, sw_if_index, tag); +} + +static inline void +vnet_clear_sw_interface_tag (vnet_main_t * vnm, u32 sw_if_index) +{ + uword *p; + p = hash_get (vnm->interface_tag_by_sw_if_index, sw_if_index); + if (p) + { + u8 *oldtag = (u8 *) p[0]; + hash_unset (vnm->interface_tag_by_sw_if_index, sw_if_index); + vec_free (oldtag); + } +} + /** * Call back walk type for walking SW indices on a HW interface */ diff --git a/vnet/vnet/vnet.h b/vnet/vnet/vnet.h index 36cdddd6ba4..5a8ae858678 100644 --- a/vnet/vnet/vnet.h +++ b/vnet/vnet/vnet.h @@ -68,6 +68,8 @@ typedef struct vnet_main_t _vnet_interface_function_list_elt_t * sw_interface_admin_up_down_functions[VNET_ITF_FUNC_N_PRIO]; + uword *interface_tag_by_sw_if_index; + /* * Last "api" error, preserved so we can issue reasonable diagnostics * at or near the top of the food chain |