diff options
Diffstat (limited to 'zebra/zebra_srv6_vty.c')
| -rw-r--r-- | zebra/zebra_srv6_vty.c | 200 |
1 files changed, 190 insertions, 10 deletions
diff --git a/zebra/zebra_srv6_vty.c b/zebra/zebra_srv6_vty.c index 963b528b86..c664a9c69f 100644 --- a/zebra/zebra_srv6_vty.c +++ b/zebra/zebra_srv6_vty.c @@ -232,7 +232,7 @@ DEFUN (show_srv6_locator_detail, if (locator->sid_format->type == SRV6_SID_FORMAT_TYPE_USID) vty_out(vty, "Behavior: uSID\n"); - } else { + } else { vty_out(vty, "Block-Bit-Len: %u\n", locator->block_bits_length); vty_out(vty, "Node-Bit-Len: %u\n", @@ -244,7 +244,7 @@ DEFUN (show_srv6_locator_detail, if (CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID)) vty_out(vty, "Behavior: uSID\n"); - } + } vty_out(vty, "Chunks:\n"); for (ALL_LIST_ELEMENTS_RO((struct list *)locator->chunks, node, @@ -286,9 +286,30 @@ DEFUN (no_srv6, struct zebra_srv6 *srv6 = zebra_srv6_get_default(); struct srv6_locator *locator; struct listnode *node, *nnode; + struct zebra_srv6_sid_block *block; + struct zebra_srv6_sid_ctx *ctx; + + for (ALL_LIST_ELEMENTS(srv6->sids, node, nnode, ctx)) { + if (ctx->sid) + zebra_srv6_sid_free(ctx->sid); + + listnode_delete(srv6->sids, ctx); + zebra_srv6_sid_ctx_free(ctx); + } + + for (ALL_LIST_ELEMENTS(srv6->locators, node, nnode, locator)) { + block = locator->sid_block; + if (block) { + block->refcnt--; + if (block->refcnt == 0) { + listnode_delete(srv6->sid_blocks, block); + zebra_srv6_sid_block_free(block); + } + locator->sid_block = NULL; + } - for (ALL_LIST_ELEMENTS(srv6->locators, node, nnode, locator)) zebra_srv6_locator_delete(locator); + } return CMD_SUCCESS; } @@ -335,12 +356,37 @@ DEFUN (no_srv6_locator, "Segment Routing SRv6 locator\n" "Specify locator-name\n") { + struct zebra_srv6 *srv6 = zebra_srv6_get_default(); + struct zebra_srv6_sid_block *block; + struct listnode *node, *nnode; + struct zebra_srv6_sid_ctx *ctx; struct srv6_locator *locator = zebra_srv6_locator_lookup(argv[2]->arg); if (!locator) { vty_out(vty, "%% Can't find SRv6 locator\n"); return CMD_WARNING_CONFIG_FAILED; } + for (ALL_LIST_ELEMENTS(srv6->sids, node, nnode, ctx)) { + if (!ctx->sid || ctx->sid->locator != locator) + continue; + + if (ctx->sid) + zebra_srv6_sid_free(ctx->sid); + + listnode_delete(srv6->sids, ctx); + zebra_srv6_sid_ctx_free(ctx); + } + + block = locator->sid_block; + if (block) { + block->refcnt--; + if (block->refcnt == 0) { + listnode_delete(srv6->sid_blocks, block); + zebra_srv6_sid_block_free(block); + } + locator->sid_block = NULL; + } + zebra_srv6_locator_delete(locator); return CMD_SUCCESS; } @@ -361,14 +407,37 @@ DEFPY (locator_prefix, VTY_DECLVAR_CONTEXT(srv6_locator, locator); struct srv6_locator_chunk *chunk = NULL; struct listnode *node = NULL; + uint8_t expected_prefixlen; + struct srv6_sid_format *format; locator->prefix = *prefix; func_bit_len = func_bit_len ?: ZEBRA_SRV6_FUNCTION_LENGTH; + expected_prefixlen = prefix->prefixlen; + format = locator->sid_format; + if (format) { + if (strmatch(format->name, SRV6_SID_FORMAT_USID_F3216_NAME)) + expected_prefixlen = + SRV6_SID_FORMAT_USID_F3216_BLOCK_LEN + + SRV6_SID_FORMAT_USID_F3216_NODE_LEN; + else if (strmatch(format->name, + SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NAME)) + expected_prefixlen = + SRV6_SID_FORMAT_UNCOMPRESSED_F4024_BLOCK_LEN + + SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE_LEN; + } + + if (prefix->prefixlen != expected_prefixlen) { + vty_out(vty, + "%% Locator prefix length '%u' inconsistent with configured format '%s'. Please either use a prefix length that is consistent with the format or change the format.\n", + prefix->prefixlen, format->name); + return CMD_WARNING_CONFIG_FAILED; + } + /* Resolve optional arguments */ if (block_bit_len == 0 && node_bit_len == 0) { - block_bit_len = - prefix->prefixlen - ZEBRA_SRV6_LOCATOR_NODE_LENGTH; + block_bit_len = prefix->prefixlen - + ZEBRA_SRV6_LOCATOR_NODE_LENGTH; node_bit_len = ZEBRA_SRV6_LOCATOR_NODE_LENGTH; } else if (block_bit_len == 0) { block_bit_len = prefix->prefixlen - node_bit_len; @@ -439,7 +508,8 @@ DEFPY (locator_prefix, } } - zebra_srv6_locator_add(locator); + zebra_srv6_locator_format_set(locator, locator->sid_format); + return CMD_SUCCESS; } @@ -460,8 +530,9 @@ DEFPY (locator_behavior, /* SRv6 locator uSID flag already set, nothing to do */ return CMD_SUCCESS; - /* Remove old locator from zclients */ - zebra_notify_srv6_locator_delete(locator); + if (!locator->sid_format) + /* Remove old locator from zclients */ + zebra_notify_srv6_locator_delete(locator); /* Set/Unset the SRV6_LOCATOR_USID */ if (no) @@ -469,8 +540,75 @@ DEFPY (locator_behavior, else SET_FLAG(locator->flags, SRV6_LOCATOR_USID); - /* Notify the new locator to zclients */ - zebra_notify_srv6_locator_add(locator); + if (!locator->sid_format) + /* Notify the new locator to zclients */ + zebra_srv6_locator_add(locator); + + return CMD_SUCCESS; +} + +DEFPY(locator_sid_format, + locator_sid_format_cmd, + "format <usid-f3216|uncompressed-f4024>$format", + "Configure SRv6 SID format\n" + "Specify usid-f3216 format\n" + "Specify uncompressed-f4024 format\n") +{ + VTY_DECLVAR_CONTEXT(srv6_locator, locator); + struct srv6_sid_format *sid_format = NULL; + uint8_t expected_prefixlen; + + expected_prefixlen = locator->prefix.prefixlen; + if (strmatch(format, SRV6_SID_FORMAT_USID_F3216_NAME)) + expected_prefixlen = SRV6_SID_FORMAT_USID_F3216_BLOCK_LEN + + SRV6_SID_FORMAT_USID_F3216_NODE_LEN; + else if (strmatch(format, SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NAME)) + expected_prefixlen = + SRV6_SID_FORMAT_UNCOMPRESSED_F4024_BLOCK_LEN + + SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE_LEN; + + if (IPV6_ADDR_SAME(&locator->prefix, &in6addr_any)) { + vty_out(vty, + "%% Unexpected configuration sequence: the prefix of the locator is required before configuring the format. Please configure the prefix first and then configure the format.\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (locator->prefix.prefixlen != expected_prefixlen) { + vty_out(vty, + "%% Locator prefix length '%u' inconsistent with configured format '%s'. Please either use a prefix length that is consistent with the format or change the format.\n", + locator->prefix.prefixlen, format); + return CMD_WARNING_CONFIG_FAILED; + } + + sid_format = srv6_sid_format_lookup(format); + if (!sid_format) { + vty_out(vty, "%% Cannot find SRv6 SID format '%s'\n", format); + return CMD_WARNING_CONFIG_FAILED; + } + + if (sid_format == locator->sid_format) + /* Format has not changed, nothing to do */ + return CMD_SUCCESS; + + zebra_srv6_locator_format_set(locator, sid_format); + + return CMD_SUCCESS; +} + +DEFPY (no_locator_sid_format, + no_locator_sid_format_cmd, + "no format [WORD]", + NO_STR + "Configure SRv6 SID format\n" + "Specify SRv6 SID format\n") +{ + VTY_DECLVAR_CONTEXT(srv6_locator, locator); + + if (!locator->sid_format) + /* SID format already unset, nothing to do */ + return CMD_SUCCESS; + + zebra_srv6_locator_format_set(locator, NULL); return CMD_SUCCESS; } @@ -550,6 +688,9 @@ DEFUN(no_srv6_sid_format_f3216_usid, format->config.usid.wlib_end = SRV6_SID_FORMAT_USID_F3216_WLIB_END; format->config.usid.ewlib_start = SRV6_SID_FORMAT_USID_F3216_EWLIB_START; + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -583,6 +724,9 @@ DEFUN(no_srv6_sid_format_f4024_uncompressed, format->config.uncompressed.explicit_start = SRV6_SID_FORMAT_UNCOMPRESSED_F4024_EXPLICIT_RANGE_START; + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -597,6 +741,9 @@ DEFPY(srv6_sid_format_usid_lib, format->config.usid.lib_start = start; + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -616,6 +763,9 @@ DEFPY(no_srv6_sid_format_usid_lib, else assert(0); + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -634,6 +784,9 @@ DEFPY(srv6_sid_format_usid_lib_explicit, format->config.usid.elib_start = start; format->config.usid.elib_end = end; + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -659,6 +812,9 @@ DEFPY(no_srv6_sid_format_usid_lib_explicit, assert(0); } + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -676,6 +832,9 @@ DEFPY(srv6_sid_format_usid_wlib, format->config.usid.wlib_start = start; format->config.usid.wlib_end = end; + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -700,6 +859,9 @@ DEFPY(no_srv6_sid_format_usid_wlib, assert(0); } + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -715,6 +877,9 @@ DEFPY(srv6_sid_format_usid_wide_lib_explicit, format->config.usid.ewlib_start = start; + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -735,6 +900,9 @@ DEFPY(no_srv6_sid_format_usid_wide_lib_explicit, else assert(0); + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -749,6 +917,9 @@ DEFPY(srv6_sid_format_explicit, format->config.uncompressed.explicit_start = start; + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -768,6 +939,9 @@ DEFPY(no_srv6_sid_format_explicit, else assert(0); + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -818,6 +992,10 @@ static int zebra_sr_config(struct vty *vty) vty_out(vty, "\n"); if (CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID)) vty_out(vty, " behavior usid\n"); + if (locator->sid_format) { + format = locator->sid_format; + vty_out(vty, " format %s\n", format->name); + } vty_out(vty, " exit\n"); vty_out(vty, " !\n"); } @@ -917,6 +1095,8 @@ void zebra_srv6_vty_init(void) /* Command for configuration */ install_element(SRV6_LOC_NODE, &locator_prefix_cmd); install_element(SRV6_LOC_NODE, &locator_behavior_cmd); + install_element(SRV6_LOC_NODE, &locator_sid_format_cmd); + install_element(SRV6_LOC_NODE, &no_locator_sid_format_cmd); install_element(SRV6_ENCAP_NODE, &srv6_src_addr_cmd); install_element(SRV6_ENCAP_NODE, &no_srv6_src_addr_cmd); install_element(SRV6_SID_FORMAT_USID_F3216_NODE, |
