static int unpack_tlvs(enum isis_tlv_context context, size_t avail_len,
struct stream *stream, struct sbuf *log, void *dest,
- int indent);
+ int indent, bool *unpacked_known_tlvs);
/* Functions related to TLVs 1 Area Addresses */
size_t subtlv_start = stream_get_getp(s);
if (unpack_tlvs(ISIS_CONTEXT_SUBTLV_NE_REACH, subtlv_len, s,
- log, NULL, indent + 4)) {
+ log, NULL, indent + 4, NULL)) {
goto out;
}
}
rv->subtlvs = isis_alloc_subtlvs(ISIS_CONTEXT_SUBTLV_IP_REACH);
+ bool unpacked_known_tlvs = false;
+
if (unpack_tlvs(ISIS_CONTEXT_SUBTLV_IP_REACH, subtlv_len, s,
- log, rv->subtlvs, indent + 4)) {
+ log, rv->subtlvs, indent + 4, &unpacked_known_tlvs)) {
goto out;
}
+ if (!unpacked_known_tlvs) {
+ isis_free_subtlvs(rv->subtlvs);
+ rv->subtlvs = NULL;
+ }
}
append_item(items, (struct isis_item *)rv);
}
rv->subtlvs = isis_alloc_subtlvs(ISIS_CONTEXT_SUBTLV_IPV6_REACH);
+ bool unpacked_known_tlvs = false;
+
if (unpack_tlvs(ISIS_CONTEXT_SUBTLV_IPV6_REACH, subtlv_len, s,
- log, rv->subtlvs, indent + 4)) {
+ log, rv->subtlvs, indent + 4, &unpacked_known_tlvs)) {
goto out;
}
+ if (!unpacked_known_tlvs) {
+ isis_free_subtlvs(rv->subtlvs);
+ rv->subtlvs = NULL;
+ }
}
append_item(items, (struct isis_item *)rv);
sbuf_push(buf, indent, " Password: %s\n", obuf);
break;
case ISIS_PASSWD_TYPE_HMAC_MD5:
- for (unsigned int i = 0; i < 16; i++) {
- snprintf(obuf + 2 * i, sizeof(obuf) - 2 * i,
- "%02" PRIx8, auth->value[i]);
+ for (unsigned int j = 0; j < 16; j++) {
+ snprintf(obuf + 2 * j, sizeof(obuf) - 2 * j,
+ "%02" PRIx8, auth->value[j]);
}
sbuf_push(buf, indent, " HMAC-MD5: %s\n", obuf);
break;
default:
sbuf_push(buf, indent, " Unknown (%" PRIu8 ")\n", auth->type);
break;
- };
+ }
}
static void free_item_auth(struct isis_item *i)
struct listnode *node;
for (ALL_LIST_ELEMENTS_RO(rv, node, fragment_tlvs))
isis_free_tlvs(fragment_tlvs);
- list_delete_and_null(&rv);
+ list_delete(&rv);
}
stream_free(dummy_stream);
static int unpack_tlv(enum isis_tlv_context context, size_t avail_len,
struct stream *stream, struct sbuf *log, void *dest,
- int indent)
+ int indent, bool *unpacked_known_tlvs)
{
uint8_t tlv_type, tlv_len;
const struct tlv_ops *ops;
ops = tlv_table[context][tlv_type];
if (ops && ops->unpack) {
+ if (unpacked_known_tlvs)
+ *unpacked_known_tlvs = true;
return ops->unpack(context, tlv_type, tlv_len, stream, log,
dest, indent + 2);
}
static int unpack_tlvs(enum isis_tlv_context context, size_t avail_len,
struct stream *stream, struct sbuf *log, void *dest,
- int indent)
+ int indent, bool *unpacked_known_tlvs)
{
int rv;
size_t tlv_start, tlv_pos;
while (tlv_pos < avail_len) {
rv = unpack_tlv(context, avail_len - tlv_pos, stream, log, dest,
- indent + 2);
+ indent + 2, unpacked_known_tlvs);
if (rv)
return rv;
result = isis_alloc_tlvs();
rv = unpack_tlvs(ISIS_CONTEXT_LSP, avail_len, stream, &logbuf, result,
- indent);
+ indent, NULL);
*log = sbuf_buf(&logbuf);
*dest = result;
struct nlpids *nlpids)
{
tlvs->protocols_supported.count = nlpids->count;
- if (tlvs->protocols_supported.protocols)
- XFREE(MTYPE_ISIS_TLV, tlvs->protocols_supported.protocols);
+ XFREE(MTYPE_ISIS_TLV, tlvs->protocols_supported.protocols);
if (nlpids->count) {
tlvs->protocols_supported.protocols =
XCALLOC(MTYPE_ISIS_TLV, nlpids->count);
{
struct listnode *node;
struct prefix_ipv6 *ip_addr;
+ unsigned int addr_count = 0;
for (ALL_LIST_ELEMENTS_RO(addresses, node, ip_addr)) {
+ if (addr_count >= 15)
+ break;
+
struct isis_ipv6_address *a =
XCALLOC(MTYPE_ISIS_TLV, sizeof(*a));
a->addr = ip_addr->prefix;
append_item(&tlvs->ipv6_address, (struct isis_item *)a);
+ addr_count++;
}
}
[ISIS_PASSWD_TYPE_HMAC_MD5] = auth_validator_hmac_md5,
};
-bool isis_tlvs_auth_is_valid(struct isis_tlvs *tlvs, struct isis_passwd *passwd,
- struct stream *stream, bool is_lsp)
+int isis_tlvs_auth_is_valid(struct isis_tlvs *tlvs, struct isis_passwd *passwd,
+ struct stream *stream, bool is_lsp)
{
/* If no auth is set, always pass authentication */
if (!passwd->type)
- return true;
+ return ISIS_AUTH_OK;
/* If we don't known how to validate the auth, return invalid */
if (passwd->type >= array_size(auth_validators)
|| !auth_validators[passwd->type])
- return false;
+ return ISIS_AUTH_NO_VALIDATOR;
struct isis_auth *auth_head = (struct isis_auth *)tlvs->isis_auth.head;
struct isis_auth *auth;
/* If matching auth TLV could not be found, return invalid */
if (!auth)
- return false;
+ return ISIS_AUTH_TYPE_FAILURE;
+
/* Perform validation and return result */
- return auth_validators[passwd->type](passwd, stream, auth, is_lsp);
+ if (auth_validators[passwd->type](passwd, stream, auth, is_lsp))
+ return ISIS_AUTH_OK;
+ else
+ return ISIS_AUTH_FAILURE;
}
bool isis_tlvs_area_addresses_match(struct isis_tlvs *tlvs,
reduced.nlpids[0] = NLPID_IP;
} else if (ipv6_supported) {
reduced.count = 1;
- reduced.nlpids[1] = NLPID_IPV6;
+ reduced.nlpids[0] = NLPID_IPV6;
} else {
reduced.count = 0;
}
void isis_tlvs_add_csnp_entries(struct isis_tlvs *tlvs, uint8_t *start_id,
uint8_t *stop_id, uint16_t num_lsps,
- dict_t *lspdb, struct isis_lsp **last_lsp)
+ struct lspdb_head *head,
+ struct isis_lsp **last_lsp)
{
- dnode_t *first = dict_lower_bound(lspdb, start_id);
+ struct isis_lsp searchfor;
+ struct isis_lsp *first, *lsp;
+
+ memcpy(&searchfor.hdr.lsp_id, start_id, sizeof(searchfor.hdr.lsp_id));
+ first = lspdb_find_gteq(head, &searchfor);
if (!first)
return;
- dnode_t *last = dict_upper_bound(lspdb, stop_id);
- dnode_t *curr = first;
-
- isis_tlvs_add_lsp_entry(tlvs, first->dict_data);
- *last_lsp = first->dict_data;
-
- while (curr) {
- curr = dict_next(lspdb, curr);
- if (curr) {
- isis_tlvs_add_lsp_entry(tlvs, curr->dict_data);
- *last_lsp = curr->dict_data;
- }
- if (curr == last || tlvs->lsp_entries.count == num_lsps)
+ for_each_from (lspdb, head, lsp, first) {
+ if (memcmp(lsp->hdr.lsp_id, stop_id, sizeof(lsp->hdr.lsp_id))
+ > 0 || tlvs->lsp_entries.count == num_lsps)
break;
+
+ isis_tlvs_add_lsp_entry(tlvs, lsp);
+ *last_lsp = lsp;
}
}