From fa1b95c3ec8c1c34116ffe1cc908fb08459bd3e4 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Tue, 8 Nov 2022 18:05:02 +0100 Subject: [PATCH] isisd: add extended admin-group Add to the Extended IS Reachability TLV the support of Extended Administrative-Groups (RFC7308) Signed-off-by: Louis Scalbert --- isisd/isis_te.c | 7 +++++ isisd/isis_tlvs.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++- isisd/isis_tlvs.h | 5 ++++ 3 files changed, 79 insertions(+), 1 deletion(-) diff --git a/isisd/isis_te.c b/isisd/isis_te.c index 993d894f22..95a1dc989f 100644 --- a/isisd/isis_te.c +++ b/isisd/isis_te.c @@ -218,6 +218,13 @@ void isis_link_params_update(struct isis_circuit *circuit, } else UNSET_SUBTLV(ext, EXT_ADM_GRP); + if (IS_PARAM_SET(ifp->link_params, LP_EXTEND_ADM_GRP)) { + admin_group_copy(&ext->ext_admin_group, + &ifp->link_params->ext_admin_grp); + SET_SUBTLV(ext, EXT_EXTEND_ADM_GRP); + } else + UNSET_SUBTLV(ext, EXT_EXTEND_ADM_GRP); + /* If known, register local IPv4 addr from ip_addr list */ if (listcount(circuit->ip_addrs) != 0) { addr = (struct prefix_ipv4 *)listgetdata( diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index ae0a208d21..8ece697b70 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -136,6 +136,8 @@ struct isis_ext_subtlvs *isis_alloc_ext_subtlvs(void) init_item_list(&ext->adj_sid); init_item_list(&ext->lan_sid); + admin_group_init(&ext->ext_admin_group); + return ext; } @@ -155,6 +157,9 @@ void isis_del_ext_subtlvs(struct isis_ext_subtlvs *ext) next_item = item->next; XFREE(MTYPE_ISIS_SUBTLV, item); } + + admin_group_term(&ext->ext_admin_group); + XFREE(MTYPE_ISIS_SUBTLV, ext); } @@ -233,6 +238,9 @@ copy_item_ext_subtlvs(struct isis_ext_subtlvs *exts, uint16_t mtid) SET_SUBTLV(rv, EXT_LAN_ADJ_SID); } + rv->ext_admin_group.bitmap.data = NULL; + admin_group_copy(&rv->ext_admin_group, &exts->ext_admin_group); + return rv; } @@ -241,6 +249,7 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, struct sbuf *buf, struct json_object *json, int indent, uint16_t mtid) { + char admin_group_buf[ADMIN_GROUP_PRINT_MAX_SIZE]; char aux_buf[255]; char cnt_buf[255]; @@ -250,9 +259,37 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, snprintfrr(aux_buf, sizeof(aux_buf), "0x%x", exts->adm_group); json_object_string_add(json, "adm-group", aux_buf); - } else + } else { sbuf_push(buf, indent, "Administrative Group: 0x%x\n", exts->adm_group); + sbuf_push(buf, indent + 2, "Bit positions: %s\n", + admin_group_standard_print( + admin_group_buf, + indent + strlen("Admin Group: "), + exts->adm_group)); + } + } + + if (IS_SUBTLV(exts, EXT_EXTEND_ADM_GRP) && + admin_group_nb_words(&exts->ext_admin_group) != 0) { + if (!json) { + /* TODO json after fix show database detail json */ + sbuf_push(buf, indent, "Ext Admin Group: %s\n", + admin_group_string( + admin_group_buf, + ADMIN_GROUP_PRINT_MAX_SIZE, + indent + strlen("Ext Admin Group: "), + &exts->ext_admin_group)); + admin_group_print(admin_group_buf, + indent + strlen("Ext Admin Group: "), + &exts->ext_admin_group); + if (admin_group_buf[0] != '\0' && + (buf->pos + strlen(admin_group_buf) + + SBUF_DEFAULT_SIZE / 2) < buf->size) + sbuf_push(buf, indent + 2, + "Bit positions: %s\n", + admin_group_buf); + } } if (IS_SUBTLV(exts, EXT_LLRI)) { if (json) { @@ -685,6 +722,24 @@ static int pack_item_ext_subtlvs(struct isis_ext_subtlvs *exts, stream_putc(s, ISIS_SUBTLV_DEF_SIZE); stream_putl(s, exts->adm_group); } + if (IS_SUBTLV(exts, EXT_EXTEND_ADM_GRP) && + admin_group_nb_words(&exts->ext_admin_group) != 0) { + /* Extended Administrative Group */ + size_t ag_length; + size_t ag_length_pos; + struct admin_group *ag; + + stream_putc(s, ISIS_SUBTLV_EXT_ADMIN_GRP); + ag_length_pos = stream_get_endp(s); + stream_putc(s, 0); /* length will be filled later*/ + + ag = &exts->ext_admin_group; + for (size_t i = 0; i < admin_group_nb_words(ag); i++) + stream_putl(s, ag->bitmap.data[i]); + + ag_length = stream_get_endp(s) - ag_length_pos - 1; + stream_putc_at(s, ag_length_pos, ag_length); + } if (IS_SUBTLV(exts, EXT_LLRI)) { stream_putc(s, ISIS_SUBTLV_LLRI); stream_putc(s, ISIS_SUBTLV_LLRI_SIZE); @@ -828,6 +883,8 @@ static int unpack_item_ext_subtlvs(uint16_t mtid, uint8_t len, struct stream *s, uint8_t sum = 0; uint8_t subtlv_type; uint8_t subtlv_len; + size_t nb_groups; + uint32_t val; struct isis_extended_reach *rv = dest; struct isis_ext_subtlvs *exts = isis_alloc_ext_subtlvs(); @@ -863,6 +920,15 @@ static int unpack_item_ext_subtlvs(uint16_t mtid, uint8_t len, struct stream *s, SET_SUBTLV(exts, EXT_ADM_GRP); } break; + case ISIS_SUBTLV_EXT_ADMIN_GRP: + nb_groups = subtlv_len / sizeof(uint32_t); + for (size_t i = 0; i < nb_groups; i++) { + val = stream_getl(s); + admin_group_bulk_set(&exts->ext_admin_group, + val, i); + } + SET_SUBTLV(exts, EXT_EXTEND_ADM_GRP); + break; case ISIS_SUBTLV_LLRI: if (subtlv_len != ISIS_SUBTLV_LLRI_SIZE) { sbuf_push(log, indent, diff --git a/isisd/isis_tlvs.h b/isisd/isis_tlvs.h index 52dfb7a84f..1dad9b1870 100644 --- a/isisd/isis_tlvs.h +++ b/isisd/isis_tlvs.h @@ -441,6 +441,9 @@ enum ext_subtlv_size { ISIS_SUBTLV_HDR_SIZE = 2, ISIS_SUBTLV_DEF_SIZE = 4, + /* RFC 7308 */ + ISIS_SUBTLV_EXT_ADMIN_GRP = 14, + ISIS_SUBTLV_MAX_SIZE = 180 }; @@ -471,6 +474,7 @@ enum ext_subtlv_size { #define EXT_RES_BW 0x040000 #define EXT_AVA_BW 0x080000 #define EXT_USE_BW 0x100000 +#define EXT_EXTEND_ADM_GRP 0x200000 /* * This structure groups all Extended IS Reachability subTLVs. @@ -491,6 +495,7 @@ struct isis_ext_subtlvs { uint32_t status; uint32_t adm_group; /* Resource Class/Color - RFC 5305 */ + struct admin_group ext_admin_group; /* Res. Class/Color - RFC 7308 */ /* Link Local/Remote Identifiers - RFC 5307 */ uint32_t local_llri; uint32_t remote_llri; -- 2.39.5