From a960d64a87849d312b32d9432ffb722672c14878 Mon Sep 17 00:00:00 2001 From: Pim van Pelt Date: Tue, 5 Mar 2024 22:59:15 +0100 Subject: [PATCH] Add the ability to skip address sync on unnumbered interfaces --- lcpng.c | 20 ++++++++++++++++++++ lcpng.h | 1 + lcpng_if_cli.c | 31 +++++++++++++++++++++++++++++++ lcpng_if_sync.c | 17 ++++++++++++++++- lcpng_interface.c | 4 ++++ lcpng_interface.h | 6 ++++++ 6 files changed, 78 insertions(+), 1 deletion(-) diff --git a/lcpng.c b/lcpng.c index 3b102b5..7e8d617 100644 --- a/lcpng.c +++ b/lcpng.c @@ -95,6 +95,26 @@ lcp_sync (void) return lcpm->lcp_sync; } +void +lcp_set_sync_unnumbered (u8 is_sync) +{ + lcp_main_t *lcpm = &lcp_main; + + lcpm->lcp_sync_unnumbered = (is_sync != 0); + + // If we set to 'on', do a one-off sync of LCP interfaces + if (is_sync) + lcp_itf_pair_sync_state_all (); +} + +int +lcp_sync_unnumbered (void) +{ + lcp_main_t *lcpm = &lcp_main; + + return lcpm->lcp_sync_unnumbered; +} + void lcp_set_auto_subint (u8 is_auto) { diff --git a/lcpng.h b/lcpng.h index cf51411..2447433 100644 --- a/lcpng.h +++ b/lcpng.h @@ -26,6 +26,7 @@ typedef struct lcp_main_s int default_ns_fd; u8 lcp_auto_subint; /* Automatically create/delete LCP sub-interfaces */ u8 lcp_sync; /* Automatically sync VPP changes to LCP */ + u8 lcp_sync_unnumbered; /* Automatically sync unnumbered interfaces to LCP */ /* Set when Unit testing */ u8 test_mode; } lcp_main_t; diff --git a/lcpng_if_cli.c b/lcpng_if_cli.c index beab982..22e44ab 100644 --- a/lcpng_if_cli.c +++ b/lcpng_if_cli.c @@ -142,6 +142,37 @@ VLIB_CLI_COMMAND (lcp_sync_command, static) = { .function = lcp_sync_command_fn, }; +static clib_error_t * +lcp_sync_unnumbered_command_fn (vlib_main_t *vm, unformat_input_t *input, + vlib_cli_command_t *cmd) +{ + unformat_input_t _line_input, *line_input = &_line_input; + + if (!unformat_user (input, unformat_line_input, line_input)) + return 0; + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "on") || unformat (line_input, "enable")) + lcp_set_sync_unnumbered (1); + else if (unformat (line_input, "off") || + unformat (line_input, "disable")) + lcp_set_sync_unnumbered (0); + else + return clib_error_return (0, "unknown input `%U'", + format_unformat_error, line_input); + } + + unformat_free (line_input); + return 0; +} + +VLIB_CLI_COMMAND (lcp_sync_unnumbered_command, static) = { + .path = "lcp lcp-sync-unnumbered", + .short_help = "lcp lcp-sync-unnumbered [on|enable|off|disable]", + .function = lcp_sync_unnumbered_command_fn, +}; + static clib_error_t * lcp_auto_subint_command_fn (vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd) diff --git a/lcpng_if_sync.c b/lcpng_if_sync.c index 43bbb0a..1c82db6 100644 --- a/lcpng_if_sync.c +++ b/lcpng_if_sync.c @@ -109,7 +109,22 @@ lcp_itf_pair_sync_state (lcp_itf_pair_t *lip) /* Linux will remove IPv6 addresses on children when the parent state * goes down, so we ensure all IPv4/IPv6 addresses are synced. */ - lcp_itf_set_interface_addr (lip); + if (sw->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED) + { + if (lcp_sync_unnumbered ()) + { + lcp_itf_set_interface_addr (lip); + } + else + { + LCP_IF_NOTICE ("sync_state: not syncing addresses on unnumbered %U", + format_lcp_itf_pair, lip); + } + } + else + { + lcp_itf_set_interface_addr (lip); + } if (vif_ns_fd != -1) close (vif_ns_fd); diff --git a/lcpng_interface.c b/lcpng_interface.c index 4e61f08..ac6f6d7 100644 --- a/lcpng_interface.c +++ b/lcpng_interface.c @@ -133,6 +133,8 @@ lcp_itf_pair_show (u32 phy_sw_if_index) vlib_cli_output (vm, "lcp lcp-auto-subint %s\n", lcp_auto_subint () ? "on" : "off"); vlib_cli_output (vm, "lcp lcp-sync %s\n", lcp_sync () ? "on" : "off"); + vlib_cli_output (vm, "lcp lcp-sync-unnumbered %s\n", + lcp_sync_unnumbered () ? "on" : "off"); if (phy_sw_if_index == ~0) { @@ -1233,6 +1235,8 @@ lcp_itf_pair_init (vlib_main_t *vm) tcp_punt_unknown (vm, 0, 1); tcp_punt_unknown (vm, 1, 1); + lcp_main.lcp_sync_unnumbered = 1; + return NULL; } diff --git a/lcpng_interface.h b/lcpng_interface.h index 9a6d64d..caf43e1 100644 --- a/lcpng_interface.h +++ b/lcpng_interface.h @@ -166,6 +166,12 @@ int lcp_auto_subint (void); void lcp_set_sync (u8 is_auto); int lcp_sync (void); +/** + * sync address of unnumbered interfaces from VPP into LCP + */ +void lcp_set_sync_unnumbered (u8 is_sync); +int lcp_sync_unnumbered (void); + typedef void (*lcp_itf_pair_add_cb_t) (lcp_itf_pair_t *); typedef void (*lcp_itf_pair_del_cb_t) (lcp_itf_pair_t *);