summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Franke <chris@opensourcerouting.org>2017-07-05 18:37:36 +0200
committerChristian Franke <chris@opensourcerouting.org>2017-08-03 11:34:04 +0200
commitaf8ac8f98fbe565b182020895553d862ad743012 (patch)
tree1e934f37d3015ee84edb4b0ef4e03ddf94e35897
parentisisd: send/receive *SNPs with new parser (diff)
downloadfrr-af8ac8f98fbe565b182020895553d862ad743012.tar.xz
frr-af8ac8f98fbe565b182020895553d862ad743012.zip
isisd: send/receive LSPs with new parser
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
-rw-r--r--isisd/Makefile.am4
-rw-r--r--isisd/isis_adjacency.c10
-rw-r--r--isisd/isis_circuit.c1
-rw-r--r--isisd/isis_common.h10
-rw-r--r--isisd/isis_csm.c1
-rw-r--r--isisd/isis_dr.c1
-rw-r--r--isisd/isis_dynhn.c29
-rw-r--r--isisd/isis_dynhn.h4
-rw-r--r--isisd/isis_events.c1
-rw-r--r--isisd/isis_lsp.c1919
-rw-r--r--isisd/isis_lsp.h36
-rw-r--r--isisd/isis_main.c1
-rw-r--r--isisd/isis_misc.c22
-rw-r--r--isisd/isis_misc.h1
-rw-r--r--isisd/isis_mt.c199
-rw-r--r--isisd/isis_mt.h43
-rw-r--r--isisd/isis_pdu.c498
-rw-r--r--isisd/isis_pdu.h34
-rw-r--r--isisd/isis_redist.c1
-rw-r--r--isisd/isis_route.c1
-rw-r--r--isisd/isis_routemap.c1
-rw-r--r--isisd/isis_spf.c235
-rw-r--r--isisd/isis_te.c392
-rw-r--r--isisd/isis_te.h11
-rw-r--r--isisd/isis_tlv.c1453
-rw-r--r--isisd/isis_tlv.h340
-rw-r--r--isisd/isis_zebra.c1
-rw-r--r--isisd/isisd.c1
-rw-r--r--isisd/iso_checksum.c2
29 files changed, 977 insertions, 4275 deletions
diff --git a/isisd/Makefile.am b/isisd/Makefile.am
index 4e8665cd8..ca212f5b4 100644
--- a/isisd/Makefile.am
+++ b/isisd/Makefile.am
@@ -13,7 +13,7 @@ sbin_PROGRAMS = isisd
libisis_a_SOURCES = \
isis_memory.c \
isis_adjacency.c isis_lsp.c dict.c isis_circuit.c isis_pdu.c \
- isis_tlv.c isisd.c isis_misc.c isis_zebra.c isis_dr.c \
+ isisd.c isis_misc.c isis_zebra.c isis_dr.c \
isis_flags.c isis_dynhn.c iso_checksum.c isis_csm.c isis_events.c \
isis_spf.c isis_redist.c isis_route.c isis_routemap.c isis_te.c \
isis_vty.c isis_mt.c \
@@ -22,7 +22,7 @@ libisis_a_SOURCES = \
noinst_HEADERS = \
isis_memory.h \
- isisd.h isis_pdu.h isis_tlv.h isis_adjacency.h isis_constants.h \
+ isisd.h isis_pdu.h isis_adjacency.h isis_constants.h \
isis_lsp.h dict.h isis_circuit.h isis_misc.h isis_network.h \
isis_zebra.h isis_dr.h isis_flags.h isis_dynhn.h isis_common.h \
iso_checksum.h isis_csm.h isis_events.h isis_spf.h isis_redist.h \
diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c
index e13b3769e..0afa65d72 100644
--- a/isisd/isis_adjacency.c
+++ b/isisd/isis_adjacency.c
@@ -43,7 +43,6 @@
#include "isisd/isis_dr.h"
#include "isisd/isis_dynhn.h"
#include "isisd/isis_pdu.h"
-#include "isisd/isis_tlv.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_spf.h"
#include "isisd/isis_events.h"
@@ -187,7 +186,7 @@ void isis_adj_state_change(struct isis_adjacency *adj,
dyn = dynhn_find_by_id(adj->sysid);
if (dyn)
- adj_name = (const char *)dyn->name.name;
+ adj_name = dyn->hostname;
else
adj_name = sysid_print(adj->sysid);
@@ -301,7 +300,7 @@ void isis_adj_print(struct isis_adjacency *adj)
return;
dyn = dynhn_find_by_id(adj->sysid);
if (dyn)
- zlog_debug("%s", dyn->name.name);
+ zlog_debug("%s", dyn->hostname);
zlog_debug("SystemId %20s SNPA %s, level %d\nHolding Time %d",
sysid_print(adj->sysid), snpa_print(adj->snpa), adj->level,
@@ -355,7 +354,7 @@ void isis_adj_print_vty(struct isis_adjacency *adj, struct vty *vty,
dyn = dynhn_find_by_id(adj->sysid);
if (dyn)
- vty_out(vty, " %-20s", dyn->name.name);
+ vty_out(vty, " %-20s", dyn->hostname);
else
vty_out(vty, " %-20s", sysid_print(adj->sysid));
@@ -416,8 +415,7 @@ void isis_adj_print_vty(struct isis_adjacency *adj, struct vty *vty,
&& (adj->circuit->circ_type == CIRCUIT_T_BROADCAST)) {
dyn = dynhn_find_by_id(adj->lanid);
if (dyn)
- vty_out(vty, ", LAN id: %s.%02x",
- dyn->name.name,
+ vty_out(vty, ", LAN id: %s.%02x", dyn->hostname,
adj->lanid[ISIS_SYS_ID_LEN]);
else
vty_out(vty, ", LAN id: %s.%02x",
diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c
index 72810532b..c321677de 100644
--- a/isisd/isis_circuit.c
+++ b/isisd/isis_circuit.c
@@ -48,7 +48,6 @@
#include "isisd/isis_common.h"
#include "isisd/isis_flags.h"
#include "isisd/isis_circuit.h"
-#include "isisd/isis_tlv.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_pdu.h"
#include "isisd/isis_network.h"
diff --git a/isisd/isis_common.h b/isisd/isis_common.h
index ba6c5f876..b157bb183 100644
--- a/isisd/isis_common.h
+++ b/isisd/isis_common.h
@@ -47,16 +47,6 @@ struct isis_passwd {
};
/*
- * (Dynamic) Hostname
- * one struct for cache list
- * one struct for LSP TLV
- */
-struct hostname {
- u_char namelen;
- u_char name[255];
-};
-
-/*
* Supported Protocol IDs
*/
struct nlpids {
diff --git a/isisd/isis_csm.c b/isisd/isis_csm.c
index b0ccdee76..10870d5c5 100644
--- a/isisd/isis_csm.c
+++ b/isisd/isis_csm.c
@@ -37,7 +37,6 @@
#include "isisd/isis_common.h"
#include "isisd/isis_flags.h"
#include "isisd/isis_circuit.h"
-#include "isisd/isis_tlv.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_pdu.h"
#include "isisd/isis_network.h"
diff --git a/isisd/isis_dr.c b/isisd/isis_dr.c
index 3f532ecf8..2db827191 100644
--- a/isisd/isis_dr.c
+++ b/isisd/isis_dr.c
@@ -42,7 +42,6 @@
#include "isisd/isis_adjacency.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_pdu.h"
-#include "isisd/isis_tlv.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_dr.h"
#include "isisd/isis_events.h"
diff --git a/isisd/isis_dynhn.c b/isisd/isis_dynhn.c
index 9249ad629..6fa798830 100644
--- a/isisd/isis_dynhn.c
+++ b/isisd/isis_dynhn.c
@@ -94,38 +94,26 @@ struct isis_dynhn *dynhn_find_by_name(const char *hostname)
struct isis_dynhn *dyn = NULL;
for (ALL_LIST_ELEMENTS_RO(dyn_cache, node, dyn))
- if (strncmp((char *)dyn->name.name, hostname, 255) == 0)
+ if (strncmp(dyn->hostname, hostname, 255) == 0)
return dyn;
return NULL;
}
-void isis_dynhn_insert(const u_char *id, struct hostname *hostname, int level)
+void isis_dynhn_insert(const u_char *id, const char *hostname, int level)
{
struct isis_dynhn *dyn;
dyn = dynhn_find_by_id(id);
- if (dyn) {
- memcpy(&dyn->name, hostname, hostname->namelen + 1);
- memcpy(dyn->id, id, ISIS_SYS_ID_LEN);
- dyn->refresh = time(NULL);
- return;
- }
- dyn = XCALLOC(MTYPE_ISIS_DYNHN, sizeof(struct isis_dynhn));
if (!dyn) {
- zlog_warn("isis_dynhn_insert(): out of memory!");
- return;
+ dyn = XCALLOC(MTYPE_ISIS_DYNHN, sizeof(struct isis_dynhn));
+ memcpy(dyn->id, id, ISIS_SYS_ID_LEN);
+ dyn->level = level;
+ listnode_add(dyn_cache, dyn);
}
- /* we also copy the length */
- memcpy(&dyn->name, hostname, hostname->namelen + 1);
- memcpy(dyn->id, id, ISIS_SYS_ID_LEN);
+ snprintf(dyn->hostname, sizeof(dyn->hostname), "%s", hostname);
dyn->refresh = time(NULL);
- dyn->level = level;
-
- listnode_add(dyn_cache, dyn);
-
- return;
}
void isis_dynhn_remove(const u_char *id)
@@ -137,7 +125,6 @@ void isis_dynhn_remove(const u_char *id)
return;
listnode_delete(dyn_cache, dyn);
XFREE(MTYPE_ISIS_DYNHN, dyn);
- return;
}
/*
@@ -155,7 +142,7 @@ void dynhn_print_all(struct vty *vty)
for (ALL_LIST_ELEMENTS_RO(dyn_cache, node, dyn)) {
vty_out(vty, "%-7d", dyn->level);
vty_out(vty, "%-15s%-15s\n", sysid_print(dyn->id),
- dyn->name.name);
+ dyn->hostname);
}
vty_out(vty, " * %s %s\n", sysid_print(isis->sysid),
diff --git a/isisd/isis_dynhn.h b/isisd/isis_dynhn.h
index f3ca94d40..635d79f3f 100644
--- a/isisd/isis_dynhn.h
+++ b/isisd/isis_dynhn.h
@@ -25,13 +25,13 @@
struct isis_dynhn {
u_char id[ISIS_SYS_ID_LEN];
- struct hostname name;
+ char hostname[256];
time_t refresh;
int level;
};
void dyn_cache_init(void);
-void isis_dynhn_insert(const u_char *id, struct hostname *hostname, int level);
+void isis_dynhn_insert(const u_char *id, const char *hostname, int level);
void isis_dynhn_remove(const u_char *id);
struct isis_dynhn *dynhn_find_by_id(const u_char *id);
struct isis_dynhn *dynhn_find_by_name(const char *hostname);
diff --git a/isisd/isis_events.c b/isisd/isis_events.c
index 9af256ba3..1cc90d031 100644
--- a/isisd/isis_events.c
+++ b/isisd/isis_events.c
@@ -37,7 +37,6 @@
#include "isisd/isis_common.h"
#include "isisd/isis_flags.h"
#include "isisd/isis_circuit.h"
-#include "isisd/isis_tlv.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_pdu.h"
#include "isisd/isis_network.h"
diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c
index 76022bdea..243853c97 100644
--- a/isisd/isis_lsp.c
+++ b/isisd/isis_lsp.c
@@ -44,7 +44,6 @@
#include "isisd/isis_flags.h"
#include "isisd/isis_circuit.h"
#include "isisd/isisd.h"
-#include "isisd/isis_tlv.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_pdu.h"
#include "isisd/isis_dynhn.h"
@@ -54,6 +53,7 @@
#include "isisd/isis_spf.h"
#include "isisd/isis_te.h"
#include "isisd/isis_mt.h"
+#include "isisd/isis_tlvs2.h"
/* staticly assigned vars for printing purposes */
char lsp_bits_string[200]; /* FIXME: enough ? */
@@ -105,19 +105,8 @@ static void lsp_clear_data(struct isis_lsp *lsp)
if (!lsp)
return;
- if (lsp->tlv_data.hostname)
- isis_dynhn_remove(lsp->lsp_header->lsp_id);
-
- if (lsp->own_lsp) {
- if (lsp->tlv_data.nlpids)
- XFREE(MTYPE_ISIS_TLV, lsp->tlv_data.nlpids);
- if (lsp->tlv_data.hostname)
- XFREE(MTYPE_ISIS_TLV, lsp->tlv_data.hostname);
- if (lsp->tlv_data.router_id)
- XFREE(MTYPE_ISIS_TLV, lsp->tlv_data.router_id);
- }
-
- free_tlvs(&lsp->tlv_data);
+ isis_free_tlvs(lsp->tlvs);
+ lsp->tlvs = NULL;
}
static void lsp_destroy(struct isis_lsp *lsp)
@@ -146,7 +135,7 @@ static void lsp_destroy(struct isis_lsp *lsp)
lsp_clear_data(lsp);
- if (LSP_FRAGMENT(lsp->lsp_header->lsp_id) == 0 && lsp->lspu.frags) {
+ if (LSP_FRAGMENT(lsp->hdr.lsp_id) == 0 && lsp->lspu.frags) {
list_delete(lsp->lspu.frags);
lsp->lspu.frags = NULL;
}
@@ -187,7 +176,7 @@ static void lsp_remove_frags(struct list *frags, dict_t *lspdb)
struct isis_lsp *lsp;
for (ALL_LIST_ELEMENTS(frags, lnode, lnnode, lsp)) {
- dnode = dict_lookup(lspdb, lsp->lsp_header->lsp_id);
+ dnode = dict_lookup(lspdb, lsp->hdr.lsp_id);
lsp_destroy(lsp);
dnode_destroy(dict_delete(lspdb, dnode));
}
@@ -209,7 +198,7 @@ void lsp_search_and_destroy(u_char *id, dict_t *lspdb)
/*
* If this is a zero lsp, remove all the frags now
*/
- if (LSP_FRAGMENT(lsp->lsp_header->lsp_id) == 0) {
+ if (LSP_FRAGMENT(lsp->hdr.lsp_id) == 0) {
if (lsp->lspu.frags)
lsp_remove_frags(lsp->lspu.frags, lspdb);
} else {
@@ -231,33 +220,25 @@ void lsp_search_and_destroy(u_char *id, dict_t *lspdb)
* Compares a LSP to given values
* Params are given in net order
*/
-int lsp_compare(char *areatag, struct isis_lsp *lsp, u_int32_t seq_num,
- u_int16_t checksum, u_int16_t rem_lifetime)
+int lsp_compare(char *areatag, struct isis_lsp *lsp, uint32_t seqno,
+ uint16_t checksum, uint16_t rem_lifetime)
{
- seq_num = htonl(seq_num);
- checksum = htons(checksum);
- rem_lifetime = htons(rem_lifetime);
-
- /* no point in double ntohl on seqnum */
- if (lsp->lsp_header->seq_num == seq_num
- && lsp->lsp_header->checksum == checksum &&
- /*comparing with 0, no need to do ntohl */
- ((lsp->lsp_header->rem_lifetime == 0 && rem_lifetime == 0)
- || (lsp->lsp_header->rem_lifetime != 0 && rem_lifetime != 0))) {
+ if (lsp->hdr.seqno == seqno && lsp->hdr.checksum == checksum
+ && ((lsp->hdr.rem_lifetime == 0 && rem_lifetime == 0)
+ || (lsp->hdr.rem_lifetime != 0 && rem_lifetime != 0))) {
if (isis->debugs & DEBUG_SNP_PACKETS) {
zlog_debug(
- "ISIS-Snp (%s): Compare LSP %s seq 0x%08x, cksum 0x%04x,"
- " lifetime %us",
- areatag,
- rawlspid_print(lsp->lsp_header->lsp_id),
- ntohl(lsp->lsp_header->seq_num),
- ntohs(lsp->lsp_header->checksum),
- ntohs(lsp->lsp_header->rem_lifetime));
+ "ISIS-Snp (%s): Compare LSP %s seq 0x%08" PRIx32
+ ", cksum 0x%04" PRIx16 ", lifetime %" PRIu16
+ "s",
+ areatag, rawlspid_print(lsp->hdr.lsp_id),
+ lsp->hdr.seqno, lsp->hdr.checksum,
+ lsp->hdr.rem_lifetime);
zlog_debug(
- "ISIS-Snp (%s): is equal to ours seq 0x%08x,"
- " cksum 0x%04x, lifetime %us",
- areatag, ntohl(seq_num), ntohs(checksum),
- ntohs(rem_lifetime));
+ "ISIS-Snp (%s): is equal to ours seq 0x%08" PRIx32
+ ", cksum 0x%04" PRIx16 ", lifetime %" PRIu16
+ "s",
+ areatag, seqno, checksum, rem_lifetime);
}
return LSP_EQUAL;
}
@@ -274,171 +255,136 @@ int lsp_compare(char *areatag, struct isis_lsp *lsp, u_int32_t seq_num,
* as given
* in 7.3.16.2.
*/
- if (ntohl(seq_num) > ntohl(lsp->lsp_header->seq_num)
- || (ntohl(seq_num) == ntohl(lsp->lsp_header->seq_num)
- && ((lsp->lsp_header->rem_lifetime != 0 && rem_lifetime == 0)
- || lsp->lsp_header->checksum != checksum))) {
+ if (seqno > lsp->hdr.seqno
+ || (seqno == lsp->hdr.seqno
+ && ((lsp->hdr.rem_lifetime != 0 && rem_lifetime == 0)
+ || lsp->hdr.checksum != checksum))) {
if (isis->debugs & DEBUG_SNP_PACKETS) {
zlog_debug(
- "ISIS-Snp (%s): Compare LSP %s seq 0x%08x, cksum 0x%04x,"
- " lifetime %us",
- areatag,
- rawlspid_print(lsp->lsp_header->lsp_id),
- ntohl(seq_num), ntohs(checksum),
- ntohs(rem_lifetime));
+ "ISIS-Snp (%s): Compare LSP %s seq 0x%08" PRIx32
+ ", cksum 0x%04" PRIx16 ", lifetime %" PRIu16
+ "s",
+ areatag, rawlspid_print(lsp->hdr.lsp_id), seqno,
+ checksum, rem_lifetime);
zlog_debug(
- "ISIS-Snp (%s): is newer than ours seq 0x%08x, "
- "cksum 0x%04x, lifetime %us",
- areatag, ntohl(lsp->lsp_header->seq_num),
- ntohs(lsp->lsp_header->checksum),
- ntohs(lsp->lsp_header->rem_lifetime));
+ "ISIS-Snp (%s): is newer than ours seq 0x%08" PRIx32
+ ", cksum 0x%04" PRIx16 ", lifetime %" PRIu16
+ "s",
+ areatag, lsp->hdr.seqno, lsp->hdr.checksum,
+ lsp->hdr.rem_lifetime);
}
return LSP_NEWER;
}
if (isis->debugs & DEBUG_SNP_PACKETS) {
+ zlog_debug("ISIS-Snp (%s): Compare LSP %s seq 0x%08" PRIx32
+ ", cksum 0x%04" PRIx16 ", lifetime %" PRIu16 "s",
+ areatag, rawlspid_print(lsp->hdr.lsp_id), seqno,
+ checksum, rem_lifetime);
zlog_debug(
- "ISIS-Snp (%s): Compare LSP %s seq 0x%08x, cksum 0x%04x, lifetime %us",
- areatag, rawlspid_print(lsp->lsp_header->lsp_id),
- ntohl(seq_num), ntohs(checksum), ntohs(rem_lifetime));
- zlog_debug(
- "ISIS-Snp (%s): is older than ours seq 0x%08x,"
- " cksum 0x%04x, lifetime %us",
- areatag, ntohl(lsp->lsp_header->seq_num),
- ntohs(lsp->lsp_header->checksum),
- ntohs(lsp->lsp_header->rem_lifetime));
+ "ISIS-Snp (%s): is older than ours seq 0x%08" PRIx32
+ ", cksum 0x%04" PRIx16 ", lifetime %" PRIu16 "s",
+ areatag, lsp->hdr.seqno, lsp->hdr.checksum,
+ lsp->hdr.rem_lifetime);
}
return LSP_OLDER;
}
-static void lsp_auth_add(struct isis_lsp *lsp)
+static void put_lsp_hdr(struct isis_lsp *lsp, size_t *len_pointer)
{
- struct isis_passwd *passwd;
- unsigned char hmac_md5_hash[ISIS_AUTH_MD5_SIZE];
-
- /*
- * Add the authentication info if its present
- */
- (lsp->level == IS_LEVEL_1) ? (passwd = &lsp->area->area_passwd)
- : (passwd = &lsp->area->domain_passwd);
- switch (passwd->type) {
- /* Cleartext */
- case ISIS_PASSWD_TYPE_CLEARTXT:
- memcpy(&lsp->tlv_data.auth_info, passwd,
- sizeof(struct isis_passwd));
- tlv_add_authinfo(passwd->type, passwd->len, passwd->passwd,
- lsp->pdu);
- break;
-
- /* HMAC MD5 */
- case ISIS_PASSWD_TYPE_HMAC_MD5:
- /* Remember where TLV is written so we can later
- * overwrite the MD5 hash */
- lsp->auth_tlv_offset = stream_get_endp(lsp->pdu);
- memset(&hmac_md5_hash, 0, ISIS_AUTH_MD5_SIZE);
- lsp->tlv_data.auth_info.type = ISIS_PASSWD_TYPE_HMAC_MD5;
- lsp->tlv_data.auth_info.len = ISIS_AUTH_MD5_SIZE;
- memcpy(&lsp->tlv_data.auth_info.passwd, hmac_md5_hash,
- ISIS_AUTH_MD5_SIZE);
- tlv_add_authinfo(passwd->type, ISIS_AUTH_MD5_SIZE,
- hmac_md5_hash, lsp->pdu);
- break;
-
- default:
- break;
- }
+ uint8_t pdu_type =
+ (lsp->level == IS_LEVEL_1) ? L1_LINK_STATE : L2_LINK_STATE;
+ struct isis_lsp_hdr *hdr = &lsp->hdr;
+ struct stream *stream = lsp->pdu;
+
+ fill_fixed_hdr(pdu_type, stream);
+
+ if (len_pointer)
+ *len_pointer = stream_get_endp(stream);
+ stream_putw(stream, hdr->pdu_len);
+ stream_putw(stream, hdr->rem_lifetime);
+ stream_put(stream, hdr->lsp_id, sizeof(hdr->lsp_id));
+ stream_putl(stream, hdr->seqno);
+ stream_putw(stream, hdr->checksum);
+ stream_putc(stream, hdr->lsp_bits);
}
-static void lsp_auth_update(struct isis_lsp *lsp)
+static void lsp_add_auth(struct isis_lsp *lsp)
{
struct isis_passwd *passwd;
- unsigned char hmac_md5_hash[ISIS_AUTH_MD5_SIZE];
- uint16_t checksum, rem_lifetime;
+ passwd = (lsp->level == IS_LEVEL_1) ? &lsp->area->area_passwd
+ : &lsp->area->domain_passwd;
+ isis_tlvs_add_auth(lsp->tlvs, passwd);
+}
- /* For HMAC MD5 we need to recompute the md5 hash and store it */
- (lsp->level == IS_LEVEL_1) ? (passwd = &lsp->area->area_passwd)
- : (passwd = &lsp->area->domain_passwd);
- if (passwd->type != ISIS_PASSWD_TYPE_HMAC_MD5)
- return;
+static void lsp_pack_pdu(struct isis_lsp *lsp)
+{
+ if (!lsp->tlvs)
+ lsp->tlvs = isis_alloc_tlvs();
- /*
- * In transient conditions (when net is configured where authentication
- * config and lsp regenerate schedule is not yet run), there could be
- * an own_lsp with auth_tlv_offset set to 0. In such a case, simply
- * return, when lsp_regenerate is run, lsp will have auth tlv.
- */
- if (lsp->auth_tlv_offset == 0)
- return;
+ lsp_add_auth(lsp);
- /*
- * RFC 5304 set auth value, checksum and remaining lifetime to zero
- * before computation and reset to old values after computation.
- */
- checksum = lsp->lsp_header->checksum;
- rem_lifetime = lsp->lsp_header->rem_lifetime;
- lsp->lsp_header->checksum = 0;
- lsp->lsp_header->rem_lifetime = 0;
- /* Set the authentication value as well to zero */
- memset(STREAM_DATA(lsp->pdu) + lsp->auth_tlv_offset + 3, 0,
- ISIS_AUTH_MD5_SIZE);
- /* Compute autentication value */
- hmac_md5(STREAM_DATA(lsp->pdu), stream_get_endp(lsp->pdu),
- (unsigned char *)&passwd->passwd, passwd->len,
- (unsigned char *)&hmac_md5_hash);
- /* Copy the hash into the stream */
- memcpy(STREAM_DATA(lsp->pdu) + lsp->auth_tlv_offset + 3, hmac_md5_hash,
- ISIS_AUTH_MD5_SIZE);
- memcpy(&lsp->tlv_data.auth_info.passwd, hmac_md5_hash,
- ISIS_AUTH_MD5_SIZE);
- /* Copy back the checksum and remaining lifetime */
- lsp->lsp_header->checksum = checksum;
- lsp->lsp_header->rem_lifetime = rem_lifetime;
+ size_t len_pointer;
+ stream_reset(lsp->pdu);
+ put_lsp_hdr(lsp, &len_pointer);
+ isis_pack_tlvs(lsp->tlvs, lsp->pdu, len_pointer, false, true);
+
+ lsp->hdr.pdu_len = stream_get_endp(lsp->pdu);
+ lsp->hdr.checksum =
+ ntohs(fletcher_checksum(STREAM_DATA(lsp->pdu) + 12,
+ stream_get_endp(lsp->pdu) - 12, 12));
}
-void lsp_inc_seqnum(struct isis_lsp *lsp, u_int32_t seq_num)
+void lsp_inc_seqno(struct isis_lsp *lsp, uint32_t seqno)
{
- u_int32_t newseq;
+ uint32_t newseq;
- if (seq_num == 0 || ntohl(lsp->lsp_header->seq_num) > seq_num)
- newseq = ntohl(lsp->lsp_header->seq_num) + 1;
+ if (seqno == 0 || lsp->hdr.seqno > seqno)
+ newseq = lsp->hdr.seqno + 1;
else
- newseq = seq_num + 1;
-
- lsp->lsp_header->seq_num = htonl(newseq);
-
- /* Recompute authentication and checksum information */
- lsp_auth_update(lsp);
- /* ISO 10589 - 7.3.11 Generation of the checksum
- * The checksum shall be computed over all fields in the LSP which
- * appear
- * after the Remaining Lifetime field. This field (and those appearing
- * before it) are excluded so that the LSP may be aged by systems
- * without
- * requiring recomputation.
- */
- fletcher_checksum(STREAM_DATA(lsp->pdu) + 12,
- ntohs(lsp->lsp_header->pdu_len) - 12, 12);
+ newseq = seqno + 1;
+ lsp->hdr.seqno = newseq;
+
+ lsp_pack_pdu(lsp);
isis_spf_schedule(lsp->area, lsp->level);
+}
- return;
+static void lsp_purge(struct isis_lsp *lsp, int level)
+{
+ /* reset stream */
+ lsp_clear_data(lsp);
+ stream_reset(lsp->pdu);
+
+ /* update header */
+ lsp->hdr.checksum = 0;
+ lsp->hdr.rem_lifetime = 0;
+ lsp->level = level;
+ lsp->age_out = lsp->area->max_lsp_lifetime[level - 1];
+
+ lsp_pack_pdu(lsp);
+ lsp_set_all_srmflags(lsp);
}
/*
- * Genetates checksum for LSP and its frags
+ * Generates checksum for LSP and its frags
*/
-static void lsp_seqnum_update(struct isis_lsp *lsp0)
+static void lsp_seqno_update(struct isis_lsp *lsp0)
{
struct isis_lsp *lsp;
struct listnode *node;
- lsp_inc_seqnum(lsp0, 0);
+ lsp_inc_seqno(lsp0, 0);
if (!lsp0->lspu.frags)
return;
- for (ALL_LIST_ELEMENTS_RO(lsp0->lspu.frags, node, lsp))
- lsp_inc_seqnum(lsp, 0);
+ for (ALL_LIST_ELEMENTS_RO(lsp0->lspu.frags, node, lsp)) {
+ if (lsp->tlvs)
+ lsp_inc_seqno(lsp, 0);
+ else
+ lsp_purge(lsp, lsp0->level);
+ }
return;
}
@@ -457,12 +403,10 @@ static u_int8_t lsp_bits_generate(int level, int overload_bit, int attached_bit)
return lsp_bits;
}
-static void lsp_update_data(struct isis_lsp *lsp, struct stream *stream,
+static void lsp_update_data(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr,
+ struct isis_tlvs *tlvs, struct stream *stream,
struct isis_area *area, int level)
{
- uint32_t expected = 0, found;
- int retval;
-
/* free the old lsp data */
lsp_clear_data(lsp);
@@ -471,49 +415,17 @@ static void lsp_update_data(struct isis_lsp *lsp, struct stream *stream,
stream_free(lsp->pdu);
lsp->pdu = stream_dup(stream);
- /* setting pointers to the correct place */
- lsp->lsp_header = (struct isis_link_state_hdr *)(STREAM_DATA(lsp->pdu)
- + ISIS_FIXED_HDR_LEN);
+ memcpy(&lsp->hdr, hdr, sizeof(lsp->hdr));
lsp->area = area;
lsp->level = level;
lsp->age_out = ZERO_AGE_LIFETIME;
lsp->installed = time(NULL);
- /*
- * Get LSP data i.e. TLVs
- */
- expected |= TLVFLAG_AUTH_INFO;
- expected |= TLVFLAG_AREA_ADDRS;
- expected |= TLVFLAG_IS_NEIGHS;
- expected |= TLVFLAG_NLPID;
- if (area->dynhostname)
- expected |= TLVFLAG_DYN_HOSTNAME;
- if (area->newmetric) {
- expected |= TLVFLAG_TE_IS_NEIGHS;
- expected |= TLVFLAG_TE_IPV4_REACHABILITY;
- expected |= TLVFLAG_TE_ROUTER_ID;
- }
- expected |= TLVFLAG_MT_ROUTER_INFORMATION;
- expected |= TLVFLAG_IPV4_ADDR;
- expected |= TLVFLAG_IPV4_INT_REACHABILITY;
- expected |= TLVFLAG_IPV4_EXT_REACHABILITY;
- expected |= TLVFLAG_IPV6_ADDR;
- expected |= TLVFLAG_IPV6_REACHABILITY;
-
- retval = parse_tlvs(area->area_tag,
- STREAM_DATA(lsp->pdu) + ISIS_FIXED_HDR_LEN
- + ISIS_LSP_HDR_LEN,
- ntohs(lsp->lsp_header->pdu_len) - ISIS_FIXED_HDR_LEN
- - ISIS_LSP_HDR_LEN,
- &expected, &found, &lsp->tlv_data, NULL);
- if (retval != ISIS_OK) {
- zlog_warn("Could not parse LSP");
- return;
- }
- if ((found & TLVFLAG_DYN_HOSTNAME) && (area->dynhostname)) {
- isis_dynhn_insert(lsp->lsp_header->lsp_id,
- lsp->tlv_data.hostname,
- (lsp->lsp_header->lsp_bits & LSPBIT_IST)
+ lsp->tlvs = tlvs;
+
+ if (area->dynhostname && lsp->tlvs->hostname) {
+ isis_dynhn_insert(lsp->hdr.lsp_id, lsp->tlvs->hostname,
+ (lsp->hdr.lsp_bits & LSPBIT_IST)
== IS_LEVEL_1_AND_2
? IS_LEVEL_2
: IS_LEVEL_1);
@@ -522,7 +434,8 @@ static void lsp_update_data(struct isis_lsp *lsp, struct stream *stream,
return;
}
-void lsp_update(struct isis_lsp *lsp, struct stream *stream,
+void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr,
+ struct isis_tlvs *tlvs, struct stream *stream,
struct isis_area *area, int level)
{
dnode_t *dnode = NULL;
@@ -530,36 +443,35 @@ void lsp_update(struct isis_lsp *lsp, struct stream *stream,
/* Remove old LSP from database. This is required since the
* lsp_update_data will free the lsp->pdu (which has the key, lsp_id)
* and will update it with the new data in the stream. */
- dnode = dict_lookup(area->lspdb[level - 1], lsp->lsp_header->lsp_id);
+ dnode = dict_lookup(area->lspdb[level - 1], lsp->hdr.lsp_id);
if (dnode)
dnode_destroy(dict_delete(area->lspdb[level - 1], dnode));
if (lsp->own_lsp) {
zlog_err(
"ISIS-Upd (%s): BUG updating LSP %s still marked as own LSP",
- area->area_tag,
- rawlspid_print(lsp->lsp_header->lsp_id));
+ area->area_tag, rawlspid_print(lsp->hdr.lsp_id));
lsp_clear_data(lsp);
lsp->own_lsp = 0;
}
/* rebuild the lsp data */
- lsp_update_data(lsp, stream, area, level);
+ lsp_update_data(lsp, hdr, tlvs, stream, area, level);
/* insert the lsp back into the database */
lsp_insert(lsp, area->lspdb[level - 1]);
}
/* creation of LSP directly from what we received */
-struct isis_lsp *lsp_new_from_stream_ptr(struct stream *stream,
- u_int16_t pdu_len,
- struct isis_lsp *lsp0,
- struct isis_area *area, int level)
+struct isis_lsp *lsp_new_from_recv(struct isis_lsp_hdr *hdr,
+ struct isis_tlvs *tlvs,
+ struct stream *stream, struct isis_lsp *lsp0,
+ struct isis_area *area, int level)
{
struct isis_lsp *lsp;
lsp = XCALLOC(MTYPE_ISIS_LSP, sizeof(struct isis_lsp));
- lsp_update_data(lsp, stream, area, level);
+ lsp_update_data(lsp, hdr, tlvs, stream, area, level);
if (lsp0 == NULL) {
/*
@@ -579,12 +491,10 @@ struct isis_lsp *lsp_new_from_stream_ptr(struct stream *stream,
}
struct isis_lsp *lsp_new(struct isis_area *area, u_char *lsp_id,
- u_int16_t rem_lifetime, u_int32_t seq_num,
- u_int8_t lsp_bits, u_int16_t checksum, int level)
+ uint16_t rem_lifetime, uint32_t seqno,
+ uint8_t lsp_bits, uint16_t checksum, int level)
{
struct isis_lsp *lsp;
- uint8_t pdu_type =
- (level == IS_LEVEL_1) ? L1_LINK_STATE : L2_LINK_STATE;
lsp = XCALLOC(MTYPE_ISIS_LSP, sizeof(struct isis_lsp));
lsp->area = area;
@@ -593,40 +503,31 @@ struct isis_lsp *lsp_new(struct isis_area *area, u_char *lsp_id,
if (LSP_FRAGMENT(lsp_id) == 0)
lsp->lspu.frags = list_new();
- fill_fixed_hdr(pdu_type, lsp->pdu);
-
- /* now for the LSP HEADER */
/* Minimal LSP PDU size */
- lsp->lsp_header = (struct isis_link_state_hdr *)(STREAM_DATA(lsp->pdu)
- + ISIS_FIXED_HDR_LEN);
- lsp->lsp_header->pdu_len = htons(ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN);
- memcpy(lsp->lsp_header->lsp_id, lsp_id, ISIS_SYS_ID_LEN + 2);
- lsp->lsp_header->checksum = htons(checksum);
- lsp->lsp_header->seq_num = htonl(seq_num);
- lsp->lsp_header->rem_lifetime = htons(rem_lifetime);
- lsp->lsp_header->lsp_bits = lsp_bits;
+ lsp->hdr.pdu_len = ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN;
+ memcpy(lsp->hdr.lsp_id, lsp_id, sizeof(lsp->hdr.lsp_id));
+ lsp->hdr.checksum = checksum;
+ lsp->hdr.seqno = seqno;
+ lsp->hdr.rem_lifetime = rem_lifetime;
+ lsp->hdr.lsp_bits = lsp_bits;
lsp->level = level;
lsp->age_out = ZERO_AGE_LIFETIME;
-
- stream_forward_endp(lsp->pdu, ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN);
+ put_lsp_hdr(lsp, NULL);
if (isis->debugs & DEBUG_EVENTS)
zlog_debug("New LSP with ID %s-%02x-%02x len %d seqnum %08x",
- sysid_print(lsp_id),
- LSP_PSEUDO_ID(lsp->lsp_header->lsp_id),
- LSP_FRAGMENT(lsp->lsp_header->lsp_id),
- ntohl(lsp->lsp_header->pdu_len),
- ntohl(lsp->lsp_header->seq_num));
+ sysid_print(lsp_id), LSP_PSEUDO_ID(lsp->hdr.lsp_id),
+ LSP_FRAGMENT(lsp->hdr.lsp_id), lsp->hdr.pdu_len,
+ lsp->hdr.seqno);
return lsp;
}
void lsp_insert(struct isis_lsp *lsp, dict_t *lspdb)
{
- dict_alloc_insert(lspdb, lsp->lsp_header->lsp_id, lsp);
- if (lsp->lsp_header->seq_num != 0) {
+ dict_alloc_insert(lspdb, lsp->hdr.lsp_id, lsp);
+ if (lsp->hdr.seqno)
isis_spf_schedule(lsp->area, lsp->level);
- }
}
/*
@@ -645,14 +546,13 @@ void lsp_build_list_nonzero_ht(u_char *start_id, u_char *stop_id,
curr = first;
- if (((struct isis_lsp *)(curr->dict_data))->lsp_header->rem_lifetime)
+ if (((struct isis_lsp *)(curr->dict_data))->hdr.rem_lifetime)
listnode_add(list, first->dict_data);
while (curr) {
curr = dict_next(lspdb, curr);
if (curr
- && ((struct isis_lsp *)(curr->dict_data))
- ->lsp_header->rem_lifetime)
+ && ((struct isis_lsp *)(curr->dict_data))->hdr.rem_lifetime)
listnode_add(list, curr->dict_data);
if (curr == last)
break;
@@ -665,14 +565,15 @@ static void lsp_set_time(struct isis_lsp *lsp)
{
assert(lsp);
- if (lsp->lsp_header->rem_lifetime == 0) {
+ if (lsp->hdr.rem_lifetime == 0) {
if (lsp->age_out > 0)
lsp->age_out--;
return;
}
- lsp->lsp_header->rem_lifetime =
- htons(ntohs(lsp->lsp_header->rem_lifetime) - 1);
+ lsp->hdr.rem_lifetime--;
+ if (lsp->pdu && stream_get_endp(lsp->pdu) >= 12)
+ stream_putw_at(lsp->pdu, 10, lsp->hdr.rem_lifetime);
}
static void lspid_print(u_char *lsp_id, u_char *trg, char dynhost, char frag)
@@ -686,7 +587,7 @@ static void lspid_print(u_char *lsp_id, u_char *trg, char dynhost, char frag)
dyn = NULL;
if (dyn)
- sprintf((char *)id, "%.14s", dyn->name.name);
+ sprintf((char *)id, "%.14s", dyn->hostname);
else if (!memcmp(isis->sysid, lsp_id, ISIS_SYS_ID_LEN) && dynhost)
sprintf((char *)id, "%.14s", unix_hostname());
else
@@ -699,21 +600,21 @@ static void lspid_print(u_char *lsp_id, u_char *trg, char dynhost, char frag)
}
/* Convert the lsp attribute bits to attribute string */
-const char *lsp_bits2string(u_char *lsp_bits)
+static const char *lsp_bits2string(uint8_t lsp_bits)
{
char *pos = lsp_bits_string;
- if (!*lsp_bits)
+ if (!lsp_bits)
return " none";
/* we only focus on the default metric */
pos += sprintf(pos, "%d/",
- ISIS_MASK_LSP_ATT_DEFAULT_BIT(*lsp_bits) ? 1 : 0);
+ ISIS_MASK_LSP_ATT_DEFAULT_BIT(lsp_bits) ? 1 : 0);
pos += sprintf(pos, "%d/",
- ISIS_MASK_LSP_PARTITION_BIT(*lsp_bits) ? 1 : 0);
+ ISIS_MASK_LSP_PARTITION_BIT(lsp_bits) ? 1 : 0);
- pos += sprintf(pos, "%d", ISIS_MASK_LSP_OL_BIT(*lsp_bits) ? 1 : 0);
+ pos += sprintf(pos, "%d", ISIS_MASK_LSP_OL_BIT(lsp_bits) ? 1 : 0);
*(pos) = '\0';
@@ -726,276 +627,26 @@ void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost)
u_char LSPid[255];
char age_out[8];
- lspid_print(lsp->lsp_header->lsp_id, LSPid, dynhost, 1);
+ lspid_print(lsp->hdr.lsp_id, LSPid, dynhost, 1);
vty_out(vty, "%-21s%c ", LSPid, lsp->own_lsp ? '*' : ' ');
- vty_out(vty, "%5u ", ntohs(lsp->lsp_header->pdu_len));
- vty_out(vty, "0x%08x ", ntohl(lsp->lsp_header->seq_num));
- vty_out(vty, "0x%04x ", ntohs(lsp->lsp_header->checksum));
- if (ntohs(lsp->lsp_header->rem_lifetime) == 0) {
- snprintf(age_out, 8, "(%u)", lsp->age_out);
+ vty_out(vty, "%5" PRIu16 " ", lsp->hdr.pdu_len);
+ vty_out(vty, "0x%08" PRIx32 " ", lsp->hdr.seqno);
+ vty_out(vty, "0x%04" PRIx16 " ", lsp->hdr.checksum);
+ if (lsp->hdr.rem_lifetime == 0) {
+ snprintf(age_out, 8, "(%d)", lsp->age_out);
age_out[7] = '\0';
vty_out(vty, "%7s ", age_out);
} else
- vty_out(vty, " %5u ", ntohs(lsp->lsp_header->rem_lifetime));
- vty_out(vty, "%s\n", lsp_bits2string(&lsp->lsp_header->lsp_bits));
-}
-
-static void lsp_print_mt_reach(struct list *list, struct vty *vty, char dynhost,
- uint16_t mtid)
-{
- struct listnode *node;
- struct te_is_neigh *neigh;
-
- for (ALL_LIST_ELEMENTS_RO(list, node, neigh)) {
- u_char lspid[255];
-
- lspid_print(neigh->neigh_id, lspid, dynhost, 0);
- if (mtid == ISIS_MT_IPV4_UNICAST) {
- vty_out(vty,
- " Metric : %-8u IS-Extended : %s\n",
- GET_TE_METRIC(neigh), lspid);
- } else {
- vty_out(vty,
- " Metric : %-8u MT-Reach : %s %s\n",
- GET_TE_METRIC(neigh), lspid,
- isis_mtid2str(mtid));
- }
- if (IS_MPLS_TE(isisMplsTE))
- mpls_te_print_detail(vty, neigh);
- }
-}
-
-static void lsp_print_mt_ipv6_reach(struct list *list, struct vty *vty,
- uint16_t mtid)
-{
- struct listnode *node;
- struct ipv6_reachability *ipv6_reach;
- struct in6_addr in6;
- u_char buff[BUFSIZ];
-
- for (ALL_LIST_ELEMENTS_RO(list, node, ipv6_reach)) {
- memset(&in6, 0, sizeof(in6));
- memcpy(in6.s6_addr, ipv6_reach->prefix,
- PSIZE(ipv6_reach->prefix_len));
- inet_ntop(AF_INET6, &in6, (char *)buff, BUFSIZ);
- if (mtid == ISIS_MT_IPV4_UNICAST) {
- if ((ipv6_reach->control_info & CTRL_INFO_DISTRIBUTION)
- == DISTRIBUTION_INTERNAL)
- vty_out(vty, " Metric : %-8" PRIu32
- " IPv6-Internal : %s/%d\n",
- ntohl(ipv6_reach->metric), buff,
- ipv6_reach->prefix_len);
- else
- vty_out(vty, " Metric : %-8" PRIu32
- " IPv6-External : %s/%d\n",
- ntohl(ipv6_reach->metric), buff,
- ipv6_reach->prefix_len);
- } else {
- if ((ipv6_reach->control_info & CTRL_INFO_DISTRIBUTION)
- == DISTRIBUTION_INTERNAL)
- vty_out(vty, " Metric : %-8" PRIu32
- " IPv6-MT-Int : %s/%d %s\n",
- ntohl(ipv6_reach->metric), buff,
- ipv6_reach->prefix_len,
- isis_mtid2str(mtid));
- else
- vty_out(vty, " Metric : %-8" PRIu32
- " IPv6-MT-Ext : %s/%d %s\n",
- ntohl(ipv6_reach->metric), buff,
- ipv6_reach->prefix_len,
- isis_mtid2str(mtid));
- }
- }
-}
-
-static void lsp_print_mt_ipv4_reach(struct list *list, struct vty *vty,
- uint16_t mtid)
-{
- struct listnode *node;
- struct te_ipv4_reachability *te_ipv4_reach;
-
- for (ALL_LIST_ELEMENTS_RO(list, node, te_ipv4_reach)) {
- if (mtid == ISIS_MT_IPV4_UNICAST) {
- /* FIXME: There should be better way to output this
- * stuff. */
- vty_out(vty, " Metric : %-8" PRIu32
- " IPv4-Extended : %s/%d\n",
- ntohl(te_ipv4_reach->te_metric),
- inet_ntoa(newprefix2inaddr(
- &te_ipv4_reach->prefix_start,
- te_ipv4_reach->control)),
- te_ipv4_reach->control & 0x3F);
- } else {
- /* FIXME: There should be better way to output this
- * stuff. */
- vty_out(vty, " Metric : %-8" PRIu32
- " IPv4-MT : %s/%d %s\n",
- ntohl(te_ipv4_reach->te_metric),
- inet_ntoa(newprefix2inaddr(
- &te_ipv4_reach->prefix_start,
- te_ipv4_reach->control)),
- te_ipv4_reach->control & 0x3F,
- isis_mtid2str(mtid));
- }
- }
+ vty_out(vty, " %5" PRIu16 " ", lsp->hdr.rem_lifetime);
+ vty_out(vty, "%s\n", lsp_bits2string(lsp->hdr.lsp_bits));
}
void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty, char dynhost)
{
- struct area_addr *area_addr;
- int i;
- struct listnode *lnode;
- struct is_neigh *is_neigh;
- struct ipv4_reachability *ipv4_reach;
- struct in_addr *ipv4_addr;
- struct mt_router_info *mt_router_info;
- struct tlv_mt_ipv6_reachs *mt_ipv6_reachs;
- struct tlv_mt_neighbors *mt_is_neigh;
- struct tlv_mt_ipv4_reachs *mt_ipv4_reachs;
- u_char LSPid[255];
- u_char hostname[255];
- u_char ipv4_reach_prefix[20];
- u_char ipv4_reach_mask[20];
- u_char ipv4_address[20];
-
- lspid_print(lsp->lsp_header->lsp_id, LSPid, dynhost, 1);
lsp_print(lsp, vty, dynhost);
-
- /* for all area address */
- if (lsp->tlv_data.area_addrs)
- for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.area_addrs, lnode,
- area_addr)) {
- vty_out(vty, " Area Address: %s\n",
- isonet_print(area_addr->area_addr,
- area_addr->addr_len));
- }
-
- /* for the nlpid tlv */
- if (lsp->tlv_data.nlpids) {
- for (i = 0; i < lsp->tlv_data.nlpids->count; i++) {
- switch (lsp->tlv_data.nlpids->nlpids[i]) {
- case NLPID_IP:
- case NLPID_IPV6:
- vty_out(vty, " NLPID : 0x%X\n",
- lsp->tlv_data.nlpids->nlpids[i]);
- break;
- default:
- vty_out(vty, " NLPID : %s\n", "unknown");
- break;
- }
- }
- }
-
- for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.mt_router_info, lnode,
- mt_router_info)) {
- vty_out(vty, " MT : %s%s\n",
- isis_mtid2str(mt_router_info->mtid),
- mt_router_info->overload ? " (overload)" : "");
- }
-
- /* for the hostname tlv */
- if (lsp->tlv_data.hostname) {
- bzero(hostname, sizeof(hostname));
- memcpy(hostname, lsp->tlv_data.hostname->name,
- lsp->tlv_data.hostname->namelen);
- vty_out(vty, " Hostname : %s\n", hostname);
- }
-
- /* authentication tlv */
- if (lsp->tlv_data.auth_info.type != ISIS_PASSWD_TYPE_UNUSED) {
- if (lsp->tlv_data.auth_info.type == ISIS_PASSWD_TYPE_HMAC_MD5)
- vty_out(vty, " Auth type : md5\n");
- else if (lsp->tlv_data.auth_info.type
- == ISIS_PASSWD_TYPE_CLEARTXT)
- vty_out(vty, " Auth type : clear text\n");
- }
-
- /* TE router id */
- if (lsp->tlv_data.router_id) {
- memcpy(ipv4_address, inet_ntoa(lsp->tlv_data.router_id->id),
- sizeof(ipv4_address));
- vty_out(vty, " Router ID : %s\n", ipv4_address);
- }
-
- if (lsp->tlv_data.ipv4_addrs)
- for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.ipv4_addrs, lnode,
- ipv4_addr)) {
- memcpy(ipv4_address, inet_ntoa(*ipv4_addr),
- sizeof(ipv4_address));
- vty_out(vty, " IPv4 Address: %s\n", ipv4_address);
- }
-
- /* for the IS neighbor tlv */
- if (lsp->tlv_data.is_neighs)
- for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.is_neighs, lnode,
- is_neigh)) {
- lspid_print(is_neigh->neigh_id, LSPid, dynhost, 0);
- vty_out(vty, " Metric : %-8" PRIu8
- " IS : %s\n",
- is_neigh->metrics.metric_default, LSPid);
- }
-
- /* for the internal reachable tlv */
- if (lsp->tlv_data.ipv4_int_reachs)
- for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.ipv4_int_reachs, lnode,
- ipv4_reach)) {
- memcpy(ipv4_reach_prefix, inet_ntoa(ipv4_reach->prefix),
- sizeof(ipv4_reach_prefix));
- memcpy(ipv4_reach_mask, inet_ntoa(ipv4_reach->mask),
- sizeof(ipv4_reach_mask));
- vty_out(vty, " Metric : %-8" PRIu8
- " IPv4-Internal : %s %s\n",
- ipv4_reach->metrics.metric_default,
- ipv4_reach_prefix, ipv4_reach_mask);
- }
-
- /* for the external reachable tlv */
- if (lsp->tlv_data.ipv4_ext_reachs)
- for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.ipv4_ext_reachs, lnode,
- ipv4_reach)) {
- memcpy(ipv4_reach_prefix, inet_ntoa(ipv4_reach->prefix),
- sizeof(ipv4_reach_prefix));
- memcpy(ipv4_reach_mask, inet_ntoa(ipv4_reach->mask),
- sizeof(ipv4_reach_mask));
- vty_out(vty, " Metric : %-8" PRIu8
- " IPv4-External : %s %s\n",
- ipv4_reach->metrics.metric_default,
- ipv4_reach_prefix, ipv4_reach_mask);
- }
-
- /* IPv6 tlv */
- lsp_print_mt_ipv6_reach(lsp->tlv_data.ipv6_reachs, vty,
- ISIS_MT_IPV4_UNICAST);
-
- /* MT IPv6 reachability tlv */
- for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.mt_ipv6_reachs, lnode,
- mt_ipv6_reachs))
- lsp_print_mt_ipv6_reach(mt_ipv6_reachs->list, vty,
- mt_ipv6_reachs->mtid);
-
- /* TE IS neighbor tlv */
- lsp_print_mt_reach(lsp->tlv_data.te_is_neighs, vty, dynhost,
- ISIS_MT_IPV4_UNICAST);
-
- /* MT IS neighbor tlv */
- for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.mt_is_neighs, lnode,
- mt_is_neigh))
- lsp_print_mt_reach(mt_is_neigh->list, vty, dynhost,
- mt_is_neigh->mtid);
-
- /* TE IPv4 tlv */
- lsp_print_mt_ipv4_reach(lsp->tlv_data.te_ipv4_reachs, vty,
- ISIS_MT_IPV4_UNICAST);
-
- /* MT IPv4 reachability tlv */
- for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.mt_ipv4_reachs, lnode,
- mt_ipv4_reachs))
- lsp_print_mt_ipv4_reach(mt_ipv4_reachs->list, vty,
- mt_ipv4_reachs->mtid);
-
+ if (lsp->tlvs)
+ vty_multiline(vty, " ", "%s", isis_format_tlvs(lsp->tlvs));
vty_out(vty, "\n");
-
- return;
}
/* print all the lsps info in the local lspdb */
@@ -1026,85 +677,6 @@ int lsp_print_all(struct vty *vty, dict_t *lspdb, char detail, char dynhost)
return lsp_count;
}
-static void _lsp_tlv_fit(struct isis_lsp *lsp, struct list **from,
- struct list **to, int frag_thold,
- unsigned int tlv_build_func(struct list *,
- struct stream *,
- void *arg),
- void *arg)
-{
- while (*from && listcount(*from)) {
- unsigned int count;
-
- count = tlv_build_func(*from, lsp->pdu, arg);
-
- if (listcount(*to) != 0 || count != listcount(*from)) {
- struct listnode *node, *nnode;
- void *elem;
-
- for (ALL_LIST_ELEMENTS(*from, node, nnode, elem)) {
- if (!count)
- break;
- listnode_add(*to, elem);
- list_delete_node(*from, node);
- --count;
- }
- } else {
- list_free(*to);
- *to = *from;
- *from = NULL;
- }
- }
-}
-
-#define FRAG_THOLD(S, T) ((STREAM_SIZE(S) * T) / 100)
-
-/* stream*, area->lsp_frag_threshold, increment */
-#define FRAG_NEEDED(S, T, I) \
- (STREAM_SIZE(S) - STREAM_REMAIN(S) + (I) > FRAG_THOLD(S, T))
-
-/* FIXME: It shouldn't be necessary to pass tlvsize here, TLVs can have
- * variable length (TE TLVs, sub TLVs). */
-static void lsp_tlv_fit(struct isis_lsp *lsp, struct list **from,
- struct list **to, int tlvsize, int frag_thold,
- int tlv_build_func(struct list *, struct stream *))
-{
- int count, i;
-
- /* can we fit all ? */
- if (!FRAG_NEEDED(lsp->pdu, frag_thold,
- listcount(*from) * tlvsize + 2)) {
- tlv_build_func(*from, lsp->pdu);
- if (listcount(*to) != 0) {
- struct listnode *node, *nextnode;
- void *elem;
-
- for (ALL_LIST_ELEMENTS(*from, node, nextnode, elem)) {
- listnode_add(*to, elem);
- list_delete_node(*from, node);
- }
- } else {
- list_free(*to);
- *to = *from;
- *from = NULL;
- }
- } else if (!FRAG_NEEDED(lsp->pdu, frag_thold, tlvsize + 2)) {
- /* fit all we can */
- count = FRAG_THOLD(lsp->pdu, frag_thold) - 2
- - (STREAM_SIZE(lsp->pdu) - STREAM_REMAIN(lsp->pdu));
- count = count / tlvsize;
- if (count > (int)listcount(*from))
- count = listcount(*from);
- for (i = 0; i < count; i++) {
- listnode_add(*to, listgetdata(listhead(*from)));
- listnode_delete(*from, listgetdata(listhead(*from)));
- }
- tlv_build_func(*to, lsp->pdu);
- }
- lsp->lsp_header->pdu_len = htons(stream_get_endp(lsp->pdu));
- return;
-}
-
static u_int16_t lsp_rem_lifetime(struct isis_area *area, int level)
{
u_int16_t rem_lifetime;
@@ -1147,155 +719,90 @@ static u_int16_t lsp_refresh_time(struct isis_lsp *lsp, u_int16_t rem_lifetime)
return refresh_time;
}
-static struct isis_lsp *lsp_next_frag(u_char frag_num, struct isis_lsp *lsp0,
- struct isis_area *area, int level)
-{
- struct isis_lsp *lsp;
- u_char frag_id[ISIS_SYS_ID_LEN + 2];
-
- memcpy(frag_id, lsp0->lsp_header->lsp_id, ISIS_SYS_ID_LEN + 1);
- LSP_FRAGMENT(frag_id) = frag_num;
- /* FIXME add authentication TLV for fragment LSPs */
- lsp = lsp_search(frag_id, area->lspdb[level - 1]);
- if (lsp) {
- /* Clear the TLVs */
- lsp_clear_data(lsp);
- return lsp;
- }
- lsp = lsp_new(area, frag_id, ntohs(lsp0->lsp_header->rem_lifetime), 0,
- lsp_bits_generate(level, area->overload_bit,
- area->attached_bit),
- 0, level);
- lsp->area = area;
- lsp->own_lsp = 1;
- lsp_insert(lsp, area->lspdb[level - 1]);
- listnode_add(lsp0->lspu.frags, lsp);
- lsp->lspu.zero_lsp = lsp0;
- return lsp;
-}
-
static void lsp_build_ext_reach_ipv4(struct isis_lsp *lsp,
- struct isis_area *area,
- struct tlvs *tlv_data)
+ struct isis_area *area)
{
- struct route_table *er_table;
- struct route_node *rn;
- struct prefix_ipv4 *ipv4;
- struct isis_ext_info *info;
- struct ipv4_reachability *ipreach;
- struct te_ipv4_reachability *te_ipreach;
-
- er_table = get_ext_reach(area, AF_INET, lsp->level);
+ struct route_table *er_table = get_ext_reach(area, AF_INET, lsp->level);
if (!er_table)
return;
- for (rn = route_top(er_table); rn; rn = route_next(rn)) {
+ for (struct route_node *rn = route_top(er_table); rn;
+ rn = route_next(rn)) {
if (!rn->info)
continue;
- ipv4 = (struct prefix_ipv4 *)&rn->p;
- info = rn->info;
- if (area->oldmetric) {
- if (tlv_data->ipv4_ext_reachs == NULL) {
- tlv_data->ipv4_ext_reachs = list_new();
- tlv_data->ipv4_ext_reachs->del = free_tlv;
- }
- ipreach = XMALLOC(MTYPE_ISIS_TLV, sizeof(*ipreach));
-
- ipreach->prefix.s_addr = ipv4->prefix.s_addr;
- masklen2ip(ipv4->prefixlen, &ipreach->mask);
- ipreach->prefix.s_addr &= ipreach->mask.s_addr;
-
- if ((info->metric & 0x3f) != info->metric)
- ipreach->metrics.metric_default = 0x3f;
- else
- ipreach->metrics.metric_default = info->metric;
- ipreach->metrics.metric_expense = METRICS_UNSUPPORTED;
- ipreach->metrics.metric_error = METRICS_UNSUPPORTED;
- ipreach->metrics.metric_delay = METRICS_UNSUPPORTED;
- listnode_add(tlv_data->ipv4_ext_reachs, ipreach);
- }
- if (area->newmetric) {
- if (tlv_data->te_ipv4_reachs == NULL) {
- tlv_data->te_ipv4_reachs = list_new();
- tlv_data->te_ipv4_reachs->del = free_tlv;
- }
- te_ipreach = XCALLOC(MTYPE_ISIS_TLV,
- sizeof(*te_ipreach) - 1
- + PSIZE(ipv4->prefixlen));
- if (info->metric > MAX_WIDE_PATH_METRIC)
- te_ipreach->te_metric =
- htonl(MAX_WIDE_PATH_METRIC);
- else
- te_ipreach->te_metric = htonl(info->metric);
- te_ipreach->control = ipv4->prefixlen & 0x3f;
- memcpy(&te_ipreach->prefix_start, &ipv4->prefix.s_addr,
- PSIZE(ipv4->prefixlen));
- listnode_add(tlv_data->te_ipv4_reachs, te_ipreach);
- }
- }
-}
+ struct prefix_ipv4 *ipv4 = (struct prefix_ipv4 *)&rn->p;
+ struct isis_ext_info *info = rn->info;
-static struct list *tlv_get_ipv6_reach_list(struct isis_area *area,
- struct tlvs *tlv_data)
-{
- uint16_t mtid = isis_area_ipv6_topology(area);
- if (mtid == ISIS_MT_IPV4_UNICAST) {
- if (!tlv_data->ipv6_reachs) {
- tlv_data->ipv6_reachs = list_new();
- tlv_data->ipv6_reachs->del = free_tlv;
- }
- return tlv_data->ipv6_reachs;
- }
+ uint32_t metric = info->metric;
+ if (metric > MAX_WIDE_PATH_METRIC)
+ metric = MAX_WIDE_PATH_METRIC;
+ if (area->oldmetric && metric > 0x3f)
+ metric = 0x3f;
- struct tlv_mt_ipv6_reachs *reachs =
- tlvs_get_mt_ipv6_reachs(tlv_data, mtid);
- return reachs->list;
+ if (area->oldmetric)
+ isis_tlvs_add_oldstyle_ip_reach(lsp->tlvs, ipv4,
+ metric);
+ if (area->newmetric)
+ isis_tlvs_add_extended_ip_reach(lsp->tlvs, ipv4,
+ metric);
+ }
}
static void lsp_build_ext_reach_ipv6(struct isis_lsp *lsp,
- struct isis_area *area,
- struct tlvs *tlv_data)
+ struct isis_area *area)
{
- struct route_table *er_table;
- struct route_node *rn;
- struct prefix_ipv6 *ipv6;
- struct isis_ext_info *info;
- struct ipv6_reachability *ip6reach;
- struct list *reach_list = NULL;
-
- er_table = get_ext_reach(area, AF_INET6, lsp->level);
+ struct route_table *er_table =
+ get_ext_reach(area, AF_INET6, lsp->level);
if (!er_table)
return;
- for (rn = route_top(er_table); rn; rn = route_next(rn)) {
+ for (struct route_node *rn = route_top(er_table); rn;
+ rn = route_next(rn)) {
if (!rn->info)
continue;
- ipv6 = (struct prefix_ipv6 *)&rn->p;
- info = rn->info;
+ struct prefix_ipv6 *ipv6 = (struct prefix_ipv6 *)&rn->p;
+ struct isis_ext_info *info = rn->info;
- if (!reach_list)
- reach_list = tlv_get_ipv6_reach_list(area, tlv_data);
-
- ip6reach = XCALLOC(MTYPE_ISIS_TLV, sizeof(*ip6reach));
+ uint32_t metric = info->metric;
if (info->metric > MAX_WIDE_PATH_METRIC)
- ip6reach->metric = htonl(MAX_WIDE_PATH_METRIC);
- else
- ip6reach->metric = htonl(info->metric);
- ip6reach->control_info = DISTRIBUTION_EXTERNAL;
- ip6reach->prefix_len = ipv6->prefixlen;
- memcpy(ip6reach->prefix, ipv6->prefix.s6_addr,
- sizeof(ip6reach->prefix));
- listnode_add(reach_list, ip6reach);
+ metric = MAX_WIDE_PATH_METRIC;
+ isis_tlvs_add_ipv6_reach(
+ lsp->tlvs, isis_area_ipv6_topology(area), ipv6, metric);
}
}
-static void lsp_build_ext_reach(struct isis_lsp *lsp, struct isis_area *area,
- struct tlvs *tlv_data)
+static void lsp_build_ext_reach(struct isis_lsp *lsp, struct isis_area *area)
{
- lsp_build_ext_reach_ipv4(lsp, area, tlv_data);
- lsp_build_ext_reach_ipv6(lsp, area, tlv_data);
+ lsp_build_ext_reach_ipv4(lsp, area);
+ lsp_build_ext_reach_ipv6(lsp, area);
+}
+
+static struct isis_lsp *lsp_next_frag(uint8_t frag_num, struct isis_lsp *lsp0,
+ struct isis_area *area, int level)
+{
+ struct isis_lsp *lsp;
+ uint8_t frag_id[ISIS_SYS_ID_LEN + 2];
+
+ memcpy(frag_id, lsp0->hdr.lsp_id, ISIS_SYS_ID_LEN + 1);
+ LSP_FRAGMENT(frag_id) = frag_num;
+
+ lsp = lsp_search(frag_id, area->lspdb[level - 1]);
+ if (lsp) {
+ lsp_clear_data(lsp);
+ return lsp;
+ }
+
+ lsp = lsp_new(area, frag_id, lsp0->hdr.rem_lifetime, 0,
+ lsp_bits_generate(level, area->overload_bit,
+ area->attached_bit),
+ 0, level);
+ lsp->own_lsp = 1;
+ lsp_insert(lsp, area->lspdb[level - 1]);
+ listnode_add(lsp0->lspu.frags, lsp);
+ lsp->lspu.zero_lsp = lsp0;
+ return lsp;
}
/*
@@ -1304,126 +811,69 @@ static void lsp_build_ext_reach(struct isis_lsp *lsp, struct isis_area *area,
*/
static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
{
- struct is_neigh *is_neigh;
- struct te_is_neigh *te_is_neigh;
- struct listnode *node, *ipnode;
int level = lsp->level;
- struct isis_circuit *circuit;
- struct prefix_ipv4 *ipv4;
- struct ipv4_reachability *ipreach;
- struct te_ipv4_reachability *te_ipreach;
- struct isis_adjacency *nei;
- struct prefix_ipv6 *ipv6, ip6prefix;
- struct list *ipv6_reachs = NULL;
- struct ipv6_reachability *ip6reach;
- struct tlvs tlv_data;
- struct isis_lsp *lsp0 = lsp;
- struct in_addr *routerid;
- uint32_t expected = 0, found = 0;
- uint32_t metric;
- u_char zero_id[ISIS_SYS_ID_LEN + 1];
- int retval = ISIS_OK;
- char buf[BUFSIZ];
+ char buf[PREFIX2STR_BUFFER];
+ struct listnode *node;
+ struct isis_lsp *frag;
+
+ lsp_clear_data(lsp);
+ for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag))
+ lsp_clear_data(frag);
+ lsp->tlvs = isis_alloc_tlvs();
lsp_debug("ISIS (%s): Constructing local system LSP for level %d",
area->area_tag, level);
- /*
- * Building the zero lsp
- */
- memset(zero_id, 0, ISIS_SYS_ID_LEN + 1);
-
- /* Reset stream endp. Stream is always there and on every LSP refresh
- * only
- * TLV part of it is overwritten. So we must seek past header we will
- * not
- * touch. */
- stream_reset(lsp->pdu);
- stream_forward_endp(lsp->pdu, ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN);
+ lsp->hdr.lsp_bits = lsp_bits_generate(level, area->overload_bit,
+ area->attached_bit);
- /*
- * Add the authentication info if its present
- */
- lsp_auth_add(lsp);
+ lsp_add_auth(lsp);
- /*
- * First add the tlvs related to area
- */
-
- /* Area addresses */
- if (lsp->tlv_data.area_addrs == NULL)
- lsp->tlv_data.area_addrs = list_new();
- list_add_list(lsp->tlv_data.area_addrs, area->area_addrs);
- if (listcount(lsp->tlv_data.area_addrs) > 0)
- tlv_add_area_addrs(lsp->tlv_data.area_addrs, lsp->pdu);
+ isis_tlvs_add_area_addresses(lsp->tlvs, area->area_addrs);
/* Protocols Supported */
if (area->ip_circuits > 0 || area->ipv6_circuits > 0) {
- lsp->tlv_data.nlpids =
- XCALLOC(MTYPE_ISIS_TLV, sizeof(struct nlpids));
- lsp->tlv_data.nlpids->count = 0;
+ struct nlpids nlpids = {.count = 0};
if (area->ip_circuits > 0) {
lsp_debug(
"ISIS (%s): Found IPv4 circuit, adding IPv4 to NLPIDs",
area->area_tag);
- lsp->tlv_data.nlpids->count++;
- lsp->tlv_data.nlpids->nlpids[0] = NLPID_IP;
+ nlpids.nlpids[nlpids.count] = NLPID_IP;
+ nlpids.count++;
}
if (area->ipv6_circuits > 0) {
lsp_debug(
"ISIS (%s): Found IPv6 circuit, adding IPv6 to NLPIDs",
area->area_tag);
- lsp->tlv_data.nlpids->count++;
- lsp->tlv_data.nlpids
- ->nlpids[lsp->tlv_data.nlpids->count - 1] =
- NLPID_IPV6;
+ nlpids.nlpids[nlpids.count] = NLPID_IPV6;
+ nlpids.count++;
}
- tlv_add_nlpid(lsp->tlv_data.nlpids, lsp->pdu);
+ isis_tlvs_set_protocols_supported(lsp->tlvs, &nlpids);
}
if (area_is_mt(area)) {
lsp_debug("ISIS (%s): Adding MT router tlv...", area->area_tag);
- lsp->tlv_data.mt_router_info = list_new();
- lsp->tlv_data.mt_router_info->del = free_tlv;
struct isis_area_mt_setting **mt_settings;
unsigned int mt_count;
mt_settings = area_mt_settings(area, &mt_count);
for (unsigned int i = 0; i < mt_count; i++) {
- struct mt_router_info *info;
-
- info = XCALLOC(MTYPE_ISIS_TLV, sizeof(*info));
- info->mtid = mt_settings[i]->mtid;
- info->overload = mt_settings[i]->overload;
- listnode_add(lsp->tlv_data.mt_router_info, info);
+ isis_tlvs_add_mt_router_info(
+ lsp->tlvs, mt_settings[i]->mtid,
+ mt_settings[i]->overload, false);
lsp_debug("ISIS (%s): MT %s", area->area_tag,
- isis_mtid2str(info->mtid));
+ isis_mtid2str(mt_settings[i]->mtid));
}
- tlv_add_mt_router_info(lsp->tlv_data.mt_router_info, lsp->pdu);
} else {
lsp_debug("ISIS (%s): Not adding MT router tlv (disabled)",
area->area_tag);
}
/* Dynamic Hostname */
if (area->dynhostname) {
- const char *hostname = unix_hostname();
- size_t hostname_len = strlen(hostname);
-
- lsp->tlv_data.hostname =
- XMALLOC(MTYPE_ISIS_TLV, sizeof(struct hostname));
-
- strncpy((char *)lsp->tlv_data.hostname->name, hostname,
- sizeof(lsp->tlv_data.hostname->name));
- if (hostname_len <= MAX_TLV_LEN)
- lsp->tlv_data.hostname->namelen = hostname_len;
- else
- lsp->tlv_data.hostname->namelen = MAX_TLV_LEN;
-
- lsp_debug("ISIS (%s): Adding dynamic hostname '%.*s'",
- area->area_tag, lsp->tlv_data.hostname->namelen,
- lsp->tlv_data.hostname->name);
- tlv_add_dynamic_hostname(lsp->tlv_data.hostname, lsp->pdu);
+ isis_tlvs_set_dynamic_hostname(lsp->tlvs, unix_hostname());
+ lsp_debug("ISIS (%s): Adding dynamic hostname '%s'",
+ area->area_tag, unix_hostname());
} else {
lsp_debug("ISIS (%s): Not adding dynamic hostname (disabled)",
area->area_tag);
@@ -1434,45 +884,31 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
* into
* LSP and this address is same as router id. */
if (isis->router_id != 0) {
- inet_ntop(AF_INET, &isis->router_id, buf, sizeof(buf));
+ struct in_addr id = {.s_addr = isis->router_id};
+ inet_ntop(AF_INET, &id, buf, sizeof(buf));
lsp_debug("ISIS (%s): Adding router ID %s as IPv4 tlv.",
area->area_tag, buf);
- if (lsp->tlv_data.ipv4_addrs == NULL) {
- lsp->tlv_data.ipv4_addrs = list_new();
- lsp->tlv_data.ipv4_addrs->del = free_tlv;
- }
-
- routerid = XMALLOC(MTYPE_ISIS_TLV, sizeof(struct in_addr));
- routerid->s_addr = isis->router_id;
- listnode_add(lsp->tlv_data.ipv4_addrs, routerid);
- tlv_add_in_addr(routerid, lsp->pdu, IPV4_ADDR);
+ isis_tlvs_add_ipv4_address(lsp->tlvs, &id);
/* Exactly same data is put into TE router ID TLV, but only if
* new style
* TLV's are in use. */
if (area->newmetric) {
+
lsp_debug(
"ISIS (%s): Adding router ID also as TE router ID tlv.",
area->area_tag);
- lsp->tlv_data.router_id =
- XMALLOC(MTYPE_ISIS_TLV, sizeof(struct in_addr));
- lsp->tlv_data.router_id->id.s_addr = isis->router_id;
- tlv_add_in_addr(&lsp->tlv_data.router_id->id, lsp->pdu,
- TE_ROUTER_ID);
+ isis_tlvs_set_te_router_id(lsp->tlvs, &id);
}
} else {
lsp_debug("ISIS (%s): Router ID is unset. Not adding tlv.",
area->area_tag);
}
- memset(&tlv_data, 0, sizeof(struct tlvs));
-
lsp_debug("ISIS (%s): Adding circuit specific information.",
area->area_tag);
- /*
- * Then build lists of tlvs related to circuits
- */
+ struct isis_circuit *circuit;
for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
if (!circuit->interface)
lsp_debug(
@@ -1492,245 +928,94 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
continue;
}
- /*
- * Add IPv4 internal reachability of this circuit
- */
+ uint32_t metric = area->oldmetric
+ ? circuit->metric[level - 1]
+ : circuit->te_metric[level - 1];
+
if (circuit->ip_router && circuit->ip_addrs
&& circuit->ip_addrs->count > 0) {
lsp_debug(
"ISIS (%s): Circuit has IPv4 active, adding respective TLVs.",
area->area_tag);
- if (area->oldmetric) {
- if (tlv_data.ipv4_int_reachs == NULL) {
- tlv_data.ipv4_int_reachs = list_new();
- tlv_data.ipv4_int_reachs->del =
- free_tlv;
- }
- for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs,
- ipnode, ipv4)) {
- ipreach = XMALLOC(
- MTYPE_ISIS_TLV,
- sizeof(struct
- ipv4_reachability));
- ipreach->metrics.metric_default =
- circuit->metric[level - 1];
- ipreach->metrics.metric_expense =
- METRICS_UNSUPPORTED;
- ipreach->metrics.metric_error =
- METRICS_UNSUPPORTED;
- ipreach->metrics.metric_delay =
- METRICS_UNSUPPORTED;
- masklen2ip(ipv4->prefixlen,
- &ipreach->mask);
- ipreach->prefix.s_addr =
- ((ipreach->mask.s_addr)
- & (ipv4->prefix.s_addr));
- inet_ntop(AF_INET,
- &ipreach->prefix.s_addr, buf,
- sizeof(buf));
+ struct listnode *ipnode;
+ struct prefix_ipv4 *ipv4;
+ for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, ipnode,
+ ipv4)) {
+ if (area->oldmetric) {
lsp_debug(
- "ISIS (%s): Adding old-style IP reachability for %s/%d",
- area->area_tag, buf,
- ipv4->prefixlen);
- listnode_add(tlv_data.ipv4_int_reachs,
- ipreach);
- }
- }
- if (area->newmetric) {
- if (tlv_data.te_ipv4_reachs == NULL) {
- tlv_data.te_ipv4_reachs = list_new();
- tlv_data.te_ipv4_reachs->del = free_tlv;
+ "ISIS (%s): Adding old-style IP reachability for %s",
+ area->area_tag,
+ prefix2str(ipv4, buf,
+ sizeof(buf)));
+ isis_tlvs_add_oldstyle_ip_reach(
+ lsp->tlvs, ipv4, metric);
}
- for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs,
- ipnode, ipv4)) {
- /* FIXME All this assumes that we have
- * no sub TLVs. */
- te_ipreach = XCALLOC(
- MTYPE_ISIS_TLV,
- sizeof(struct
- te_ipv4_reachability)
- + ((ipv4->prefixlen + 7)
- / 8)
- - 1);
-
- if (area->oldmetric)
- te_ipreach->te_metric = htonl(
- circuit->metric[level
- - 1]);
- else
- te_ipreach->te_metric = htonl(
- circuit->te_metric
- [level - 1]);
-
- te_ipreach->control =
- (ipv4->prefixlen & 0x3F);
- memcpy(&te_ipreach->prefix_start,
- &ipv4->prefix.s_addr,
- (ipv4->prefixlen + 7) / 8);
- inet_ntop(AF_INET, &ipv4->prefix.s_addr,
- buf, sizeof(buf));
+
+ if (area->newmetric) {
lsp_debug(
- "ISIS (%s): Adding te-style IP reachability for %s/%d",
- area->area_tag, buf,
- ipv4->prefixlen);
- listnode_add(tlv_data.te_ipv4_reachs,
- te_ipreach);
+ "ISIS (%s): Adding te-style IP reachability for %s",
+ area->area_tag,
+ prefix2str(ipv4, buf,
+ sizeof(buf)));
+ isis_tlvs_add_extended_ip_reach(
+ lsp->tlvs, ipv4, metric);
}
}
}
- /*
- * Add IPv6 reachability of this circuit
- */
if (circuit->ipv6_router && circuit->ipv6_non_link
&& circuit->ipv6_non_link->count > 0) {
- if (!ipv6_reachs)
- ipv6_reachs = tlv_get_ipv6_reach_list(
- area, &tlv_data);
-
+ struct listnode *ipnode;
+ struct prefix_ipv6 *ipv6;
for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link,
ipnode, ipv6)) {
- ip6reach = XCALLOC(
- MTYPE_ISIS_TLV,
- sizeof(struct ipv6_reachability));
-
- if (area->oldmetric)
- ip6reach->metric = htonl(
- circuit->metric[level - 1]);
- else
- ip6reach->metric = htonl(
- circuit->te_metric[level - 1]);
-
- ip6reach->control_info = 0;
- ip6reach->prefix_len = ipv6->prefixlen;
- memcpy(&ip6prefix, ipv6, sizeof(ip6prefix));
- apply_mask_ipv6(&ip6prefix);
-
- inet_ntop(AF_INET6, &ip6prefix.prefix.s6_addr,
- buf, sizeof(buf));
lsp_debug(
- "ISIS (%s): Adding IPv6 reachability for %s/%d",
- area->area_tag, buf, ipv6->prefixlen);
-
- memcpy(ip6reach->prefix,
- ip6prefix.prefix.s6_addr,
- sizeof(ip6reach->prefix));
- listnode_add(ipv6_reachs, ip6reach);
+ "ISIS (%s): Adding IPv6 reachability for %s",
+ area->area_tag,
+ prefix2str(ipv6, buf, sizeof(buf)));
+ isis_tlvs_add_ipv6_reach(
+ lsp->tlvs,
+ isis_area_ipv6_topology(area), ipv6,
+ metric);
}
}
switch (circuit->circ_type) {
case CIRCUIT_T_BROADCAST:
if (level & circuit->is_type) {
- if (area->oldmetric) {
- if (tlv_data.is_neighs == NULL) {
- tlv_data.is_neighs = list_new();
- tlv_data.is_neighs->del =
- free_tlv;
- }
- is_neigh = XCALLOC(
- MTYPE_ISIS_TLV,
- sizeof(struct is_neigh));
- if (level == IS_LEVEL_1)
- memcpy(is_neigh->neigh_id,
- circuit->u.bc
- .l1_desig_is,
- ISIS_SYS_ID_LEN + 1);
- else
- memcpy(is_neigh->neigh_id,
- circuit->u.bc
- .l2_desig_is,
- ISIS_SYS_ID_LEN + 1);
- is_neigh->metrics.metric_default =
- circuit->metric[level - 1];
- is_neigh->metrics.metric_expense =
- METRICS_UNSUPPORTED;
- is_neigh->metrics.metric_error =
- METRICS_UNSUPPORTED;
- is_neigh->metrics.metric_delay =
- METRICS_UNSUPPORTED;
- if (!memcmp(is_neigh->neigh_id, zero_id,
- ISIS_SYS_ID_LEN + 1)) {
- XFREE(MTYPE_ISIS_TLV, is_neigh);
- lsp_debug(
- "ISIS (%s): No DIS for circuit, not adding old-style IS neighbor.",
- area->area_tag);
- } else {
- listnode_add(tlv_data.is_neighs,
- is_neigh);
+ uint8_t *ne_id =
+ (level == IS_LEVEL_1)
+ ? circuit->u.bc.l1_desig_is
+ : circuit->u.bc.l2_desig_is;
+
+ if (LSP_PSEUDO_ID(ne_id)) {
+ if (area->oldmetric) {
lsp_debug(
"ISIS (%s): Adding DIS %s.%02x as old-style neighbor",
area->area_tag,
- sysid_print(
- is_neigh->neigh_id),
- LSP_PSEUDO_ID(
- is_neigh->neigh_id));
- }
- }
- if (area->newmetric) {
- if (tlv_data.te_is_neighs == NULL) {
- tlv_data.te_is_neighs =
- list_new();
- tlv_data.te_is_neighs->del =
- free_tlv;
+ sysid_print(ne_id),
+ LSP_PSEUDO_ID(ne_id));
+ isis_tlvs_add_oldstyle_reach(
+ lsp->tlvs, ne_id,
+ metric);
}
- te_is_neigh = XCALLOC(
- MTYPE_ISIS_TLV,
- sizeof(struct te_is_neigh));
- if (level == IS_LEVEL_1)
- memcpy(te_is_neigh->neigh_id,
- circuit->u.bc
- .l1_desig_is,
- ISIS_SYS_ID_LEN + 1);
- else
- memcpy(te_is_neigh->neigh_id,
- circuit->u.bc
- .l2_desig_is,
- ISIS_SYS_ID_LEN + 1);
- if (area->oldmetric)
- metric = circuit->metric[level
- - 1];
- else
- metric =
- circuit->te_metric[level
- - 1];
- SET_TE_METRIC(te_is_neigh, metric);
- if (!memcmp(te_is_neigh->neigh_id,
- zero_id,
- ISIS_SYS_ID_LEN + 1)) {
- XFREE(MTYPE_ISIS_TLV,
- te_is_neigh);
- lsp_debug(
- "ISIS (%s): No DIS for circuit, not adding te-style IS neighbor.",
- area->area_tag);
- } else {
- /* Check if MPLS_TE is activate
- */
+ if (area->newmetric) {
+ uint8_t subtlvs[256];
+ uint8_t subtlv_len;
+
if (IS_MPLS_TE(isisMplsTE)
&& HAS_LINK_PARAMS(
circuit->interface))
- /* Add SubTLVs & Adjust
- * real size of SubTLVs
- */
- te_is_neigh
- ->sub_tlvs_length = add_te_subtlvs(
- te_is_neigh
- ->sub_tlvs,
+ subtlv_len = add_te_subtlvs(
+ subtlvs,
circuit->mtc);
else
- /* Or keep only TE
- * metric with no
- * SubTLVs if MPLS_TE is
- * off */
- te_is_neigh
- ->sub_tlvs_length =
- 0;
+ subtlv_len = 0;
tlvs_add_mt_bcast(
- &tlv_data, circuit,
- level, te_is_neigh);
- XFREE(MTYPE_ISIS_TLV,
- te_is_neigh);
+ lsp->tlvs, circuit,
+ level, ne_id, metric,
+ subtlvs, subtlv_len);
}
}
} else {
@@ -1739,53 +1024,25 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
area->area_tag);
}
break;
- case CIRCUIT_T_P2P:
- nei = circuit->u.p2p.neighbor;
+ case CIRCUIT_T_P2P: {
+ struct isis_adjacency *nei = circuit->u.p2p.neighbor;
if (nei && (level & nei->circuit_t)) {
+ uint8_t ne_id[7];
+ memcpy(ne_id, nei->sysid, ISIS_SYS_ID_LEN);
+ LSP_PSEUDO_ID(ne_id) = 0;
+
if (area->oldmetric) {
- if (tlv_data.is_neighs == NULL) {
- tlv_data.is_neighs = list_new();
- tlv_data.is_neighs->del =
- free_tlv;
- }
- is_neigh = XCALLOC(
- MTYPE_ISIS_TLV,
- sizeof(struct is_neigh));
- memcpy(is_neigh->neigh_id, nei->sysid,
- ISIS_SYS_ID_LEN);
- is_neigh->metrics.metric_default =
- circuit->metric[level - 1];
- is_neigh->metrics.metric_expense =
- METRICS_UNSUPPORTED;
- is_neigh->metrics.metric_error =
- METRICS_UNSUPPORTED;
- is_neigh->metrics.metric_delay =
- METRICS_UNSUPPORTED;
- listnode_add(tlv_data.is_neighs,
- is_neigh);
lsp_debug(
"ISIS (%s): Adding old-style is reach for %s",
area->area_tag,
- sysid_print(
- is_neigh->neigh_id));
+ sysid_print(ne_id));
+ isis_tlvs_add_oldstyle_reach(
+ lsp->tlvs, ne_id, metric);
}
if (area->newmetric) {
- uint32_t metric;
+ uint8_t subtlvs[256];
+ uint8_t subtlv_len;
- if (tlv_data.te_is_neighs == NULL) {
- tlv_data.te_is_neighs =
- list_new();
- tlv_data.te_is_neighs->del =
- free_tlv;
- }
- te_is_neigh = XCALLOC(
- MTYPE_ISIS_TLV,
- sizeof(struct te_is_neigh));
- memcpy(te_is_neigh->neigh_id,
- nei->sysid, ISIS_SYS_ID_LEN);
- metric = circuit->te_metric[level - 1];
- SET_TE_METRIC(te_is_neigh, metric);
- /* Check if MPLS_TE is activate */
if (IS_MPLS_TE(isisMplsTE)
&& HAS_LINK_PARAMS(
circuit->interface))
@@ -1804,28 +1061,24 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
/* Add SubTLVs & Adjust real
* size of SubTLVs */
- te_is_neigh->sub_tlvs_length =
- add_te_subtlvs(
- te_is_neigh
- ->sub_tlvs,
- circuit->mtc);
+ subtlv_len = add_te_subtlvs(
+ subtlvs, circuit->mtc);
else
/* Or keep only TE metric with
* no SubTLVs if MPLS_TE is off
*/
- te_is_neigh->sub_tlvs_length =
- 0;
+ subtlv_len = 0;
- tlvs_add_mt_p2p(&tlv_data, circuit,
- te_is_neigh);
- XFREE(MTYPE_ISIS_TLV, te_is_neigh);
+ tlvs_add_mt_p2p(lsp->tlvs, circuit,
+ ne_id, metric, subtlvs,
+ subtlv_len);
}
} else {
lsp_debug(
"ISIS (%s): No adjacency for given level on this circuit. Not adding IS neighbors",
area->area_tag);
}
- break;
+ } break;
case CIRCUIT_T_LOOPBACK:
break;
default:
@@ -1833,169 +1086,36 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
}
}
- lsp_build_ext_reach(lsp, area, &tlv_data);
-
- lsp_debug("ISIS (%s): LSP construction is complete. Serializing...",
- area->area_tag);
-
- while (tlv_data.ipv4_int_reachs
- && listcount(tlv_data.ipv4_int_reachs)) {
- if (lsp->tlv_data.ipv4_int_reachs == NULL)
- lsp->tlv_data.ipv4_int_reachs = list_new();
- lsp_tlv_fit(lsp, &tlv_data.ipv4_int_reachs,
- &lsp->tlv_data.ipv4_int_reachs, IPV4_REACH_LEN,
- area->lsp_frag_threshold, tlv_add_ipv4_int_reachs);
- if (tlv_data.ipv4_int_reachs
- && listcount(tlv_data.ipv4_int_reachs))
- lsp = lsp_next_frag(
- LSP_FRAGMENT(lsp->lsp_header->lsp_id) + 1, lsp0,
- area, level);
- }
-
- while (tlv_data.ipv4_ext_reachs
- && listcount(tlv_data.ipv4_ext_reachs)) {
- if (lsp->tlv_data.ipv4_ext_reachs == NULL)
- lsp->tlv_data.ipv4_ext_reachs = list_new();
- lsp_tlv_fit(lsp, &tlv_data.ipv4_ext_reachs,
- &lsp->tlv_data.ipv4_ext_reachs, IPV4_REACH_LEN,
- area->lsp_frag_threshold, tlv_add_ipv4_ext_reachs);
- if (tlv_data.ipv4_ext_reachs
- && listcount(tlv_data.ipv4_ext_reachs))
- lsp = lsp_next_frag(
- LSP_FRAGMENT(lsp->lsp_header->lsp_id) + 1, lsp0,
- area, level);
- }
-
- while (tlv_data.te_ipv4_reachs && listcount(tlv_data.te_ipv4_reachs)) {
- if (lsp->tlv_data.te_ipv4_reachs == NULL)
- lsp->tlv_data.te_ipv4_reachs = list_new();
- _lsp_tlv_fit(lsp, &tlv_data.te_ipv4_reachs,
- &lsp->tlv_data.te_ipv4_reachs,
- area->lsp_frag_threshold, tlv_add_te_ipv4_reachs,
- NULL);
- if (tlv_data.te_ipv4_reachs
- && listcount(tlv_data.te_ipv4_reachs))
- lsp = lsp_next_frag(
- LSP_FRAGMENT(lsp->lsp_header->lsp_id) + 1, lsp0,
- area, level);
- }
-
- struct tlv_mt_ipv4_reachs *mt_ipv4_reachs;
- for (ALL_LIST_ELEMENTS_RO(tlv_data.mt_ipv4_reachs, node,
- mt_ipv4_reachs)) {
- while (mt_ipv4_reachs->list
- && listcount(mt_ipv4_reachs->list)) {
- struct tlv_mt_ipv4_reachs *frag_mt_ipv4_reachs;
-
- frag_mt_ipv4_reachs = tlvs_get_mt_ipv4_reachs(
- &lsp->tlv_data, mt_ipv4_reachs->mtid);
- _lsp_tlv_fit(lsp, &mt_ipv4_reachs->list,
- &frag_mt_ipv4_reachs->list,
- area->lsp_frag_threshold,
- tlv_add_te_ipv4_reachs,
- &mt_ipv4_reachs->mtid);
- if (mt_ipv4_reachs->list
- && listcount(mt_ipv4_reachs->list))
- lsp = lsp_next_frag(
- LSP_FRAGMENT(lsp->lsp_header->lsp_id)
- + 1,
- lsp0, area, level);
- }
- }
-
- while (tlv_data.ipv6_reachs && listcount(tlv_data.ipv6_reachs)) {
- if (lsp->tlv_data.ipv6_reachs == NULL)
- lsp->tlv_data.ipv6_reachs = list_new();
- _lsp_tlv_fit(
- lsp, &tlv_data.ipv6_reachs, &lsp->tlv_data.ipv6_reachs,
- area->lsp_frag_threshold, tlv_add_ipv6_reachs, NULL);
- if (tlv_data.ipv6_reachs && listcount(tlv_data.ipv6_reachs))
- lsp = lsp_next_frag(
- LSP_FRAGMENT(lsp->lsp_header->lsp_id) + 1, lsp0,
- area, level);
- }
+ lsp_build_ext_reach(lsp, area);
- struct tlv_mt_ipv6_reachs *mt_ipv6_reachs;
- for (ALL_LIST_ELEMENTS_RO(tlv_data.mt_ipv6_reachs, node,
- mt_ipv6_reachs)) {
- while (mt_ipv6_reachs->list
- && listcount(mt_ipv6_reachs->list)) {
- struct tlv_mt_ipv6_reachs *frag_mt_ipv6_reachs;
-
- frag_mt_ipv6_reachs = tlvs_get_mt_ipv6_reachs(
- &lsp->tlv_data, mt_ipv6_reachs->mtid);
- _lsp_tlv_fit(lsp, &mt_ipv6_reachs->list,
- &frag_mt_ipv6_reachs->list,
- area->lsp_frag_threshold,
- tlv_add_ipv6_reachs,
- &mt_ipv6_reachs->mtid);
- if (mt_ipv6_reachs->list
- && listcount(mt_ipv6_reachs->list))
- lsp = lsp_next_frag(
- LSP_FRAGMENT(lsp->lsp_header->lsp_id)
- + 1,
- lsp0, area, level);
- }
- }
+ struct isis_tlvs *tlvs = lsp->tlvs;
+ lsp->tlvs = NULL;
- while (tlv_data.is_neighs && listcount(tlv_data.is_neighs)) {
- if (lsp->tlv_data.is_neighs == NULL)
- lsp->tlv_data.is_neighs = list_new();
- lsp_tlv_fit(lsp, &tlv_data.is_neighs, &lsp->tlv_data.is_neighs,
- IS_NEIGHBOURS_LEN, area->lsp_frag_threshold,
- tlv_add_is_neighs);
- if (tlv_data.is_neighs && listcount(tlv_data.is_neighs))
- lsp = lsp_next_frag(
- LSP_FRAGMENT(lsp->lsp_header->lsp_id) + 1, lsp0,
- area, level);
- }
+ lsp_pack_pdu(lsp);
+ size_t tlv_space = STREAM_WRITEABLE(lsp->pdu) - LLC_LEN;
+ lsp_clear_data(lsp);
- while (tlv_data.te_is_neighs && listcount(tlv_data.te_is_neighs)) {
- if (lsp->tlv_data.te_is_neighs == NULL)
- lsp->tlv_data.te_is_neighs = list_new();
- _lsp_tlv_fit(lsp, &tlv_data.te_is_neighs,
- &lsp->tlv_data.te_is_neighs,
- area->lsp_frag_threshold, tlv_add_te_is_neighs,
- NULL);
- if (tlv_data.te_is_neighs && listcount(tlv_data.te_is_neighs))
- lsp = lsp_next_frag(
- LSP_FRAGMENT(lsp->lsp_header->lsp_id) + 1, lsp0,
- area, level);
+ struct list *fragments = isis_fragment_tlvs(tlvs, tlv_space);
+ if (!fragments) {
+ zlog_warn("BUG: could not fragment own LSP:");
+ log_multiline(LOG_WARNING, " ", "%s", isis_format_tlvs(tlvs));
+ isis_free_tlvs(tlvs);
+ return;
}
+ isis_free_tlvs(tlvs);
- struct tlv_mt_neighbors *mt_neighs;
- for (ALL_LIST_ELEMENTS_RO(tlv_data.mt_is_neighs, node, mt_neighs)) {
- while (mt_neighs->list && listcount(mt_neighs->list)) {
- struct tlv_mt_neighbors *frag_mt_neighs;
-
- frag_mt_neighs = tlvs_get_mt_neighbors(&lsp->tlv_data,
- mt_neighs->mtid);
- _lsp_tlv_fit(lsp, &mt_neighs->list,
- &frag_mt_neighs->list,
- area->lsp_frag_threshold,
- tlv_add_te_is_neighs, &mt_neighs->mtid);
- if (mt_neighs->list && listcount(mt_neighs->list))
- lsp = lsp_next_frag(
- LSP_FRAGMENT(lsp->lsp_header->lsp_id)
- + 1,
- lsp0, area, level);
+ frag = lsp;
+ for (ALL_LIST_ELEMENTS_RO(fragments, node, tlvs)) {
+ if (node != listhead(fragments)) {
+ frag = lsp_next_frag(LSP_FRAGMENT(frag->hdr.lsp_id) + 1,
+ lsp, area, level);
}
+ frag->tlvs = tlvs;
}
-
- lsp->lsp_header->pdu_len = htons(stream_get_endp(lsp->pdu));
-
- free_tlvs(&tlv_data);
-
- /* Validate the LSP */
- retval = parse_tlvs(area->area_tag,
- STREAM_DATA(lsp->pdu) + ISIS_FIXED_HDR_LEN
- + ISIS_LSP_HDR_LEN,
- stream_get_endp(lsp->pdu) - ISIS_FIXED_HDR_LEN
- - ISIS_LSP_HDR_LEN,
- &expected, &found, &tlv_data, NULL);
- assert(retval == ISIS_OK);
-
+ list_delete(fragments);
+ lsp_debug("ISIS (%s): LSP construction is complete. Serializing...",
+ area->area_tag);
return;
}
@@ -2019,8 +1139,8 @@ int lsp_generate(struct isis_area *area, int level)
oldlsp = lsp_search(lspid, area->lspdb[level - 1]);
if (oldlsp) {
/* FIXME: we should actually initiate a purge */
- seq_num = ntohl(oldlsp->lsp_header->seq_num);
- lsp_search_and_destroy(oldlsp->lsp_header->lsp_id,
+ seq_num = oldlsp->hdr.seqno;
+ lsp_search_and_destroy(oldlsp->hdr.lsp_id,
area->lspdb[level - 1]);
}
rem_lifetime = lsp_rem_lifetime(area, level);
@@ -2035,7 +1155,7 @@ int lsp_generate(struct isis_area *area, int level)
/* build_lsp_data (newlsp, area); */
lsp_build(newlsp, area);
/* time to calculate our checksum */
- lsp_seqnum_update(newlsp);
+ lsp_seqno_update(newlsp);
newlsp->last_generated = time(NULL);
lsp_set_all_srmflags(newlsp);
@@ -2051,15 +1171,14 @@ int lsp_generate(struct isis_area *area, int level)
&area->t_lsp_refresh[level - 1]);
if (isis->debugs & DEBUG_UPDATE_PACKETS) {
- zlog_debug(
- "ISIS-Upd (%s): Building L%d LSP %s, len %d, "
- "seq 0x%08x, cksum 0x%04x, lifetime %us refresh %us",
- area->area_tag, level,
- rawlspid_print(newlsp->lsp_header->lsp_id),
- ntohl(newlsp->lsp_header->pdu_len),
- ntohl(newlsp->lsp_header->seq_num),
- ntohs(newlsp->lsp_header->checksum),
- ntohs(newlsp->lsp_header->rem_lifetime), refresh_time);
+ zlog_debug("ISIS-Upd (%s): Building L%d LSP %s, len %" PRIu16
+ ", seq 0x%08" PRIx32 ", cksum 0x%04" PRIx16
+ ", lifetime %" PRIu16 "s refresh %" PRIu16 "s",
+ area->area_tag, level,
+ rawlspid_print(newlsp->hdr.lsp_id),
+ newlsp->hdr.pdu_len, newlsp->hdr.seqno,
+ newlsp->hdr.checksum, newlsp->hdr.rem_lifetime,
+ refresh_time);
}
sched_debug(
"ISIS (%s): Built L%d LSP. Set triggered regenerate to non-pending.",
@@ -2097,24 +1216,21 @@ static int lsp_regenerate(struct isis_area *area, int level)
lsp_clear_data(lsp);
lsp_build(lsp, area);
- lsp->lsp_header->lsp_bits = lsp_bits_generate(level, area->overload_bit,
- area->attached_bit);
rem_lifetime = lsp_rem_lifetime(area, level);
- lsp->lsp_header->rem_lifetime = htons(rem_lifetime);
- lsp_seqnum_update(lsp);
-
+ lsp->hdr.rem_lifetime = rem_lifetime;
lsp->last_generated = time(NULL);
lsp_set_all_srmflags(lsp);
for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag)) {
- frag->lsp_header->lsp_bits = lsp_bits_generate(
+ frag->hdr.lsp_bits = lsp_bits_generate(
level, area->overload_bit, area->attached_bit);
/* Set the lifetime values of all the fragments to the same
* value,
* so that no fragment expires before the lsp is refreshed.
*/
- frag->lsp_header->rem_lifetime = htons(rem_lifetime);
+ frag->hdr.rem_lifetime = rem_lifetime;
lsp_set_all_srmflags(frag);
}
+ lsp_seqno_update(lsp);
refresh_time = lsp_refresh_time(lsp, rem_lifetime);
if (level == IS_LEVEL_1)
@@ -2127,14 +1243,12 @@ static int lsp_regenerate(struct isis_area *area, int level)
if (isis->debugs & DEBUG_UPDATE_PACKETS) {
zlog_debug(
- "ISIS-Upd (%s): Refreshing our L%d LSP %s, len %d, "
- "seq 0x%08x, cksum 0x%04x, lifetime %us refresh %us",
- area->area_tag, level,
- rawlspid_print(lsp->lsp_header->lsp_id),
- ntohl(lsp->lsp_header->pdu_len),
- ntohl(lsp->lsp_header->seq_num),
- ntohs(lsp->lsp_header->checksum),
- ntohs(lsp->lsp_header->rem_lifetime), refresh_time);
+ "ISIS-Upd (%s): Refreshed our L%d LSP %s, len %" PRIu16
+ ", seq 0x%08" PRIx32 ", cksum 0x%04" PRIx16
+ ", lifetime %" PRIu16 "s refresh %" PRIu16 "s",
+ area->area_tag, level, rawlspid_print(lsp->hdr.lsp_id),
+ lsp->hdr.pdu_len, lsp->hdr.seqno, lsp->hdr.checksum,
+ lsp->hdr.rem_lifetime, refresh_time);
}
sched_debug(
"ISIS (%s): Rebuilt L%d LSP. Set triggered regenerate to non-pending.",
@@ -2294,164 +1408,89 @@ static void lsp_build_pseudo(struct isis_lsp *lsp, struct isis_circuit *circuit,
int level)
{
struct isis_adjacency *adj;
- struct is_neigh *is_neigh;
- struct te_is_neigh *te_is_neigh;
- struct es_neigh *es_neigh;
struct list *adj_list;
struct listnode *node;
struct isis_area *area = circuit->area;
+ lsp_clear_data(lsp);
+ lsp->tlvs = isis_alloc_tlvs();
lsp_debug(
"ISIS (%s): Constructing pseudo LSP %s for interface %s level %d",
- area->area_tag, rawlspid_print(lsp->lsp_header->lsp_id),
+ area->area_tag, rawlspid_print(lsp->hdr.lsp_id),
circuit->interface->name, level);
lsp->level = level;
/* RFC3787 section 4 SHOULD not set overload bit in pseudo LSPs */
- lsp->lsp_header->lsp_bits =
+ lsp->hdr.lsp_bits =
lsp_bits_generate(level, 0, circuit->area->attached_bit);
/*
* add self to IS neighbours
*/
- if (circuit->area->oldmetric) {
- if (lsp->tlv_data.is_neighs == NULL) {
- lsp->tlv_data.is_neighs = list_new();
- lsp->tlv_data.is_neighs->del = free_tlv;
- }
- is_neigh = XCALLOC(MTYPE_ISIS_TLV, sizeof(struct is_neigh));
+ uint8_t ne_id[ISIS_SYS_ID_LEN + 1];
+
+ memcpy(ne_id, isis->sysid, ISIS_SYS_ID_LEN);
+ LSP_PSEUDO_ID(ne_id) = 0;
- memcpy(&is_neigh->neigh_id, isis->sysid, ISIS_SYS_ID_LEN);
- listnode_add(lsp->tlv_data.is_neighs, is_neigh);
+ if (circuit->area->oldmetric) {
+ isis_tlvs_add_oldstyle_reach(lsp->tlvs, ne_id, 0);
lsp_debug(
"ISIS (%s): Adding %s.%02x as old-style neighbor (self)",
- area->area_tag, sysid_print(is_neigh->neigh_id),
- LSP_PSEUDO_ID(is_neigh->neigh_id));
+ area->area_tag, sysid_print(ne_id),
+ LSP_PSEUDO_ID(ne_id));
}
if (circuit->area->newmetric) {
- if (lsp->tlv_data.te_is_neighs == NULL) {
- lsp->tlv_data.te_is_neighs = list_new();
- lsp->tlv_data.te_is_neighs->del = free_tlv;
- }
- te_is_neigh =
- XCALLOC(MTYPE_ISIS_TLV, sizeof(struct te_is_neigh));
-
- memcpy(&te_is_neigh->neigh_id, isis->sysid, ISIS_SYS_ID_LEN);
- listnode_add(lsp->tlv_data.te_is_neighs, te_is_neigh);
+ isis_tlvs_add_extended_reach(lsp->tlvs, ISIS_MT_IPV4_UNICAST,
+ ne_id, 0, NULL, 0);
lsp_debug(
"ISIS (%s): Adding %s.%02x as te-style neighbor (self)",
- area->area_tag, sysid_print(te_is_neigh->neigh_id),
- LSP_PSEUDO_ID(te_is_neigh->neigh_id));
+ area->area_tag, sysid_print(ne_id),
+ LSP_PSEUDO_ID(ne_id));
}
adj_list = list_new();
isis_adj_build_up_list(circuit->u.bc.adjdb[level - 1], adj_list);
for (ALL_LIST_ELEMENTS_RO(adj_list, node, adj)) {
- if (adj->level & level) {
- if ((level == IS_LEVEL_1
- && adj->sys_type == ISIS_SYSTYPE_L1_IS)
- || (level == IS_LEVEL_1
- && adj->sys_type == ISIS_SYSTYPE_L2_IS
- && adj->adj_usage == ISIS_ADJ_LEVEL1AND2)
- || (level == IS_LEVEL_2
- && adj->sys_type == ISIS_SYSTYPE_L2_IS)) {
- /* an IS neighbour -> add it */
- if (circuit->area->oldmetric) {
- is_neigh = XCALLOC(
- MTYPE_ISIS_TLV,
- sizeof(struct is_neigh));
-
- memcpy(&is_neigh->neigh_id, adj->sysid,
- ISIS_SYS_ID_LEN);
- listnode_add(lsp->tlv_data.is_neighs,
- is_neigh);
- lsp_debug(
- "ISIS (%s): Adding %s.%02x as old-style neighbor (peer)",
- area->area_tag,
- sysid_print(is_neigh->neigh_id),
- LSP_PSEUDO_ID(
- is_neigh->neigh_id));
- }
- if (circuit->area->newmetric) {
- te_is_neigh = XCALLOC(
- MTYPE_ISIS_TLV,
- sizeof(struct te_is_neigh));
- memcpy(&te_is_neigh->neigh_id,
- adj->sysid, ISIS_SYS_ID_LEN);
- listnode_add(lsp->tlv_data.te_is_neighs,
- te_is_neigh);
- lsp_debug(
- "ISIS (%s): Adding %s.%02x as te-style neighbor (peer)",
- area->area_tag,
- sysid_print(
- te_is_neigh->neigh_id),
- LSP_PSEUDO_ID(
- te_is_neigh->neigh_id));
- }
- } else if (level == IS_LEVEL_1
- && adj->sys_type == ISIS_SYSTYPE_ES) {
- /* an ES neigbour add it, if we are building
- * level 1 LSP */
- /* FIXME: the tlv-format is hard to use here */
- if (lsp->tlv_data.es_neighs == NULL) {
- lsp->tlv_data.es_neighs = list_new();
- lsp->tlv_data.es_neighs->del = free_tlv;
- }
- es_neigh = XCALLOC(MTYPE_ISIS_TLV,
- sizeof(struct es_neigh));
-
- memcpy(&es_neigh->first_es_neigh, adj->sysid,
- ISIS_SYS_ID_LEN);
- listnode_add(lsp->tlv_data.es_neighs, es_neigh);
- lsp_debug(
- "ISIS (%s): Adding %s as ES neighbor (peer)",
- area->area_tag,
- sysid_print(es_neigh->first_es_neigh));
- } else {
- lsp_debug(
- "ISIS (%s): Ignoring neighbor %s, level does not match",
- area->area_tag,
- sysid_print(adj->sysid));
- }
- } else {
+ if (!(adj->level & level)) {
lsp_debug(
"ISIS (%s): Ignoring neighbor %s, level does not intersect",
area->area_tag, sysid_print(adj->sysid));
+ continue;
}
- }
- list_delete(adj_list);
-
- lsp_debug("ISIS (%s): Pseudo LSP construction is complete.",
- area->area_tag);
-
- /* Reset endp of stream to overwrite only TLV part of it. */
- stream_reset(lsp->pdu);
- stream_forward_endp(lsp->pdu, ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN);
- /*
- * Add the authentication info if it's present
- */
- lsp_auth_add(lsp);
-
- if (lsp->tlv_data.is_neighs && listcount(lsp->tlv_data.is_neighs) > 0)
- tlv_add_is_neighs(lsp->tlv_data.is_neighs, lsp->pdu);
-
- if (lsp->tlv_data.te_is_neighs
- && listcount(lsp->tlv_data.te_is_neighs) > 0)
- tlv_add_te_is_neighs(lsp->tlv_data.te_is_neighs, lsp->pdu,
- NULL);
-
- if (lsp->tlv_data.es_neighs && listcount(lsp->tlv_data.es_neighs) > 0)
- tlv_add_is_neighs(lsp->tlv_data.es_neighs, lsp->pdu);
-
- lsp->lsp_header->pdu_len = htons(stream_get_endp(lsp->pdu));
-
- /* Recompute authentication and checksum information */
- lsp_auth_update(lsp);
- fletcher_checksum(STREAM_DATA(lsp->pdu) + 12,
- ntohs(lsp->lsp_header->pdu_len) - 12, 12);
+ if (!(level == IS_LEVEL_1
+ && adj->sys_type == ISIS_SYSTYPE_L1_IS)
+ && !(level == IS_LEVEL_1
+ && adj->sys_type == ISIS_SYSTYPE_L2_IS
+ && adj->adj_usage == ISIS_ADJ_LEVEL1AND2)
+ && !(level == IS_LEVEL_2
+ && adj->sys_type == ISIS_SYSTYPE_L2_IS)) {
+ lsp_debug(
+ "ISIS (%s): Ignoring neighbor %s, level does not match",
+ area->area_tag, sysid_print(adj->sysid));
+ continue;
+ }
+ memcpy(ne_id, adj->sysid, ISIS_SYS_ID_LEN);
+ if (circuit->area->oldmetric) {
+ isis_tlvs_add_oldstyle_reach(lsp->tlvs, ne_id, 0);
+ lsp_debug(
+ "ISIS (%s): Adding %s.%02x as old-style neighbor (peer)",
+ area->area_tag, sysid_print(ne_id),
+ LSP_PSEUDO_ID(ne_id));
+ }
+ if (circuit->area->newmetric) {
+ isis_tlvs_add_extended_reach(lsp->tlvs,
+ ISIS_MT_IPV4_UNICAST,
+ ne_id, 0, NULL, 0);
+ lsp_debug(
+ "ISIS (%s): Adding %s.%02x as te-style neighbor (peer)",
+ area->area_tag, sysid_print(ne_id),
+ LSP_PSEUDO_ID(ne_id));
+ }
+ }
+ list_delete(adj_list);
return;
}
@@ -2486,7 +1525,7 @@ int lsp_generate_pseudo(struct isis_circuit *circuit, int level)
lsp->area = circuit->area;
lsp_build_pseudo(lsp, circuit, level);
-
+ lsp_pack_pdu(lsp);
lsp->own_lsp = 1;
lsp_insert(lsp, lspdb);
lsp_set_all_srmflags(lsp);
@@ -2505,14 +1544,13 @@ int lsp_generate_pseudo(struct isis_circuit *circuit, int level)
if (isis->debugs & DEBUG_UPDATE_PACKETS) {
zlog_debug(
- "ISIS-Upd (%s): Building L%d Pseudo LSP %s, len %d, "
- "seq 0x%08x, cksum 0x%04x, lifetime %us, refresh %us",
+ "ISIS-Upd (%s): Built L%d Pseudo LSP %s, len %" PRIu16
+ ", seq 0x%08" PRIx32 ", cksum 0x%04" PRIx16
+ ", lifetime %" PRIu16 "s, refresh %" PRIu16 "s",
circuit->area->area_tag, level,
- rawlspid_print(lsp->lsp_header->lsp_id),
- ntohl(lsp->lsp_header->pdu_len),
- ntohl(lsp->lsp_header->seq_num),
- ntohs(lsp->lsp_header->checksum),
- ntohs(lsp->lsp_header->rem_lifetime), refresh_time);
+ rawlspid_print(lsp->hdr.lsp_id), lsp->hdr.pdu_len,
+ lsp->hdr.seqno, lsp->hdr.checksum,
+ lsp->hdr.rem_lifetime, refresh_time);
}
return ISIS_OK;
@@ -2542,16 +1580,11 @@ static int lsp_regenerate_pseudo(struct isis_circuit *circuit, int level)
rawlspid_print(lsp_id));
return ISIS_ERROR;
}
- lsp_clear_data(lsp);
- lsp_build_pseudo(lsp, circuit, level);
-
- /* RFC3787 section 4 SHOULD not set overload bit in pseudo LSPs */
- lsp->lsp_header->lsp_bits =
- lsp_bits_generate(level, 0, circuit->area->attached_bit);
rem_lifetime = lsp_rem_lifetime(circuit->area, level);
- lsp->lsp_header->rem_lifetime = htons(rem_lifetime);
- lsp_inc_seqnum(lsp, 0);
+ lsp->hdr.rem_lifetime = rem_lifetime;
+ lsp_build_pseudo(lsp, circuit, level);
+ lsp_inc_seqno(lsp, 0);
lsp->last_generated = time(NULL);
lsp_set_all_srmflags(lsp);
@@ -2567,14 +1600,13 @@ static int lsp_regenerate_pseudo(struct isis_circuit *circuit, int level)
if (isis->debugs & DEBUG_UPDATE_PACKETS) {
zlog_debug(
- "ISIS-Upd (%s): Refreshing L%d Pseudo LSP %s, len %d, "
- "seq 0x%08x, cksum 0x%04x, lifetime %us, refresh %us",
+ "ISIS-Upd (%s): Refreshed L%d Pseudo LSP %s, len %" PRIu16
+ ", seq 0x%08" PRIx32 ", cksum 0x%04" PRIx16
+ ", lifetime %" PRIu16 "s, refresh %" PRIu16 "s",
circuit->area->area_tag, level,
- rawlspid_print(lsp->lsp_header->lsp_id),
- ntohl(lsp->lsp_header->pdu_len),
- ntohl(lsp->lsp_header->seq_num),
- ntohs(lsp->lsp_header->checksum),
- ntohs(lsp->lsp_header->rem_lifetime), refresh_time);
+ rawlspid_print(lsp->hdr.lsp_id), lsp->hdr.pdu_len,
+ lsp->hdr.seqno, lsp->hdr.checksum,
+ lsp->hdr.rem_lifetime, refresh_time);
}
return ISIS_OK;
@@ -2771,8 +1803,7 @@ int lsp_tick(struct thread *thread)
* when
* the first time rem_lifetime becomes 0.
*/
- rem_lifetime =
- ntohs(lsp->lsp_header->rem_lifetime);
+ rem_lifetime = lsp->hdr.rem_lifetime;
lsp_set_time(lsp);
/*
@@ -2782,8 +1813,7 @@ int lsp_tick(struct thread *thread)
* time.
* ISO 10589 - 7.3.16.4 first paragraph.
*/
- if (rem_lifetime == 1
- && lsp->lsp_header->seq_num != 0) {
+ if (rem_lifetime == 1 && lsp->hdr.seqno != 0) {
/* 7.3.16.4 a) set SRM flags on all */
lsp_set_all_srmflags(lsp);
/* 7.3.16.4 b) retain only the header
@@ -2800,13 +1830,11 @@ int lsp_tick(struct thread *thread)
if (lsp->age_out == 0) {
zlog_debug(
- "ISIS-Upd (%s): L%u LSP %s seq 0x%08x aged out",
+ "ISIS-Upd (%s): L%u LSP %s seq "
+ "0x%08" PRIx32 " aged out",
area->area_tag, lsp->level,
- rawlspid_print(
- lsp->lsp_header
- ->lsp_id),
- ntohl(lsp->lsp_header
- ->seq_num));
+ rawlspid_print(lsp->hdr.lsp_id),
+ lsp->hdr.seqno);
lsp_destroy(lsp);
lsp = NULL;
dict_delete_free(area->lspdb[level],
@@ -2867,56 +1895,22 @@ int lsp_tick(struct thread *thread)
void lsp_purge_pseudo(u_char *id, struct isis_circuit *circuit, int level)
{
struct isis_lsp *lsp;
- u_int16_t seq_num;
- u_int8_t lsp_bits;
lsp = lsp_search(id, circuit->area->lspdb[level - 1]);
if (!lsp)
return;
- /* store old values */
- seq_num = lsp->lsp_header->seq_num;
- lsp_bits = lsp->lsp_header->lsp_bits;
-
- /* reset stream */
- lsp_clear_data(lsp);
- stream_reset(lsp->pdu);
-
- /* update header */
- lsp->lsp_header->pdu_len = htons(ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN);
- memcpy(lsp->lsp_header->lsp_id, id, ISIS_SYS_ID_LEN + 2);
- lsp->lsp_header->checksum = 0;
- lsp->lsp_header->seq_num = seq_num;
- lsp->lsp_header->rem_lifetime = 0;
- lsp->lsp_header->lsp_bits = lsp_bits;
- lsp->level = level;
- lsp->age_out = lsp->area->max_lsp_lifetime[level - 1];
- stream_forward_endp(lsp->pdu, ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN);
-
- /*
- * Add and update the authentication info if its present
- */
- lsp_auth_add(lsp);
- lsp->lsp_header->pdu_len = htons(stream_get_endp(lsp->pdu));
- lsp_auth_update(lsp);
- fletcher_checksum(STREAM_DATA(lsp->pdu) + 12,
- ntohs(lsp->lsp_header->pdu_len) - 12, 12);
-
- lsp_set_all_srmflags(lsp);
-
- return;
+ lsp_purge(lsp, level);
}
/*
* Purge own LSP that is received and we don't have.
* -> Do as in 7.3.16.4
*/
-void lsp_purge_non_exist(int level, struct isis_link_state_hdr *lsp_hdr,
+void lsp_purge_non_exist(int level, struct isis_lsp_hdr *hdr,
struct isis_area *area)
{
struct isis_lsp *lsp;
- uint8_t pdu_type =
- (level == IS_LEVEL_1) ? L1_LINK_STATE : L2_LINK_STATE;
/*
* We need to create the LSP to be purged
@@ -2925,37 +1919,14 @@ void lsp_purge_non_exist(int level, struct isis_link_state_hdr *lsp_hdr,
lsp->area = area;
lsp->level = level;
lsp->pdu = stream_new(LLC_LEN + area->lsp_mtu);
- fill_fixed_hdr(pdu_type, lsp->pdu);
-
- lsp->lsp_header = (struct isis_link_state_hdr *)(STREAM_DATA(lsp->pdu)
- + ISIS_FIXED_HDR_LEN);
- memcpy(lsp->lsp_header, lsp_hdr, ISIS_LSP_HDR_LEN);
- stream_forward_endp(lsp->pdu, ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN);
-
- /*
- * Set the remaining lifetime to 0
- */
- lsp->lsp_header->rem_lifetime = 0;
+ lsp->age_out = ZERO_AGE_LIFETIME;
- /*
- * Add and update the authentication info if its present
- */
- lsp_auth_add(lsp);
- lsp_auth_update(lsp);
+ memcpy(&lsp->hdr, hdr, sizeof(lsp->hdr));
+ lsp->hdr.rem_lifetime = 0;
- /*
- * Update the PDU length to header plus any authentication TLV.
- */
- lsp->lsp_header->pdu_len = htons(stream_get_endp(lsp->pdu));
+ lsp_pack_pdu(lsp);
- /*
- * Put the lsp into LSPdb
- */
lsp_insert(lsp, area->lspdb[lsp->level - 1]);
-
- /*
- * Send in to whole area
- */
lsp_set_all_srmflags(lsp);
return;
diff --git a/isisd/isis_lsp.h b/isisd/isis_lsp.h
index 429cd1942..8b62ed551 100644
--- a/isisd/isis_lsp.h
+++ b/isisd/isis_lsp.h
@@ -24,18 +24,19 @@
#ifndef _ZEBRA_ISIS_LSP_H
#define _ZEBRA_ISIS_LSP_H
+#include "isisd/isis_pdu.h"
+
/* Structure for isis_lsp, this structure will only support the fixed
* System ID (Currently 6) (atleast for now). In order to support more
* We will have to split the header into two parts, and for readability
* sake it should better be avoided */
struct isis_lsp {
- struct isis_link_state_hdr *lsp_header; /* pdu + isis_header_len */
- struct stream *pdu; /* full pdu lsp */
+ struct isis_lsp_hdr hdr;
+ struct stream *pdu; /* full pdu lsp */
union {
struct list *frags;
struct isis_lsp *zero_lsp;
} lspu;
- u_int32_t auth_tlv_offset; /* authentication TLV position in the pdu */
u_int32_t SRMflags[ISIS_MAX_CIRCUITS];
u_int32_t SSNflags[ISIS_MAX_CIRCUITS];
int level; /* L1 or L2? */
@@ -46,7 +47,7 @@ struct isis_lsp {
/* used for 60 second counting when rem_lifetime is zero */
int age_out;
struct isis_area *area;
- struct tlvs tlv_data; /* Simplifies TLV access */
+ struct isis_tlvs *tlvs;
};
dict_t *lsp_db_init(void);
@@ -58,13 +59,13 @@ int lsp_regenerate_schedule(struct isis_area *area, int level, int all_pseudo);
int lsp_generate_pseudo(struct isis_circuit *circuit, int level);
int lsp_regenerate_schedule_pseudo(struct isis_circuit *circuit, int level);
-struct isis_lsp *lsp_new(struct isis_area *area, u_char *lsp_id,
- u_int16_t rem_lifetime, u_int32_t seq_num,
- u_int8_t lsp_bits, u_int16_t checksum, int level);
-struct isis_lsp *lsp_new_from_stream_ptr(struct stream *stream,
- u_int16_t pdu_len,
- struct isis_lsp *lsp0,
- struct isis_area *area, int level);
+struct isis_lsp *lsp_new(struct isis_area *area, uint8_t *lsp_id,
+ uint16_t rem_lifetime, uint32_t seq_num,
+ uint8_t lsp_bits, uint16_t checksum, int level);
+struct isis_lsp *lsp_new_from_recv(struct isis_lsp_hdr *hdr,
+ struct isis_tlvs *tlvs,
+ struct stream *stream, struct isis_lsp *lsp0,
+ struct isis_area *area, int level);
void lsp_insert(struct isis_lsp *lsp, dict_t *lspdb);
struct isis_lsp *lsp_search(u_char *id, dict_t *lspdb);
@@ -74,7 +75,7 @@ void lsp_build_list_nonzero_ht(u_char *start_id, u_char *stop_id,
struct list *list, dict_t *lspdb);
void lsp_search_and_destroy(u_char *id, dict_t *lspdb);
void lsp_purge_pseudo(u_char *id, struct isis_circuit *circuit, int level);
-void lsp_purge_non_exist(int level, struct isis_link_state_hdr *lsp_hdr,
+void lsp_purge_non_exist(int level, struct isis_lsp_hdr *hdr,
struct isis_area *area);
#define LSP_EQUAL 1
@@ -88,16 +89,15 @@ void lsp_purge_non_exist(int level, struct isis_link_state_hdr *lsp_hdr,
(I)[ISIS_SYS_ID_LEN] = 0; \
(I)[ISIS_SYS_ID_LEN + 1] = 0
int lsp_id_cmp(u_char *id1, u_char *id2);
-int lsp_compare(char *areatag, struct isis_lsp *lsp, u_int32_t seq_num,
- u_int16_t checksum, u_int16_t rem_lifetime);
-void lsp_update(struct isis_lsp *lsp, struct stream *stream,
+int lsp_compare(char *areatag, struct isis_lsp *lsp, uint32_t seqno,
+ uint16_t checksum, uint16_t rem_lifetime);
+void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr,
+ struct isis_tlvs *tlvs, struct stream *stream,
struct isis_area *area, int level);
-void lsp_inc_seqnum(struct isis_lsp *lsp, u_int32_t seq_num);
+void lsp_inc_seqno(struct isis_lsp *lsp, uint32_t seqno);
void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost);
void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty, char dynhost);
int lsp_print_all(struct vty *vty, dict_t *lspdb, char detail, char dynhost);
-const char *lsp_bits2string(u_char *);
-
/* sets SRMflags for all active circuits of an lsp */
void lsp_set_all_srmflags(struct isis_lsp *lsp);
diff --git a/isisd/isis_main.c b/isisd/isis_main.c
index 463e3abcf..40ceb99fb 100644
--- a/isisd/isis_main.c
+++ b/isisd/isis_main.c
@@ -52,7 +52,6 @@
#include "isisd/isis_route.h"
#include "isisd/isis_routemap.h"
#include "isisd/isis_zebra.h"
-#include "isisd/isis_tlv.h"
#include "isisd/isis_te.h"
/* Default configuration file name */
diff --git a/isisd/isis_misc.c b/isisd/isis_misc.c
index cf6558c13..4d7b4c381 100644
--- a/isisd/isis_misc.c
+++ b/isisd/isis_misc.c
@@ -39,7 +39,6 @@
#include "isisd/isisd.h"
#include "isisd/isis_misc.h"
-#include "isisd/isis_tlv.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_adjacency.h"
@@ -216,25 +215,6 @@ char *nlpid2string(struct nlpids *nlpids)
}
/*
- * supports the given af ?
- */
-int speaks(struct nlpids *nlpids, int family)
-{
- int i, speaks = 0;
-
- if (nlpids == (struct nlpids *)NULL)
- return speaks;
- for (i = 0; i < nlpids->count; i++) {
- if (family == AF_INET && nlpids->nlpids[i] == NLPID_IP)
- speaks = 1;
- if (family == AF_INET6 && nlpids->nlpids[i] == NLPID_IPV6)
- speaks = 1;
- }
-
- return speaks;
-}
-
-/*
* Returns 0 on error, IS-IS Circuit Type on ok
*/
int string2circuit_t(const char *str)
@@ -486,7 +466,7 @@ const char *print_sys_hostname(const u_char *sysid)
dyn = dynhn_find_by_id(sysid);
if (dyn)
- return (const char *)dyn->name.name;
+ return dyn->hostname;
return sysid_print(sysid);
}
diff --git a/isisd/isis_misc.h b/isisd/isis_misc.h
index 0ff33f831..7de534ec7 100644
--- a/isisd/isis_misc.h
+++ b/isisd/isis_misc.h
@@ -55,7 +55,6 @@ void zlog_dump_data(void *data, int len);
/*
* misc functions
*/
-int speaks(struct nlpids *nlpids, int family);
unsigned long isis_jitter(unsigned long timer, unsigned long jitter);
const char *unix_hostname(void);
diff --git a/isisd/isis_mt.c b/isisd/isis_mt.c
index ff0b95487..e1ff81e23 100644
--- a/isisd/isis_mt.c
+++ b/isisd/isis_mt.c
@@ -24,7 +24,6 @@
#include "isisd/isis_memory.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_adjacency.h"
-#include "isisd/isis_tlv.h"
#include "isisd/isis_misc.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_mt.h"
@@ -33,11 +32,6 @@
DEFINE_MTYPE_STATIC(ISISD, MT_AREA_SETTING, "ISIS MT Area Setting")
DEFINE_MTYPE_STATIC(ISISD, MT_CIRCUIT_SETTING, "ISIS MT Circuit Setting")
DEFINE_MTYPE_STATIC(ISISD, MT_ADJ_INFO, "ISIS MT Adjacency Info")
-DEFINE_MTYPE_STATIC(ISISD, MT_NEIGHBORS, "ISIS MT Neighbors for TLV")
-DEFINE_MTYPE_STATIC(ISISD, MT_IPV4_REACHS,
- "ISIS MT IPv4 Reachabilities for TLV")
-DEFINE_MTYPE_STATIC(ISISD, MT_IPV6_REACHS,
- "ISIS MT IPv6 Reachabilities for TLV")
uint16_t isis_area_ipv6_topology(struct isis_area *area)
{
@@ -389,7 +383,8 @@ bool tlvs_to_adj_mt_set(struct isis_tlvs *tlvs, bool v4_usable, bool v6_usable,
mt_settings = circuit_mt_settings(adj->circuit, &circuit_mt_count);
for (unsigned int i = 0; i < circuit_mt_count; i++) {
- if (tlvs->mt_router_info.count && !tlvs->mt_router_info_empty) {
+ if (!tlvs->mt_router_info.count
+ && !tlvs->mt_router_info_empty) {
/* Other end does not have MT enabled */
if (mt_settings[i]->mtid == ISIS_MT_IPV4_UNICAST
&& v4_usable)
@@ -459,153 +454,6 @@ void adj_mt_finish(struct isis_adjacency *adj)
adj->mt_count = 0;
}
-/* TLV Router info api */
-struct mt_router_info *tlvs_lookup_mt_router_info(struct tlvs *tlvs,
- uint16_t mtid)
-{
- return lookup_mt_setting(tlvs->mt_router_info, mtid);
-}
-
-/* TLV MT Neighbors api */
-struct tlv_mt_neighbors *tlvs_lookup_mt_neighbors(struct tlvs *tlvs,
- uint16_t mtid)
-{
- return lookup_mt_setting(tlvs->mt_is_neighs, mtid);
-}
-
-static struct tlv_mt_neighbors *tlvs_new_mt_neighbors(uint16_t mtid)
-{
- struct tlv_mt_neighbors *rv;
-
- rv = XCALLOC(MTYPE_MT_NEIGHBORS, sizeof(*rv));
- rv->mtid = mtid;
- rv->list = list_new();
-
- return rv;
-};
-
-static void tlvs_free_mt_neighbors(void *arg)
-{
- struct tlv_mt_neighbors *neighbors = arg;
-
- if (neighbors && neighbors->list)
- list_delete(neighbors->list);
- XFREE(MTYPE_MT_NEIGHBORS, neighbors);
-}
-
-static void tlvs_add_mt_neighbors(struct tlvs *tlvs,
- struct tlv_mt_neighbors *neighbors)
-{
- add_mt_setting(&tlvs->mt_is_neighs, neighbors);
- tlvs->mt_is_neighs->del = tlvs_free_mt_neighbors;
-}
-
-struct tlv_mt_neighbors *tlvs_get_mt_neighbors(struct tlvs *tlvs, uint16_t mtid)
-{
- struct tlv_mt_neighbors *neighbors;
-
- neighbors = tlvs_lookup_mt_neighbors(tlvs, mtid);
- if (!neighbors) {
- neighbors = tlvs_new_mt_neighbors(mtid);
- tlvs_add_mt_neighbors(tlvs, neighbors);
- }
- return neighbors;
-}
-
-/* TLV MT IPv4 reach api */
-struct tlv_mt_ipv4_reachs *tlvs_lookup_mt_ipv4_reachs(struct tlvs *tlvs,
- uint16_t mtid)
-{
- return lookup_mt_setting(tlvs->mt_ipv4_reachs, mtid);
-}
-
-static struct tlv_mt_ipv4_reachs *tlvs_new_mt_ipv4_reachs(uint16_t mtid)
-{
- struct tlv_mt_ipv4_reachs *rv;
-
- rv = XCALLOC(MTYPE_MT_IPV4_REACHS, sizeof(*rv));
- rv->mtid = mtid;
- rv->list = list_new();
-
- return rv;
-};
-
-static void tlvs_free_mt_ipv4_reachs(void *arg)
-{
- struct tlv_mt_ipv4_reachs *reachs = arg;
-
- if (reachs && reachs->list)
- list_delete(reachs->list);
- XFREE(MTYPE_MT_IPV4_REACHS, reachs);
-}
-
-static void tlvs_add_mt_ipv4_reachs(struct tlvs *tlvs,
- struct tlv_mt_ipv4_reachs *reachs)
-{
- add_mt_setting(&tlvs->mt_ipv4_reachs, reachs);
- tlvs->mt_ipv4_reachs->del = tlvs_free_mt_ipv4_reachs;
-}
-
-struct tlv_mt_ipv4_reachs *tlvs_get_mt_ipv4_reachs(struct tlvs *tlvs,
- uint16_t mtid)
-{
- struct tlv_mt_ipv4_reachs *reachs;
-
- reachs = tlvs_lookup_mt_ipv4_reachs(tlvs, mtid);
- if (!reachs) {
- reachs = tlvs_new_mt_ipv4_reachs(mtid);
- tlvs_add_mt_ipv4_reachs(tlvs, reachs);
- }
- return reachs;
-}
-
-/* TLV MT IPv6 reach api */
-struct tlv_mt_ipv6_reachs *tlvs_lookup_mt_ipv6_reachs(struct tlvs *tlvs,
- uint16_t mtid)
-{
- return lookup_mt_setting(tlvs->mt_ipv6_reachs, mtid);
-}
-
-static struct tlv_mt_ipv6_reachs *tlvs_new_mt_ipv6_reachs(uint16_t mtid)
-{
- struct tlv_mt_ipv6_reachs *rv;
-
- rv = XCALLOC(MTYPE_MT_IPV6_REACHS, sizeof(*rv));
- rv->mtid = mtid;
- rv->list = list_new();
-
- return rv;
-};
-
-static void tlvs_free_mt_ipv6_reachs(void *arg)
-{
- struct tlv_mt_ipv6_reachs *reachs = arg;
-
- if (reachs && reachs->list)
- list_delete(reachs->list);
- XFREE(MTYPE_MT_IPV6_REACHS, reachs);
-}
-
-static void tlvs_add_mt_ipv6_reachs(struct tlvs *tlvs,
- struct tlv_mt_ipv6_reachs *reachs)
-{
- add_mt_setting(&tlvs->mt_ipv6_reachs, reachs);
- tlvs->mt_ipv6_reachs->del = tlvs_free_mt_ipv6_reachs;
-}
-
-struct tlv_mt_ipv6_reachs *tlvs_get_mt_ipv6_reachs(struct tlvs *tlvs,
- uint16_t mtid)
-{
- struct tlv_mt_ipv6_reachs *reachs;
-
- reachs = tlvs_lookup_mt_ipv6_reachs(tlvs, mtid);
- if (!reachs) {
- reachs = tlvs_new_mt_ipv6_reachs(mtid);
- tlvs_add_mt_ipv6_reachs(tlvs, reachs);
- }
- return reachs;
-}
-
static void mt_set_add(uint16_t **mt_set, unsigned int *size,
unsigned int *index, uint16_t mtid)
{
@@ -650,51 +498,46 @@ static uint16_t *circuit_bcast_mt_set(struct isis_circuit *circuit, int level,
return rv;
}
-static void tlvs_add_mt_set(struct isis_area *area, struct tlvs *tlvs,
+static void tlvs_add_mt_set(struct isis_area *area, struct isis_tlvs *tlvs,
unsigned int mt_count, uint16_t *mt_set,
- struct te_is_neigh *neigh)
+ uint8_t *id, uint32_t metric, uint8_t *subtlvs,
+ uint8_t subtlv_len)
{
for (unsigned int i = 0; i < mt_count; i++) {
uint16_t mtid = mt_set[i];
- struct te_is_neigh *ne_copy;
-
- ne_copy = XCALLOC(MTYPE_ISIS_TLV, sizeof(*ne_copy));
- memcpy(ne_copy, neigh, sizeof(*ne_copy));
-
if (mt_set[i] == ISIS_MT_IPV4_UNICAST) {
- listnode_add(tlvs->te_is_neighs, ne_copy);
lsp_debug(
"ISIS (%s): Adding %s.%02x as te-style neighbor",
- area->area_tag, sysid_print(ne_copy->neigh_id),
- LSP_PSEUDO_ID(ne_copy->neigh_id));
+ area->area_tag, sysid_print(id),
+ LSP_PSEUDO_ID(id));
} else {
- struct tlv_mt_neighbors *neighbors;
-
- neighbors = tlvs_get_mt_neighbors(tlvs, mtid);
- neighbors->list->del = free_tlv;
- listnode_add(neighbors->list, ne_copy);
lsp_debug(
"ISIS (%s): Adding %s.%02x as mt-style neighbor for %s",
- area->area_tag, sysid_print(ne_copy->neigh_id),
- LSP_PSEUDO_ID(ne_copy->neigh_id),
- isis_mtid2str(mtid));
+ area->area_tag, sysid_print(id),
+ LSP_PSEUDO_ID(id), isis_mtid2str(mtid));
}
+ isis_tlvs_add_extended_reach(tlvs, mtid, id, metric, subtlvs,
+ subtlv_len);
}
}
-void tlvs_add_mt_bcast(struct tlvs *tlvs, struct isis_circuit *circuit,
- int level, struct te_is_neigh *neigh)
+void tlvs_add_mt_bcast(struct isis_tlvs *tlvs, struct isis_circuit *circuit,
+ int level, uint8_t *id, uint32_t metric,
+ uint8_t *subtlvs, uint8_t subtlv_len)
{
unsigned int mt_count;
uint16_t *mt_set = circuit_bcast_mt_set(circuit, level, &mt_count);
- tlvs_add_mt_set(circuit->area, tlvs, mt_count, mt_set, neigh);
+ tlvs_add_mt_set(circuit->area, tlvs, mt_count, mt_set, id, metric,
+ subtlvs, subtlv_len);
}
-void tlvs_add_mt_p2p(struct tlvs *tlvs, struct isis_circuit *circuit,
- struct te_is_neigh *neigh)
+void tlvs_add_mt_p2p(struct isis_tlvs *tlvs, struct isis_circuit *circuit,
+ uint8_t *id, uint32_t metric, uint8_t *subtlvs,
+ uint8_t subtlv_len)
{
struct isis_adjacency *adj = circuit->u.p2p.neighbor;
- tlvs_add_mt_set(circuit->area, tlvs, adj->mt_count, adj->mt_set, neigh);
+ tlvs_add_mt_set(circuit->area, tlvs, adj->mt_count, adj->mt_set, id,
+ metric, subtlvs, subtlv_len);
}
diff --git a/isisd/isis_mt.h b/isisd/isis_mt.h
index 496da8558..95aa99dba 100644
--- a/isisd/isis_mt.h
+++ b/isisd/isis_mt.h
@@ -65,21 +65,6 @@ struct isis_circuit_mt_setting {
bool enabled;
};
-struct tlv_mt_neighbors {
- ISIS_MT_INFO_FIELDS
- struct list *list;
-};
-
-struct tlv_mt_ipv4_reachs {
- ISIS_MT_INFO_FIELDS
- struct list *list;
-};
-
-struct tlv_mt_ipv6_reachs {
- ISIS_MT_INFO_FIELDS
- struct list *list;
-};
-
const char *isis_mtid2str(uint16_t mtid);
uint16_t isis_str2mtid(const char *name);
@@ -92,24 +77,6 @@ struct isis_tlvs;
uint16_t isis_area_ipv6_topology(struct isis_area *area);
-struct mt_router_info *tlvs_lookup_mt_router_info(struct tlvs *tlvs,
- uint16_t mtid);
-
-struct tlv_mt_neighbors *tlvs_lookup_mt_neighbors(struct tlvs *tlvs,
- uint16_t mtid);
-struct tlv_mt_neighbors *tlvs_get_mt_neighbors(struct tlvs *tlvs,
- uint16_t mtid);
-
-struct tlv_mt_ipv4_reachs *tlvs_lookup_mt_ipv4_reachs(struct tlvs *tlvs,
- uint16_t mtid);
-struct tlv_mt_ipv4_reachs *tlvs_get_mt_ipv4_reachs(struct tlvs *tlvs,
- uint16_t mtid);
-
-struct tlv_mt_ipv6_reachs *tlvs_lookup_mt_ipv6_reachs(struct tlvs *tlvs,
- uint16_t mtid);
-struct tlv_mt_ipv6_reachs *tlvs_get_mt_ipv6_reachs(struct tlvs *tlvs,
- uint16_t mtid);
-
struct isis_area_mt_setting *area_lookup_mt_setting(struct isis_area *area,
uint16_t mtid);
struct isis_area_mt_setting *area_new_mt_setting(struct isis_area *area,
@@ -143,8 +110,10 @@ bool tlvs_to_adj_mt_set(struct isis_tlvs *tlvs, bool v4_usable, bool v6_usable,
struct isis_adjacency *adj);
bool adj_has_mt(struct isis_adjacency *adj, uint16_t mtid);
void adj_mt_finish(struct isis_adjacency *adj);
-void tlvs_add_mt_bcast(struct tlvs *tlvs, struct isis_circuit *circuit,
- int level, struct te_is_neigh *neigh);
-void tlvs_add_mt_p2p(struct tlvs *tlvs, struct isis_circuit *circuit,
- struct te_is_neigh *neigh);
+void tlvs_add_mt_bcast(struct isis_tlvs *tlvs, struct isis_circuit *circuit,
+ int level, uint8_t *id, uint32_t metric,
+ uint8_t *subtlvs, uint8_t subtlv_len);
+void tlvs_add_mt_p2p(struct isis_tlvs *tlvs, struct isis_circuit *circuit,
+ uint8_t *id, uint32_t metric, uint8_t *subtlvs,
+ uint8_t subtlv_len);
#endif
diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c
index 5ab5a1e99..aee2cf381 100644
--- a/isisd/isis_pdu.c
+++ b/isisd/isis_pdu.c
@@ -44,7 +44,6 @@
#include "isisd/isis_network.h"
#include "isisd/isis_misc.h"
#include "isisd/isis_dr.h"
-#include "isisd/isis_tlv.h"
#include "isisd/isisd.h"
#include "isisd/isis_dynhn.h"
#include "isisd/isis_lsp.h"
@@ -56,135 +55,40 @@
#include "isisd/isis_mt.h"
#include "isisd/isis_tlvs2.h"
-#define ISIS_MINIMUM_FIXED_HDR_LEN 15
-#define ISIS_MIN_PDU_LEN 13 /* partial seqnum pdu with id_len=2 */
-
-#ifndef PNBBY
-#define PNBBY 8
-#endif /* PNBBY */
-
-/*
- * HELPER FUNCS
- */
-
-/*
- * Checks whether we should accept a PDU of given level
- */
-static int accept_level(int level, int circuit_t)
-{
- int retval = ((circuit_t & level) == level); /* simple approach */
-
- return retval;
-}
-
-/*
- * Verify authentication information
- * Support cleartext and HMAC MD5 authentication
- */
-static int authentication_check(struct isis_passwd *remote,
- struct isis_passwd *local,
- struct stream *stream, uint32_t auth_tlv_offset)
+static int ack_lsp(struct isis_lsp_hdr *hdr, struct isis_circuit *circuit,
+ int level)
{
- unsigned char digest[ISIS_AUTH_MD5_SIZE];
-
- /* Auth fail () - passwd type mismatch */
- if (local->type != remote->type)
- return ISIS_ERROR;
-
- switch (local->type) {
- /* No authentication required */
- case ISIS_PASSWD_TYPE_UNUSED:
- break;
-
- /* Cleartext (ISO 10589) */
- case ISIS_PASSWD_TYPE_CLEARTXT:
- /* Auth fail () - passwd len mismatch */
- if (remote->len != local->len)
- return ISIS_ERROR;
- return memcmp(local->passwd, remote->passwd, local->len);
-
- /* HMAC MD5 (RFC 3567) */
- case ISIS_PASSWD_TYPE_HMAC_MD5:
- /* Auth fail () - passwd len mismatch */
- if (remote->len != ISIS_AUTH_MD5_SIZE)
- return ISIS_ERROR;
- /* Set the authentication value to 0 before the check */
- memset(STREAM_DATA(stream) + auth_tlv_offset + 3, 0,
- ISIS_AUTH_MD5_SIZE);
- /* Compute the digest */
- hmac_md5(STREAM_DATA(stream), stream_get_endp(stream),
- (unsigned char *)&(local->passwd), local->len,
- (unsigned char *)&digest);
- /* Copy back the authentication value after the check */
- memcpy(STREAM_DATA(stream) + auth_tlv_offset + 3,
- remote->passwd, ISIS_AUTH_MD5_SIZE);
- return memcmp(digest, remote->passwd, ISIS_AUTH_MD5_SIZE);
-
- default:
- zlog_err("Unsupported authentication type");
- return ISIS_ERROR;
- }
+ unsigned long lenp;
+ int retval;
+ u_int16_t length;
+ uint8_t pdu_type =
+ (level == IS_LEVEL_1) ? L1_PARTIAL_SEQ_NUM : L2_PARTIAL_SEQ_NUM;
- /* Authentication pass when no authentication is configured */
- return ISIS_OK;
-}
+ isis_circuit_stream(circuit, &circuit->snd_stream);
-static int lsp_authentication_check(struct stream *stream,
- struct isis_area *area, int level,
- struct isis_passwd *passwd)
-{
- struct isis_link_state_hdr *hdr;
- uint32_t expected = 0, found = 0, auth_tlv_offset = 0;
- uint16_t checksum, rem_lifetime, pdu_len;
- struct tlvs tlvs;
- int retval = ISIS_OK;
+ fill_fixed_hdr(pdu_type, circuit->snd_stream);
- hdr = (struct isis_link_state_hdr *)(STREAM_PNT(stream));
- pdu_len = ntohs(hdr->pdu_len);
- expected |= TLVFLAG_AUTH_INFO;
- auth_tlv_offset = stream_get_getp(stream) + ISIS_LSP_HDR_LEN;
- retval = parse_tlvs(area->area_tag,
- STREAM_PNT(stream) + ISIS_LSP_HDR_LEN,
- pdu_len - ISIS_FIXED_HDR_LEN - ISIS_LSP_HDR_LEN,
- &expected, &found, &tlvs, &auth_tlv_offset);
+ lenp = stream_get_endp(circuit->snd_stream);
+ stream_putw(circuit->snd_stream, 0); /* PDU length */
+ stream_put(circuit->snd_stream, isis->sysid, ISIS_SYS_ID_LEN);
+ stream_putc(circuit->snd_stream, circuit->idx);
+ stream_putc(circuit->snd_stream, 9); /* code */
+ stream_putc(circuit->snd_stream, 16); /* len */
- if (retval != ISIS_OK) {
- zlog_err(
- "ISIS-Upd (%s): Parse failed L%d LSP %s, seq 0x%08x, "
- "cksum 0x%04x, lifetime %us, len %u",
- area->area_tag, level, rawlspid_print(hdr->lsp_id),
- ntohl(hdr->seq_num), ntohs(hdr->checksum),
- ntohs(hdr->rem_lifetime), pdu_len);
- if ((isis->debugs & DEBUG_UPDATE_PACKETS)
- && (isis->debugs & DEBUG_PACKET_DUMP))
- zlog_dump_data(STREAM_DATA(stream),
- stream_get_endp(stream));
- return retval;
- }
-
- if (!(found & TLVFLAG_AUTH_INFO)) {
- zlog_err("No authentication tlv in LSP");
- return ISIS_ERROR;
- }
+ stream_putw(circuit->snd_stream, hdr->rem_lifetime);
+ stream_put(circuit->snd_stream, hdr->lsp_id, ISIS_SYS_ID_LEN + 2);
+ stream_putl(circuit->snd_stream, hdr->seqno);
+ stream_putw(circuit->snd_stream, hdr->checksum);
- if (tlvs.auth_info.type != ISIS_PASSWD_TYPE_CLEARTXT
- && tlvs.auth_info.type != ISIS_PASSWD_TYPE_HMAC_MD5) {
- zlog_err("Unknown authentication type in LSP");
- return ISIS_ERROR;
- }
+ length = (u_int16_t)stream_get_endp(circuit->snd_stream);
+ /* Update PDU length */
+ stream_putw_at(circuit->snd_stream, lenp, length);
- /*
- * RFC 5304 set checksum and remaining lifetime to zero before
- * verification and reset to old values after verification.
- */
- checksum = hdr->checksum;
- rem_lifetime = hdr->rem_lifetime;
- hdr->checksum = 0;
- hdr->rem_lifetime = 0;
- retval = authentication_check(&tlvs.auth_info, passwd, stream,
- auth_tlv_offset);
- hdr->checksum = checksum;
- hdr->rem_lifetime = rem_lifetime;
+ retval = circuit->tx(circuit, level);
+ if (retval != ISIS_OK)
+ zlog_err("ISIS-Upd (%s): Send L%d LSP PSNP on %s failed",
+ circuit->area->area_tag, level,
+ circuit->interface->name);
return retval;
}
@@ -670,7 +574,7 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
return ISIS_WARNING;
}
- if (!accept_level(level, circuit->is_type)) {
+ if (!(circuit->is_type & level)) {
if (isis->debugs & DEBUG_ADJ_PACKETS) {
zlog_debug(
"ISIS-Adj (%s): Interface level mismatch, %s",
@@ -731,7 +635,7 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
}
if (!isis_tlvs_auth_is_valid(iih.tlvs, &circuit->passwd,
- circuit->rcv_stream)) {
+ circuit->rcv_stream, false)) {
isis_event_auth_failure(circuit->area->area_tag,
"IIH authentication failure",
iih.sys_id);
@@ -780,17 +684,10 @@ out:
* ISO - 10589
* Section 7.3.15.1 - Action on receipt of a link state PDU
*/
-static int process_lsp(int level, struct isis_circuit *circuit,
+static int process_lsp(uint8_t pdu_type, struct isis_circuit *circuit,
const u_char *ssnpa)
{
- struct isis_link_state_hdr *hdr;
- struct isis_adjacency *adj = NULL;
- struct isis_lsp *lsp, *lsp0 = NULL;
- int retval = ISIS_OK, comp = 0;
- u_char lspid[ISIS_SYS_ID_LEN + 2];
- struct isis_passwd *passwd;
- uint16_t pdu_len;
- int lsp_confusion;
+ int level = (pdu_type == L1_LINK_STATE) ? ISIS_LEVEL1 : ISIS_LEVEL2;
if (isis->debugs & DEBUG_UPDATE_PACKETS) {
zlog_debug(
@@ -804,65 +701,50 @@ static int process_lsp(int level, struct isis_circuit *circuit,
stream_get_endp(circuit->rcv_stream));
}
- if ((stream_get_endp(circuit->rcv_stream)
- - stream_get_getp(circuit->rcv_stream))
- < ISIS_LSP_HDR_LEN) {
- zlog_warn("Packet too short");
- return ISIS_WARNING;
- }
-
- /* Reference the header */
- hdr = (struct isis_link_state_hdr *)STREAM_PNT(circuit->rcv_stream);
- pdu_len = ntohs(hdr->pdu_len);
+ struct isis_lsp_hdr hdr = {};
- /* lsp length check */
- if (pdu_len < (ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN)
- || pdu_len > ISO_MTU(circuit)
- || pdu_len > stream_get_endp(circuit->rcv_stream)) {
- zlog_debug("ISIS-Upd (%s): LSP %s invalid LSP length %d",
- circuit->area->area_tag, rawlspid_print(hdr->lsp_id),
- pdu_len);
+ hdr.pdu_len = stream_getw(circuit->rcv_stream);
+ hdr.rem_lifetime = stream_getw(circuit->rcv_stream);
+ stream_get(hdr.lsp_id, circuit->rcv_stream, sizeof(hdr.lsp_id));
+ hdr.seqno = stream_getl(circuit->rcv_stream);
+ hdr.checksum = stream_getw(circuit->rcv_stream);
+ hdr.lsp_bits = stream_getc(circuit->rcv_stream);
+ if (pdu_len_validate(hdr.pdu_len, circuit)) {
+ zlog_debug("ISIS-Upd (%s): LSP %s invalid LSP length %" PRIu16,
+ circuit->area->area_tag, rawlspid_print(hdr.lsp_id),
+ hdr.pdu_len);
return ISIS_WARNING;
}
- /*
- * Set the stream endp to PDU length, ignoring additional padding
- * introduced by transport chips.
- */
- if (pdu_len < stream_get_endp(circuit->rcv_stream))
- stream_set_endp(circuit->rcv_stream, pdu_len);
-
if (isis->debugs & DEBUG_UPDATE_PACKETS) {
- zlog_debug(
- "ISIS-Upd (%s): Rcvd L%d LSP %s, seq 0x%08x, cksum 0x%04x, "
- "lifetime %us, len %u, on %s",
- circuit->area->area_tag, level,
- rawlspid_print(hdr->lsp_id), ntohl(hdr->seq_num),
- ntohs(hdr->checksum), ntohs(hdr->rem_lifetime), pdu_len,
- circuit->interface->name);
+ zlog_debug("ISIS-Upd (%s): Rcvd L%d LSP %s, seq 0x%08" PRIx32
+ ", cksum 0x%04" PRIx16 ", lifetime %" PRIu16
+ "s, len %" PRIu16 ", on %s",
+ circuit->area->area_tag, level,
+ rawlspid_print(hdr.lsp_id), hdr.seqno, hdr.checksum,
+ hdr.rem_lifetime, hdr.pdu_len,
+ circuit->interface->name);
}
/* lsp is_type check */
- if ((hdr->lsp_bits & IS_LEVEL_1_AND_2) != IS_LEVEL_1
- && (hdr->lsp_bits & IS_LEVEL_1_AND_2) != IS_LEVEL_1_AND_2) {
- zlog_debug("ISIS-Upd (%s): LSP %s invalid LSP is type %x",
- circuit->area->area_tag, rawlspid_print(hdr->lsp_id),
- hdr->lsp_bits);
+ if ((hdr.lsp_bits & IS_LEVEL_1) != IS_LEVEL_1) {
+ zlog_debug(
+ "ISIS-Upd (%s): LSP %s invalid LSP is type 0x%" PRIx8,
+ circuit->area->area_tag, rawlspid_print(hdr.lsp_id),
+ hdr.lsp_bits & IS_LEVEL_1_AND_2);
/* continue as per RFC1122 Be liberal in what you accept, and
* conservative in what you send */
}
/* Checksum sanity check - FIXME: move to correct place */
/* 12 = sysid+pdu+remtime */
- if (iso_csum_verify(STREAM_PNT(circuit->rcv_stream) + 4, pdu_len - 12,
- hdr->checksum,
- offsetof(struct isis_link_state_hdr, checksum)
- - 4)) {
- zlog_debug("ISIS-Upd (%s): LSP %s invalid LSP checksum 0x%04x",
- circuit->area->area_tag, rawlspid_print(hdr->lsp_id),
- ntohs(hdr->checksum));
-
+ if (iso_csum_verify(STREAM_DATA(circuit->rcv_stream) + 12,
+ hdr.pdu_len - 12, hdr.checksum, 12)) {
+ zlog_debug(
+ "ISIS-Upd (%s): LSP %s invalid LSP checksum 0x%04" PRIx16,
+ circuit->area->area_tag, rawlspid_print(hdr.lsp_id),
+ hdr.checksum);
return ISIS_WARNING;
}
@@ -871,47 +753,56 @@ static int process_lsp(int level, struct isis_circuit *circuit,
zlog_debug(
"ISIS-Upd (%s): LSP %s received at level %d over circuit with "
"externalDomain = true",
- circuit->area->area_tag, rawlspid_print(hdr->lsp_id),
+ circuit->area->area_tag, rawlspid_print(hdr.lsp_id),
level);
-
return ISIS_WARNING;
}
/* 7.3.15.1 a) 2,3 - manualL2OnlyMode not implemented */
- if (!accept_level(level, circuit->is_type)) {
+ if (!(circuit->is_type & level)) {
zlog_debug(
"ISIS-Upd (%s): LSP %s received at level %d over circuit of"
" type %s",
- circuit->area->area_tag, rawlspid_print(hdr->lsp_id),
+ circuit->area->area_tag, rawlspid_print(hdr.lsp_id),
level, circuit_t2string(circuit->is_type));
-
return ISIS_WARNING;
}
+ struct isis_tlvs *tlvs = NULL;
+ int retval = ISIS_WARNING;
+ const char *error_log;
+
+ if (isis_unpack_tlvs(STREAM_READABLE(circuit->rcv_stream),
+ circuit->rcv_stream, &tlvs, &error_log)) {
+ zlog_warn("Something went wrong unpacking the LSP: %s",
+ error_log);
+ goto out;
+ }
+
/* 7.3.15.1 a) 4 - need to make sure IDLength matches */
/* 7.3.15.1 a) 5 - maximum area match, can be ommited since we only use
* 3 */
/* 7.3.15.1 a) 7 - password check */
- (level == IS_LEVEL_1) ? (passwd = &circuit->area->area_passwd)
- : (passwd = &circuit->area->domain_passwd);
- if (passwd->type) {
- if (lsp_authentication_check(circuit->rcv_stream, circuit->area,
- level, passwd)) {
- isis_event_auth_failure(circuit->area->area_tag,
- "LSP authentication failure",
- hdr->lsp_id);
- return ISIS_WARNING;
- }
+ struct isis_passwd *passwd = (level == ISIS_LEVEL1)
+ ? &circuit->area->area_passwd
+ : &circuit->area->domain_passwd;
+ if (!isis_tlvs_auth_is_valid(tlvs, passwd, circuit->rcv_stream, true)) {
+ isis_event_auth_failure(circuit->area->area_tag,
+ "LSP authentication failure",
+ hdr.lsp_id);
+ goto out;
}
+
/* Find the LSP in our database and compare it to this Link State header
*/
- lsp = lsp_search(hdr->lsp_id, circuit->area->lspdb[level - 1]);
+ struct isis_lsp *lsp =
+ lsp_search(hdr.lsp_id, circuit->area->lspdb[level - 1]);
+ int comp = 0;
if (lsp)
- comp = lsp_compare(circuit->area->area_tag, lsp,
- ntohl(hdr->seq_num), ntohs(hdr->checksum),
- ntohs(hdr->rem_lifetime));
+ comp = lsp_compare(circuit->area->area_tag, lsp, hdr.seqno,
+ hdr.checksum, hdr.rem_lifetime);
if (lsp && (lsp->own_lsp))
goto dontcheckadj;
@@ -920,25 +811,24 @@ static int process_lsp(int level, struct isis_circuit *circuit,
/* for broadcast circuits, snpa should be compared */
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
- adj = isis_adj_lookup_snpa(ssnpa,
- circuit->u.bc.adjdb[level - 1]);
- if (!adj) {
- zlog_debug(
- "(%s): DS ======= LSP %s, seq 0x%08x, cksum 0x%04x, "
- "lifetime %us on %s",
- circuit->area->area_tag,
- rawlspid_print(hdr->lsp_id),
- ntohl(hdr->seq_num), ntohs(hdr->checksum),
- ntohs(hdr->rem_lifetime),
- circuit->interface->name);
- return ISIS_WARNING; /* Silently discard */
+ if (!isis_adj_lookup_snpa(ssnpa,
+ circuit->u.bc.adjdb[level - 1])) {
+ zlog_debug("(%s): DS ======= LSP %s, seq 0x%08" PRIx32
+ ", cksum 0x%04" PRIx16 ", lifetime %" PRIu16
+ "s on %s",
+ circuit->area->area_tag,
+ rawlspid_print(hdr.lsp_id), hdr.seqno,
+ hdr.checksum, hdr.rem_lifetime,
+ circuit->interface->name);
+ goto out; /* Silently discard */
}
}
/* for non broadcast, we just need to find same level adj */
else {
/* If no adj, or no sharing of level */
if (!circuit->u.p2p.neighbor) {
- return ISIS_OK; /* Silently discard */
+ retval = ISIS_OK;
+ goto out;
} else {
if (((level == IS_LEVEL_1)
&& (circuit->u.p2p.neighbor->adj_usage
@@ -946,10 +836,12 @@ static int process_lsp(int level, struct isis_circuit *circuit,
|| ((level == IS_LEVEL_2)
&& (circuit->u.p2p.neighbor->adj_usage
== ISIS_ADJ_LEVEL1)))
- return ISIS_WARNING; /* Silently discard */
+ goto out;
}
}
+ bool lsp_confusion;
+
dontcheckadj:
/* 7.3.15.1 a) 7 - Passwords for level 1 - not implemented */
@@ -961,33 +853,35 @@ dontcheckadj:
/* 7.3.16.2 - If this is an LSP from another IS with identical seq_num
* but
* wrong checksum, initiate a purge. */
- if (lsp && (lsp->lsp_header->seq_num == hdr->seq_num)
- && (lsp->lsp_header->checksum != hdr->checksum)) {
- zlog_warn(
- "ISIS-Upd (%s): LSP %s seq 0x%08x with confused checksum received.",
- circuit->area->area_tag, rawlspid_print(hdr->lsp_id),
- ntohl(hdr->seq_num));
- hdr->rem_lifetime = 0;
- lsp_confusion = 1;
+ if (lsp && (lsp->hdr.seqno == hdr.seqno)
+ && (lsp->hdr.checksum != hdr.checksum)) {
+ zlog_warn("ISIS-Upd (%s): LSP %s seq 0x%08" PRIx32
+ " with confused checksum received.",
+ circuit->area->area_tag, rawlspid_print(hdr.lsp_id),
+ hdr.seqno);
+ hdr.rem_lifetime = 0;
+ lsp_confusion = true;
} else
- lsp_confusion = 0;
+ lsp_confusion = false;
/* 7.3.15.1 b) - If the remaining life time is 0, we perform 7.3.16.4 */
- if (hdr->rem_lifetime == 0) {
+ if (hdr.rem_lifetime == 0) {
if (!lsp) {
/* 7.3.16.4 a) 1) No LSP in db -> send an ack, but don't
* save */
/* only needed on explicit update, eg - p2p */
if (circuit->circ_type == CIRCUIT_T_P2P)
- ack_lsp(hdr, circuit, level);
- return retval; /* FIXME: do we need a purge? */
+ ack_lsp(&hdr, circuit, level);
+ goto out; /* FIXME: do we need a purge? */
} else {
- if (memcmp(hdr->lsp_id, isis->sysid, ISIS_SYS_ID_LEN)) {
+ if (memcmp(hdr.lsp_id, isis->sysid, ISIS_SYS_ID_LEN)) {
/* LSP by some other system -> do 7.3.16.4 b) */
/* 7.3.16.4 b) 1) */
if (comp == LSP_NEWER) {
- lsp_update(lsp, circuit->rcv_stream,
+ lsp_update(lsp, &hdr, tlvs,
+ circuit->rcv_stream,
circuit->area, level);
+ tlvs = NULL;
/* ii */
lsp_set_all_srmflags(lsp);
/* v */
@@ -1028,11 +922,10 @@ dontcheckadj:
ISIS_SET_FLAG(lsp->SRMflags, circuit);
ISIS_CLEAR_FLAG(lsp->SSNflags, circuit);
}
- } else if (lsp->lsp_header->rem_lifetime != 0) {
+ } else if (lsp->hdr.rem_lifetime != 0) {
/* our own LSP -> 7.3.16.4 c) */
if (comp == LSP_NEWER) {
- lsp_inc_seqnum(lsp,
- ntohl(hdr->seq_num));
+ lsp_inc_seqno(lsp, hdr.seqno);
lsp_set_all_srmflags(lsp);
} else {
ISIS_SET_FLAG(lsp->SRMflags, circuit);
@@ -1040,23 +933,22 @@ dontcheckadj:
}
if (isis->debugs & DEBUG_UPDATE_PACKETS)
zlog_debug(
- "ISIS-Upd (%s): (1) re-originating LSP %s new "
- "seq 0x%08x",
+ "ISIS-Upd (%s): (1) re-originating LSP %s new seq 0x%08" PRIx32,
circuit->area->area_tag,
- rawlspid_print(hdr->lsp_id),
- ntohl(lsp->lsp_header
- ->seq_num));
+ rawlspid_print(hdr.lsp_id),
+ lsp->hdr.seqno);
}
}
- return retval;
+ goto out;
}
/* 7.3.15.1 c) - If this is our own lsp and we don't have it initiate a
* purge */
- if (memcmp(hdr->lsp_id, isis->sysid, ISIS_SYS_ID_LEN) == 0) {
+ if (memcmp(hdr.lsp_id, isis->sysid, ISIS_SYS_ID_LEN) == 0) {
if (!lsp) {
/* 7.3.16.4: initiate a purge */
- lsp_purge_non_exist(level, hdr, circuit->area);
- return ISIS_OK;
+ lsp_purge_non_exist(level, &hdr, circuit->area);
+ retval = ISIS_OK;
+ goto out;
}
/* 7.3.15.1 d) - If this is our own lsp and we have it */
@@ -1066,16 +958,15 @@ dontcheckadj:
* is
* "greater" than that held by S, ... */
- if (ntohl(hdr->seq_num) > ntohl(lsp->lsp_header->seq_num)) {
+ if (hdr.seqno > lsp->hdr.seqno) {
/* 7.3.16.1 */
- lsp_inc_seqnum(lsp, ntohl(hdr->seq_num));
+ lsp_inc_seqno(lsp, hdr.seqno);
if (isis->debugs & DEBUG_UPDATE_PACKETS)
zlog_debug(
- "ISIS-Upd (%s): (2) re-originating LSP %s new seq "
- "0x%08x",
+ "ISIS-Upd (%s): (2) re-originating LSP %s new seq 0x%08" PRIx32,
circuit->area->area_tag,
- rawlspid_print(hdr->lsp_id),
- ntohl(lsp->lsp_header->seq_num));
+ rawlspid_print(hdr.lsp_id),
+ lsp->hdr.seqno);
}
/* If the received LSP is older or equal,
* resend the LSP which will act as ACK */
@@ -1090,8 +981,10 @@ dontcheckadj:
* If this lsp is a frag, need to see if we have zero
* lsp present
*/
- if (LSP_FRAGMENT(hdr->lsp_id) != 0) {
- memcpy(lspid, hdr->lsp_id, ISIS_SYS_ID_LEN + 1);
+ struct isis_lsp *lsp0 = NULL;
+ if (LSP_FRAGMENT(hdr.lsp_id) != 0) {
+ uint8_t lspid[ISIS_SYS_ID_LEN + 2];
+ memcpy(lspid, hdr.lsp_id, ISIS_SYS_ID_LEN + 1);
LSP_FRAGMENT(lspid) = 0;
lsp0 = lsp_search(
lspid, circuit->area->lspdb[level - 1]);
@@ -1103,15 +996,17 @@ dontcheckadj:
}
/* i */
if (!lsp) {
- lsp = lsp_new_from_stream_ptr(
- circuit->rcv_stream, pdu_len, lsp0,
+ lsp = lsp_new_from_recv(
+ &hdr, tlvs, circuit->rcv_stream, lsp0,
circuit->area, level);
+ tlvs = NULL;
lsp_insert(lsp,
circuit->area->lspdb[level - 1]);
} else /* exists, so we overwrite */
{
- lsp_update(lsp, circuit->rcv_stream,
+ lsp_update(lsp, &hdr, tlvs, circuit->rcv_stream,
circuit->area, level);
+ tlvs = NULL;
}
/* ii */
lsp_set_all_srmflags(lsp);
@@ -1126,8 +1021,9 @@ dontcheckadj:
/* 7.3.15.1 e) 2) LSP equal to the one in db */
else if (comp == LSP_EQUAL) {
ISIS_CLEAR_FLAG(lsp->SRMflags, circuit);
- lsp_update(lsp, circuit->rcv_stream, circuit->area,
- level);
+ lsp_update(lsp, &hdr, tlvs, circuit->rcv_stream,
+ circuit->area, level);
+ tlvs = NULL;
if (circuit->circ_type != CIRCUIT_T_BROADCAST)
ISIS_SET_FLAG(lsp->SSNflags, circuit);
}
@@ -1137,6 +1033,11 @@ dontcheckadj:
ISIS_CLEAR_FLAG(lsp->SSNflags, circuit);
}
}
+
+ retval = ISIS_OK;
+
+out:
+ isis_free_tlvs(tlvs);
return retval;
}
@@ -1202,8 +1103,7 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
}
/* 7.3.15.2 a) 2,3 - manualL2OnlyMode not implemented */
- if (!accept_level(level, circuit->is_type)) {
-
+ if (!(circuit->is_type & level)) {
zlog_debug(
"ISIS-Snp (%s): Rcvd L%d %cSNP on %s, "
"skipping: circuit type %s does not match level %d",
@@ -1264,7 +1164,8 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
? &circuit->area->area_passwd
: &circuit->area->domain_passwd;
if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_RECV)
- && !isis_tlvs_auth_is_valid(tlvs, passwd, circuit->rcv_stream)) {
+ && !isis_tlvs_auth_is_valid(tlvs, passwd, circuit->rcv_stream,
+ false)) {
isis_event_auth_failure(circuit->area->area_tag,
"SNP authentication failure",
rem_sys_id);
@@ -1317,7 +1218,7 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
on p2p */
else {
if (own_lsp) {
- lsp_inc_seqnum(lsp, entry->seqno);
+ lsp_inc_seqno(lsp, entry->seqno);
ISIS_SET_FLAG(lsp->SRMflags, circuit);
} else {
ISIS_SET_FLAG(lsp->SSNflags, circuit);
@@ -1362,8 +1263,7 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
for (struct isis_lsp_entry *entry = entry_head; entry;
entry = entry->next) {
for (ALL_LIST_ELEMENTS(lsp_list, node, nnode, lsp)) {
- if (lsp_id_cmp(lsp->lsp_header->lsp_id,
- entry->id)
+ if (lsp_id_cmp(lsp->hdr.lsp_id, entry->id)
== 0) {
list_delete_node(lsp_list, node);
break;
@@ -1506,10 +1406,8 @@ static int isis_handle_pdu(struct isis_circuit *circuit, u_char *ssnpa)
retval = process_hello(pdu_type, circuit, ssnpa);
break;
case L1_LINK_STATE:
- retval = process_lsp(ISIS_LEVEL1, circuit, ssnpa);
- break;
case L2_LINK_STATE:
- retval = process_lsp(ISIS_LEVEL2, circuit, ssnpa);
+ retval = process_lsp(pdu_type, circuit, ssnpa);
break;
case L1_COMPLETE_SEQ_NUM:
case L2_COMPLETE_SEQ_NUM:
@@ -1669,7 +1567,7 @@ int send_hello(struct isis_circuit *circuit, int level)
isis_tlvs_add_ipv6_addresses(tlvs, circuit->ipv6_link);
if (isis_pack_tlvs(tlvs, circuit->snd_stream, len_pointer,
- circuit->pad_hellos)) {
+ circuit->pad_hellos, false)) {
isis_free_tlvs(tlvs);
return ISIS_WARNING; /* XXX: Maybe Log TLV structure? */
}
@@ -1782,6 +1680,7 @@ int send_p2p_hello(struct thread *thread)
/*
* Count the maximum number of lsps that can be accomodated by a given size.
*/
+#define LSP_ENTRIES_LEN (10 + ISIS_SYS_ID_LEN)
static uint16_t get_max_lsp_count(uint16_t size)
{
uint16_t tlv_count;
@@ -1832,7 +1731,8 @@ int send_csnp(struct isis_circuit *circuit, int level)
isis_tlvs_add_auth(tlvs, passwd);
size_t tlv_start = stream_get_endp(circuit->snd_stream);
- if (isis_pack_tlvs(tlvs, circuit->snd_stream, len_pointer, false)) {
+ if (isis_pack_tlvs(tlvs, circuit->snd_stream, len_pointer, false,
+ false)) {
isis_free_tlvs(tlvs);
return ISIS_WARNING;
}
@@ -1862,8 +1762,7 @@ int send_csnp(struct isis_circuit *circuit, int level)
if (tlvs->lsp_entries.count < num_lsps) {
memset(stop, 0xff, ISIS_SYS_ID_LEN + 2);
} else {
- memcpy(stop, last_lsp->lsp_header->lsp_id,
- ISIS_SYS_ID_LEN + 2);
+ memcpy(stop, last_lsp->hdr.lsp_id, sizeof(stop));
}
memcpy(STREAM_DATA(circuit->snd_stream) + start_pointer, start,
@@ -1872,7 +1771,7 @@ int send_csnp(struct isis_circuit *circuit, int level)
ISIS_SYS_ID_LEN + 2);
stream_set_endp(circuit->snd_stream, tlv_start);
if (isis_pack_tlvs(tlvs, circuit->snd_stream, len_pointer,
- false)) {
+ false, false)) {
isis_free_tlvs(tlvs);
return ISIS_WARNING;
}
@@ -2001,7 +1900,8 @@ static int send_psnp(int level, struct isis_circuit *circuit)
isis_tlvs_add_auth(tlvs, passwd);
size_t tlv_start = stream_get_endp(circuit->snd_stream);
- if (isis_pack_tlvs(tlvs, circuit->snd_stream, len_pointer, false)) {
+ if (isis_pack_tlvs(tlvs, circuit->snd_stream, len_pointer, false,
+ false)) {
isis_free_tlvs(tlvs);
return ISIS_WARNING;
}
@@ -2035,7 +1935,7 @@ static int send_psnp(int level, struct isis_circuit *circuit)
stream_set_endp(circuit->snd_stream, tlv_start);
if (isis_pack_tlvs(tlvs, circuit->snd_stream, len_pointer,
- false)) {
+ false, false)) {
isis_free_tlvs(tlvs);
return ISIS_WARNING;
}
@@ -2183,14 +2083,12 @@ int send_lsp(struct thread *thread)
* the circuit's MTU. So handle and log this case here. */
if (stream_get_endp(lsp->pdu) > stream_get_size(circuit->snd_stream)) {
zlog_err(
- "ISIS-Upd (%s): Can't send L%d LSP %s, seq 0x%08x,"
- " cksum 0x%04x, lifetime %us on %s. LSP Size is %zu"
- " while interface stream size is %zu.",
+ "ISIS-Upd (%s): Can't send L%d LSP %s, seq 0x%08" PRIx32
+ ", cksum 0x%04" PRIx16 ", lifetime %" PRIu16
+ "s on %s. LSP Size is %zu while interface stream size is %zu.",
circuit->area->area_tag, lsp->level,
- rawlspid_print(lsp->lsp_header->lsp_id),
- ntohl(lsp->lsp_header->seq_num),
- ntohs(lsp->lsp_header->checksum),
- ntohs(lsp->lsp_header->rem_lifetime),
+ rawlspid_print(lsp->hdr.lsp_id), lsp->hdr.seqno,
+ lsp->hdr.checksum, lsp->hdr.rem_lifetime,
circuit->interface->name, stream_get_endp(lsp->pdu),
stream_get_size(circuit->snd_stream));
if (isis->debugs & DEBUG_PACKET_DUMP)
@@ -2204,15 +2102,13 @@ int send_lsp(struct thread *thread)
stream_copy(circuit->snd_stream, lsp->pdu);
if (isis->debugs & DEBUG_UPDATE_PACKETS) {
- zlog_debug(
- "ISIS-Upd (%s): Sending L%d LSP %s, seq 0x%08x, cksum 0x%04x,"
- " lifetime %us on %s",
- circuit->area->area_tag, lsp->level,
- rawlspid_print(lsp->lsp_header->lsp_id),
- ntohl(lsp->lsp_header->seq_num),
- ntohs(lsp->lsp_header->checksum),
- ntohs(lsp->lsp_header->rem_lifetime),
- circuit->interface->name);
+ zlog_debug("ISIS-Upd (%s): Sending L%d LSP %s, seq 0x%08" PRIx32
+ ", cksum 0x%04" PRIx16 ", lifetime %" PRIu16
+ "s on %s",
+ circuit->area->area_tag, lsp->level,
+ rawlspid_print(lsp->hdr.lsp_id), lsp->hdr.seqno,
+ lsp->hdr.checksum, lsp->hdr.rem_lifetime,
+ circuit->interface->name);
if (isis->debugs & DEBUG_PACKET_DUMP)
zlog_dump_data(STREAM_DATA(circuit->snd_stream),
stream_get_endp(circuit->snd_stream));
@@ -2246,41 +2142,3 @@ out:
return retval;
}
-
-int ack_lsp(struct isis_link_state_hdr *hdr, struct isis_circuit *circuit,
- int level)
-{
- unsigned long lenp;
- int retval;
- u_int16_t length;
- uint8_t pdu_type =
- (level == IS_LEVEL_1) ? L1_PARTIAL_SEQ_NUM : L2_PARTIAL_SEQ_NUM;
-
- isis_circuit_stream(circuit, &circuit->snd_stream);
-
- fill_fixed_hdr(pdu_type, circuit->snd_stream);
-
- lenp = stream_get_endp(circuit->snd_stream);
- stream_putw(circuit->snd_stream, 0); /* PDU length */
- stream_put(circuit->snd_stream, isis->sysid, ISIS_SYS_ID_LEN);
- stream_putc(circuit->snd_stream, circuit->idx);
- stream_putc(circuit->snd_stream, 9); /* code */
- stream_putc(circuit->snd_stream, 16); /* len */
-
- stream_putw(circuit->snd_stream, ntohs(hdr->rem_lifetime));
- stream_put(circuit->snd_stream, hdr->lsp_id, ISIS_SYS_ID_LEN + 2);
- stream_putl(circuit->snd_stream, ntohl(hdr->seq_num));
- stream_putw(circuit->snd_stream, ntohs(hdr->checksum));
-
- length = (u_int16_t)stream_get_endp(circuit->snd_stream);
- /* Update PDU length */
- stream_putw_at(circuit->snd_stream, lenp, length);
-
- retval = circuit->tx(circuit, level);
- if (retval != ISIS_OK)
- zlog_err("ISIS-Upd (%s): Send L%d LSP PSNP on %s failed",
- circuit->area->area_tag, level,
- circuit->interface->name);
-
- return retval;
-}
diff --git a/isisd/isis_pdu.h b/isisd/isis_pdu.h
index 985fc56ad..709676187 100644
--- a/isisd/isis_pdu.h
+++ b/isisd/isis_pdu.h
@@ -125,30 +125,14 @@ struct isis_p2p_hello_hdr {
#define L1_LINK_STATE 18
#define L2_LINK_STATE 20
-/*
- * L1 and L2 IS to IS link state PDU header
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * + PDU Length + 2
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * + Remaining Lifetime + 2
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | LSP ID | id_len + 2
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * + Sequence Number + 4
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * + Checksum + 2
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | P | ATT |LSPDBOL| ISTYPE |
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- */
-struct isis_link_state_hdr {
- u_int16_t pdu_len;
- u_int16_t rem_lifetime;
- u_char lsp_id[ISIS_SYS_ID_LEN + 2];
- u_int32_t seq_num;
- u_int16_t checksum;
- u_int8_t lsp_bits;
-} __attribute__((packed));
+struct isis_lsp_hdr {
+ uint16_t pdu_len;
+ uint16_t rem_lifetime;
+ uint8_t lsp_id[ISIS_SYS_ID_LEN + 2];
+ uint32_t seqno;
+ uint16_t checksum;
+ uint8_t lsp_bits;
+};
#define ISIS_LSP_HDR_LEN 19
/*
@@ -229,8 +213,6 @@ int send_l2_csnp(struct thread *thread);
int send_l1_psnp(struct thread *thread);
int send_l2_psnp(struct thread *thread);
int send_lsp(struct thread *thread);
-int ack_lsp(struct isis_link_state_hdr *hdr, struct isis_circuit *circuit,
- int level);
void fill_fixed_hdr(uint8_t pdu_type, struct stream *stream);
int send_hello(struct isis_circuit *circuit, int level);
diff --git a/isisd/isis_redist.c b/isisd/isis_redist.c
index 8e329494d..ea94b6580 100644
--- a/isisd/isis_redist.c
+++ b/isisd/isis_redist.c
@@ -37,7 +37,6 @@
#include "isisd/isis_flags.h"
#include "isisd/isis_misc.h"
#include "isisd/isis_circuit.h"
-#include "isisd/isis_tlv.h"
#include "isisd/isisd.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_route.h"
diff --git a/isisd/isis_route.c b/isisd/isis_route.c
index 8cb5aa9ed..267e72002 100644
--- a/isisd/isis_route.c
+++ b/isisd/isis_route.c
@@ -42,7 +42,6 @@
#include "isis_misc.h"
#include "isis_adjacency.h"
#include "isis_circuit.h"
-#include "isis_tlv.h"
#include "isis_pdu.h"
#include "isis_lsp.h"
#include "isis_spf.h"
diff --git a/isisd/isis_routemap.c b/isisd/isis_routemap.c
index 44d7fa040..d92207d57 100644
--- a/isisd/isis_routemap.c
+++ b/isisd/isis_routemap.c
@@ -42,7 +42,6 @@
#include "isis_misc.h"
#include "isis_adjacency.h"
#include "isis_circuit.h"
-#include "isis_tlv.h"
#include "isis_pdu.h"
#include "isis_lsp.h"
#include "isis_spf.h"
diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c
index 615c2eeaa..ffe6bf2fb 100644
--- a/isisd/isis_spf.c
+++ b/isisd/isis_spf.c
@@ -44,7 +44,6 @@
#include "isis_misc.h"
#include "isis_adjacency.h"
#include "isis_circuit.h"
-#include "isis_tlv.h"
#include "isis_pdu.h"
#include "isis_lsp.h"
#include "isis_dynhn.h"
@@ -52,9 +51,24 @@
#include "isis_route.h"
#include "isis_csm.h"
#include "isis_mt.h"
+#include "isis_tlvs2.h"
DEFINE_MTYPE_STATIC(ISISD, ISIS_SPF_RUN, "ISIS SPF Run Info");
+/*
+ * supports the given af ?
+ */
+static bool speaks(uint8_t *protocols, uint8_t count, int family)
+{
+ for (uint8_t i = 0; i < count; i++) {
+ if (family == AF_INET && protocols[i] == NLPID_IP)
+ return true;
+ if (family == AF_INET6 && protocols[i] == NLPID_IPV6)
+ return true;
+ }
+ return false;
+}
+
struct isis_spf_run {
struct isis_area *area;
int level;
@@ -340,7 +354,7 @@ static struct isis_lsp *isis_root_system_lsp(struct isis_area *area, int level,
LSP_PSEUDO_ID(lspid) = 0;
LSP_FRAGMENT(lspid) = 0;
lsp = lsp_search(lspid, area->lspdb[level - 1]);
- if (lsp && lsp->lsp_header->rem_lifetime != 0)
+ if (lsp && lsp->hdr.rem_lifetime != 0)
return lsp;
return NULL;
}
@@ -546,6 +560,13 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype,
assert(spftree && parent);
+ struct prefix p;
+ if (vtype >= VTYPE_IPREACH_INTERNAL) {
+ prefix_copy(&p, id);
+ apply_mask(&p);
+ id = &p;
+ }
+
/* RFC3787 section 5.1 */
if (spftree->area->newmetric == 1) {
if (dist > MAX_WIDE_PATH_METRIC)
@@ -632,30 +653,29 @@ static int isis_spf_process_lsp(struct isis_spftree *spftree,
uint16_t depth, u_char *root_sysid,
struct isis_vertex *parent)
{
- bool pseudo_lsp = LSP_PSEUDO_ID(lsp->lsp_header->lsp_id);
- struct listnode *node, *fragnode = NULL;
+ bool pseudo_lsp = LSP_PSEUDO_ID(lsp->hdr.lsp_id);
+ struct listnode *fragnode = NULL;
uint32_t dist;
- struct is_neigh *is_neigh;
- struct te_is_neigh *te_is_neigh;
- struct ipv4_reachability *ipreach;
- struct te_ipv4_reachability *te_ipv4_reach;
enum vertextype vtype;
- struct prefix prefix;
- struct ipv6_reachability *ip6reach;
static const u_char null_sysid[ISIS_SYS_ID_LEN];
- struct mt_router_info *mt_router_info = NULL;
+ struct isis_mt_router_info *mt_router_info = NULL;
+
+ if (!lsp->tlvs)
+ return ISIS_OK;
if (spftree->mtid != ISIS_MT_IPV4_UNICAST)
- mt_router_info = tlvs_lookup_mt_router_info(&lsp->tlv_data,
- spftree->mtid);
+ mt_router_info = isis_tlvs_lookup_mt_router_info(lsp->tlvs,
+ spftree->mtid);
if (!pseudo_lsp && (spftree->mtid == ISIS_MT_IPV4_UNICAST
- && !speaks(lsp->tlv_data.nlpids, spftree->family))
+ && !speaks(lsp->tlvs->protocols_supported.protocols,
+ lsp->tlvs->protocols_supported.count,
+ spftree->family))
&& !mt_router_info)
return ISIS_OK;
lspfragloop:
- if (lsp->lsp_header->seq_num == 0) {
+ if (lsp->hdr.seqno == 0) {
zlog_warn(
"isis_spf_process_lsp(): lsp with 0 seq_num - ignore");
return ISIS_WARNING;
@@ -663,142 +683,122 @@ lspfragloop:
#ifdef EXTREME_DEBUG
zlog_debug("ISIS-Spf: process_lsp %s",
- print_sys_hostname(lsp->lsp_header->lsp_id));
+ print_sys_hostname(lsp->hdr.lsp_id));
#endif /* EXTREME_DEBUG */
/* RFC3787 section 4 SHOULD ignore overload bit in pseudo LSPs */
if (pseudo_lsp || (spftree->mtid == ISIS_MT_IPV4_UNICAST
- && !ISIS_MASK_LSP_OL_BIT(lsp->lsp_header->lsp_bits))
+ && !ISIS_MASK_LSP_OL_BIT(lsp->hdr.lsp_bits))
|| (mt_router_info && !mt_router_info->overload))
{
if (pseudo_lsp || spftree->mtid == ISIS_MT_IPV4_UNICAST) {
- for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.is_neighs, node,
- is_neigh)) {
+ struct isis_oldstyle_reach *r;
+ for (r = (struct isis_oldstyle_reach *)
+ lsp->tlvs->oldstyle_reach.head;
+ r; r = r->next) {
/* C.2.6 a) */
/* Two way connectivity */
- if (!memcmp(is_neigh->neigh_id, root_sysid,
- ISIS_SYS_ID_LEN))
+ if (!memcmp(r->id, root_sysid, ISIS_SYS_ID_LEN))
continue;
if (!pseudo_lsp
- && !memcmp(is_neigh->neigh_id, null_sysid,
+ && !memcmp(r->id, null_sysid,
ISIS_SYS_ID_LEN))
continue;
- dist = cost + is_neigh->metrics.metric_default;
+ dist = cost + r->metric;
process_N(spftree,
- LSP_PSEUDO_ID(is_neigh->neigh_id)
+ LSP_PSEUDO_ID(r->id)
? VTYPE_PSEUDO_IS
: VTYPE_NONPSEUDO_IS,
- (void *)is_neigh->neigh_id, dist,
- depth + 1, parent);
+ (void *)r->id, dist, depth + 1,
+ parent);
}
}
- struct list *te_is_neighs = NULL;
- if (pseudo_lsp || spftree->mtid == ISIS_MT_IPV4_UNICAST) {
- te_is_neighs = lsp->tlv_data.te_is_neighs;
- } else {
- struct tlv_mt_neighbors *mt_neighbors;
- mt_neighbors = tlvs_lookup_mt_neighbors(&lsp->tlv_data,
- spftree->mtid);
- if (mt_neighbors)
- te_is_neighs = mt_neighbors->list;
- }
- for (ALL_LIST_ELEMENTS_RO(te_is_neighs, node, te_is_neigh)) {
- if (!memcmp(te_is_neigh->neigh_id, root_sysid,
- ISIS_SYS_ID_LEN))
+ struct isis_item_list *te_neighs = NULL;
+ if (pseudo_lsp || spftree->mtid == ISIS_MT_IPV4_UNICAST)
+ te_neighs = &lsp->tlvs->extended_reach;
+ else
+ te_neighs = isis_lookup_mt_items(&lsp->tlvs->mt_reach,
+ spftree->mtid);
+
+ struct isis_extended_reach *er;
+ for (er = te_neighs
+ ? (struct isis_extended_reach *)
+ te_neighs->head
+ : NULL;
+ er; er = er->next) {
+ if (!memcmp(er->id, root_sysid, ISIS_SYS_ID_LEN))
continue;
if (!pseudo_lsp
- && !memcmp(te_is_neigh->neigh_id, null_sysid,
- ISIS_SYS_ID_LEN))
+ && !memcmp(er->id, null_sysid, ISIS_SYS_ID_LEN))
continue;
- dist = cost + GET_TE_METRIC(te_is_neigh);
+ dist = cost + er->metric;
process_N(spftree,
- LSP_PSEUDO_ID(te_is_neigh->neigh_id)
- ? VTYPE_PSEUDO_TE_IS
- : VTYPE_NONPSEUDO_TE_IS,
- (void *)te_is_neigh->neigh_id, dist,
- depth + 1, parent);
+ LSP_PSEUDO_ID(er->id) ? VTYPE_PSEUDO_TE_IS
+ : VTYPE_NONPSEUDO_TE_IS,
+ (void *)er->id, dist, depth + 1, parent);
}
}
if (!pseudo_lsp && spftree->family == AF_INET
&& spftree->mtid == ISIS_MT_IPV4_UNICAST) {
- struct list *reachs[] = {lsp->tlv_data.ipv4_int_reachs,
- lsp->tlv_data.ipv4_ext_reachs};
+ struct isis_item_list *reachs[] = {
+ &lsp->tlvs->oldstyle_ip_reach,
+ &lsp->tlvs->oldstyle_ip_reach_ext};
- prefix.family = AF_INET;
for (unsigned int i = 0; i < array_size(reachs); i++) {
- vtype = (reachs[i] == lsp->tlv_data.ipv4_int_reachs)
- ? VTYPE_IPREACH_INTERNAL
- : VTYPE_IPREACH_EXTERNAL;
- for (ALL_LIST_ELEMENTS_RO(reachs[i], node, ipreach)) {
- dist = cost + ipreach->metrics.metric_default;
- prefix.u.prefix4 = ipreach->prefix;
- prefix.prefixlen = ip_masklen(ipreach->mask);
- apply_mask(&prefix);
- process_N(spftree, vtype, (void *)&prefix, dist,
- depth + 1, parent);
+ vtype = i ? VTYPE_IPREACH_EXTERNAL
+ : VTYPE_IPREACH_INTERNAL;
+
+ struct isis_oldstyle_ip_reach *r;
+ for (r = (struct isis_oldstyle_ip_reach *)reachs[i]
+ ->head;
+ r; r = r->next) {
+ dist = cost + r->metric;
+ process_N(spftree, vtype, (void *)&r->prefix,
+ dist, depth + 1, parent);
}
}
}
if (!pseudo_lsp && spftree->family == AF_INET) {
- struct list *ipv4reachs = NULL;
-
- if (spftree->mtid == ISIS_MT_IPV4_UNICAST) {
- ipv4reachs = lsp->tlv_data.te_ipv4_reachs;
- } else {
- struct tlv_mt_ipv4_reachs *mt_reachs;
- mt_reachs = tlvs_lookup_mt_ipv4_reachs(&lsp->tlv_data,
- spftree->mtid);
- if (mt_reachs)
- ipv4reachs = mt_reachs->list;
- }
-
- prefix.family = AF_INET;
- for (ALL_LIST_ELEMENTS_RO(ipv4reachs, node, te_ipv4_reach)) {
- assert((te_ipv4_reach->control & 0x3F)
- <= IPV4_MAX_BITLEN);
-
- dist = cost + ntohl(te_ipv4_reach->te_metric);
- prefix.u.prefix4 =
- newprefix2inaddr(&te_ipv4_reach->prefix_start,
- te_ipv4_reach->control);
- prefix.prefixlen = (te_ipv4_reach->control & 0x3F);
- apply_mask(&prefix);
- process_N(spftree, VTYPE_IPREACH_TE, (void *)&prefix,
+ struct isis_item_list *ipv4_reachs;
+ if (spftree->mtid == ISIS_MT_IPV4_UNICAST)
+ ipv4_reachs = &lsp->tlvs->extended_ip_reach;
+ else
+ ipv4_reachs = isis_lookup_mt_items(
+ &lsp->tlvs->mt_ip_reach, spftree->mtid);
+
+ struct isis_extended_ip_reach *r;
+ for (r = ipv4_reachs
+ ? (struct isis_extended_ip_reach *)
+ ipv4_reachs->head
+ : NULL;
+ r; r = r->next) {
+ dist = cost + r->metric;
+ process_N(spftree, VTYPE_IPREACH_TE, (void *)&r->prefix,
dist, depth + 1, parent);
}
}
if (!pseudo_lsp && spftree->family == AF_INET6) {
- struct list *ipv6reachs = NULL;
-
- if (spftree->mtid == ISIS_MT_IPV4_UNICAST) {
- ipv6reachs = lsp->tlv_data.ipv6_reachs;
- } else {
- struct tlv_mt_ipv6_reachs *mt_reachs;
- mt_reachs = tlvs_lookup_mt_ipv6_reachs(&lsp->tlv_data,
- spftree->mtid);
- if (mt_reachs)
- ipv6reachs = mt_reachs->list;
- }
-
- prefix.family = AF_INET6;
- for (ALL_LIST_ELEMENTS_RO(ipv6reachs, node, ip6reach)) {
- assert(ip6reach->prefix_len <= IPV6_MAX_BITLEN);
-
- dist = cost + ntohl(ip6reach->metric);
- vtype = (ip6reach->control_info
- & CTRL_INFO_DISTRIBUTION)
- ? VTYPE_IP6REACH_EXTERNAL
- : VTYPE_IP6REACH_INTERNAL;
- prefix.prefixlen = ip6reach->prefix_len;
- memcpy(&prefix.u.prefix6.s6_addr, ip6reach->prefix,
- PSIZE(ip6reach->prefix_len));
- apply_mask(&prefix);
- process_N(spftree, vtype, (void *)&prefix, dist,
+ struct isis_item_list *ipv6_reachs;
+ if (spftree->mtid == ISIS_MT_IPV4_UNICAST)
+ ipv6_reachs = &lsp->tlvs->ipv6_reach;
+ else
+ ipv6_reachs = isis_lookup_mt_items(
+ &lsp->tlvs->mt_ipv6_reach, spftree->mtid);
+
+ struct isis_ipv6_reach *r;
+ for (r = ipv6_reachs
+ ? (struct isis_ipv6_reach *)ipv6_reachs->head
+ : NULL;
+ r; r = r->next) {
+ dist = cost + r->metric;
+ vtype = r->external ? VTYPE_IP6REACH_EXTERNAL
+ : VTYPE_IP6REACH_INTERNAL;
+ process_N(spftree, vtype, (void *)&r->prefix, dist,
depth + 1, parent);
}
}
@@ -893,7 +893,9 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree,
if (!adj_has_mt(adj, spftree->mtid))
continue;
if (spftree->mtid == ISIS_MT_IPV4_UNICAST
- && !speaks(&adj->nlpids, spftree->family))
+ && !speaks(adj->nlpids.nlpids,
+ adj->nlpids.count,
+ spftree->family))
continue;
switch (adj->sys_type) {
case ISIS_SYSTYPE_ES:
@@ -928,8 +930,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree,
->lspdb[spftree->level
- 1]);
if (lsp == NULL
- || lsp->lsp_header->rem_lifetime
- == 0)
+ || lsp->hdr.rem_lifetime == 0)
zlog_warn(
"ISIS-Spf: No LSP %s found for IS adjacency "
"L%d on %s (ID %u)",
@@ -979,7 +980,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree,
lsp = lsp_search(
lsp_id,
spftree->area->lspdb[spftree->level - 1]);
- if (lsp == NULL || lsp->lsp_header->rem_lifetime == 0) {
+ if (lsp == NULL || lsp->hdr.rem_lifetime == 0) {
zlog_warn(
"ISIS-Spf: No lsp (%p) found from root "
"to L%d DR %s on %s (ID %d)",
@@ -1015,7 +1016,9 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree,
LSP_PSEUDO_ID(lsp_id) = 0;
LSP_FRAGMENT(lsp_id) = 0;
if (spftree->mtid != ISIS_MT_IPV4_UNICAST
- || speaks(&adj->nlpids, spftree->family))
+ || speaks(adj->nlpids.nlpids,
+ adj->nlpids.count,
+ spftree->family))
isis_spf_add_local(
spftree,
spftree->area->oldmetric
@@ -1178,7 +1181,7 @@ static int isis_run_spf(struct isis_area *area, int level, int family,
memcpy(lsp_id, vertex->N.id, ISIS_SYS_ID_LEN + 1);
LSP_FRAGMENT(lsp_id) = 0;
lsp = lsp_search(lsp_id, area->lspdb[level - 1]);
- if (lsp && lsp->lsp_header->rem_lifetime != 0) {
+ if (lsp && lsp->hdr.rem_lifetime != 0) {
isis_spf_process_lsp(spftree, lsp, vertex->d_N,
vertex->depth, sysid,
vertex);
diff --git a/isisd/isis_te.c b/isisd/isis_te.c
index 6b8f1fe16..70afef1a8 100644
--- a/isisd/isis_te.c
+++ b/isisd/isis_te.c
@@ -41,6 +41,7 @@
#include "md5.h"
#include "sockunion.h"
#include "network.h"
+#include "sbuf.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
@@ -48,7 +49,6 @@
#include "isisd/isis_flags.h"
#include "isisd/isis_circuit.h"
#include "isisd/isisd.h"
-#include "isisd/isis_tlv.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_pdu.h"
#include "isisd/isis_dynhn.h"
@@ -100,9 +100,9 @@ struct mpls_te_circuit *mpls_te_circuit_new()
/* Copy SUB TLVs parameters into a buffer - No space verification are performed
*/
/* Caller must verify before that there is enough free space in the buffer */
-u_char add_te_subtlvs(u_char *buf, struct mpls_te_circuit *mtc)
+uint8_t add_te_subtlvs(uint8_t *buf, struct mpls_te_circuit *mtc)
{
- u_char size, *tlvs = buf;
+ uint8_t size, *tlvs = buf;
zlog_debug("ISIS MPLS-TE: Add TE Sub TLVs to buffer");
@@ -232,7 +232,7 @@ u_char add_te_subtlvs(u_char *buf, struct mpls_te_circuit *mtc)
}
/* Compute total Sub-TLVs size */
-u_char subtlvs_len(struct mpls_te_circuit *mtc)
+uint8_t subtlvs_len(struct mpls_te_circuit *mtc)
{
int length = 0;
@@ -306,7 +306,7 @@ u_char subtlvs_len(struct mpls_te_circuit *mtc)
return 0;
}
- mtc->length = (u_char)length;
+ mtc->length = (uint8_t)length;
return mtc->length;
}
@@ -666,163 +666,116 @@ void isis_mpls_te_update(struct interface *ifp)
* Followings are vty session control functions.
*------------------------------------------------------------------------*/
-static u_char show_vty_subtlv_admin_grp(struct vty *vty,
- struct te_subtlv_admin_grp *tlv)
+static u_char print_subtlv_admin_grp(struct sbuf *buf, int indent,
+ struct te_subtlv_admin_grp *tlv)
{
-
- if (vty != NULL)
- vty_out(vty, " Administrative Group: 0x%x\n",
- (u_int32_t)ntohl(tlv->value));
- else
- zlog_debug(" Administrative Group: 0x%x",
- (u_int32_t)ntohl(tlv->value));
-
+ sbuf_push(buf, indent, "Administrative Group: 0x%" PRIx32 "\n",
+ ntohl(tlv->value));
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
}
-static u_char show_vty_subtlv_llri(struct vty *vty, struct te_subtlv_llri *tlv)
+static u_char print_subtlv_llri(struct sbuf *buf, int indent,
+ struct te_subtlv_llri *tlv)
{
- if (vty != NULL) {
- vty_out(vty, " Link Local ID: %d\n",
- (u_int32_t)ntohl(tlv->local));
- vty_out(vty, " Link Remote ID: %d\n",
- (u_int32_t)ntohl(tlv->remote));
- } else {
- zlog_debug(" Link Local ID: %d",
- (u_int32_t)ntohl(tlv->local));
- zlog_debug(" Link Remote ID: %d",
- (u_int32_t)ntohl(tlv->remote));
- }
+ sbuf_push(buf, indent, "Link Local ID: %" PRIu32 "\n",
+ ntohl(tlv->local));
+ sbuf_push(buf, indent, "Link Remote ID: %" PRIu32 "\n",
+ ntohl(tlv->remote));
return (SUBTLV_HDR_SIZE + TE_SUBTLV_LLRI_SIZE);
}
-static u_char show_vty_subtlv_local_ipaddr(struct vty *vty,
- struct te_subtlv_local_ipaddr *tlv)
+static u_char print_subtlv_local_ipaddr(struct sbuf *buf, int indent,
+ struct te_subtlv_local_ipaddr *tlv)
{
- if (vty != NULL)
- vty_out(vty, " Local Interface IP Address(es): %s\n",
- inet_ntoa(tlv->value));
- else
- zlog_debug(" Local Interface IP Address(es): %s",
- inet_ntoa(tlv->value));
+ sbuf_push(buf, indent, "Local Interface IP Address(es): %s\n",
+ inet_ntoa(tlv->value));
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
}
-static u_char show_vty_subtlv_rmt_ipaddr(struct vty *vty,
- struct te_subtlv_rmt_ipaddr *tlv)
+static u_char print_subtlv_rmt_ipaddr(struct sbuf *buf, int indent,
+ struct te_subtlv_rmt_ipaddr *tlv)
{
- if (vty != NULL)
- vty_out(vty, " Remote Interface IP Address(es): %s\n",
- inet_ntoa(tlv->value));
- else
- zlog_debug(" Remote Interface IP Address(es): %s",
- inet_ntoa(tlv->value));
+ sbuf_push(buf, indent, "Remote Interface IP Address(es): %s\n",
+ inet_ntoa(tlv->value));
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
}
-static u_char show_vty_subtlv_max_bw(struct vty *vty,
- struct te_subtlv_max_bw *tlv)
+static u_char print_subtlv_max_bw(struct sbuf *buf, int indent,
+ struct te_subtlv_max_bw *tlv)
{
float fval;
fval = ntohf(tlv->value);
- if (vty != NULL)
- vty_out(vty, " Maximum Bandwidth: %g (Bytes/sec)\n", fval);
- else
- zlog_debug(" Maximum Bandwidth: %g (Bytes/sec)", fval);
+ sbuf_push(buf, indent, "Maximum Bandwidth: %g (Bytes/sec)\n", fval);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
}
-static u_char show_vty_subtlv_max_rsv_bw(struct vty *vty,
- struct te_subtlv_max_rsv_bw *tlv)
+static u_char print_subtlv_max_rsv_bw(struct sbuf *buf, int indent,
+ struct te_subtlv_max_rsv_bw *tlv)
{
float fval;
fval = ntohf(tlv->value);
- if (vty != NULL)
- vty_out(vty,
- " Maximum Reservable Bandwidth: %g (Bytes/sec)\n",
- fval);
- else
- zlog_debug(" Maximum Reservable Bandwidth: %g (Bytes/sec)",
- fval);
+ sbuf_push(buf, indent, "Maximum Reservable Bandwidth: %g (Bytes/sec)\n", fval);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
}
-static u_char show_vty_subtlv_unrsv_bw(struct vty *vty,
- struct te_subtlv_unrsv_bw *tlv)
+static u_char print_subtlv_unrsv_bw(struct sbuf *buf, int indent,
+ struct te_subtlv_unrsv_bw *tlv)
{
float fval1, fval2;
int i;
- if (vty != NULL)
- vty_out(vty, " Unreserved Bandwidth:\n");
- else
- zlog_debug(" Unreserved Bandwidth:");
+ sbuf_push(buf, indent, "Unreserved Bandwidth:\n");
for (i = 0; i < MAX_CLASS_TYPE; i += 2) {
fval1 = ntohf(tlv->value[i]);
fval2 = ntohf(tlv->value[i + 1]);
- if (vty != NULL)
- vty_out(vty,
- " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
- i, fval1, i + 1, fval2);
- else
- zlog_debug(
- " [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)",
- i, fval1, i + 1, fval2);
+ sbuf_push(buf, indent + 2, "[%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
+ i, fval1, i + 1, fval2);
}
return (SUBTLV_HDR_SIZE + TE_SUBTLV_UNRSV_SIZE);
}
-static u_char show_vty_subtlv_te_metric(struct vty *vty,
- struct te_subtlv_te_metric *tlv)
+static u_char print_subtlv_te_metric(struct sbuf *buf, int indent,
+ struct te_subtlv_te_metric *tlv)
{
u_int32_t te_metric;
te_metric = tlv->value[2] | tlv->value[1] << 8 | tlv->value[0] << 16;
- if (vty != NULL)
- vty_out(vty, " Traffic Engineering Metric: %u\n", te_metric);
- else
- zlog_debug(" Traffic Engineering Metric: %u", te_metric);
+ sbuf_push(buf, indent, "Traffic Engineering Metric: %u\n", te_metric);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
}
-static u_char show_vty_subtlv_ras(struct vty *vty, struct te_subtlv_ras *tlv)
+static u_char print_subtlv_ras(struct sbuf *buf, int indent,
+ struct te_subtlv_ras *tlv)
{
- if (vty != NULL)
- vty_out(vty, " Inter-AS TE Remote AS number: %u\n",
- ntohl(tlv->value));
- else
- zlog_debug(" Inter-AS TE Remote AS number: %u",
- ntohl(tlv->value));
+ sbuf_push(buf, indent, "Inter-AS TE Remote AS number: %" PRIu32 "\n",
+ ntohl(tlv->value));
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
}
-static u_char show_vty_subtlv_rip(struct vty *vty, struct te_subtlv_rip *tlv)
+static u_char print_subtlv_rip(struct sbuf *buf, int indent,
+ struct te_subtlv_rip *tlv)
{
- if (vty != NULL)
- vty_out(vty, " Inter-AS TE Remote ASBR IP address: %s\n",
- inet_ntoa(tlv->value));
- else
- zlog_debug(" Inter-AS TE Remote ASBR IP address: %s",
- inet_ntoa(tlv->value));
+ sbuf_push(buf, indent, "Inter-AS TE Remote ASBR IP address: %s\n",
+ inet_ntoa(tlv->value));
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
}
-static u_char show_vty_subtlv_av_delay(struct vty *vty,
- struct te_subtlv_av_delay *tlv)
+static u_char print_subtlv_av_delay(struct sbuf *buf, int indent,
+ struct te_subtlv_av_delay *tlv)
{
u_int32_t delay;
u_int32_t A;
@@ -830,18 +783,14 @@ static u_char show_vty_subtlv_av_delay(struct vty *vty,
delay = (u_int32_t)ntohl(tlv->value) & TE_EXT_MASK;
A = (u_int32_t)ntohl(tlv->value) & TE_EXT_ANORMAL;
- if (vty != NULL)
- vty_out(vty, " %s Average Link Delay: %d (micro-sec)\n",
- A ? "Anomalous" : "Normal", delay);
- else
- zlog_debug(" %s Average Link Delay: %d (micro-sec)",
- A ? "Anomalous" : "Normal", delay);
+ sbuf_push(buf, indent, "%s Average Link Delay: %" PRIu32 " (micro-sec)\n",
+ A ? "Anomalous" : "Normal", delay);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
}
-static u_char show_vty_subtlv_mm_delay(struct vty *vty,
- struct te_subtlv_mm_delay *tlv)
+static u_char print_subtlv_mm_delay(struct sbuf *buf, int indent,
+ struct te_subtlv_mm_delay *tlv)
{
u_int32_t low, high;
u_int32_t A;
@@ -850,33 +799,26 @@ static u_char show_vty_subtlv_mm_delay(struct vty *vty,
A = (u_int32_t)ntohl(tlv->low) & TE_EXT_ANORMAL;
high = (u_int32_t)ntohl(tlv->high) & TE_EXT_MASK;
- if (vty != NULL)
- vty_out(vty, " %s Min/Max Link Delay: %d / %d (micro-sec)\n",
- A ? "Anomalous" : "Normal", low, high);
- else
- zlog_debug(" %s Min/Max Link Delay: %d / %d (micro-sec)",
- A ? "Anomalous" : "Normal", low, high);
+ sbuf_push(buf, indent, "%s Min/Max Link Delay: %" PRIu32 " / %" PRIu32 " (micro-sec)\n",
+ A ? "Anomalous" : "Normal", low, high);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
}
-static u_char show_vty_subtlv_delay_var(struct vty *vty,
- struct te_subtlv_delay_var *tlv)
+static u_char print_subtlv_delay_var(struct sbuf *buf, int indent,
+ struct te_subtlv_delay_var *tlv)
{
u_int32_t jitter;
jitter = (u_int32_t)ntohl(tlv->value) & TE_EXT_MASK;
- if (vty != NULL)
- vty_out(vty, " Delay Variation: %d (micro-sec)\n", jitter);
- else
- zlog_debug(" Delay Variation: %d (micro-sec)", jitter);
+ sbuf_push(buf, indent, "Delay Variation: %" PRIu32 " (micro-sec)\n", jitter);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
}
-static u_char show_vty_subtlv_pkt_loss(struct vty *vty,
- struct te_subtlv_pkt_loss *tlv)
+static u_char print_subtlv_pkt_loss(struct sbuf *buf, int indent,
+ struct te_subtlv_pkt_loss *tlv)
{
u_int32_t loss;
u_int32_t A;
@@ -886,189 +828,162 @@ static u_char show_vty_subtlv_pkt_loss(struct vty *vty,
fval = (float)(loss * LOSS_PRECISION);
A = (u_int32_t)ntohl(tlv->value) & TE_EXT_ANORMAL;
- if (vty != NULL)
- vty_out(vty, " %s Link Packet Loss: %g (%%)\n",
- A ? "Anomalous" : "Normal", fval);
- else
- zlog_debug(" %s Link Packet Loss: %g (%%)",
- A ? "Anomalous" : "Normal", fval);
+ sbuf_push(buf, indent, "%s Link Packet Loss: %g (%%)\n",
+ A ? "Anomalous" : "Normal", fval);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
}
-static u_char show_vty_subtlv_res_bw(struct vty *vty,
- struct te_subtlv_res_bw *tlv)
+static u_char print_subtlv_res_bw(struct sbuf *buf, int indent,
+ struct te_subtlv_res_bw *tlv)
{
float fval;
fval = ntohf(tlv->value);
- if (vty != NULL)
- vty_out(vty,
- " Unidirectional Residual Bandwidth: %g (Bytes/sec)\n",
- fval);
- else
- zlog_debug(
- " Unidirectional Residual Bandwidth: %g (Bytes/sec)",
- fval);
+ sbuf_push(buf, indent, "Unidirectional Residual Bandwidth: %g (Bytes/sec)\n",
+ fval);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
}
-static u_char show_vty_subtlv_ava_bw(struct vty *vty,
- struct te_subtlv_ava_bw *tlv)
+static u_char print_subtlv_ava_bw(struct sbuf *buf, int indent,
+ struct te_subtlv_ava_bw *tlv)
{
float fval;
fval = ntohf(tlv->value);
- if (vty != NULL)
- vty_out(vty,
- " Unidirectional Available Bandwidth: %g (Bytes/sec)\n",
- fval);
- else
- zlog_debug(
- " Unidirectional Available Bandwidth: %g (Bytes/sec)",
- fval);
+ sbuf_push(buf, indent, "Unidirectional Available Bandwidth: %g (Bytes/sec)\n",
+ fval);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
}
-static u_char show_vty_subtlv_use_bw(struct vty *vty,
- struct te_subtlv_use_bw *tlv)
+static u_char print_subtlv_use_bw(struct sbuf *buf, int indent,
+ struct te_subtlv_use_bw *tlv)
{
float fval;
fval = ntohf(tlv->value);
- if (vty != NULL)
- vty_out(vty,
- " Unidirectional Utilized Bandwidth: %g (Bytes/sec)\n",
- fval);
- else
- zlog_debug(
- " Unidirectional Utilized Bandwidth: %g (Bytes/sec)",
- fval);
+ sbuf_push(buf, indent, "Unidirectional Utilized Bandwidth: %g (Bytes/sec)\n",
+ fval);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
}
-static u_char show_vty_unknown_tlv(struct vty *vty, struct subtlv_header *tlvh)
+static u_char print_unknown_tlv(struct sbuf *buf, int indent,
+ struct subtlv_header *tlvh)
{
int i, rtn = 1;
u_char *v = (u_char *)tlvh;
- if (vty != NULL) {
- if (tlvh->length != 0) {
- vty_out(vty,
- " Unknown TLV: [type(%#.2x), length(%#.2x)]\n",
- tlvh->type, tlvh->length);
- vty_out(vty, " Dump: [00]");
- rtn = 1; /* initialize end of line counter */
- for (i = 0; i < tlvh->length; i++) {
- vty_out(vty, " %#.2x", v[i]);
- if (rtn == 8) {
- vty_out(vty, "\n [%.2x]",
- i + 1);
- rtn = 1;
- } else
- rtn++;
- }
- vty_out(vty, "\n");
- } else
- vty_out(vty,
- " Unknown TLV: [type(%#.2x), length(%#.2x)]\n",
- tlvh->type, tlvh->length);
+ if (tlvh->length != 0) {
+ sbuf_push(buf, indent,
+ "Unknown TLV: [type(%#.2x), length(%#.2x)]\n",
+ tlvh->type, tlvh->length);
+ sbuf_push(buf, indent + 2, "Dump: [00]");
+ rtn = 1; /* initialize end of line counter */
+ for (i = 0; i < tlvh->length; i++) {
+ sbuf_push(buf, 0, " %#.2x", v[i]);
+ if (rtn == 8) {
+ sbuf_push(buf, 0, "\n");
+ sbuf_push(buf, indent + 8,
+ "[%.2x]", i + 1);
+ rtn = 1;
+ } else
+ rtn++;
+ }
+ sbuf_push(buf, 0, "\n");
} else {
- zlog_debug(" Unknown TLV: [type(%#.2x), length(%#.2x)]",
- tlvh->type, tlvh->length);
+ sbuf_push(buf, indent,
+ "Unknown TLV: [type(%#.2x), length(%#.2x)]\n",
+ tlvh->type, tlvh->length);
}
return SUBTLV_SIZE(tlvh);
}
/* Main Show function */
-void mpls_te_print_detail(struct vty *vty, struct te_is_neigh *te)
+void mpls_te_print_detail(struct sbuf *buf, int indent,
+ uint8_t *subtlvs, uint8_t subtlv_len)
{
- struct subtlv_header *tlvh;
- u_int16_t sum = 0;
-
- zlog_debug("ISIS MPLS-TE: Show database TE detail");
+ struct subtlv_header *tlvh = (struct subtlv_header *)subtlvs;
+ uint16_t sum = 0;
- tlvh = (struct subtlv_header *)te->sub_tlvs;
-
- for (; sum < te->sub_tlvs_length; tlvh = SUBTLV_HDR_NEXT(tlvh)) {
+ for (; sum < subtlv_len; tlvh = SUBTLV_HDR_NEXT(tlvh)) {
switch (tlvh->type) {
case TE_SUBTLV_ADMIN_GRP:
- sum += show_vty_subtlv_admin_grp(
- vty, (struct te_subtlv_admin_grp *)tlvh);
+ sum += print_subtlv_admin_grp(buf, indent,
+ (struct te_subtlv_admin_grp *)tlvh);
break;
case TE_SUBTLV_LLRI:
- sum += show_vty_subtlv_llri(
- vty, (struct te_subtlv_llri *)tlvh);
+ sum += print_subtlv_llri(buf, indent,
+ (struct te_subtlv_llri *)tlvh);
break;
case TE_SUBTLV_LOCAL_IPADDR:
- sum += show_vty_subtlv_local_ipaddr(
- vty, (struct te_subtlv_local_ipaddr *)tlvh);
+ sum += print_subtlv_local_ipaddr(buf, indent,
+ (struct te_subtlv_local_ipaddr *)tlvh);
break;
case TE_SUBTLV_RMT_IPADDR:
- sum += show_vty_subtlv_rmt_ipaddr(
- vty, (struct te_subtlv_rmt_ipaddr *)tlvh);
+ sum += print_subtlv_rmt_ipaddr(buf, indent,
+ (struct te_subtlv_rmt_ipaddr *)tlvh);
break;
case TE_SUBTLV_MAX_BW:
- sum += show_vty_subtlv_max_bw(
- vty, (struct te_subtlv_max_bw *)tlvh);
+ sum += print_subtlv_max_bw(buf, indent,
+ (struct te_subtlv_max_bw *)tlvh);
break;
case TE_SUBTLV_MAX_RSV_BW:
- sum += show_vty_subtlv_max_rsv_bw(
- vty, (struct te_subtlv_max_rsv_bw *)tlvh);
+ sum += print_subtlv_max_rsv_bw(buf, indent,
+ (struct te_subtlv_max_rsv_bw *)tlvh);
break;
case TE_SUBTLV_UNRSV_BW:
- sum += show_vty_subtlv_unrsv_bw(
- vty, (struct te_subtlv_unrsv_bw *)tlvh);
+ sum += print_subtlv_unrsv_bw(buf, indent,
+ (struct te_subtlv_unrsv_bw *)tlvh);
break;
case TE_SUBTLV_TE_METRIC:
- sum += show_vty_subtlv_te_metric(
- vty, (struct te_subtlv_te_metric *)tlvh);
+ sum += print_subtlv_te_metric(buf, indent,
+ (struct te_subtlv_te_metric *)tlvh);
break;
case TE_SUBTLV_RAS:
- sum += show_vty_subtlv_ras(
- vty, (struct te_subtlv_ras *)tlvh);
+ sum += print_subtlv_ras(buf, indent,
+ (struct te_subtlv_ras *)tlvh);
break;
case TE_SUBTLV_RIP:
- sum += show_vty_subtlv_rip(
- vty, (struct te_subtlv_rip *)tlvh);
+ sum += print_subtlv_rip(buf, indent,
+ (struct te_subtlv_rip *)tlvh);
break;
case TE_SUBTLV_AV_DELAY:
- sum += show_vty_subtlv_av_delay(
- vty, (struct te_subtlv_av_delay *)tlvh);
+ sum += print_subtlv_av_delay(buf, indent,
+ (struct te_subtlv_av_delay *)tlvh);
break;
case TE_SUBTLV_MM_DELAY:
- sum += show_vty_subtlv_mm_delay(
- vty, (struct te_subtlv_mm_delay *)tlvh);
+ sum += print_subtlv_mm_delay(buf, indent,
+ (struct te_subtlv_mm_delay *)tlvh);
break;
case TE_SUBTLV_DELAY_VAR:
- sum += show_vty_subtlv_delay_var(
- vty, (struct te_subtlv_delay_var *)tlvh);
+ sum += print_subtlv_delay_var(buf, indent,
+ (struct te_subtlv_delay_var *)tlvh);
break;
case TE_SUBTLV_PKT_LOSS:
- sum += show_vty_subtlv_pkt_loss(
- vty, (struct te_subtlv_pkt_loss *)tlvh);
+ sum += print_subtlv_pkt_loss(buf, indent,
+ (struct te_subtlv_pkt_loss *)tlvh);
break;
case TE_SUBTLV_RES_BW:
- sum += show_vty_subtlv_res_bw(
- vty, (struct te_subtlv_res_bw *)tlvh);
+ sum += print_subtlv_res_bw(buf, indent,
+ (struct te_subtlv_res_bw *)tlvh);
break;
case TE_SUBTLV_AVA_BW:
- sum += show_vty_subtlv_ava_bw(
- vty, (struct te_subtlv_ava_bw *)tlvh);
+ sum += print_subtlv_ava_bw(buf, indent,
+ (struct te_subtlv_ava_bw *)tlvh);
break;
case TE_SUBTLV_USE_BW:
- sum += show_vty_subtlv_use_bw(
- vty, (struct te_subtlv_use_bw *)tlvh);
+ sum += print_subtlv_use_bw(buf, indent,
+ (struct te_subtlv_use_bw *)tlvh);
break;
default:
- sum += show_vty_unknown_tlv(vty, tlvh);
+ sum += print_unknown_tlv(buf, indent, tlvh);
break;
}
}
@@ -1252,6 +1167,9 @@ DEFUN (show_isis_mpls_te_router,
static void show_mpls_te_sub(struct vty *vty, struct interface *ifp)
{
struct mpls_te_circuit *mtc;
+ struct sbuf buf;
+
+ sbuf_init(&buf, NULL, 0);
if ((IS_MPLS_TE(isisMplsTE))
&& ((mtc = lookup_mpls_params_by_ifp(ifp)) != NULL)) {
@@ -1276,38 +1194,42 @@ static void show_mpls_te_sub(struct vty *vty, struct interface *ifp)
ifp->name);
}
- show_vty_subtlv_admin_grp(vty, &mtc->admin_grp);
+ sbuf_reset(&buf);
+ print_subtlv_admin_grp(&buf, 4, &mtc->admin_grp);
if (SUBTLV_TYPE(mtc->local_ipaddr) != 0)
- show_vty_subtlv_local_ipaddr(vty, &mtc->local_ipaddr);
+ print_subtlv_local_ipaddr(&buf, 4, &mtc->local_ipaddr);
if (SUBTLV_TYPE(mtc->rmt_ipaddr) != 0)
- show_vty_subtlv_rmt_ipaddr(vty, &mtc->rmt_ipaddr);
+ print_subtlv_rmt_ipaddr(&buf, 4, &mtc->rmt_ipaddr);
- show_vty_subtlv_max_bw(vty, &mtc->max_bw);
- show_vty_subtlv_max_rsv_bw(vty, &mtc->max_rsv_bw);
- show_vty_subtlv_unrsv_bw(vty, &mtc->unrsv_bw);
- show_vty_subtlv_te_metric(vty, &mtc->te_metric);
+ print_subtlv_max_bw(&buf, 4, &mtc->max_bw);
+ print_subtlv_max_rsv_bw(&buf, 4, &mtc->max_rsv_bw);
+ print_subtlv_unrsv_bw(&buf, 4, &mtc->unrsv_bw);
+ print_subtlv_te_metric(&buf, 4, &mtc->te_metric);
if (IS_INTER_AS(mtc->type)) {
if (SUBTLV_TYPE(mtc->ras) != 0)
- show_vty_subtlv_ras(vty, &mtc->ras);
+ print_subtlv_ras(&buf, 4, &mtc->ras);
if (SUBTLV_TYPE(mtc->rip) != 0)
- show_vty_subtlv_rip(vty, &mtc->rip);
+ print_subtlv_rip(&buf, 4, &mtc->rip);
}
- show_vty_subtlv_av_delay(vty, &mtc->av_delay);
- show_vty_subtlv_mm_delay(vty, &mtc->mm_delay);
- show_vty_subtlv_delay_var(vty, &mtc->delay_var);
- show_vty_subtlv_pkt_loss(vty, &mtc->pkt_loss);
- show_vty_subtlv_res_bw(vty, &mtc->res_bw);
- show_vty_subtlv_ava_bw(vty, &mtc->ava_bw);
- show_vty_subtlv_use_bw(vty, &mtc->use_bw);
+ print_subtlv_av_delay(&buf, 4, &mtc->av_delay);
+ print_subtlv_mm_delay(&buf, 4, &mtc->mm_delay);
+ print_subtlv_delay_var(&buf, 4, &mtc->delay_var);
+ print_subtlv_pkt_loss(&buf, 4, &mtc->pkt_loss);
+ print_subtlv_res_bw(&buf, 4, &mtc->res_bw);
+ print_subtlv_ava_bw(&buf, 4, &mtc->ava_bw);
+ print_subtlv_use_bw(&buf, 4, &mtc->use_bw);
+
+ vty_multiline(vty, "", "%s", sbuf_buf(&buf));
vty_out(vty, "---------------\n\n");
} else {
vty_out(vty, " %s: MPLS-TE is disabled on this interface\n",
ifp->name);
}
+ sbuf_free(&buf);
return;
}
diff --git a/isisd/isis_te.h b/isisd/isis_te.h
index 0bd076af1..9b29792e2 100644
--- a/isisd/isis_te.h
+++ b/isisd/isis_te.h
@@ -81,6 +81,8 @@ struct subtlv_header {
u_char length; /* Value portion only, in byte */
};
+#define MAX_SUBTLV_SIZE 256
+
#define SUBTLV_HDR_SIZE 2 /* (sizeof (struct sub_tlv_header)) */
#define SUBTLV_SIZE(stlvh) (SUBTLV_HDR_SIZE + (stlvh)->length)
@@ -306,12 +308,13 @@ struct mpls_te_circuit {
/* Prototypes. */
void isis_mpls_te_init(void);
struct mpls_te_circuit *mpls_te_circuit_new(void);
-void mpls_te_print_detail(struct vty *, struct te_is_neigh *);
+struct sbuf;
+void mpls_te_print_detail(struct sbuf *buf, int indent, uint8_t *subtlvs, uint8_t subtlv_len);
void set_circuitparams_local_ipaddr(struct mpls_te_circuit *, struct in_addr);
void set_circuitparams_rmt_ipaddr(struct mpls_te_circuit *, struct in_addr);
-u_char subtlvs_len(struct mpls_te_circuit *);
-u_char add_te_subtlvs(u_char *, struct mpls_te_circuit *);
-u_char build_te_subtlvs(u_char *, struct isis_circuit *);
+uint8_t subtlvs_len(struct mpls_te_circuit *);
+uint8_t add_te_subtlvs(uint8_t *, struct mpls_te_circuit *);
+uint8_t build_te_subtlvs(uint8_t *, struct isis_circuit *);
void isis_link_params_update(struct isis_circuit *, struct interface *);
void isis_mpls_te_update(struct interface *);
void isis_mpls_te_config_write_router(struct vty *);
diff --git a/isisd/isis_tlv.c b/isisd/isis_tlv.c
deleted file mode 100644
index a295f4dd3..000000000
--- a/isisd/isis_tlv.c
+++ /dev/null
@@ -1,1453 +0,0 @@
-/*
- * IS-IS Rout(e)ing protocol - isis_tlv.c
- * IS-IS TLV related routines
- *
- * Copyright (C) 2001,2002 Sampo Saaristo
- * Tampere University of Technology
- * Institute of Communications Engineering
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public Licenseas published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <zebra.h>
-
-#include "log.h"
-#include "linklist.h"
-#include "stream.h"
-#include "memory.h"
-#include "prefix.h"
-#include "vty.h"
-#include "if.h"
-
-#include "isisd/dict.h"
-#include "isisd/isis_constants.h"
-#include "isisd/isis_common.h"
-#include "isisd/isis_flags.h"
-#include "isisd/isis_circuit.h"
-#include "isisd/isis_tlv.h"
-#include "isisd/isisd.h"
-#include "isisd/isis_dynhn.h"
-#include "isisd/isis_misc.h"
-#include "isisd/isis_pdu.h"
-#include "isisd/isis_lsp.h"
-#include "isisd/isis_te.h"
-#include "isisd/isis_mt.h"
-
-void free_tlv(void *val)
-{
- XFREE(MTYPE_ISIS_TLV, val);
-
- return;
-}
-
-/*
- * Called after parsing of a PDU. There shouldn't be any tlv's left, so this
- * is only a caution to avoid memory leaks
- */
-void free_tlvs(struct tlvs *tlvs)
-{
- if (tlvs->area_addrs)
- list_delete(tlvs->area_addrs);
- if (tlvs->mt_router_info)
- list_delete(tlvs->mt_router_info);
- if (tlvs->is_neighs)
- list_delete(tlvs->is_neighs);
- if (tlvs->te_is_neighs)
- list_delete(tlvs->te_is_neighs);
- if (tlvs->mt_is_neighs)
- list_delete(tlvs->mt_is_neighs);
- if (tlvs->es_neighs)
- list_delete(tlvs->es_neighs);
- if (tlvs->lsp_entries)
- list_delete(tlvs->lsp_entries);
- if (tlvs->prefix_neighs)
- list_delete(tlvs->prefix_neighs);
- if (tlvs->lan_neighs)
- list_delete(tlvs->lan_neighs);
- if (tlvs->ipv4_addrs)
- list_delete(tlvs->ipv4_addrs);
- if (tlvs->ipv4_int_reachs)
- list_delete(tlvs->ipv4_int_reachs);
- if (tlvs->ipv4_ext_reachs)
- list_delete(tlvs->ipv4_ext_reachs);
- if (tlvs->te_ipv4_reachs)
- list_delete(tlvs->te_ipv4_reachs);
- if (tlvs->mt_ipv4_reachs)
- list_delete(tlvs->mt_ipv4_reachs);
- if (tlvs->ipv6_addrs)
- list_delete(tlvs->ipv6_addrs);
- if (tlvs->ipv6_reachs)
- list_delete(tlvs->ipv6_reachs);
- if (tlvs->mt_ipv6_reachs)
- list_delete(tlvs->mt_ipv6_reachs);
-
- memset(tlvs, 0, sizeof(struct tlvs));
-
- return;
-}
-
-static int parse_mtid(uint16_t *mtid, bool read_mtid, unsigned int *length,
- u_char **pnt)
-{
- if (!read_mtid) {
- *mtid = ISIS_MT_IPV4_UNICAST;
- return ISIS_OK;
- }
-
- uint16_t mtid_buf;
-
- if (*length < sizeof(mtid_buf)) {
- zlog_warn("ISIS-TLV: mt tlv too short to contain MT id");
- return ISIS_WARNING;
- }
-
- memcpy(&mtid_buf, *pnt, sizeof(mtid_buf));
- *pnt += sizeof(mtid_buf);
- *length -= sizeof(mtid_buf);
-
- *mtid = ntohs(mtid_buf) & ISIS_MT_MASK;
- return ISIS_OK;
-}
-
-static int parse_mt_is_neighs(struct tlvs *tlvs, bool read_mtid,
- unsigned int length, u_char *pnt)
-{
- struct list *neigh_list;
- uint16_t mtid;
- int rv;
-
- rv = parse_mtid(&mtid, read_mtid, &length, &pnt);
- if (rv != ISIS_OK)
- return rv;
-
- if (mtid == ISIS_MT_IPV4_UNICAST) {
- if (!tlvs->te_is_neighs) {
- tlvs->te_is_neighs = list_new();
- tlvs->te_is_neighs->del = free_tlv;
- }
- neigh_list = tlvs->te_is_neighs;
- } else {
- struct tlv_mt_neighbors *neighbors;
-
- neighbors = tlvs_get_mt_neighbors(tlvs, mtid);
- neighbors->list->del = free_tlv;
- neigh_list = neighbors->list;
- }
-
- while (length >= IS_NEIGHBOURS_LEN) {
- struct te_is_neigh *neigh =
- XCALLOC(MTYPE_ISIS_TLV, sizeof(*neigh));
-
- memcpy(neigh, pnt, IS_NEIGHBOURS_LEN);
- pnt += IS_NEIGHBOURS_LEN;
- length -= IS_NEIGHBOURS_LEN;
-
- if (neigh->sub_tlvs_length > length) {
- zlog_warn(
- "ISIS-TLV: neighbor subtlv length exceeds TLV size");
- XFREE(MTYPE_ISIS_TLV, neigh);
- return ISIS_WARNING;
- }
-
- memcpy(neigh->sub_tlvs, pnt, neigh->sub_tlvs_length);
- pnt += neigh->sub_tlvs_length;
- length -= neigh->sub_tlvs_length;
-
- listnode_add(neigh_list, neigh);
- }
-
- if (length) {
- zlog_warn("ISIS-TLV: TE/MT neighor TLV has trailing data");
- return ISIS_WARNING;
- }
-
- return ISIS_OK;
-}
-
-static int parse_mt_ipv4_reachs(struct tlvs *tlvs, bool read_mtid,
- unsigned int length, u_char *pnt)
-{
- struct list *reach_list;
- uint16_t mtid;
- int rv;
-
- rv = parse_mtid(&mtid, read_mtid, &length, &pnt);
- if (rv != ISIS_OK)
- return rv;
-
- if (mtid == ISIS_MT_IPV4_UNICAST) {
- if (!tlvs->te_ipv4_reachs) {
- tlvs->te_ipv4_reachs = list_new();
- tlvs->te_ipv4_reachs->del = free_tlv;
- }
- reach_list = tlvs->te_ipv4_reachs;
- } else {
- struct tlv_mt_ipv4_reachs *reachs;
-
- reachs = tlvs_get_mt_ipv4_reachs(tlvs, mtid);
- reachs->list->del = free_tlv;
- reach_list = reachs->list;
- }
-
- while (length >= 5) /* Metric + Control */
- {
- struct te_ipv4_reachability *reach =
- XCALLOC(MTYPE_ISIS_TLV, TE_IPV4_REACH_LEN);
-
- memcpy(reach, pnt, 5); /* Metric + Control */
- pnt += 5;
- length -= 5;
-
- unsigned char prefixlen = reach->control & 0x3F;
-
- if (prefixlen > IPV4_MAX_BITLEN) {
- zlog_warn(
- "ISIS-TLV: invalid IPv4 extended reachability prefix length %d",
- prefixlen);
- XFREE(MTYPE_ISIS_TLV, reach);
- return ISIS_WARNING;
- }
-
- if (length < (unsigned int)PSIZE(prefixlen)) {
- zlog_warn(
- "ISIS-TLV: invalid IPv4 extended reachability prefix too long for tlv");
- XFREE(MTYPE_ISIS_TLV, reach);
- return ISIS_WARNING;
- }
-
- memcpy(&reach->prefix_start, pnt, PSIZE(prefixlen));
- pnt += PSIZE(prefixlen);
- length -= PSIZE(prefixlen);
-
- if (reach->control & TE_IPV4_HAS_SUBTLV) {
- if (length < 1) {
- zlog_warn(
- "ISIS-TLV: invalid IPv4 extended reachability SubTLV missing");
- XFREE(MTYPE_ISIS_TLV, reach);
- return ISIS_WARNING;
- }
-
- u_char subtlv_len = *pnt;
- pnt++;
- length--;
-
- if (length < subtlv_len) {
- zlog_warn(
- "ISIS-TLV: invalid IPv4 extended reachability SubTLVs have oversize");
- XFREE(MTYPE_ISIS_TLV, reach);
- return ISIS_WARNING;
- }
-
- /* Skip Sub-TLVs for now */
- pnt += subtlv_len;
- length -= subtlv_len;
- }
- listnode_add(reach_list, reach);
- }
-
- if (length) {
- zlog_warn(
- "ISIS-TLV: TE/MT ipv4 reachability TLV has trailing data");
- return ISIS_WARNING;
- }
-
- return ISIS_OK;
-}
-
-static int parse_mt_ipv6_reachs(struct tlvs *tlvs, bool read_mtid,
- unsigned int length, u_char *pnt)
-{
- struct list *reach_list;
- uint16_t mtid;
- int rv;
-
- rv = parse_mtid(&mtid, read_mtid, &length, &pnt);
- if (rv != ISIS_OK)
- return rv;
-
- if (mtid == ISIS_MT_IPV4_UNICAST) {
- if (!tlvs->ipv6_reachs) {
- tlvs->ipv6_reachs = list_new();
- tlvs->ipv6_reachs->del = free_tlv;
- }
- reach_list = tlvs->ipv6_reachs;
- } else {
- struct tlv_mt_ipv6_reachs *reachs;
-
- reachs = tlvs_get_mt_ipv6_reachs(tlvs, mtid);
- reachs->list->del = free_tlv;
- reach_list = reachs->list;
- }
-
- while (length >= 6) /* Metric + Control + Prefixlen */
- {
- struct ipv6_reachability *reach =
- XCALLOC(MTYPE_ISIS_TLV, sizeof(*reach));
-
- memcpy(reach, pnt, 6); /* Metric + Control + Prefixlen */
- pnt += 6;
- length -= 6;
-
- if (reach->prefix_len > IPV6_MAX_BITLEN) {
- zlog_warn(
- "ISIS-TLV: invalid IPv6 reachability prefix length %d",
- reach->prefix_len);
- XFREE(MTYPE_ISIS_TLV, reach);
- return ISIS_WARNING;
- }
-
- if (length < (unsigned int)PSIZE(reach->prefix_len)) {
- zlog_warn(
- "ISIS-TLV: invalid IPv6 reachability prefix too long for tlv");
- XFREE(MTYPE_ISIS_TLV, reach);
- return ISIS_WARNING;
- }
-
- memcpy(&reach->prefix, pnt, PSIZE(reach->prefix_len));
- pnt += PSIZE(reach->prefix_len);
- length -= PSIZE(reach->prefix_len);
-
- if (reach->control_info & CTRL_INFO_SUBTLVS) {
- if (length < 1) {
- zlog_warn(
- "ISIS-TLV: invalid IPv6 reachability SubTLV missing");
- XFREE(MTYPE_ISIS_TLV, reach);
- return ISIS_WARNING;
- }
-
- u_char subtlv_len = *pnt;
- pnt++;
- length--;
-
- if (length < subtlv_len) {
- zlog_warn(
- "ISIS-TLV: invalid IPv6 reachability SubTLVs have oversize");
- XFREE(MTYPE_ISIS_TLV, reach);
- return ISIS_WARNING;
- }
-
- /* Skip Sub-TLVs for now */
- pnt += subtlv_len;
- length -= subtlv_len;
- }
- listnode_add(reach_list, reach);
- }
-
- if (length) {
- zlog_warn(
- "ISIS-TLV: (MT) IPv6 reachability TLV has trailing data");
- return ISIS_WARNING;
- }
-
- return ISIS_OK;
-}
-
-/*
- * Parses the tlvs found in the variant length part of the PDU.
- * Caller tells with flags in "expected" which TLV's it is interested in.
- */
-int parse_tlvs(char *areatag, u_char *stream, int size, u_int32_t *expected,
- u_int32_t *found, struct tlvs *tlvs, u_int32_t *auth_tlv_offset)
-{
- u_char type, length;
- struct lan_neigh *lan_nei;
- struct area_addr *area_addr;
- struct is_neigh *is_nei;
- struct es_neigh *es_nei;
- struct lsp_entry *lsp_entry;
- struct in_addr *ipv4_addr;
- struct ipv4_reachability *ipv4_reach;
- struct in6_addr *ipv6_addr;
- int value_len, retval = ISIS_OK;
- u_char *start = stream, *pnt = stream;
-
- *found = 0;
- memset(tlvs, 0, sizeof(struct tlvs));
-
- while (pnt < stream + size - 2) {
- type = *pnt;
- length = *(pnt + 1);
- pnt += 2;
- value_len = 0;
- if (pnt + length > stream + size) {
- zlog_warn(
- "ISIS-TLV (%s): TLV (type %d, length %d) exceeds packet "
- "boundaries",
- areatag, type, length);
- retval = ISIS_WARNING;
- break;
- }
- switch (type) {
- case AREA_ADDRESSES:
- /* +-------+-------+-------+-------+-------+-------+-------+-------+
- * | Address Length |
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | Area Address |
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * : :
- */
- *found |= TLVFLAG_AREA_ADDRS;
-#ifdef EXTREME_TLV_DEBUG
- zlog_debug("TLV Area Adresses len %d", length);
-#endif /* EXTREME_TLV_DEBUG */
- if (*expected & TLVFLAG_AREA_ADDRS) {
- while (length > value_len) {
- area_addr = (struct area_addr *)pnt;
- value_len += area_addr->addr_len + 1;
- pnt += area_addr->addr_len + 1;
- if (!tlvs->area_addrs)
- tlvs->area_addrs = list_new();
- listnode_add(tlvs->area_addrs,
- area_addr);
- }
- } else {
- pnt += length;
- }
- break;
-
- case IS_NEIGHBOURS:
- *found |= TLVFLAG_IS_NEIGHS;
-#ifdef EXTREME_TLV_DEBUG
- zlog_debug("ISIS-TLV (%s): IS Neighbours length %d",
- areatag, length);
-#endif /* EXTREME_TLV_DEBUG */
- if (TLVFLAG_IS_NEIGHS & *expected) {
- /* +-------+-------+-------+-------+-------+-------+-------+-------+
- * | Virtual Flag |
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- */
- pnt++;
- value_len++;
- /* +-------+-------+-------+-------+-------+-------+-------+-------+
- * | 0 | I/E | Default
- * Metric |
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | S | I/E | Delay Metric
- * |
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | S | I/E | Expense
- * Metric |
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | S | I/E | Error Metric
- * |
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | Neighbour ID |
- * +---------------------------------------------------------------+
- * : :
- */
- while (length > value_len) {
- is_nei = (struct is_neigh *)pnt;
- value_len += 4 + ISIS_SYS_ID_LEN + 1;
- pnt += 4 + ISIS_SYS_ID_LEN + 1;
- if (!tlvs->is_neighs)
- tlvs->is_neighs = list_new();
- listnode_add(tlvs->is_neighs, is_nei);
- }
- } else {
- pnt += length;
- }
- break;
-
- case TE_IS_NEIGHBOURS:
- *found |= TLVFLAG_TE_IS_NEIGHS;
-#ifdef EXTREME_TLV_DEBUG
- zlog_debug(
- "ISIS-TLV (%s): Extended IS Neighbours length %d",
- areatag, length);
-#endif /* EXTREME_TLV_DEBUG */
- if (TLVFLAG_TE_IS_NEIGHS & *expected)
- retval = parse_mt_is_neighs(tlvs, false, length,
- pnt);
- pnt += length;
- break;
-
- case MT_IS_NEIGHBOURS:
- *found |= TLVFLAG_TE_IS_NEIGHS;
-#ifdef EXTREME_TLV_DEBUG
- zlog_debug("ISIS-TLV (%s): MT IS Neighbours length %d",
- areatag, length);
-#endif
- if (TLVFLAG_TE_IS_NEIGHS & *expected)
- retval = parse_mt_is_neighs(tlvs, true, length,
- pnt);
- pnt += length;
- break;
-
- case ES_NEIGHBOURS:
-/* +-------+-------+-------+-------+-------+-------+-------+-------+
- * | 0 | I/E | Default Metric |
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | S | I/E | Delay Metric |
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | S | I/E | Expense Metric |
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | S | I/E | Error Metric |
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | Neighbour ID |
- * +---------------------------------------------------------------+
- * | Neighbour ID |
- * +---------------------------------------------------------------+
- * : :
- */
-#ifdef EXTREME_TLV_DEBUG
- zlog_debug("ISIS-TLV (%s): ES Neighbours length %d",
- areatag, length);
-#endif /* EXTREME_TLV_DEBUG */
- *found |= TLVFLAG_ES_NEIGHS;
- if (*expected & TLVFLAG_ES_NEIGHS) {
- es_nei = (struct es_neigh *)pnt;
- value_len += 4;
- pnt += 4;
- while (length > value_len) {
- /* FIXME FIXME FIXME - add to the list
- */
- /* sys_id->id = pnt; */
- value_len += ISIS_SYS_ID_LEN;
- pnt += ISIS_SYS_ID_LEN;
- /* if (!es_nei->neigh_ids)
- * es_nei->neigh_ids = sysid; */
- }
- if (!tlvs->es_neighs)
- tlvs->es_neighs = list_new();
- listnode_add(tlvs->es_neighs, es_nei);
- } else {
- pnt += length;
- }
- break;
-
- case LAN_NEIGHBOURS:
- /* +-------+-------+-------+-------+-------+-------+-------+-------+
- * | LAN Address |
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * : :
- */
- *found |= TLVFLAG_LAN_NEIGHS;
-#ifdef EXTREME_TLV_DEBUG
- zlog_debug("ISIS-TLV (%s): LAN Neigbours length %d",
- areatag, length);
-#endif /* EXTREME_TLV_DEBUG */
- if (TLVFLAG_LAN_NEIGHS & *expected) {
- while (length > value_len) {
- lan_nei = (struct lan_neigh *)pnt;
- if (!tlvs->lan_neighs)
- tlvs->lan_neighs = list_new();
- listnode_add(tlvs->lan_neighs, lan_nei);
- value_len += ETH_ALEN;
- pnt += ETH_ALEN;
- }
- } else {
- pnt += length;
- }
- break;
-
- case PADDING:
-#ifdef EXTREME_TLV_DEBUG
- zlog_debug("TLV padding %d", length);
-#endif /* EXTREME_TLV_DEBUG */
- pnt += length;
- break;
-
- case LSP_ENTRIES:
-/* +-------+-------+-------+-------+-------+-------+-------+-------+
- * | Remaining Lifetime | 2
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | LSP ID | id+2
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | LSP Sequence Number | 4
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | Checksum | 2
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- */
-#ifdef EXTREME_TLV_DEBUG
- zlog_debug("ISIS-TLV (%s): LSP Entries length %d",
- areatag, length);
-#endif /* EXTREME_TLV_DEBUG */
- *found |= TLVFLAG_LSP_ENTRIES;
- if (TLVFLAG_LSP_ENTRIES & *expected) {
- while (length > value_len) {
- lsp_entry = (struct lsp_entry *)pnt;
- value_len += 10 + ISIS_SYS_ID_LEN;
- pnt += 10 + ISIS_SYS_ID_LEN;
- if (!tlvs->lsp_entries)
- tlvs->lsp_entries = list_new();
- listnode_add(tlvs->lsp_entries,
- lsp_entry);
- }
- } else {
- pnt += length;
- }
- break;
-
- case CHECKSUM:
- /* +-------+-------+-------+-------+-------+-------+-------+-------+
- * | 16 bit fletcher CHECKSUM |
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * : :
- */
- *found |= TLVFLAG_CHECKSUM;
-#ifdef EXTREME_TLV_DEBUG
- zlog_debug("ISIS-TLV (%s): Checksum length %d", areatag,
- length);
-#endif /* EXTREME_TLV_DEBUG */
- if (*expected & TLVFLAG_CHECKSUM) {
- tlvs->checksum = (struct checksum *)pnt;
- }
- pnt += length;
- break;
-
- case PROTOCOLS_SUPPORTED:
- /* +-------+-------+-------+-------+-------+-------+-------+-------+
- * | NLPID |
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * : :
- */
- *found |= TLVFLAG_NLPID;
-#ifdef EXTREME_TLV_DEBUG
- zlog_debug(
- "ISIS-TLV (%s): Protocols Supported length %d",
- areatag, length);
-#endif /* EXTREME_TLV_DEBUG */
- if (*expected & TLVFLAG_NLPID) {
- tlvs->nlpids = (struct nlpids *)(pnt - 1);
- }
- pnt += length;
- break;
-
- case IPV4_ADDR:
- /* +-------+-------+-------+-------+-------+-------+-------+-------+
- * + IP version 4 address + 4
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * : :
- */
- *found |= TLVFLAG_IPV4_ADDR;
-#ifdef EXTREME_TLV_DEBUG
- zlog_debug("ISIS-TLV (%s): IPv4 Address length %d",
- areatag, length);
-#endif /* EXTREME_TLV_DEBUG */
- if (*expected & TLVFLAG_IPV4_ADDR) {
- while (length > value_len) {
- ipv4_addr = (struct in_addr *)pnt;
-#ifdef EXTREME_TLV_DEBUG
- zlog_debug(
- "ISIS-TLV (%s) : IP ADDR %s, pnt %p",
- areatag, inet_ntoa(*ipv4_addr),
- pnt);
-#endif /* EXTREME_TLV_DEBUG */
- if (!tlvs->ipv4_addrs)
- tlvs->ipv4_addrs = list_new();
- listnode_add(tlvs->ipv4_addrs,
- ipv4_addr);
- value_len += 4;
- pnt += 4;
- }
- } else {
- pnt += length;
- }
- break;
-
- case AUTH_INFO:
- *found |= TLVFLAG_AUTH_INFO;
-#ifdef EXTREME_TLV_DEBUG
- zlog_debug(
- "ISIS-TLV (%s): IS-IS Authentication Information",
- areatag);
-#endif
- if (*expected & TLVFLAG_AUTH_INFO) {
- tlvs->auth_info.type = *pnt;
- if (length == 0) {
- zlog_warn(
- "ISIS-TLV (%s): TLV (type %d, length %d) "
- "incorrect.",
- areatag, type, length);
- return ISIS_WARNING;
- }
- --length;
- tlvs->auth_info.len = length;
- pnt++;
- memcpy(tlvs->auth_info.passwd, pnt, length);
- /* Return the authentication tlv pos for later
- * computation
- * of MD5 (RFC 5304, 2)
- */
- if (auth_tlv_offset)
- *auth_tlv_offset += (pnt - start - 3);
- pnt += length;
- } else {
- pnt += length;
- }
- break;
-
- case DYNAMIC_HOSTNAME:
- *found |= TLVFLAG_DYN_HOSTNAME;
-#ifdef EXTREME_TLV_DEBUG
- zlog_debug("ISIS-TLV (%s): Dynamic Hostname length %d",
- areatag, length);
-#endif /* EXTREME_TLV_DEBUG */
- if (*expected & TLVFLAG_DYN_HOSTNAME) {
- /* the length is also included in the pointed
- * struct */
- tlvs->hostname = (struct hostname *)(pnt - 1);
- }
- pnt += length;
- break;
-
- case TE_ROUTER_ID:
- /* +---------------------------------------------------------------+
- * + Router ID + 4
- * +---------------------------------------------------------------+
- */
- *found |= TLVFLAG_TE_ROUTER_ID;
-#ifdef EXTREME_TLV_DEBUG
- zlog_debug("ISIS-TLV (%s): TE Router ID %d", areatag,
- length);
-#endif /* EXTREME_TLV_DEBUG */
- if (*expected & TLVFLAG_TE_ROUTER_ID)
- tlvs->router_id = (struct te_router_id *)(pnt);
- pnt += length;
- break;
-
- case IPV4_INT_REACHABILITY:
- /* +-------+-------+-------+-------+-------+-------+-------+-------+
- * | 0 | I/E | Default Metric | 1
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | S | I/E | Delay Metric | 1
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | S | I/E | Expense Metric | 1
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | S | I/E | Error Metric | 1
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | ip address | 4
- * +---------------------------------------------------------------+
- * | address mask | 4
- * +---------------------------------------------------------------+
- * : :
- */
- *found |= TLVFLAG_IPV4_INT_REACHABILITY;
-#ifdef EXTREME_TLV_DEBUG
- zlog_debug(
- "ISIS-TLV (%s): IPv4 internal Reachability length %d",
- areatag, length);
-#endif /* EXTREME_TLV_DEBUG */
- if (*expected & TLVFLAG_IPV4_INT_REACHABILITY) {
- while (length > value_len) {
- ipv4_reach =
- (struct ipv4_reachability *)pnt;
- if (!tlvs->ipv4_int_reachs)
- tlvs->ipv4_int_reachs =
- list_new();
- listnode_add(tlvs->ipv4_int_reachs,
- ipv4_reach);
- value_len += 12;
- pnt += 12;
- }
- } else {
- pnt += length;
- }
- break;
-
- case IPV4_EXT_REACHABILITY:
- /* +-------+-------+-------+-------+-------+-------+-------+-------+
- * | 0 | I/E | Default Metric | 1
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | S | I/E | Delay Metric | 1
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | S | I/E | Expense Metric | 1
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | S | I/E | Error Metric | 1
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | ip address | 4
- * +---------------------------------------------------------------+
- * | address mask | 4
- * +---------------------------------------------------------------+
- * : :
- */
- *found |= TLVFLAG_IPV4_EXT_REACHABILITY;
-#ifdef EXTREME_TLV_DEBUG
- zlog_debug(
- "ISIS-TLV (%s): IPv4 external Reachability length %d",
- areatag, length);
-#endif /* EXTREME_TLV_DEBUG */
- if (*expected & TLVFLAG_IPV4_EXT_REACHABILITY) {
- while (length > value_len) {
- ipv4_reach =
- (struct ipv4_reachability *)pnt;
- if (!tlvs->ipv4_ext_reachs)
- tlvs->ipv4_ext_reachs =
- list_new();
- listnode_add(tlvs->ipv4_ext_reachs,
- ipv4_reach);
- value_len += 12;
- pnt += 12;
- }
- } else {
- pnt += length;
- }
- break;
-
- case TE_IPV4_REACHABILITY:
- *found |= TLVFLAG_TE_IPV4_REACHABILITY;
-#ifdef EXTREME_TLV_DEBUG
- zlog_debug(
- "ISIS-TLV (%s): IPv4 extended Reachability length %d",
- areatag, length);
-#endif /* EXTREME_TLV_DEBUG */
- if (*expected & TLVFLAG_TE_IPV4_REACHABILITY)
- retval = parse_mt_ipv4_reachs(tlvs, false,
- length, pnt);
- pnt += length;
- break;
- case MT_IPV4_REACHABILITY:
- *found |= TLVFLAG_TE_IPV4_REACHABILITY;
-#ifdef EXTREME_TLV_DEBUG
- zlog_debug(
- "ISIS-TLV (%s): IPv4 MT Reachability length %d",
- areatag, length);
-#endif /* EXTREME_TLV_DEBUG */
- if (*expected & TLVFLAG_TE_IPV4_REACHABILITY)
- retval = parse_mt_ipv4_reachs(tlvs, true,
- length, pnt);
- pnt += length;
- break;
- case IPV6_ADDR:
- /* +-------+-------+-------+-------+-------+-------+-------+-------+
- * + IP version 6 address + 16
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * : :
- */
- *found |= TLVFLAG_IPV6_ADDR;
-#ifdef EXTREME_TLV_DEBUG
- zlog_debug("ISIS-TLV (%s): IPv6 Address length %d",
- areatag, length);
-#endif /* EXTREME_TLV_DEBUG */
- if (*expected & TLVFLAG_IPV6_ADDR) {
- while (length > value_len) {
- ipv6_addr = (struct in6_addr *)pnt;
- if (!tlvs->ipv6_addrs)
- tlvs->ipv6_addrs = list_new();
- listnode_add(tlvs->ipv6_addrs,
- ipv6_addr);
- value_len += 16;
- pnt += 16;
- }
- } else {
- pnt += length;
- }
- break;
-
- case IPV6_REACHABILITY:
- *found |= TLVFLAG_IPV6_REACHABILITY;
-#ifdef EXTREME_TLV_DEBUG
- zlog_debug("ISIS-TLV (%s): IPv6 Reachability length %d",
- areatag, length);
-#endif /* EXTREME_TLV_DEBUG */
- if (*expected & TLVFLAG_IPV6_REACHABILITY)
- retval = parse_mt_ipv6_reachs(tlvs, false,
- length, pnt);
- pnt += length;
- break;
- case MT_IPV6_REACHABILITY:
- *found |= TLVFLAG_IPV6_REACHABILITY;
-#ifdef EXTREME_TLV_DEBUG
- zlog_debug("ISIS-TLV (%s): IPv6 Reachability length %d",
- areatag, length);
-#endif /* EXTREME_TLV_DEBUG */
- if (*expected & TLVFLAG_IPV6_REACHABILITY)
- retval = parse_mt_ipv6_reachs(tlvs, true,
- length, pnt);
- pnt += length;
- break;
- case WAY3_HELLO:
- /* +---------------------------------------------------------------+
- * | Adjacency state | 1
- * +---------------------------------------------------------------+
- * | Extended Local Circuit ID | 4
- * +---------------------------------------------------------------+
- * | Neighbor System ID (If known)
- * | 0-8
- * (probably 6)
- * +---------------------------------------------------------------+
- * | Neighbor Local Circuit ID (If
- * known) | 4
- * +---------------------------------------------------------------+
- */
- *found |= TLVFLAG_3WAY_HELLO;
- if (*expected & TLVFLAG_3WAY_HELLO) {
- while (length > value_len) {
- /* FIXME: make this work */
- /* Adjacency State (one
- octet):
- 0 = Up
- 1 = Initializing
- 2 = Down
- Extended Local Circuit ID
- (four octets)
- Neighbor System ID if known
- (zero to eight octets)
- Neighbor Extended Local
- Circuit ID (four octets, if Neighbor
- System ID is present) */
- pnt += length;
- value_len += length;
- }
- } else {
- pnt += length;
- }
-
- break;
- case GRACEFUL_RESTART:
- /* +-------+-------+-------+-------+-------+-------+-------+-------+
- * | Reserved | SA | RA
- * | RR | 1
- * +-------+-------+-------+-------+-------+-------+-------+-------+
- * | Remaining Time | 2
- * +---------------------------------------------------------------+
- * | Restarting Neighbor ID (If known)
- * | 0-8
- * +---------------------------------------------------------------+
- */
- *found |= TLVFLAG_GRACEFUL_RESTART;
- if (*expected & TLVFLAG_GRACEFUL_RESTART) {
- /* FIXME: make this work */
- }
- pnt += length;
- break;
-
- case MT_ROUTER_INFORMATION:
- *found |= TLVFLAG_MT_ROUTER_INFORMATION;
- if (*expected & TLVFLAG_MT_ROUTER_INFORMATION) {
- if (!tlvs->mt_router_info) {
- tlvs->mt_router_info = list_new();
- tlvs->mt_router_info->del = free_tlv;
- }
- while (length > value_len) {
- uint16_t mt_info;
- struct mt_router_info *info;
-
- if (value_len + sizeof(mt_info)
- > length) {
- zlog_warn(
- "ISIS-TLV (%s): TLV 229 is truncated.",
- areatag);
- pnt += length - value_len;
- break;
- }
-
- memcpy(&mt_info, pnt, sizeof(mt_info));
- pnt += sizeof(mt_info);
- value_len += sizeof(mt_info);
-
- mt_info = ntohs(mt_info);
- info = XCALLOC(MTYPE_ISIS_TLV,
- sizeof(*info));
- info->mtid = mt_info & ISIS_MT_MASK;
- info->overload =
- mt_info & ISIS_MT_OL_MASK;
- listnode_add(tlvs->mt_router_info,
- info);
- }
- } else {
- pnt += length;
- }
- break;
- default:
- zlog_warn(
- "ISIS-TLV (%s): unsupported TLV type %d, length %d",
- areatag, type, length);
-
- pnt += length;
- break;
- }
- /* Abort Parsing if error occured */
- if (retval != ISIS_OK)
- return retval;
- }
-
- return retval;
-}
-
-int add_tlv(u_char tag, u_char len, u_char *value, struct stream *stream)
-{
- if ((stream_get_size(stream) - stream_get_endp(stream))
- < (((unsigned)len) + 2)) {
- zlog_warn(
- "No room for TLV of type %d "
- "(total size %d available %d required %d)",
- tag, (int)stream_get_size(stream),
- (int)(stream_get_size(stream)
- - stream_get_endp(stream)),
- len + 2);
- return ISIS_WARNING;
- }
-
- stream_putc(stream, tag); /* TAG */
- stream_putc(stream, len); /* LENGTH */
- stream_put(stream, value, (int)len); /* VALUE */
-
-#ifdef EXTREME_DEBUG
- zlog_debug("Added TLV %d len %d", tag, len);
-#endif /* EXTREME DEBUG */
- return ISIS_OK;
-}
-
-int tlv_add_mt_router_info(struct list *mt_router_info, struct stream *stream)
-{
- struct listnode *node;
- struct mt_router_info *info;
-
- uint16_t value[127];
- uint16_t *pos = value;
-
- for (ALL_LIST_ELEMENTS_RO(mt_router_info, node, info)) {
- uint16_t mt_info;
-
- mt_info = info->mtid;
- if (info->overload)
- mt_info |= ISIS_MT_OL_MASK;
-
- *pos = htons(mt_info);
- pos++;
- }
-
- return add_tlv(MT_ROUTER_INFORMATION, (pos - value) * sizeof(*pos),
- (u_char *)value, stream);
-}
-
-int tlv_add_area_addrs(struct list *area_addrs, struct stream *stream)
-{
- struct listnode *node;
- struct area_addr *area_addr;
-
- u_char value[255];
- u_char *pos = value;
-
- for (ALL_LIST_ELEMENTS_RO(area_addrs, node, area_addr)) {
- if (pos - value + area_addr->addr_len > 255)
- goto err;
- *pos = area_addr->addr_len;
- pos++;
- memcpy(pos, area_addr->area_addr, (int)area_addr->addr_len);
- pos += area_addr->addr_len;
- }
-
- return add_tlv(AREA_ADDRESSES, pos - value, value, stream);
-
-err:
- zlog_warn("tlv_add_area_addrs(): TLV longer than 255");
- return ISIS_WARNING;
-}
-
-int tlv_add_is_neighs(struct list *is_neighs, struct stream *stream)
-{
- struct listnode *node;
- struct is_neigh *is_neigh;
- u_char value[255];
- u_char *pos = value;
- int retval;
-
- *pos = 0; /*is_neigh->virtual; */
- pos++;
-
- for (ALL_LIST_ELEMENTS_RO(is_neighs, node, is_neigh)) {
- if (pos - value + IS_NEIGHBOURS_LEN > 255) {
- retval = add_tlv(IS_NEIGHBOURS, pos - value, value,
- stream);
- if (retval != ISIS_OK)
- return retval;
- pos = value;
- }
- *pos = is_neigh->metrics.metric_default;
- pos++;
- *pos = is_neigh->metrics.metric_delay;
- pos++;
- *pos = is_neigh->metrics.metric_expense;
- pos++;
- *pos = is_neigh->metrics.metric_error;
- pos++;
- memcpy(pos, is_neigh->neigh_id, ISIS_SYS_ID_LEN + 1);
- pos += ISIS_SYS_ID_LEN + 1;
- }
-
- return add_tlv(IS_NEIGHBOURS, pos - value, value, stream);
-}
-
-static size_t max_tlv_size(struct stream *stream)
-{
- size_t avail = stream_get_size(stream) - stream_get_endp(stream);
-
- if (avail < 2)
- return 0;
-
- if (avail < 257)
- return avail - 2;
-
- return 255;
-}
-
-unsigned int tlv_add_te_is_neighs(struct list *te_is_neighs,
- struct stream *stream, void *arg)
-{
- struct listnode *node;
- struct te_is_neigh *te_is_neigh;
- u_char value[255];
- u_char *pos = value;
- uint16_t mtid = arg ? *(uint16_t *)arg : ISIS_MT_IPV4_UNICAST;
- unsigned int consumed = 0;
- size_t max_size = max_tlv_size(stream);
-
- if (mtid != ISIS_MT_IPV4_UNICAST) {
- uint16_t mtid_conversion = ntohs(mtid);
- memcpy(pos, &mtid_conversion, sizeof(mtid_conversion));
- pos += sizeof(mtid_conversion);
- }
-
- for (ALL_LIST_ELEMENTS_RO(te_is_neighs, node, te_is_neigh)) {
- /* FIXME: Check if Total SubTLVs size doesn't exceed 255 */
- if ((size_t)(pos - value) + IS_NEIGHBOURS_LEN
- + te_is_neigh->sub_tlvs_length
- > max_size)
- break;
-
- memcpy(pos, te_is_neigh->neigh_id, ISIS_SYS_ID_LEN + 1);
- pos += ISIS_SYS_ID_LEN + 1;
- memcpy(pos, te_is_neigh->te_metric, 3);
- pos += 3;
- /* Set the total size of Sub TLVs */
- *pos = te_is_neigh->sub_tlvs_length;
- pos++;
- /* Copy Sub TLVs if any */
- if (te_is_neigh->sub_tlvs_length > 0) {
- memcpy(pos, te_is_neigh->sub_tlvs,
- te_is_neigh->sub_tlvs_length);
- pos += te_is_neigh->sub_tlvs_length;
- }
- consumed++;
- }
-
- if (consumed) {
- int rv = add_tlv((mtid != ISIS_MT_IPV4_UNICAST)
- ? MT_IS_NEIGHBOURS
- : TE_IS_NEIGHBOURS,
- pos - value, value, stream);
- assert(rv == ISIS_OK);
- }
- return consumed;
-}
-
-int tlv_add_lan_neighs(struct list *lan_neighs, struct stream *stream)
-{
- struct listnode *node;
- u_char *snpa;
- u_char value[255];
- u_char *pos = value;
- int retval;
-
- for (ALL_LIST_ELEMENTS_RO(lan_neighs, node, snpa)) {
- if (pos - value + ETH_ALEN > 255) {
- retval = add_tlv(LAN_NEIGHBOURS, pos - value, value,
- stream);
- if (retval != ISIS_OK)
- return retval;
- pos = value;
- }
- memcpy(pos, snpa, ETH_ALEN);
- pos += ETH_ALEN;
- }
-
- return add_tlv(LAN_NEIGHBOURS, pos - value, value, stream);
-}
-
-int tlv_add_nlpid(struct nlpids *nlpids, struct stream *stream)
-{
- return add_tlv(PROTOCOLS_SUPPORTED, nlpids->count, nlpids->nlpids,
- stream);
-}
-
-int tlv_add_authinfo(u_char auth_type, u_char auth_len, u_char *auth_value,
- struct stream *stream)
-{
- u_char value[255];
- u_char *pos = value;
- *pos++ = auth_type;
- memcpy(pos, auth_value, auth_len);
-
- return add_tlv(AUTH_INFO, auth_len + 1, value, stream);
-}
-
-int tlv_add_checksum(struct checksum *checksum, struct stream *stream)
-{
- u_char value[255];
- u_char *pos = value;
- return add_tlv(CHECKSUM, pos - value, value, stream);
-}
-
-int tlv_add_ip_addrs(struct list *ip_addrs, struct stream *stream)
-{
- struct listnode *node;
- struct prefix_ipv4 *ipv4;
- u_char value[255];
- u_char *pos = value;
-
- for (ALL_LIST_ELEMENTS_RO(ip_addrs, node, ipv4)) {
- if (pos - value + IPV4_MAX_BYTELEN > 255) {
- /* RFC 1195 s4.2: only one tuple of 63 allowed. */
- zlog_warn(
- "tlv_add_ip_addrs(): cutting off at 63 IP addresses");
- break;
- }
- *(u_int32_t *)pos = ipv4->prefix.s_addr;
- pos += IPV4_MAX_BYTELEN;
- }
-
- return add_tlv(IPV4_ADDR, pos - value, value, stream);
-}
-
-/* Used to add TLV containing just one IPv4 address - either IPv4 address TLV
- * (in case of LSP) or TE router ID TLV. */
-int tlv_add_in_addr(struct in_addr *addr, struct stream *stream, u_char tag)
-{
- u_char value[255];
- u_char *pos = value;
-
- memcpy(pos, addr, IPV4_MAX_BYTELEN);
- pos += IPV4_MAX_BYTELEN;
-
- return add_tlv(tag, pos - value, value, stream);
-}
-
-int tlv_add_dynamic_hostname(struct hostname *hostname, struct stream *stream)
-{
- return add_tlv(DYNAMIC_HOSTNAME, hostname->namelen, hostname->name,
- stream);
-}
-
-int tlv_add_lsp_entries(struct list *lsps, struct stream *stream)
-{
- struct listnode *node;
- struct isis_lsp *lsp;
- u_char value[255];
- u_char *pos = value;
- int retval;
-
- for (ALL_LIST_ELEMENTS_RO(lsps, node, lsp)) {
- if (pos - value + LSP_ENTRIES_LEN > 255) {
- retval = add_tlv(LSP_ENTRIES, pos - value, value,
- stream);
- if (retval != ISIS_OK)
- return retval;
- pos = value;
- }
- *((u_int16_t *)pos) = lsp->lsp_header->rem_lifetime;
- pos += 2;
- memcpy(pos, lsp->lsp_header->lsp_id, ISIS_SYS_ID_LEN + 2);
- pos += ISIS_SYS_ID_LEN + 2;
- *((u_int32_t *)pos) = lsp->lsp_header->seq_num;
- pos += 4;
- *((u_int16_t *)pos) = lsp->lsp_header->checksum;
- pos += 2;
- }
-
- return add_tlv(LSP_ENTRIES, pos - value, value, stream);
-}
-
-static int tlv_add_ipv4_reachs(u_char tag, struct list *ipv4_reachs,
- struct stream *stream)
-{
- struct listnode *node;
- struct ipv4_reachability *reach;
- u_char value[255];
- u_char *pos = value;
- int retval;
-
- for (ALL_LIST_ELEMENTS_RO(ipv4_reachs, node, reach)) {
- if (pos - value + IPV4_REACH_LEN > 255) {
- retval = add_tlv(tag, pos - value, value, stream);
- if (retval != ISIS_OK)
- return retval;
- pos = value;
- }
- *pos = reach->metrics.metric_default;
- pos++;
- *pos = reach->metrics.metric_delay;
- pos++;
- *pos = reach->metrics.metric_expense;
- pos++;
- *pos = reach->metrics.metric_error;
- pos++;
- *(u_int32_t *)pos = reach->prefix.s_addr;
- pos += IPV4_MAX_BYTELEN;
- *(u_int32_t *)pos = reach->mask.s_addr;
- pos += IPV4_MAX_BYTELEN;
- }
-
- return add_tlv(tag, pos - value, value, stream);
-}
-
-int tlv_add_ipv4_int_reachs(struct list *ipv4_reachs, struct stream *stream)
-{
- return tlv_add_ipv4_reachs(IPV4_INT_REACHABILITY, ipv4_reachs, stream);
-}
-
-int tlv_add_ipv4_ext_reachs(struct list *ipv4_reachs, struct stream *stream)
-{
- return tlv_add_ipv4_reachs(IPV4_EXT_REACHABILITY, ipv4_reachs, stream);
-}
-
-
-unsigned int tlv_add_te_ipv4_reachs(struct list *te_ipv4_reachs,
- struct stream *stream, void *arg)
-{
- struct listnode *node;
- struct te_ipv4_reachability *te_reach;
- u_char value[255];
- u_char *pos = value;
- uint16_t mtid = arg ? *(uint16_t *)arg : ISIS_MT_IPV4_UNICAST;
- unsigned int consumed = 0;
- size_t max_size = max_tlv_size(stream);
-
- if (mtid != ISIS_MT_IPV4_UNICAST) {
- uint16_t mtid_conversion = ntohs(mtid);
- memcpy(pos, &mtid_conversion, sizeof(mtid_conversion));
- pos += sizeof(mtid_conversion);
- }
-
- for (ALL_LIST_ELEMENTS_RO(te_ipv4_reachs, node, te_reach)) {
- unsigned char prefixlen = te_reach->control & 0x3F;
-
- if ((size_t)(pos - value) + 5 + PSIZE(prefixlen) > max_size)
- break;
-
- *(u_int32_t *)pos = te_reach->te_metric;
- pos += 4;
- *pos = te_reach->control;
- pos++;
- memcpy(pos, &te_reach->prefix_start, PSIZE(prefixlen));
- pos += PSIZE(prefixlen);
- consumed++;
- }
-
- if (consumed) {
- int rv = add_tlv((mtid != ISIS_MT_IPV4_UNICAST)
- ? MT_IPV4_REACHABILITY
- : TE_IPV4_REACHABILITY,
- pos - value, value, stream);
- assert(rv == ISIS_OK);
- }
-
- return consumed;
-}
-
-int tlv_add_ipv6_addrs(struct list *ipv6_addrs, struct stream *stream)
-{
- struct listnode *node;
- struct prefix_ipv6 *ipv6;
- u_char value[255];
- u_char *pos = value;
- int retval;
-
- for (ALL_LIST_ELEMENTS_RO(ipv6_addrs, node, ipv6)) {
- if (pos - value + IPV6_MAX_BYTELEN > 255) {
- retval = add_tlv(IPV6_ADDR, pos - value, value, stream);
- if (retval != ISIS_OK)
- return retval;
- pos = value;
- }
- memcpy(pos, ipv6->prefix.s6_addr, IPV6_MAX_BYTELEN);
- pos += IPV6_MAX_BYTELEN;
- }
-
- return add_tlv(IPV6_ADDR, pos - value, value, stream);
-}
-
-unsigned int tlv_add_ipv6_reachs(struct list *ipv6_reachs,
- struct stream *stream, void *arg)
-{
- struct listnode *node;
- struct ipv6_reachability *ip6reach;
- u_char value[255];
- u_char *pos = value;
- uint16_t mtid = arg ? *(uint16_t *)arg : ISIS_MT_IPV4_UNICAST;
- unsigned int consumed = 0;
- size_t max_size = max_tlv_size(stream);
-
- if (mtid != ISIS_MT_IPV4_UNICAST) {
- uint16_t mtid_conversion = ntohs(mtid);
- memcpy(pos, &mtid_conversion, sizeof(mtid_conversion));
- pos += sizeof(mtid_conversion);
- }
-
- for (ALL_LIST_ELEMENTS_RO(ipv6_reachs, node, ip6reach)) {
- if ((size_t)(pos - value) + 6 + PSIZE(ip6reach->prefix_len)
- > max_size)
- break;
-
- *(uint32_t *)pos = ip6reach->metric;
- pos += 4;
- *pos = ip6reach->control_info;
- pos++;
- *pos = ip6reach->prefix_len;
- pos++;
- memcpy(pos, ip6reach->prefix, PSIZE(ip6reach->prefix_len));
- pos += PSIZE(ip6reach->prefix_len);
- consumed++;
- }
-
- if (consumed) {
- int rv = add_tlv((mtid != ISIS_MT_IPV4_UNICAST)
- ? MT_IPV6_REACHABILITY
- : IPV6_REACHABILITY,
- pos - value, value, stream);
- assert(rv == ISIS_OK);
- }
-
- return consumed;
-}
-
-int tlv_add_padding(struct stream *stream)
-{
- int fullpads, i, left;
-
- /*
- * How many times can we add full padding ?
- */
- fullpads = (stream_get_size(stream) - stream_get_endp(stream)) / 257;
- for (i = 0; i < fullpads; i++) {
- if (!stream_putc(stream, (u_char)PADDING)) /* TAG */
- goto err;
- if (!stream_putc(stream, (u_char)255)) /* LENGHT */
- goto err;
- stream_put(stream, NULL, 255); /* zero padding */
- }
-
- left = stream_get_size(stream) - stream_get_endp(stream);
-
- if (left < 2)
- return ISIS_OK;
-
- if (left == 2) {
- stream_putc(stream, PADDING);
- stream_putc(stream, 0);
- return ISIS_OK;
- }
-
- stream_putc(stream, PADDING);
- stream_putc(stream, left - 2);
- stream_put(stream, NULL, left - 2);
-
- return ISIS_OK;
-
-err:
- zlog_warn("tlv_add_padding(): no room for tlv");
- return ISIS_WARNING;
-}
diff --git a/isisd/isis_tlv.h b/isisd/isis_tlv.h
deleted file mode 100644
index d06548519..000000000
--- a/isisd/isis_tlv.h
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * IS-IS Rout(e)ing protocol - isis_tlv.h
- * IS-IS TLV related routines
- *
- * Copyright (C) 2001,2002 Sampo Saaristo
- * Tampere University of Technology
- * Institute of Communications Engineering
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public Licenseas published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _ZEBRA_ISIS_TLV_H
-#define _ZEBRA_ISIS_TLV_H
-
-#include "isisd/isis_mt.h"
-
-/*
- * The list of TLVs we (should) support.
- * ____________________________________________________________________________
- * Name Value IIH LSP SNP Status
- * LAN
- * ____________________________________________________________________________
- *
- * Area Addresses 1 y y n ISO10589
- * IIS Neighbors 2 n y n ISO10589
- * ES Neighbors 3 n y n ISO10589
- * IIS Neighbors 6 y n n ISO10589
- * Padding 8 y n n ISO10589
- * LSP Entries 9 n n y ISO10589
- * Authentication 10 y y y ISO10589, RFC3567
- * Checksum 12 y n y RFC3358
- * Extended IS Reachability 22 n y n RFC5305
- * IS Alias 24 n y n RFC3786
- * IP Int. Reachability 128 n y n RFC1195
- * Protocols Supported 129 y y n RFC1195
- * IP Ext. Reachability 130 n y n RFC1195
- * IDRPI 131 n y y RFC1195
- * IP Interface Address 132 y y n RFC1195
- * TE Router ID 134 n y n RFC5305
- * Extended IP Reachability 135 n y n RFC5305
- * Dynamic Hostname 137 n y n RFC2763
- * Shared Risk Link Group 138 n y y RFC5307
- * Inter-AS Reachability 141 n y n RFC5316
- * Restart TLV 211 y n n RFC3847
- * MT IS Reachability 222 n y n RFC5120
- * MT Supported 229 y y n RFC5120
- * IPv6 Interface Address 232 y y n RFC5308
- * MT IP Reachability 235 n y n RFC5120
- * IPv6 IP Reachability 236 n y n RFC5308
- * MT IPv6 IP Reachability 237 n y n RFC5120
- * P2P Adjacency State 240 y n n RFC3373
- * IIH Sequence Number 241 y n n draft-shen-isis-iih-sequence
- * Router Capability 242 n y n RFC4971
- *
- *
- * IS Reachability sub-TLVs we support (See isis_te.[c,h])
- * ____________________________________________________________________________
- * Name Value Status
- * ____________________________________________________________________________
- * Administartive group (color) 3 RFC5305
- * Link Local/Remote Identifiers 4 RFC5307
- * IPv4 interface address 6 RFC5305
- * IPv4 neighbor address 8 RFC5305
- * Maximum link bandwidth 9 RFC5305
- * Reservable link bandwidth 10 RFC5305
- * Unreserved bandwidth 11 RFC5305
- * TE Default metric 18 RFC5305
- * Link Protection Type 20 RFC5307
- * Interface Switching Capability 21 RFC5307
- * Remote AS number 24 RFC5316
- * IPv4 Remote ASBR identifier 25 RFC5316
- *
- *
- * IP Reachability sub-TLVs we (should) support.
- * ____________________________________________________________________________
- * Name Value Status
- * ____________________________________________________________________________
- * 32bit administrative tag 1 RFC5130
- * 64bit administrative tag 2 RFC5130
- * Management prefix color 117 RFC5120
- */
-
-#define AREA_ADDRESSES 1
-#define IS_NEIGHBOURS 2
-#define ES_NEIGHBOURS 3
-#define LAN_NEIGHBOURS 6
-#define PADDING 8
-#define LSP_ENTRIES 9
-#define AUTH_INFO 10
-#define CHECKSUM 12
-#define TE_IS_NEIGHBOURS 22
-#define IS_ALIAS 24
-#define IPV4_INT_REACHABILITY 128
-#define PROTOCOLS_SUPPORTED 129
-#define IPV4_EXT_REACHABILITY 130
-#define IDRP_INFO 131
-#define IPV4_ADDR 132
-#define TE_ROUTER_ID 134
-#define TE_IPV4_REACHABILITY 135
-#define DYNAMIC_HOSTNAME 137
-#define GRACEFUL_RESTART 211
-#define MT_IS_NEIGHBOURS 222
-#define MT_ROUTER_INFORMATION 229
-#define IPV6_ADDR 232
-#define MT_IPV4_REACHABILITY 235
-#define IPV6_REACHABILITY 236
-#define MT_IPV6_REACHABILITY 237
-#define WAY3_HELLO 240
-#define ROUTER_INFORMATION 242
-
-#define AUTH_INFO_HDRLEN 3
-
-#define MAX_TLV_LEN 255
-
-#define IS_NEIGHBOURS_LEN (ISIS_SYS_ID_LEN + 5)
-#define LAN_NEIGHBOURS_LEN 6
-#define LSP_ENTRIES_LEN (10 + ISIS_SYS_ID_LEN) /* FIXME: should be entry */
-#define IPV4_REACH_LEN 12
-#define IPV6_REACH_LEN 22
-#define TE_IPV4_REACH_LEN 9
-
-#define MAX_SUBTLV_SIZE 256
-
-/* struct for neighbor */
-struct is_neigh {
- struct metric metrics;
- u_char neigh_id[ISIS_SYS_ID_LEN + 1];
-};
-
-/* struct for te metric */
-struct te_is_neigh {
- u_char neigh_id[ISIS_SYS_ID_LEN + 1];
- u_char te_metric[3];
- u_char sub_tlvs_length;
- /* Theorical Maximum SubTLVs is 256 because the sub_tlvs_length is 8
- * bits */
- /* Practically, 118 bytes are necessary to store all supported TE
- * parameters */
- /* FIXME: A pointer will use less memory, but need to be free */
- /* which is hard to fix, especially within free_tlvs() function */
- /* and malloc() / free() as a CPU cost compared to the memory usage */
- u_char sub_tlvs[MAX_SUBTLV_SIZE]; /* SUB TLVs storage */
-};
-
-/* Decode and encode three-octet metric into host byte order integer */
-#define GET_TE_METRIC(t) \
- (((unsigned)(t)->te_metric[0] << 16) | ((t)->te_metric[1] << 8) \
- | (t)->te_metric[2])
-#define SET_TE_METRIC(t, m) \
- (((t)->te_metric[0] = (m) >> 16), ((t)->te_metric[1] = (m) >> 8), \
- ((t)->te_metric[2] = (m)))
-
-/* struct for es neighbors */
-struct es_neigh {
- struct metric metrics;
- /* approximate position of first, we use the
- * length ((uchar*)metric-1) to know all */
- u_char first_es_neigh[ISIS_SYS_ID_LEN];
-};
-
-struct partition_desig_level2_is {
- struct list *isis_system_ids;
-};
-
-/* struct for lan neighbors */
-struct lan_neigh {
- u_char LAN_addr[6];
-};
-
-#ifdef __SUNPRO_C
-#pragma pack(1)
-#endif
-
-/* struct for LSP entry */
-struct lsp_entry {
- u_int16_t rem_lifetime;
- u_char lsp_id[ISIS_SYS_ID_LEN + 2];
- u_int32_t seq_num;
- u_int16_t checksum;
-} __attribute__((packed));
-
-#ifdef __SUNPRO_C
-#pragma pack()
-#endif
-
-/* struct for checksum */
-struct checksum {
- u_int16_t checksum;
-};
-
-/* ipv4 reachability */
-struct ipv4_reachability {
- struct metric metrics;
- struct in_addr prefix;
- struct in_addr mask;
-};
-
-/* te router id */
-struct te_router_id {
- struct in_addr id;
-};
-
-/* te ipv4 reachability */
-struct te_ipv4_reachability {
- u_int32_t te_metric;
- u_char control;
- u_char prefix_start; /* since this is variable length by nature it only
- */
-}; /* points to an approximate location */
-
-#define TE_IPV4_HAS_SUBTLV (0x40)
-
-struct idrp_info {
- u_char len;
- u_char *value;
-};
-
-struct ipv6_reachability {
- u_int32_t metric;
- u_char control_info;
- u_char prefix_len;
- u_char prefix[16];
-};
-
-/* bits in control_info */
-#define CTRL_INFO_DIRECTION 0x80
-#define DIRECTION_UP 0x00
-#define DIRECTION_DOWN 0x80
-
-#define CTRL_INFO_DISTRIBUTION 0x40
-#define DISTRIBUTION_INTERNAL 0x00
-#define DISTRIBUTION_EXTERNAL 0x40
-
-#define CTRL_INFO_SUBTLVS 0x20
-
-struct mt_router_info {
- ISIS_MT_INFO_FIELDS
- bool overload;
-};
-
-/*
- * Pointer to each tlv type, filled by parse_tlvs()
- */
-struct tlvs {
- struct checksum *checksum;
- struct hostname *hostname;
- struct nlpids *nlpids;
- struct te_router_id *router_id;
- struct list *area_addrs;
- struct list *mt_router_info;
- struct list *is_neighs;
- struct list *te_is_neighs;
- struct list *mt_is_neighs;
- struct list *es_neighs;
- struct list *lsp_entries;
- struct list *prefix_neighs;
- struct list *lan_neighs;
- struct list *ipv4_addrs;
- struct list *ipv4_int_reachs;
- struct list *ipv4_ext_reachs;
- struct list *te_ipv4_reachs;
- struct list *mt_ipv4_reachs;
- struct list *ipv6_addrs;
- struct list *ipv6_reachs;
- struct list *mt_ipv6_reachs;
- struct isis_passwd auth_info;
-};
-
-/*
- * Own definitions - used to bitmask found and expected
- */
-
-#define TLVFLAG_AREA_ADDRS (1<<0)
-#define TLVFLAG_IS_NEIGHS (1<<1)
-#define TLVFLAG_ES_NEIGHS (1<<2)
-#define TLVFLAG_PARTITION_DESIG_LEVEL2_IS (1<<3)
-#define TLVFLAG_PREFIX_NEIGHS (1<<4)
-#define TLVFLAG_LAN_NEIGHS (1<<5)
-#define TLVFLAG_LSP_ENTRIES (1<<6)
-#define TLVFLAG_PADDING (1<<7)
-#define TLVFLAG_AUTH_INFO (1<<8)
-#define TLVFLAG_IPV4_INT_REACHABILITY (1<<9)
-#define TLVFLAG_NLPID (1<<10)
-#define TLVFLAG_IPV4_EXT_REACHABILITY (1<<11)
-#define TLVFLAG_IPV4_ADDR (1<<12)
-#define TLVFLAG_DYN_HOSTNAME (1<<13)
-#define TLVFLAG_IPV6_ADDR (1<<14)
-#define TLVFLAG_IPV6_REACHABILITY (1<<15)
-#define TLVFLAG_TE_IS_NEIGHS (1<<16)
-#define TLVFLAG_TE_IPV4_REACHABILITY (1<<17)
-#define TLVFLAG_3WAY_HELLO (1<<18)
-#define TLVFLAG_TE_ROUTER_ID (1<<19)
-#define TLVFLAG_CHECKSUM (1<<20)
-#define TLVFLAG_GRACEFUL_RESTART (1<<21)
-#define TLVFLAG_MT_ROUTER_INFORMATION (1<<22)
-
-void init_tlvs(struct tlvs *tlvs, uint32_t expected);
-void free_tlvs(struct tlvs *tlvs);
-int parse_tlvs(char *areatag, u_char *stream, int size, u_int32_t *expected,
- u_int32_t *found, struct tlvs *tlvs, u_int32_t *auth_tlv_offset);
-int add_tlv(u_char, u_char, u_char *, struct stream *);
-void free_tlv(void *val);
-
-int tlv_add_mt_router_info(struct list *mt_router_info, struct stream *stream);
-int tlv_add_area_addrs(struct list *area_addrs, struct stream *stream);
-int tlv_add_is_neighs(struct list *is_neighs, struct stream *stream);
-unsigned int tlv_add_te_is_neighs(struct list *te_is_neighs,
- struct stream *stream, void *arg);
-int tlv_add_lan_neighs(struct list *lan_neighs, struct stream *stream);
-int tlv_add_nlpid(struct nlpids *nlpids, struct stream *stream);
-int tlv_add_checksum(struct checksum *checksum, struct stream *stream);
-int tlv_add_authinfo(u_char auth_type, u_char authlen, u_char *auth_value,
- struct stream *stream);
-int tlv_add_ip_addrs(struct list *ip_addrs, struct stream *stream);
-int tlv_add_in_addr(struct in_addr *, struct stream *stream, u_char tag);
-int tlv_add_dynamic_hostname(struct hostname *hostname, struct stream *stream);
-int tlv_add_lsp_entries(struct list *lsps, struct stream *stream);
-int tlv_add_ipv4_int_reachs(struct list *ipv4_reachs, struct stream *stream);
-int tlv_add_ipv4_ext_reachs(struct list *ipv4_reachs, struct stream *stream);
-unsigned int tlv_add_te_ipv4_reachs(struct list *te_ipv4_reachs,
- struct stream *stream, void *arg);
-int tlv_add_ipv6_addrs(struct list *ipv6_addrs, struct stream *stream);
-unsigned int tlv_add_ipv6_reachs(struct list *ipv6_reachs,
- struct stream *stream, void *arg);
-
-int tlv_add_padding(struct stream *stream);
-
-#endif /* _ZEBRA_ISIS_TLV_H */
diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c
index 18a59d1fc..8c6968f8e 100644
--- a/isisd/isis_zebra.c
+++ b/isisd/isis_zebra.c
@@ -42,7 +42,6 @@
#include "isisd/isis_flags.h"
#include "isisd/isis_misc.h"
#include "isisd/isis_circuit.h"
-#include "isisd/isis_tlv.h"
#include "isisd/isisd.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_csm.h"
diff --git a/isisd/isisd.c b/isisd/isisd.c
index 8bbb5cf94..05797fb73 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -49,7 +49,6 @@
#include "isisd/isis_pdu.h"
#include "isisd/isis_misc.h"
#include "isisd/isis_constants.h"
-#include "isisd/isis_tlv.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_spf.h"
#include "isisd/isis_route.h"
diff --git a/isisd/iso_checksum.c b/isisd/iso_checksum.c
index e0a4ba370..25a870991 100644
--- a/isisd/iso_checksum.c
+++ b/isisd/iso_checksum.c
@@ -67,7 +67,7 @@ int iso_csum_verify(u_char *buffer, int len, uint16_t csum, int offset)
return 1;
checksum = fletcher_checksum(buffer, len, offset);
- if (checksum == csum)
+ if (checksum == htons(csum))
return 0;
return 1;
}