isisd: send/receive LSPs with new parser

Signed-off-by: Christian Franke <chris@opensourcerouting.org>
This commit is contained in:
Christian Franke 2017-07-05 18:37:36 +02:00
parent 17c9dcd5f1
commit af8ac8f98f
29 changed files with 988 additions and 4286 deletions

View File

@ -13,7 +13,7 @@ sbin_PROGRAMS = isisd
libisis_a_SOURCES = \ libisis_a_SOURCES = \
isis_memory.c \ isis_memory.c \
isis_adjacency.c isis_lsp.c dict.c isis_circuit.c isis_pdu.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_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_spf.c isis_redist.c isis_route.c isis_routemap.c isis_te.c \
isis_vty.c isis_mt.c \ isis_vty.c isis_mt.c \
@ -22,7 +22,7 @@ libisis_a_SOURCES = \
noinst_HEADERS = \ noinst_HEADERS = \
isis_memory.h \ 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_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 \ 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 \ iso_checksum.h isis_csm.h isis_events.h isis_spf.h isis_redist.h \

View File

@ -43,7 +43,6 @@
#include "isisd/isis_dr.h" #include "isisd/isis_dr.h"
#include "isisd/isis_dynhn.h" #include "isisd/isis_dynhn.h"
#include "isisd/isis_pdu.h" #include "isisd/isis_pdu.h"
#include "isisd/isis_tlv.h"
#include "isisd/isis_lsp.h" #include "isisd/isis_lsp.h"
#include "isisd/isis_spf.h" #include "isisd/isis_spf.h"
#include "isisd/isis_events.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); dyn = dynhn_find_by_id(adj->sysid);
if (dyn) if (dyn)
adj_name = (const char *)dyn->name.name; adj_name = dyn->hostname;
else else
adj_name = sysid_print(adj->sysid); adj_name = sysid_print(adj->sysid);
@ -301,7 +300,7 @@ void isis_adj_print(struct isis_adjacency *adj)
return; return;
dyn = dynhn_find_by_id(adj->sysid); dyn = dynhn_find_by_id(adj->sysid);
if (dyn) if (dyn)
zlog_debug("%s", dyn->name.name); zlog_debug("%s", dyn->hostname);
zlog_debug("SystemId %20s SNPA %s, level %d\nHolding Time %d", zlog_debug("SystemId %20s SNPA %s, level %d\nHolding Time %d",
sysid_print(adj->sysid), snpa_print(adj->snpa), adj->level, 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); dyn = dynhn_find_by_id(adj->sysid);
if (dyn) if (dyn)
vty_out(vty, " %-20s", dyn->name.name); vty_out(vty, " %-20s", dyn->hostname);
else else
vty_out(vty, " %-20s", sysid_print(adj->sysid)); 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)) { && (adj->circuit->circ_type == CIRCUIT_T_BROADCAST)) {
dyn = dynhn_find_by_id(adj->lanid); dyn = dynhn_find_by_id(adj->lanid);
if (dyn) if (dyn)
vty_out(vty, ", LAN id: %s.%02x", vty_out(vty, ", LAN id: %s.%02x", dyn->hostname,
dyn->name.name,
adj->lanid[ISIS_SYS_ID_LEN]); adj->lanid[ISIS_SYS_ID_LEN]);
else else
vty_out(vty, ", LAN id: %s.%02x", vty_out(vty, ", LAN id: %s.%02x",

View File

@ -48,7 +48,6 @@
#include "isisd/isis_common.h" #include "isisd/isis_common.h"
#include "isisd/isis_flags.h" #include "isisd/isis_flags.h"
#include "isisd/isis_circuit.h" #include "isisd/isis_circuit.h"
#include "isisd/isis_tlv.h"
#include "isisd/isis_lsp.h" #include "isisd/isis_lsp.h"
#include "isisd/isis_pdu.h" #include "isisd/isis_pdu.h"
#include "isisd/isis_network.h" #include "isisd/isis_network.h"

View File

@ -46,16 +46,6 @@ struct isis_passwd {
u_char passwd[255]; u_char passwd[255];
}; };
/*
* (Dynamic) Hostname
* one struct for cache list
* one struct for LSP TLV
*/
struct hostname {
u_char namelen;
u_char name[255];
};
/* /*
* Supported Protocol IDs * Supported Protocol IDs
*/ */

View File

@ -37,7 +37,6 @@
#include "isisd/isis_common.h" #include "isisd/isis_common.h"
#include "isisd/isis_flags.h" #include "isisd/isis_flags.h"
#include "isisd/isis_circuit.h" #include "isisd/isis_circuit.h"
#include "isisd/isis_tlv.h"
#include "isisd/isis_lsp.h" #include "isisd/isis_lsp.h"
#include "isisd/isis_pdu.h" #include "isisd/isis_pdu.h"
#include "isisd/isis_network.h" #include "isisd/isis_network.h"

View File

@ -42,7 +42,6 @@
#include "isisd/isis_adjacency.h" #include "isisd/isis_adjacency.h"
#include "isisd/isis_constants.h" #include "isisd/isis_constants.h"
#include "isisd/isis_pdu.h" #include "isisd/isis_pdu.h"
#include "isisd/isis_tlv.h"
#include "isisd/isis_lsp.h" #include "isisd/isis_lsp.h"
#include "isisd/isis_dr.h" #include "isisd/isis_dr.h"
#include "isisd/isis_events.h" #include "isisd/isis_events.h"

View File

@ -94,38 +94,26 @@ struct isis_dynhn *dynhn_find_by_name(const char *hostname)
struct isis_dynhn *dyn = NULL; struct isis_dynhn *dyn = NULL;
for (ALL_LIST_ELEMENTS_RO(dyn_cache, node, dyn)) 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 dyn;
return NULL; 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; struct isis_dynhn *dyn;
dyn = dynhn_find_by_id(id); 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) { if (!dyn) {
zlog_warn("isis_dynhn_insert(): out of memory!"); dyn = XCALLOC(MTYPE_ISIS_DYNHN, sizeof(struct isis_dynhn));
return; memcpy(dyn->id, id, ISIS_SYS_ID_LEN);
dyn->level = level;
listnode_add(dyn_cache, dyn);
} }
/* we also copy the length */ snprintf(dyn->hostname, sizeof(dyn->hostname), "%s", hostname);
memcpy(&dyn->name, hostname, hostname->namelen + 1);
memcpy(dyn->id, id, ISIS_SYS_ID_LEN);
dyn->refresh = time(NULL); dyn->refresh = time(NULL);
dyn->level = level;
listnode_add(dyn_cache, dyn);
return;
} }
void isis_dynhn_remove(const u_char *id) void isis_dynhn_remove(const u_char *id)
@ -137,7 +125,6 @@ void isis_dynhn_remove(const u_char *id)
return; return;
listnode_delete(dyn_cache, dyn); listnode_delete(dyn_cache, dyn);
XFREE(MTYPE_ISIS_DYNHN, 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)) { for (ALL_LIST_ELEMENTS_RO(dyn_cache, node, dyn)) {
vty_out(vty, "%-7d", dyn->level); vty_out(vty, "%-7d", dyn->level);
vty_out(vty, "%-15s%-15s\n", sysid_print(dyn->id), 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), vty_out(vty, " * %s %s\n", sysid_print(isis->sysid),

View File

@ -25,13 +25,13 @@
struct isis_dynhn { struct isis_dynhn {
u_char id[ISIS_SYS_ID_LEN]; u_char id[ISIS_SYS_ID_LEN];
struct hostname name; char hostname[256];
time_t refresh; time_t refresh;
int level; int level;
}; };
void dyn_cache_init(void); 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); 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_id(const u_char *id);
struct isis_dynhn *dynhn_find_by_name(const char *hostname); struct isis_dynhn *dynhn_find_by_name(const char *hostname);

View File

@ -37,7 +37,6 @@
#include "isisd/isis_common.h" #include "isisd/isis_common.h"
#include "isisd/isis_flags.h" #include "isisd/isis_flags.h"
#include "isisd/isis_circuit.h" #include "isisd/isis_circuit.h"
#include "isisd/isis_tlv.h"
#include "isisd/isis_lsp.h" #include "isisd/isis_lsp.h"
#include "isisd/isis_pdu.h" #include "isisd/isis_pdu.h"
#include "isisd/isis_network.h" #include "isisd/isis_network.h"

File diff suppressed because it is too large Load Diff

View File

@ -24,18 +24,19 @@
#ifndef _ZEBRA_ISIS_LSP_H #ifndef _ZEBRA_ISIS_LSP_H
#define _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 /* Structure for isis_lsp, this structure will only support the fixed
* System ID (Currently 6) (atleast for now). In order to support more * 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 * We will have to split the header into two parts, and for readability
* sake it should better be avoided */ * sake it should better be avoided */
struct isis_lsp { struct isis_lsp {
struct isis_link_state_hdr *lsp_header; /* pdu + isis_header_len */ struct isis_lsp_hdr hdr;
struct stream *pdu; /* full pdu lsp */ struct stream *pdu; /* full pdu lsp */
union { union {
struct list *frags; struct list *frags;
struct isis_lsp *zero_lsp; struct isis_lsp *zero_lsp;
} lspu; } lspu;
u_int32_t auth_tlv_offset; /* authentication TLV position in the pdu */
u_int32_t SRMflags[ISIS_MAX_CIRCUITS]; u_int32_t SRMflags[ISIS_MAX_CIRCUITS];
u_int32_t SSNflags[ISIS_MAX_CIRCUITS]; u_int32_t SSNflags[ISIS_MAX_CIRCUITS];
int level; /* L1 or L2? */ int level; /* L1 or L2? */
@ -46,7 +47,7 @@ struct isis_lsp {
/* used for 60 second counting when rem_lifetime is zero */ /* used for 60 second counting when rem_lifetime is zero */
int age_out; int age_out;
struct isis_area *area; struct isis_area *area;
struct tlvs tlv_data; /* Simplifies TLV access */ struct isis_tlvs *tlvs;
}; };
dict_t *lsp_db_init(void); dict_t *lsp_db_init(void);
@ -58,12 +59,12 @@ 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_generate_pseudo(struct isis_circuit *circuit, int level);
int lsp_regenerate_schedule_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, struct isis_lsp *lsp_new(struct isis_area *area, uint8_t *lsp_id,
u_int16_t rem_lifetime, u_int32_t seq_num, uint16_t rem_lifetime, uint32_t seq_num,
u_int8_t lsp_bits, u_int16_t checksum, int level); uint8_t lsp_bits, uint16_t checksum, int level);
struct isis_lsp *lsp_new_from_stream_ptr(struct stream *stream, struct isis_lsp *lsp_new_from_recv(struct isis_lsp_hdr *hdr,
u_int16_t pdu_len, struct isis_tlvs *tlvs,
struct isis_lsp *lsp0, struct stream *stream, struct isis_lsp *lsp0,
struct isis_area *area, int level); struct isis_area *area, int level);
void lsp_insert(struct isis_lsp *lsp, dict_t *lspdb); void lsp_insert(struct isis_lsp *lsp, dict_t *lspdb);
struct isis_lsp *lsp_search(u_char *id, 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); struct list *list, dict_t *lspdb);
void lsp_search_and_destroy(u_char *id, 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_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); struct isis_area *area);
#define LSP_EQUAL 1 #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] = 0; \
(I)[ISIS_SYS_ID_LEN + 1] = 0 (I)[ISIS_SYS_ID_LEN + 1] = 0
int lsp_id_cmp(u_char *id1, u_char *id2); int lsp_id_cmp(u_char *id1, u_char *id2);
int lsp_compare(char *areatag, struct isis_lsp *lsp, u_int32_t seq_num, int lsp_compare(char *areatag, struct isis_lsp *lsp, uint32_t seqno,
u_int16_t checksum, u_int16_t rem_lifetime); uint16_t checksum, uint16_t rem_lifetime);
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); 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(struct isis_lsp *lsp, struct vty *vty, char dynhost);
void lsp_print_detail(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); 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 */ /* sets SRMflags for all active circuits of an lsp */
void lsp_set_all_srmflags(struct isis_lsp *lsp); void lsp_set_all_srmflags(struct isis_lsp *lsp);

View File

@ -52,7 +52,6 @@
#include "isisd/isis_route.h" #include "isisd/isis_route.h"
#include "isisd/isis_routemap.h" #include "isisd/isis_routemap.h"
#include "isisd/isis_zebra.h" #include "isisd/isis_zebra.h"
#include "isisd/isis_tlv.h"
#include "isisd/isis_te.h" #include "isisd/isis_te.h"
/* Default configuration file name */ /* Default configuration file name */

View File

@ -39,7 +39,6 @@
#include "isisd/isisd.h" #include "isisd/isisd.h"
#include "isisd/isis_misc.h" #include "isisd/isis_misc.h"
#include "isisd/isis_tlv.h"
#include "isisd/isis_lsp.h" #include "isisd/isis_lsp.h"
#include "isisd/isis_constants.h" #include "isisd/isis_constants.h"
#include "isisd/isis_adjacency.h" #include "isisd/isis_adjacency.h"
@ -215,25 +214,6 @@ char *nlpid2string(struct nlpids *nlpids)
return nlpidstring; return nlpidstring;
} }
/*
* 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 * Returns 0 on error, IS-IS Circuit Type on ok
*/ */
@ -486,7 +466,7 @@ const char *print_sys_hostname(const u_char *sysid)
dyn = dynhn_find_by_id(sysid); dyn = dynhn_find_by_id(sysid);
if (dyn) if (dyn)
return (const char *)dyn->name.name; return dyn->hostname;
return sysid_print(sysid); return sysid_print(sysid);
} }

View File

@ -55,7 +55,6 @@ void zlog_dump_data(void *data, int len);
/* /*
* misc functions * misc functions
*/ */
int speaks(struct nlpids *nlpids, int family);
unsigned long isis_jitter(unsigned long timer, unsigned long jitter); unsigned long isis_jitter(unsigned long timer, unsigned long jitter);
const char *unix_hostname(void); const char *unix_hostname(void);

View File

@ -24,7 +24,6 @@
#include "isisd/isis_memory.h" #include "isisd/isis_memory.h"
#include "isisd/isis_circuit.h" #include "isisd/isis_circuit.h"
#include "isisd/isis_adjacency.h" #include "isisd/isis_adjacency.h"
#include "isisd/isis_tlv.h"
#include "isisd/isis_misc.h" #include "isisd/isis_misc.h"
#include "isisd/isis_lsp.h" #include "isisd/isis_lsp.h"
#include "isisd/isis_mt.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_AREA_SETTING, "ISIS MT Area Setting")
DEFINE_MTYPE_STATIC(ISISD, MT_CIRCUIT_SETTING, "ISIS MT Circuit 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_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) 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); mt_settings = circuit_mt_settings(adj->circuit, &circuit_mt_count);
for (unsigned int i = 0; i < circuit_mt_count; i++) { 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 */ /* Other end does not have MT enabled */
if (mt_settings[i]->mtid == ISIS_MT_IPV4_UNICAST if (mt_settings[i]->mtid == ISIS_MT_IPV4_UNICAST
&& v4_usable) && v4_usable)
@ -459,153 +454,6 @@ void adj_mt_finish(struct isis_adjacency *adj)
adj->mt_count = 0; 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, static void mt_set_add(uint16_t **mt_set, unsigned int *size,
unsigned int *index, uint16_t mtid) 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; 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, 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++) { for (unsigned int i = 0; i < mt_count; i++) {
uint16_t mtid = mt_set[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) { if (mt_set[i] == ISIS_MT_IPV4_UNICAST) {
listnode_add(tlvs->te_is_neighs, ne_copy);
lsp_debug( lsp_debug(
"ISIS (%s): Adding %s.%02x as te-style neighbor", "ISIS (%s): Adding %s.%02x as te-style neighbor",
area->area_tag, sysid_print(ne_copy->neigh_id), area->area_tag, sysid_print(id),
LSP_PSEUDO_ID(ne_copy->neigh_id)); LSP_PSEUDO_ID(id));
} else { } 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( lsp_debug(
"ISIS (%s): Adding %s.%02x as mt-style neighbor for %s", "ISIS (%s): Adding %s.%02x as mt-style neighbor for %s",
area->area_tag, sysid_print(ne_copy->neigh_id), area->area_tag, sysid_print(id),
LSP_PSEUDO_ID(ne_copy->neigh_id), LSP_PSEUDO_ID(id), isis_mtid2str(mtid));
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, void tlvs_add_mt_bcast(struct isis_tlvs *tlvs, struct isis_circuit *circuit,
int level, struct te_is_neigh *neigh) int level, uint8_t *id, uint32_t metric,
uint8_t *subtlvs, uint8_t subtlv_len)
{ {
unsigned int mt_count; unsigned int mt_count;
uint16_t *mt_set = circuit_bcast_mt_set(circuit, level, &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, void tlvs_add_mt_p2p(struct isis_tlvs *tlvs, struct isis_circuit *circuit,
struct te_is_neigh *neigh) uint8_t *id, uint32_t metric, uint8_t *subtlvs,
uint8_t subtlv_len)
{ {
struct isis_adjacency *adj = circuit->u.p2p.neighbor; 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);
} }

View File

@ -65,21 +65,6 @@ struct isis_circuit_mt_setting {
bool enabled; 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); const char *isis_mtid2str(uint16_t mtid);
uint16_t isis_str2mtid(const char *name); uint16_t isis_str2mtid(const char *name);
@ -92,24 +77,6 @@ struct isis_tlvs;
uint16_t isis_area_ipv6_topology(struct isis_area *area); 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, struct isis_area_mt_setting *area_lookup_mt_setting(struct isis_area *area,
uint16_t mtid); uint16_t mtid);
struct isis_area_mt_setting *area_new_mt_setting(struct isis_area *area, 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); struct isis_adjacency *adj);
bool adj_has_mt(struct isis_adjacency *adj, uint16_t mtid); bool adj_has_mt(struct isis_adjacency *adj, uint16_t mtid);
void adj_mt_finish(struct isis_adjacency *adj); void adj_mt_finish(struct isis_adjacency *adj);
void tlvs_add_mt_bcast(struct tlvs *tlvs, struct isis_circuit *circuit, void tlvs_add_mt_bcast(struct isis_tlvs *tlvs, struct isis_circuit *circuit,
int level, struct te_is_neigh *neigh); int level, uint8_t *id, uint32_t metric,
void tlvs_add_mt_p2p(struct tlvs *tlvs, struct isis_circuit *circuit, uint8_t *subtlvs, uint8_t subtlv_len);
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);
#endif #endif

View File

@ -44,7 +44,6 @@
#include "isisd/isis_network.h" #include "isisd/isis_network.h"
#include "isisd/isis_misc.h" #include "isisd/isis_misc.h"
#include "isisd/isis_dr.h" #include "isisd/isis_dr.h"
#include "isisd/isis_tlv.h"
#include "isisd/isisd.h" #include "isisd/isisd.h"
#include "isisd/isis_dynhn.h" #include "isisd/isis_dynhn.h"
#include "isisd/isis_lsp.h" #include "isisd/isis_lsp.h"
@ -56,135 +55,40 @@
#include "isisd/isis_mt.h" #include "isisd/isis_mt.h"
#include "isisd/isis_tlvs2.h" #include "isisd/isis_tlvs2.h"
#define ISIS_MINIMUM_FIXED_HDR_LEN 15 static int ack_lsp(struct isis_lsp_hdr *hdr, struct isis_circuit *circuit,
#define ISIS_MIN_PDU_LEN 13 /* partial seqnum pdu with id_len=2 */ int level)
#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 */ 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;
return retval; isis_circuit_stream(circuit, &circuit->snd_stream);
}
/* fill_fixed_hdr(pdu_type, circuit->snd_stream);
* 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)
{
unsigned char digest[ISIS_AUTH_MD5_SIZE];
/* Auth fail () - passwd type mismatch */ lenp = stream_get_endp(circuit->snd_stream);
if (local->type != remote->type) stream_putw(circuit->snd_stream, 0); /* PDU length */
return ISIS_ERROR; 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 */
switch (local->type) { stream_putw(circuit->snd_stream, hdr->rem_lifetime);
/* No authentication required */ stream_put(circuit->snd_stream, hdr->lsp_id, ISIS_SYS_ID_LEN + 2);
case ISIS_PASSWD_TYPE_UNUSED: stream_putl(circuit->snd_stream, hdr->seqno);
break; stream_putw(circuit->snd_stream, hdr->checksum);
/* Cleartext (ISO 10589) */ length = (u_int16_t)stream_get_endp(circuit->snd_stream);
case ISIS_PASSWD_TYPE_CLEARTXT: /* Update PDU length */
/* Auth fail () - passwd len mismatch */ stream_putw_at(circuit->snd_stream, lenp, length);
if (remote->len != local->len)
return ISIS_ERROR;
return memcmp(local->passwd, remote->passwd, local->len);
/* HMAC MD5 (RFC 3567) */ retval = circuit->tx(circuit, level);
case ISIS_PASSWD_TYPE_HMAC_MD5: if (retval != ISIS_OK)
/* Auth fail () - passwd len mismatch */ zlog_err("ISIS-Upd (%s): Send L%d LSP PSNP on %s failed",
if (remote->len != ISIS_AUTH_MD5_SIZE) circuit->area->area_tag, level,
return ISIS_ERROR; circuit->interface->name);
/* 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;
}
/* Authentication pass when no authentication is configured */
return ISIS_OK;
}
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;
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);
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;
}
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;
}
/*
* 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;
return retval; return retval;
} }
@ -670,7 +574,7 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
return ISIS_WARNING; return ISIS_WARNING;
} }
if (!accept_level(level, circuit->is_type)) { if (!(circuit->is_type & level)) {
if (isis->debugs & DEBUG_ADJ_PACKETS) { if (isis->debugs & DEBUG_ADJ_PACKETS) {
zlog_debug( zlog_debug(
"ISIS-Adj (%s): Interface level mismatch, %s", "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, 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, isis_event_auth_failure(circuit->area->area_tag,
"IIH authentication failure", "IIH authentication failure",
iih.sys_id); iih.sys_id);
@ -780,17 +684,10 @@ out:
* ISO - 10589 * ISO - 10589
* Section 7.3.15.1 - Action on receipt of a link state PDU * 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) const u_char *ssnpa)
{ {
struct isis_link_state_hdr *hdr; int level = (pdu_type == L1_LINK_STATE) ? ISIS_LEVEL1 : ISIS_LEVEL2;
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;
if (isis->debugs & DEBUG_UPDATE_PACKETS) { if (isis->debugs & DEBUG_UPDATE_PACKETS) {
zlog_debug( zlog_debug(
@ -804,65 +701,50 @@ static int process_lsp(int level, struct isis_circuit *circuit,
stream_get_endp(circuit->rcv_stream)); stream_get_endp(circuit->rcv_stream));
} }
if ((stream_get_endp(circuit->rcv_stream) struct isis_lsp_hdr hdr = {};
- stream_get_getp(circuit->rcv_stream))
< ISIS_LSP_HDR_LEN) { hdr.pdu_len = stream_getw(circuit->rcv_stream);
zlog_warn("Packet too short"); 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; return ISIS_WARNING;
} }
/* Reference the header */
hdr = (struct isis_link_state_hdr *)STREAM_PNT(circuit->rcv_stream);
pdu_len = ntohs(hdr->pdu_len);
/* 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);
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) { if (isis->debugs & DEBUG_UPDATE_PACKETS) {
zlog_debug( zlog_debug("ISIS-Upd (%s): Rcvd L%d LSP %s, seq 0x%08" PRIx32
"ISIS-Upd (%s): Rcvd L%d LSP %s, seq 0x%08x, cksum 0x%04x, " ", cksum 0x%04" PRIx16 ", lifetime %" PRIu16
"lifetime %us, len %u, on %s", "s, len %" PRIu16 ", on %s",
circuit->area->area_tag, level, circuit->area->area_tag, level,
rawlspid_print(hdr->lsp_id), ntohl(hdr->seq_num), rawlspid_print(hdr.lsp_id), hdr.seqno, hdr.checksum,
ntohs(hdr->checksum), ntohs(hdr->rem_lifetime), pdu_len, hdr.rem_lifetime, hdr.pdu_len,
circuit->interface->name); circuit->interface->name);
} }
/* lsp is_type check */ /* lsp is_type check */
if ((hdr->lsp_bits & IS_LEVEL_1_AND_2) != IS_LEVEL_1 if ((hdr.lsp_bits & IS_LEVEL_1) != IS_LEVEL_1) {
&& (hdr->lsp_bits & IS_LEVEL_1_AND_2) != IS_LEVEL_1_AND_2) { zlog_debug(
zlog_debug("ISIS-Upd (%s): LSP %s invalid LSP is type %x", "ISIS-Upd (%s): LSP %s invalid LSP is type 0x%" PRIx8,
circuit->area->area_tag, rawlspid_print(hdr->lsp_id), circuit->area->area_tag, rawlspid_print(hdr.lsp_id),
hdr->lsp_bits); hdr.lsp_bits & IS_LEVEL_1_AND_2);
/* continue as per RFC1122 Be liberal in what you accept, and /* continue as per RFC1122 Be liberal in what you accept, and
* conservative in what you send */ * conservative in what you send */
} }
/* Checksum sanity check - FIXME: move to correct place */ /* Checksum sanity check - FIXME: move to correct place */
/* 12 = sysid+pdu+remtime */ /* 12 = sysid+pdu+remtime */
if (iso_csum_verify(STREAM_PNT(circuit->rcv_stream) + 4, pdu_len - 12, if (iso_csum_verify(STREAM_DATA(circuit->rcv_stream) + 12,
hdr->checksum, hdr.pdu_len - 12, hdr.checksum, 12)) {
offsetof(struct isis_link_state_hdr, checksum) zlog_debug(
- 4)) { "ISIS-Upd (%s): LSP %s invalid LSP checksum 0x%04" PRIx16,
zlog_debug("ISIS-Upd (%s): LSP %s invalid LSP checksum 0x%04x", circuit->area->area_tag, rawlspid_print(hdr.lsp_id),
circuit->area->area_tag, rawlspid_print(hdr->lsp_id), hdr.checksum);
ntohs(hdr->checksum));
return ISIS_WARNING; return ISIS_WARNING;
} }
@ -871,47 +753,56 @@ static int process_lsp(int level, struct isis_circuit *circuit,
zlog_debug( zlog_debug(
"ISIS-Upd (%s): LSP %s received at level %d over circuit with " "ISIS-Upd (%s): LSP %s received at level %d over circuit with "
"externalDomain = true", "externalDomain = true",
circuit->area->area_tag, rawlspid_print(hdr->lsp_id), circuit->area->area_tag, rawlspid_print(hdr.lsp_id),
level); level);
return ISIS_WARNING; return ISIS_WARNING;
} }
/* 7.3.15.1 a) 2,3 - manualL2OnlyMode not implemented */ /* 7.3.15.1 a) 2,3 - manualL2OnlyMode not implemented */
if (!accept_level(level, circuit->is_type)) { if (!(circuit->is_type & level)) {
zlog_debug( zlog_debug(
"ISIS-Upd (%s): LSP %s received at level %d over circuit of" "ISIS-Upd (%s): LSP %s received at level %d over circuit of"
" type %s", " 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)); level, circuit_t2string(circuit->is_type));
return ISIS_WARNING; 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) 4 - need to make sure IDLength matches */
/* 7.3.15.1 a) 5 - maximum area match, can be ommited since we only use /* 7.3.15.1 a) 5 - maximum area match, can be ommited since we only use
* 3 */ * 3 */
/* 7.3.15.1 a) 7 - password check */ /* 7.3.15.1 a) 7 - password check */
(level == IS_LEVEL_1) ? (passwd = &circuit->area->area_passwd) struct isis_passwd *passwd = (level == ISIS_LEVEL1)
: (passwd = &circuit->area->domain_passwd); ? &circuit->area->area_passwd
if (passwd->type) { : &circuit->area->domain_passwd;
if (lsp_authentication_check(circuit->rcv_stream, circuit->area, if (!isis_tlvs_auth_is_valid(tlvs, passwd, circuit->rcv_stream, true)) {
level, passwd)) {
isis_event_auth_failure(circuit->area->area_tag, isis_event_auth_failure(circuit->area->area_tag,
"LSP authentication failure", "LSP authentication failure",
hdr->lsp_id); hdr.lsp_id);
return ISIS_WARNING; goto out;
}
} }
/* Find the LSP in our database and compare it to this Link State header /* 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) if (lsp)
comp = lsp_compare(circuit->area->area_tag, lsp, comp = lsp_compare(circuit->area->area_tag, lsp, hdr.seqno,
ntohl(hdr->seq_num), ntohs(hdr->checksum), hdr.checksum, hdr.rem_lifetime);
ntohs(hdr->rem_lifetime));
if (lsp && (lsp->own_lsp)) if (lsp && (lsp->own_lsp))
goto dontcheckadj; goto dontcheckadj;
@ -920,25 +811,24 @@ static int process_lsp(int level, struct isis_circuit *circuit,
/* for broadcast circuits, snpa should be compared */ /* for broadcast circuits, snpa should be compared */
if (circuit->circ_type == CIRCUIT_T_BROADCAST) { if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
adj = isis_adj_lookup_snpa(ssnpa, if (!isis_adj_lookup_snpa(ssnpa,
circuit->u.bc.adjdb[level - 1]); circuit->u.bc.adjdb[level - 1])) {
if (!adj) { zlog_debug("(%s): DS ======= LSP %s, seq 0x%08" PRIx32
zlog_debug( ", cksum 0x%04" PRIx16 ", lifetime %" PRIu16
"(%s): DS ======= LSP %s, seq 0x%08x, cksum 0x%04x, " "s on %s",
"lifetime %us on %s",
circuit->area->area_tag, circuit->area->area_tag,
rawlspid_print(hdr->lsp_id), rawlspid_print(hdr.lsp_id), hdr.seqno,
ntohl(hdr->seq_num), ntohs(hdr->checksum), hdr.checksum, hdr.rem_lifetime,
ntohs(hdr->rem_lifetime),
circuit->interface->name); circuit->interface->name);
return ISIS_WARNING; /* Silently discard */ goto out; /* Silently discard */
} }
} }
/* for non broadcast, we just need to find same level adj */ /* for non broadcast, we just need to find same level adj */
else { else {
/* If no adj, or no sharing of level */ /* If no adj, or no sharing of level */
if (!circuit->u.p2p.neighbor) { if (!circuit->u.p2p.neighbor) {
return ISIS_OK; /* Silently discard */ retval = ISIS_OK;
goto out;
} else { } else {
if (((level == IS_LEVEL_1) if (((level == IS_LEVEL_1)
&& (circuit->u.p2p.neighbor->adj_usage && (circuit->u.p2p.neighbor->adj_usage
@ -946,10 +836,12 @@ static int process_lsp(int level, struct isis_circuit *circuit,
|| ((level == IS_LEVEL_2) || ((level == IS_LEVEL_2)
&& (circuit->u.p2p.neighbor->adj_usage && (circuit->u.p2p.neighbor->adj_usage
== ISIS_ADJ_LEVEL1))) == ISIS_ADJ_LEVEL1)))
return ISIS_WARNING; /* Silently discard */ goto out;
} }
} }
bool lsp_confusion;
dontcheckadj: dontcheckadj:
/* 7.3.15.1 a) 7 - Passwords for level 1 - not implemented */ /* 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 /* 7.3.16.2 - If this is an LSP from another IS with identical seq_num
* but * but
* wrong checksum, initiate a purge. */ * wrong checksum, initiate a purge. */
if (lsp && (lsp->lsp_header->seq_num == hdr->seq_num) if (lsp && (lsp->hdr.seqno == hdr.seqno)
&& (lsp->lsp_header->checksum != hdr->checksum)) { && (lsp->hdr.checksum != hdr.checksum)) {
zlog_warn( zlog_warn("ISIS-Upd (%s): LSP %s seq 0x%08" PRIx32
"ISIS-Upd (%s): LSP %s seq 0x%08x with confused checksum received.", " with confused checksum received.",
circuit->area->area_tag, rawlspid_print(hdr->lsp_id), circuit->area->area_tag, rawlspid_print(hdr.lsp_id),
ntohl(hdr->seq_num)); hdr.seqno);
hdr->rem_lifetime = 0; hdr.rem_lifetime = 0;
lsp_confusion = 1; lsp_confusion = true;
} else } 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 */ /* 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) { if (!lsp) {
/* 7.3.16.4 a) 1) No LSP in db -> send an ack, but don't /* 7.3.16.4 a) 1) No LSP in db -> send an ack, but don't
* save */ * save */
/* only needed on explicit update, eg - p2p */ /* only needed on explicit update, eg - p2p */
if (circuit->circ_type == CIRCUIT_T_P2P) if (circuit->circ_type == CIRCUIT_T_P2P)
ack_lsp(hdr, circuit, level); ack_lsp(&hdr, circuit, level);
return retval; /* FIXME: do we need a purge? */ goto out; /* FIXME: do we need a purge? */
} else { } 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) */ /* LSP by some other system -> do 7.3.16.4 b) */
/* 7.3.16.4 b) 1) */ /* 7.3.16.4 b) 1) */
if (comp == LSP_NEWER) { if (comp == LSP_NEWER) {
lsp_update(lsp, circuit->rcv_stream, lsp_update(lsp, &hdr, tlvs,
circuit->rcv_stream,
circuit->area, level); circuit->area, level);
tlvs = NULL;
/* ii */ /* ii */
lsp_set_all_srmflags(lsp); lsp_set_all_srmflags(lsp);
/* v */ /* v */
@ -1028,11 +922,10 @@ dontcheckadj:
ISIS_SET_FLAG(lsp->SRMflags, circuit); ISIS_SET_FLAG(lsp->SRMflags, circuit);
ISIS_CLEAR_FLAG(lsp->SSNflags, 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) */ /* our own LSP -> 7.3.16.4 c) */
if (comp == LSP_NEWER) { if (comp == LSP_NEWER) {
lsp_inc_seqnum(lsp, lsp_inc_seqno(lsp, hdr.seqno);
ntohl(hdr->seq_num));
lsp_set_all_srmflags(lsp); lsp_set_all_srmflags(lsp);
} else { } else {
ISIS_SET_FLAG(lsp->SRMflags, circuit); ISIS_SET_FLAG(lsp->SRMflags, circuit);
@ -1040,23 +933,22 @@ dontcheckadj:
} }
if (isis->debugs & DEBUG_UPDATE_PACKETS) if (isis->debugs & DEBUG_UPDATE_PACKETS)
zlog_debug( zlog_debug(
"ISIS-Upd (%s): (1) re-originating LSP %s new " "ISIS-Upd (%s): (1) re-originating LSP %s new seq 0x%08" PRIx32,
"seq 0x%08x",
circuit->area->area_tag, circuit->area->area_tag,
rawlspid_print(hdr->lsp_id), rawlspid_print(hdr.lsp_id),
ntohl(lsp->lsp_header lsp->hdr.seqno);
->seq_num));
} }
} }
return retval; goto out;
} }
/* 7.3.15.1 c) - If this is our own lsp and we don't have it initiate a /* 7.3.15.1 c) - If this is our own lsp and we don't have it initiate a
* purge */ * 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) { if (!lsp) {
/* 7.3.16.4: initiate a purge */ /* 7.3.16.4: initiate a purge */
lsp_purge_non_exist(level, hdr, circuit->area); lsp_purge_non_exist(level, &hdr, circuit->area);
return ISIS_OK; retval = ISIS_OK;
goto out;
} }
/* 7.3.15.1 d) - If this is our own lsp and we have it */ /* 7.3.15.1 d) - If this is our own lsp and we have it */
@ -1066,16 +958,15 @@ dontcheckadj:
* is * is
* "greater" than that held by S, ... */ * "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 */ /* 7.3.16.1 */
lsp_inc_seqnum(lsp, ntohl(hdr->seq_num)); lsp_inc_seqno(lsp, hdr.seqno);
if (isis->debugs & DEBUG_UPDATE_PACKETS) if (isis->debugs & DEBUG_UPDATE_PACKETS)
zlog_debug( zlog_debug(
"ISIS-Upd (%s): (2) re-originating LSP %s new seq " "ISIS-Upd (%s): (2) re-originating LSP %s new seq 0x%08" PRIx32,
"0x%08x",
circuit->area->area_tag, circuit->area->area_tag,
rawlspid_print(hdr->lsp_id), rawlspid_print(hdr.lsp_id),
ntohl(lsp->lsp_header->seq_num)); lsp->hdr.seqno);
} }
/* If the received LSP is older or equal, /* If the received LSP is older or equal,
* resend the LSP which will act as ACK */ * 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 * If this lsp is a frag, need to see if we have zero
* lsp present * lsp present
*/ */
if (LSP_FRAGMENT(hdr->lsp_id) != 0) { struct isis_lsp *lsp0 = NULL;
memcpy(lspid, hdr->lsp_id, ISIS_SYS_ID_LEN + 1); 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; LSP_FRAGMENT(lspid) = 0;
lsp0 = lsp_search( lsp0 = lsp_search(
lspid, circuit->area->lspdb[level - 1]); lspid, circuit->area->lspdb[level - 1]);
@ -1103,15 +996,17 @@ dontcheckadj:
} }
/* i */ /* i */
if (!lsp) { if (!lsp) {
lsp = lsp_new_from_stream_ptr( lsp = lsp_new_from_recv(
circuit->rcv_stream, pdu_len, lsp0, &hdr, tlvs, circuit->rcv_stream, lsp0,
circuit->area, level); circuit->area, level);
tlvs = NULL;
lsp_insert(lsp, lsp_insert(lsp,
circuit->area->lspdb[level - 1]); circuit->area->lspdb[level - 1]);
} else /* exists, so we overwrite */ } else /* exists, so we overwrite */
{ {
lsp_update(lsp, circuit->rcv_stream, lsp_update(lsp, &hdr, tlvs, circuit->rcv_stream,
circuit->area, level); circuit->area, level);
tlvs = NULL;
} }
/* ii */ /* ii */
lsp_set_all_srmflags(lsp); lsp_set_all_srmflags(lsp);
@ -1126,8 +1021,9 @@ dontcheckadj:
/* 7.3.15.1 e) 2) LSP equal to the one in db */ /* 7.3.15.1 e) 2) LSP equal to the one in db */
else if (comp == LSP_EQUAL) { else if (comp == LSP_EQUAL) {
ISIS_CLEAR_FLAG(lsp->SRMflags, circuit); ISIS_CLEAR_FLAG(lsp->SRMflags, circuit);
lsp_update(lsp, circuit->rcv_stream, circuit->area, lsp_update(lsp, &hdr, tlvs, circuit->rcv_stream,
level); circuit->area, level);
tlvs = NULL;
if (circuit->circ_type != CIRCUIT_T_BROADCAST) if (circuit->circ_type != CIRCUIT_T_BROADCAST)
ISIS_SET_FLAG(lsp->SSNflags, circuit); ISIS_SET_FLAG(lsp->SSNflags, circuit);
} }
@ -1137,6 +1033,11 @@ dontcheckadj:
ISIS_CLEAR_FLAG(lsp->SSNflags, circuit); ISIS_CLEAR_FLAG(lsp->SSNflags, circuit);
} }
} }
retval = ISIS_OK;
out:
isis_free_tlvs(tlvs);
return retval; 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 */ /* 7.3.15.2 a) 2,3 - manualL2OnlyMode not implemented */
if (!accept_level(level, circuit->is_type)) { if (!(circuit->is_type & level)) {
zlog_debug( zlog_debug(
"ISIS-Snp (%s): Rcvd L%d %cSNP on %s, " "ISIS-Snp (%s): Rcvd L%d %cSNP on %s, "
"skipping: circuit type %s does not match level %d", "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->area_passwd
: &circuit->area->domain_passwd; : &circuit->area->domain_passwd;
if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_RECV) 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, isis_event_auth_failure(circuit->area->area_tag,
"SNP authentication failure", "SNP authentication failure",
rem_sys_id); rem_sys_id);
@ -1317,7 +1218,7 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
on p2p */ on p2p */
else { else {
if (own_lsp) { if (own_lsp) {
lsp_inc_seqnum(lsp, entry->seqno); lsp_inc_seqno(lsp, entry->seqno);
ISIS_SET_FLAG(lsp->SRMflags, circuit); ISIS_SET_FLAG(lsp->SRMflags, circuit);
} else { } else {
ISIS_SET_FLAG(lsp->SSNflags, circuit); 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; for (struct isis_lsp_entry *entry = entry_head; entry;
entry = entry->next) { entry = entry->next) {
for (ALL_LIST_ELEMENTS(lsp_list, node, nnode, lsp)) { for (ALL_LIST_ELEMENTS(lsp_list, node, nnode, lsp)) {
if (lsp_id_cmp(lsp->lsp_header->lsp_id, if (lsp_id_cmp(lsp->hdr.lsp_id, entry->id)
entry->id)
== 0) { == 0) {
list_delete_node(lsp_list, node); list_delete_node(lsp_list, node);
break; break;
@ -1506,10 +1406,8 @@ static int isis_handle_pdu(struct isis_circuit *circuit, u_char *ssnpa)
retval = process_hello(pdu_type, circuit, ssnpa); retval = process_hello(pdu_type, circuit, ssnpa);
break; break;
case L1_LINK_STATE: case L1_LINK_STATE:
retval = process_lsp(ISIS_LEVEL1, circuit, ssnpa);
break;
case L2_LINK_STATE: case L2_LINK_STATE:
retval = process_lsp(ISIS_LEVEL2, circuit, ssnpa); retval = process_lsp(pdu_type, circuit, ssnpa);
break; break;
case L1_COMPLETE_SEQ_NUM: case L1_COMPLETE_SEQ_NUM:
case L2_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); isis_tlvs_add_ipv6_addresses(tlvs, circuit->ipv6_link);
if (isis_pack_tlvs(tlvs, circuit->snd_stream, len_pointer, if (isis_pack_tlvs(tlvs, circuit->snd_stream, len_pointer,
circuit->pad_hellos)) { circuit->pad_hellos, false)) {
isis_free_tlvs(tlvs); isis_free_tlvs(tlvs);
return ISIS_WARNING; /* XXX: Maybe Log TLV structure? */ 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. * 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) static uint16_t get_max_lsp_count(uint16_t size)
{ {
uint16_t tlv_count; uint16_t tlv_count;
@ -1832,7 +1731,8 @@ int send_csnp(struct isis_circuit *circuit, int level)
isis_tlvs_add_auth(tlvs, passwd); isis_tlvs_add_auth(tlvs, passwd);
size_t tlv_start = stream_get_endp(circuit->snd_stream); 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); isis_free_tlvs(tlvs);
return ISIS_WARNING; return ISIS_WARNING;
} }
@ -1862,8 +1762,7 @@ int send_csnp(struct isis_circuit *circuit, int level)
if (tlvs->lsp_entries.count < num_lsps) { if (tlvs->lsp_entries.count < num_lsps) {
memset(stop, 0xff, ISIS_SYS_ID_LEN + 2); memset(stop, 0xff, ISIS_SYS_ID_LEN + 2);
} else { } else {
memcpy(stop, last_lsp->lsp_header->lsp_id, memcpy(stop, last_lsp->hdr.lsp_id, sizeof(stop));
ISIS_SYS_ID_LEN + 2);
} }
memcpy(STREAM_DATA(circuit->snd_stream) + start_pointer, start, 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); ISIS_SYS_ID_LEN + 2);
stream_set_endp(circuit->snd_stream, tlv_start); stream_set_endp(circuit->snd_stream, tlv_start);
if (isis_pack_tlvs(tlvs, circuit->snd_stream, len_pointer, if (isis_pack_tlvs(tlvs, circuit->snd_stream, len_pointer,
false)) { false, false)) {
isis_free_tlvs(tlvs); isis_free_tlvs(tlvs);
return ISIS_WARNING; return ISIS_WARNING;
} }
@ -2001,7 +1900,8 @@ static int send_psnp(int level, struct isis_circuit *circuit)
isis_tlvs_add_auth(tlvs, passwd); isis_tlvs_add_auth(tlvs, passwd);
size_t tlv_start = stream_get_endp(circuit->snd_stream); 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); isis_free_tlvs(tlvs);
return ISIS_WARNING; 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); stream_set_endp(circuit->snd_stream, tlv_start);
if (isis_pack_tlvs(tlvs, circuit->snd_stream, len_pointer, if (isis_pack_tlvs(tlvs, circuit->snd_stream, len_pointer,
false)) { false, false)) {
isis_free_tlvs(tlvs); isis_free_tlvs(tlvs);
return ISIS_WARNING; return ISIS_WARNING;
} }
@ -2183,14 +2083,12 @@ int send_lsp(struct thread *thread)
* the circuit's MTU. So handle and log this case here. */ * the circuit's MTU. So handle and log this case here. */
if (stream_get_endp(lsp->pdu) > stream_get_size(circuit->snd_stream)) { if (stream_get_endp(lsp->pdu) > stream_get_size(circuit->snd_stream)) {
zlog_err( zlog_err(
"ISIS-Upd (%s): Can't send L%d LSP %s, seq 0x%08x," "ISIS-Upd (%s): Can't send L%d LSP %s, seq 0x%08" PRIx32
" cksum 0x%04x, lifetime %us on %s. LSP Size is %zu" ", cksum 0x%04" PRIx16 ", lifetime %" PRIu16
" while interface stream size is %zu.", "s on %s. LSP Size is %zu while interface stream size is %zu.",
circuit->area->area_tag, lsp->level, circuit->area->area_tag, lsp->level,
rawlspid_print(lsp->lsp_header->lsp_id), rawlspid_print(lsp->hdr.lsp_id), lsp->hdr.seqno,
ntohl(lsp->lsp_header->seq_num), lsp->hdr.checksum, lsp->hdr.rem_lifetime,
ntohs(lsp->lsp_header->checksum),
ntohs(lsp->lsp_header->rem_lifetime),
circuit->interface->name, stream_get_endp(lsp->pdu), circuit->interface->name, stream_get_endp(lsp->pdu),
stream_get_size(circuit->snd_stream)); stream_get_size(circuit->snd_stream));
if (isis->debugs & DEBUG_PACKET_DUMP) if (isis->debugs & DEBUG_PACKET_DUMP)
@ -2204,14 +2102,12 @@ int send_lsp(struct thread *thread)
stream_copy(circuit->snd_stream, lsp->pdu); stream_copy(circuit->snd_stream, lsp->pdu);
if (isis->debugs & DEBUG_UPDATE_PACKETS) { if (isis->debugs & DEBUG_UPDATE_PACKETS) {
zlog_debug( zlog_debug("ISIS-Upd (%s): Sending L%d LSP %s, seq 0x%08" PRIx32
"ISIS-Upd (%s): Sending L%d LSP %s, seq 0x%08x, cksum 0x%04x," ", cksum 0x%04" PRIx16 ", lifetime %" PRIu16
" lifetime %us on %s", "s on %s",
circuit->area->area_tag, lsp->level, circuit->area->area_tag, lsp->level,
rawlspid_print(lsp->lsp_header->lsp_id), rawlspid_print(lsp->hdr.lsp_id), lsp->hdr.seqno,
ntohl(lsp->lsp_header->seq_num), lsp->hdr.checksum, lsp->hdr.rem_lifetime,
ntohs(lsp->lsp_header->checksum),
ntohs(lsp->lsp_header->rem_lifetime),
circuit->interface->name); circuit->interface->name);
if (isis->debugs & DEBUG_PACKET_DUMP) if (isis->debugs & DEBUG_PACKET_DUMP)
zlog_dump_data(STREAM_DATA(circuit->snd_stream), zlog_dump_data(STREAM_DATA(circuit->snd_stream),
@ -2246,41 +2142,3 @@ out:
return retval; 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;
}

View File

@ -125,30 +125,14 @@ struct isis_p2p_hello_hdr {
#define L1_LINK_STATE 18 #define L1_LINK_STATE 18
#define L2_LINK_STATE 20 #define L2_LINK_STATE 20
/* struct isis_lsp_hdr {
* L1 and L2 IS to IS link state PDU header uint16_t pdu_len;
* +-------+-------+-------+-------+-------+-------+-------+-------+ uint16_t rem_lifetime;
* + PDU Length + 2 uint8_t lsp_id[ISIS_SYS_ID_LEN + 2];
* +-------+-------+-------+-------+-------+-------+-------+-------+ uint32_t seqno;
* + Remaining Lifetime + 2 uint16_t checksum;
* +-------+-------+-------+-------+-------+-------+-------+-------+ uint8_t lsp_bits;
* | 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));
#define ISIS_LSP_HDR_LEN 19 #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_l1_psnp(struct thread *thread);
int send_l2_psnp(struct thread *thread); int send_l2_psnp(struct thread *thread);
int send_lsp(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); void fill_fixed_hdr(uint8_t pdu_type, struct stream *stream);
int send_hello(struct isis_circuit *circuit, int level); int send_hello(struct isis_circuit *circuit, int level);

View File

@ -37,7 +37,6 @@
#include "isisd/isis_flags.h" #include "isisd/isis_flags.h"
#include "isisd/isis_misc.h" #include "isisd/isis_misc.h"
#include "isisd/isis_circuit.h" #include "isisd/isis_circuit.h"
#include "isisd/isis_tlv.h"
#include "isisd/isisd.h" #include "isisd/isisd.h"
#include "isisd/isis_lsp.h" #include "isisd/isis_lsp.h"
#include "isisd/isis_route.h" #include "isisd/isis_route.h"

View File

@ -42,7 +42,6 @@
#include "isis_misc.h" #include "isis_misc.h"
#include "isis_adjacency.h" #include "isis_adjacency.h"
#include "isis_circuit.h" #include "isis_circuit.h"
#include "isis_tlv.h"
#include "isis_pdu.h" #include "isis_pdu.h"
#include "isis_lsp.h" #include "isis_lsp.h"
#include "isis_spf.h" #include "isis_spf.h"

View File

@ -42,7 +42,6 @@
#include "isis_misc.h" #include "isis_misc.h"
#include "isis_adjacency.h" #include "isis_adjacency.h"
#include "isis_circuit.h" #include "isis_circuit.h"
#include "isis_tlv.h"
#include "isis_pdu.h" #include "isis_pdu.h"
#include "isis_lsp.h" #include "isis_lsp.h"
#include "isis_spf.h" #include "isis_spf.h"

View File

@ -44,7 +44,6 @@
#include "isis_misc.h" #include "isis_misc.h"
#include "isis_adjacency.h" #include "isis_adjacency.h"
#include "isis_circuit.h" #include "isis_circuit.h"
#include "isis_tlv.h"
#include "isis_pdu.h" #include "isis_pdu.h"
#include "isis_lsp.h" #include "isis_lsp.h"
#include "isis_dynhn.h" #include "isis_dynhn.h"
@ -52,9 +51,24 @@
#include "isis_route.h" #include "isis_route.h"
#include "isis_csm.h" #include "isis_csm.h"
#include "isis_mt.h" #include "isis_mt.h"
#include "isis_tlvs2.h"
DEFINE_MTYPE_STATIC(ISISD, ISIS_SPF_RUN, "ISIS SPF Run Info"); 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_spf_run {
struct isis_area *area; struct isis_area *area;
int level; 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_PSEUDO_ID(lspid) = 0;
LSP_FRAGMENT(lspid) = 0; LSP_FRAGMENT(lspid) = 0;
lsp = lsp_search(lspid, area->lspdb[level - 1]); 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 lsp;
return NULL; return NULL;
} }
@ -546,6 +560,13 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype,
assert(spftree && parent); assert(spftree && parent);
struct prefix p;
if (vtype >= VTYPE_IPREACH_INTERNAL) {
prefix_copy(&p, id);
apply_mask(&p);
id = &p;
}
/* RFC3787 section 5.1 */ /* RFC3787 section 5.1 */
if (spftree->area->newmetric == 1) { if (spftree->area->newmetric == 1) {
if (dist > MAX_WIDE_PATH_METRIC) 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, uint16_t depth, u_char *root_sysid,
struct isis_vertex *parent) struct isis_vertex *parent)
{ {
bool pseudo_lsp = LSP_PSEUDO_ID(lsp->lsp_header->lsp_id); bool pseudo_lsp = LSP_PSEUDO_ID(lsp->hdr.lsp_id);
struct listnode *node, *fragnode = NULL; struct listnode *fragnode = NULL;
uint32_t dist; 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; enum vertextype vtype;
struct prefix prefix;
struct ipv6_reachability *ip6reach;
static const u_char null_sysid[ISIS_SYS_ID_LEN]; 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) if (spftree->mtid != ISIS_MT_IPV4_UNICAST)
mt_router_info = tlvs_lookup_mt_router_info(&lsp->tlv_data, mt_router_info = isis_tlvs_lookup_mt_router_info(lsp->tlvs,
spftree->mtid); spftree->mtid);
if (!pseudo_lsp && (spftree->mtid == ISIS_MT_IPV4_UNICAST 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) && !mt_router_info)
return ISIS_OK; return ISIS_OK;
lspfragloop: lspfragloop:
if (lsp->lsp_header->seq_num == 0) { if (lsp->hdr.seqno == 0) {
zlog_warn( zlog_warn(
"isis_spf_process_lsp(): lsp with 0 seq_num - ignore"); "isis_spf_process_lsp(): lsp with 0 seq_num - ignore");
return ISIS_WARNING; return ISIS_WARNING;
@ -663,142 +683,122 @@ lspfragloop:
#ifdef EXTREME_DEBUG #ifdef EXTREME_DEBUG
zlog_debug("ISIS-Spf: process_lsp %s", 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 */ #endif /* EXTREME_DEBUG */
/* RFC3787 section 4 SHOULD ignore overload bit in pseudo LSPs */ /* RFC3787 section 4 SHOULD ignore overload bit in pseudo LSPs */
if (pseudo_lsp || (spftree->mtid == ISIS_MT_IPV4_UNICAST 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)) || (mt_router_info && !mt_router_info->overload))
{ {
if (pseudo_lsp || spftree->mtid == ISIS_MT_IPV4_UNICAST) { if (pseudo_lsp || spftree->mtid == ISIS_MT_IPV4_UNICAST) {
for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.is_neighs, node, struct isis_oldstyle_reach *r;
is_neigh)) { for (r = (struct isis_oldstyle_reach *)
lsp->tlvs->oldstyle_reach.head;
r; r = r->next) {
/* C.2.6 a) */ /* C.2.6 a) */
/* Two way connectivity */ /* Two way connectivity */
if (!memcmp(is_neigh->neigh_id, root_sysid, if (!memcmp(r->id, root_sysid, ISIS_SYS_ID_LEN))
ISIS_SYS_ID_LEN))
continue; continue;
if (!pseudo_lsp if (!pseudo_lsp
&& !memcmp(is_neigh->neigh_id, null_sysid, && !memcmp(r->id, null_sysid,
ISIS_SYS_ID_LEN)) ISIS_SYS_ID_LEN))
continue; continue;
dist = cost + is_neigh->metrics.metric_default; dist = cost + r->metric;
process_N(spftree, process_N(spftree,
LSP_PSEUDO_ID(is_neigh->neigh_id) LSP_PSEUDO_ID(r->id)
? VTYPE_PSEUDO_IS ? VTYPE_PSEUDO_IS
: VTYPE_NONPSEUDO_IS, : VTYPE_NONPSEUDO_IS,
(void *)is_neigh->neigh_id, dist, (void *)r->id, dist, depth + 1,
depth + 1, parent); parent);
} }
} }
struct list *te_is_neighs = NULL; struct isis_item_list *te_neighs = NULL;
if (pseudo_lsp || spftree->mtid == ISIS_MT_IPV4_UNICAST) { if (pseudo_lsp || spftree->mtid == ISIS_MT_IPV4_UNICAST)
te_is_neighs = lsp->tlv_data.te_is_neighs; te_neighs = &lsp->tlvs->extended_reach;
} else { else
struct tlv_mt_neighbors *mt_neighbors; te_neighs = isis_lookup_mt_items(&lsp->tlvs->mt_reach,
mt_neighbors = tlvs_lookup_mt_neighbors(&lsp->tlv_data,
spftree->mtid); spftree->mtid);
if (mt_neighbors)
te_is_neighs = mt_neighbors->list; struct isis_extended_reach *er;
} for (er = te_neighs
for (ALL_LIST_ELEMENTS_RO(te_is_neighs, node, te_is_neigh)) { ? (struct isis_extended_reach *)
if (!memcmp(te_is_neigh->neigh_id, root_sysid, te_neighs->head
ISIS_SYS_ID_LEN)) : NULL;
er; er = er->next) {
if (!memcmp(er->id, root_sysid, ISIS_SYS_ID_LEN))
continue; continue;
if (!pseudo_lsp if (!pseudo_lsp
&& !memcmp(te_is_neigh->neigh_id, null_sysid, && !memcmp(er->id, null_sysid, ISIS_SYS_ID_LEN))
ISIS_SYS_ID_LEN))
continue; continue;
dist = cost + GET_TE_METRIC(te_is_neigh); dist = cost + er->metric;
process_N(spftree, process_N(spftree,
LSP_PSEUDO_ID(te_is_neigh->neigh_id) LSP_PSEUDO_ID(er->id) ? VTYPE_PSEUDO_TE_IS
? VTYPE_PSEUDO_TE_IS
: VTYPE_NONPSEUDO_TE_IS, : VTYPE_NONPSEUDO_TE_IS,
(void *)te_is_neigh->neigh_id, dist, (void *)er->id, dist, depth + 1, parent);
depth + 1, parent);
} }
} }
if (!pseudo_lsp && spftree->family == AF_INET if (!pseudo_lsp && spftree->family == AF_INET
&& spftree->mtid == ISIS_MT_IPV4_UNICAST) { && spftree->mtid == ISIS_MT_IPV4_UNICAST) {
struct list *reachs[] = {lsp->tlv_data.ipv4_int_reachs, struct isis_item_list *reachs[] = {
lsp->tlv_data.ipv4_ext_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++) { for (unsigned int i = 0; i < array_size(reachs); i++) {
vtype = (reachs[i] == lsp->tlv_data.ipv4_int_reachs) vtype = i ? VTYPE_IPREACH_EXTERNAL
? VTYPE_IPREACH_INTERNAL : VTYPE_IPREACH_INTERNAL;
: VTYPE_IPREACH_EXTERNAL;
for (ALL_LIST_ELEMENTS_RO(reachs[i], node, ipreach)) { struct isis_oldstyle_ip_reach *r;
dist = cost + ipreach->metrics.metric_default; for (r = (struct isis_oldstyle_ip_reach *)reachs[i]
prefix.u.prefix4 = ipreach->prefix; ->head;
prefix.prefixlen = ip_masklen(ipreach->mask); r; r = r->next) {
apply_mask(&prefix); dist = cost + r->metric;
process_N(spftree, vtype, (void *)&prefix, dist, process_N(spftree, vtype, (void *)&r->prefix,
depth + 1, parent); dist, depth + 1, parent);
} }
} }
} }
if (!pseudo_lsp && spftree->family == AF_INET) { if (!pseudo_lsp && spftree->family == AF_INET) {
struct list *ipv4reachs = NULL; 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);
if (spftree->mtid == ISIS_MT_IPV4_UNICAST) { struct isis_extended_ip_reach *r;
ipv4reachs = lsp->tlv_data.te_ipv4_reachs; for (r = ipv4_reachs
} else { ? (struct isis_extended_ip_reach *)
struct tlv_mt_ipv4_reachs *mt_reachs; ipv4_reachs->head
mt_reachs = tlvs_lookup_mt_ipv4_reachs(&lsp->tlv_data, : NULL;
spftree->mtid); r; r = r->next) {
if (mt_reachs) dist = cost + r->metric;
ipv4reachs = mt_reachs->list; process_N(spftree, VTYPE_IPREACH_TE, (void *)&r->prefix,
}
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,
dist, depth + 1, parent); dist, depth + 1, parent);
} }
} }
if (!pseudo_lsp && spftree->family == AF_INET6) { if (!pseudo_lsp && spftree->family == AF_INET6) {
struct list *ipv6reachs = NULL; 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);
if (spftree->mtid == ISIS_MT_IPV4_UNICAST) { struct isis_ipv6_reach *r;
ipv6reachs = lsp->tlv_data.ipv6_reachs; for (r = ipv6_reachs
} else { ? (struct isis_ipv6_reach *)ipv6_reachs->head
struct tlv_mt_ipv6_reachs *mt_reachs; : NULL;
mt_reachs = tlvs_lookup_mt_ipv6_reachs(&lsp->tlv_data, r; r = r->next) {
spftree->mtid); dist = cost + r->metric;
if (mt_reachs) vtype = r->external ? VTYPE_IP6REACH_EXTERNAL
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; : VTYPE_IP6REACH_INTERNAL;
prefix.prefixlen = ip6reach->prefix_len; process_N(spftree, vtype, (void *)&r->prefix, dist,
memcpy(&prefix.u.prefix6.s6_addr, ip6reach->prefix,
PSIZE(ip6reach->prefix_len));
apply_mask(&prefix);
process_N(spftree, vtype, (void *)&prefix, dist,
depth + 1, parent); depth + 1, parent);
} }
} }
@ -893,7 +893,9 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree,
if (!adj_has_mt(adj, spftree->mtid)) if (!adj_has_mt(adj, spftree->mtid))
continue; continue;
if (spftree->mtid == ISIS_MT_IPV4_UNICAST if (spftree->mtid == ISIS_MT_IPV4_UNICAST
&& !speaks(&adj->nlpids, spftree->family)) && !speaks(adj->nlpids.nlpids,
adj->nlpids.count,
spftree->family))
continue; continue;
switch (adj->sys_type) { switch (adj->sys_type) {
case ISIS_SYSTYPE_ES: case ISIS_SYSTYPE_ES:
@ -928,8 +930,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree,
->lspdb[spftree->level ->lspdb[spftree->level
- 1]); - 1]);
if (lsp == NULL if (lsp == NULL
|| lsp->lsp_header->rem_lifetime || lsp->hdr.rem_lifetime == 0)
== 0)
zlog_warn( zlog_warn(
"ISIS-Spf: No LSP %s found for IS adjacency " "ISIS-Spf: No LSP %s found for IS adjacency "
"L%d on %s (ID %u)", "L%d on %s (ID %u)",
@ -979,7 +980,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree,
lsp = lsp_search( lsp = lsp_search(
lsp_id, lsp_id,
spftree->area->lspdb[spftree->level - 1]); 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( zlog_warn(
"ISIS-Spf: No lsp (%p) found from root " "ISIS-Spf: No lsp (%p) found from root "
"to L%d DR %s on %s (ID %d)", "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_PSEUDO_ID(lsp_id) = 0;
LSP_FRAGMENT(lsp_id) = 0; LSP_FRAGMENT(lsp_id) = 0;
if (spftree->mtid != ISIS_MT_IPV4_UNICAST 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( isis_spf_add_local(
spftree, spftree,
spftree->area->oldmetric 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); memcpy(lsp_id, vertex->N.id, ISIS_SYS_ID_LEN + 1);
LSP_FRAGMENT(lsp_id) = 0; LSP_FRAGMENT(lsp_id) = 0;
lsp = lsp_search(lsp_id, area->lspdb[level - 1]); 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, isis_spf_process_lsp(spftree, lsp, vertex->d_N,
vertex->depth, sysid, vertex->depth, sysid,
vertex); vertex);

View File

@ -41,6 +41,7 @@
#include "md5.h" #include "md5.h"
#include "sockunion.h" #include "sockunion.h"
#include "network.h" #include "network.h"
#include "sbuf.h"
#include "isisd/dict.h" #include "isisd/dict.h"
#include "isisd/isis_constants.h" #include "isisd/isis_constants.h"
@ -48,7 +49,6 @@
#include "isisd/isis_flags.h" #include "isisd/isis_flags.h"
#include "isisd/isis_circuit.h" #include "isisd/isis_circuit.h"
#include "isisd/isisd.h" #include "isisd/isisd.h"
#include "isisd/isis_tlv.h"
#include "isisd/isis_lsp.h" #include "isisd/isis_lsp.h"
#include "isisd/isis_pdu.h" #include "isisd/isis_pdu.h"
#include "isisd/isis_dynhn.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 /* 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 */ /* 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"); 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 */ /* 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; int length = 0;
@ -306,7 +306,7 @@ u_char subtlvs_len(struct mpls_te_circuit *mtc)
return 0; return 0;
} }
mtc->length = (u_char)length; mtc->length = (uint8_t)length;
return mtc->length; return mtc->length;
} }
@ -666,162 +666,115 @@ void isis_mpls_te_update(struct interface *ifp)
* Followings are vty session control functions. * Followings are vty session control functions.
*------------------------------------------------------------------------*/ *------------------------------------------------------------------------*/
static u_char show_vty_subtlv_admin_grp(struct vty *vty, static u_char print_subtlv_admin_grp(struct sbuf *buf, int indent,
struct te_subtlv_admin_grp *tlv) struct te_subtlv_admin_grp *tlv)
{ {
sbuf_push(buf, indent, "Administrative Group: 0x%" PRIx32 "\n",
if (vty != NULL) ntohl(tlv->value));
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));
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); 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) { sbuf_push(buf, indent, "Link Local ID: %" PRIu32 "\n",
vty_out(vty, " Link Local ID: %d\n", ntohl(tlv->local));
(u_int32_t)ntohl(tlv->local)); sbuf_push(buf, indent, "Link Remote ID: %" PRIu32 "\n",
vty_out(vty, " Link Remote ID: %d\n", ntohl(tlv->remote));
(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));
}
return (SUBTLV_HDR_SIZE + TE_SUBTLV_LLRI_SIZE); return (SUBTLV_HDR_SIZE + TE_SUBTLV_LLRI_SIZE);
} }
static u_char show_vty_subtlv_local_ipaddr(struct vty *vty, static u_char print_subtlv_local_ipaddr(struct sbuf *buf, int indent,
struct te_subtlv_local_ipaddr *tlv) struct te_subtlv_local_ipaddr *tlv)
{ {
if (vty != NULL) sbuf_push(buf, indent, "Local Interface IP Address(es): %s\n",
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)); inet_ntoa(tlv->value));
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
} }
static u_char show_vty_subtlv_rmt_ipaddr(struct vty *vty, static u_char print_subtlv_rmt_ipaddr(struct sbuf *buf, int indent,
struct te_subtlv_rmt_ipaddr *tlv) struct te_subtlv_rmt_ipaddr *tlv)
{ {
if (vty != NULL) sbuf_push(buf, indent, "Remote Interface IP Address(es): %s\n",
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)); inet_ntoa(tlv->value));
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
} }
static u_char show_vty_subtlv_max_bw(struct vty *vty, static u_char print_subtlv_max_bw(struct sbuf *buf, int indent,
struct te_subtlv_max_bw *tlv) struct te_subtlv_max_bw *tlv)
{ {
float fval; float fval;
fval = ntohf(tlv->value); fval = ntohf(tlv->value);
if (vty != NULL) sbuf_push(buf, indent, "Maximum Bandwidth: %g (Bytes/sec)\n", fval);
vty_out(vty, " Maximum Bandwidth: %g (Bytes/sec)\n", fval);
else
zlog_debug(" Maximum Bandwidth: %g (Bytes/sec)", fval);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
} }
static u_char show_vty_subtlv_max_rsv_bw(struct vty *vty, static u_char print_subtlv_max_rsv_bw(struct sbuf *buf, int indent,
struct te_subtlv_max_rsv_bw *tlv) struct te_subtlv_max_rsv_bw *tlv)
{ {
float fval; float fval;
fval = ntohf(tlv->value); fval = ntohf(tlv->value);
if (vty != NULL) sbuf_push(buf, indent, "Maximum Reservable Bandwidth: %g (Bytes/sec)\n", fval);
vty_out(vty,
" Maximum Reservable Bandwidth: %g (Bytes/sec)\n",
fval);
else
zlog_debug(" Maximum Reservable Bandwidth: %g (Bytes/sec)",
fval);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
} }
static u_char show_vty_subtlv_unrsv_bw(struct vty *vty, static u_char print_subtlv_unrsv_bw(struct sbuf *buf, int indent,
struct te_subtlv_unrsv_bw *tlv) struct te_subtlv_unrsv_bw *tlv)
{ {
float fval1, fval2; float fval1, fval2;
int i; int i;
if (vty != NULL) sbuf_push(buf, indent, "Unreserved Bandwidth:\n");
vty_out(vty, " Unreserved Bandwidth:\n");
else
zlog_debug(" Unreserved Bandwidth:");
for (i = 0; i < MAX_CLASS_TYPE; i += 2) { for (i = 0; i < MAX_CLASS_TYPE; i += 2) {
fval1 = ntohf(tlv->value[i]); fval1 = ntohf(tlv->value[i]);
fval2 = ntohf(tlv->value[i + 1]); fval2 = ntohf(tlv->value[i + 1]);
if (vty != NULL) sbuf_push(buf, indent + 2, "[%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
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); i, fval1, i + 1, fval2);
} }
return (SUBTLV_HDR_SIZE + TE_SUBTLV_UNRSV_SIZE); return (SUBTLV_HDR_SIZE + TE_SUBTLV_UNRSV_SIZE);
} }
static u_char show_vty_subtlv_te_metric(struct vty *vty, static u_char print_subtlv_te_metric(struct sbuf *buf, int indent,
struct te_subtlv_te_metric *tlv) struct te_subtlv_te_metric *tlv)
{ {
u_int32_t te_metric; u_int32_t te_metric;
te_metric = tlv->value[2] | tlv->value[1] << 8 | tlv->value[0] << 16; te_metric = tlv->value[2] | tlv->value[1] << 8 | tlv->value[0] << 16;
if (vty != NULL) sbuf_push(buf, indent, "Traffic Engineering Metric: %u\n", te_metric);
vty_out(vty, " Traffic Engineering Metric: %u\n", te_metric);
else
zlog_debug(" Traffic Engineering Metric: %u", te_metric);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); 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) sbuf_push(buf, indent, "Inter-AS TE Remote AS number: %" PRIu32 "\n",
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)); ntohl(tlv->value));
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); 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) sbuf_push(buf, indent, "Inter-AS TE Remote ASBR IP address: %s\n",
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)); inet_ntoa(tlv->value));
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
} }
static u_char show_vty_subtlv_av_delay(struct vty *vty, static u_char print_subtlv_av_delay(struct sbuf *buf, int indent,
struct te_subtlv_av_delay *tlv) struct te_subtlv_av_delay *tlv)
{ {
u_int32_t delay; u_int32_t delay;
@ -830,17 +783,13 @@ static u_char show_vty_subtlv_av_delay(struct vty *vty,
delay = (u_int32_t)ntohl(tlv->value) & TE_EXT_MASK; delay = (u_int32_t)ntohl(tlv->value) & TE_EXT_MASK;
A = (u_int32_t)ntohl(tlv->value) & TE_EXT_ANORMAL; A = (u_int32_t)ntohl(tlv->value) & TE_EXT_ANORMAL;
if (vty != NULL) sbuf_push(buf, indent, "%s Average Link Delay: %" PRIu32 " (micro-sec)\n",
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); A ? "Anomalous" : "Normal", delay);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
} }
static u_char show_vty_subtlv_mm_delay(struct vty *vty, static u_char print_subtlv_mm_delay(struct sbuf *buf, int indent,
struct te_subtlv_mm_delay *tlv) struct te_subtlv_mm_delay *tlv)
{ {
u_int32_t low, high; u_int32_t low, high;
@ -850,32 +799,25 @@ static u_char show_vty_subtlv_mm_delay(struct vty *vty,
A = (u_int32_t)ntohl(tlv->low) & TE_EXT_ANORMAL; A = (u_int32_t)ntohl(tlv->low) & TE_EXT_ANORMAL;
high = (u_int32_t)ntohl(tlv->high) & TE_EXT_MASK; high = (u_int32_t)ntohl(tlv->high) & TE_EXT_MASK;
if (vty != NULL) sbuf_push(buf, indent, "%s Min/Max Link Delay: %" PRIu32 " / %" PRIu32 " (micro-sec)\n",
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); A ? "Anomalous" : "Normal", low, high);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
} }
static u_char show_vty_subtlv_delay_var(struct vty *vty, static u_char print_subtlv_delay_var(struct sbuf *buf, int indent,
struct te_subtlv_delay_var *tlv) struct te_subtlv_delay_var *tlv)
{ {
u_int32_t jitter; u_int32_t jitter;
jitter = (u_int32_t)ntohl(tlv->value) & TE_EXT_MASK; jitter = (u_int32_t)ntohl(tlv->value) & TE_EXT_MASK;
if (vty != NULL) sbuf_push(buf, indent, "Delay Variation: %" PRIu32 " (micro-sec)\n", jitter);
vty_out(vty, " Delay Variation: %d (micro-sec)\n", jitter);
else
zlog_debug(" Delay Variation: %d (micro-sec)", jitter);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
} }
static u_char show_vty_subtlv_pkt_loss(struct vty *vty, static u_char print_subtlv_pkt_loss(struct sbuf *buf, int indent,
struct te_subtlv_pkt_loss *tlv) struct te_subtlv_pkt_loss *tlv)
{ {
u_int32_t loss; u_int32_t loss;
@ -886,101 +828,77 @@ static u_char show_vty_subtlv_pkt_loss(struct vty *vty,
fval = (float)(loss * LOSS_PRECISION); fval = (float)(loss * LOSS_PRECISION);
A = (u_int32_t)ntohl(tlv->value) & TE_EXT_ANORMAL; A = (u_int32_t)ntohl(tlv->value) & TE_EXT_ANORMAL;
if (vty != NULL) sbuf_push(buf, indent, "%s Link Packet Loss: %g (%%)\n",
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); A ? "Anomalous" : "Normal", fval);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
} }
static u_char show_vty_subtlv_res_bw(struct vty *vty, static u_char print_subtlv_res_bw(struct sbuf *buf, int indent,
struct te_subtlv_res_bw *tlv) struct te_subtlv_res_bw *tlv)
{ {
float fval; float fval;
fval = ntohf(tlv->value); fval = ntohf(tlv->value);
if (vty != NULL) sbuf_push(buf, indent, "Unidirectional Residual Bandwidth: %g (Bytes/sec)\n",
vty_out(vty,
" Unidirectional Residual Bandwidth: %g (Bytes/sec)\n",
fval);
else
zlog_debug(
" Unidirectional Residual Bandwidth: %g (Bytes/sec)",
fval); fval);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
} }
static u_char show_vty_subtlv_ava_bw(struct vty *vty, static u_char print_subtlv_ava_bw(struct sbuf *buf, int indent,
struct te_subtlv_ava_bw *tlv) struct te_subtlv_ava_bw *tlv)
{ {
float fval; float fval;
fval = ntohf(tlv->value); fval = ntohf(tlv->value);
if (vty != NULL) sbuf_push(buf, indent, "Unidirectional Available Bandwidth: %g (Bytes/sec)\n",
vty_out(vty,
" Unidirectional Available Bandwidth: %g (Bytes/sec)\n",
fval);
else
zlog_debug(
" Unidirectional Available Bandwidth: %g (Bytes/sec)",
fval); fval);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
} }
static u_char show_vty_subtlv_use_bw(struct vty *vty, static u_char print_subtlv_use_bw(struct sbuf *buf, int indent,
struct te_subtlv_use_bw *tlv) struct te_subtlv_use_bw *tlv)
{ {
float fval; float fval;
fval = ntohf(tlv->value); fval = ntohf(tlv->value);
if (vty != NULL) sbuf_push(buf, indent, "Unidirectional Utilized Bandwidth: %g (Bytes/sec)\n",
vty_out(vty,
" Unidirectional Utilized Bandwidth: %g (Bytes/sec)\n",
fval);
else
zlog_debug(
" Unidirectional Utilized Bandwidth: %g (Bytes/sec)",
fval); fval);
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE); 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; int i, rtn = 1;
u_char *v = (u_char *)tlvh; u_char *v = (u_char *)tlvh;
if (vty != NULL) {
if (tlvh->length != 0) { if (tlvh->length != 0) {
vty_out(vty, sbuf_push(buf, indent,
" Unknown TLV: [type(%#.2x), length(%#.2x)]\n", "Unknown TLV: [type(%#.2x), length(%#.2x)]\n",
tlvh->type, tlvh->length); tlvh->type, tlvh->length);
vty_out(vty, " Dump: [00]"); sbuf_push(buf, indent + 2, "Dump: [00]");
rtn = 1; /* initialize end of line counter */ rtn = 1; /* initialize end of line counter */
for (i = 0; i < tlvh->length; i++) { for (i = 0; i < tlvh->length; i++) {
vty_out(vty, " %#.2x", v[i]); sbuf_push(buf, 0, " %#.2x", v[i]);
if (rtn == 8) { if (rtn == 8) {
vty_out(vty, "\n [%.2x]", sbuf_push(buf, 0, "\n");
i + 1); sbuf_push(buf, indent + 8,
"[%.2x]", i + 1);
rtn = 1; rtn = 1;
} else } else
rtn++; rtn++;
} }
vty_out(vty, "\n"); sbuf_push(buf, 0, "\n");
} else
vty_out(vty,
" Unknown TLV: [type(%#.2x), length(%#.2x)]\n",
tlvh->type, tlvh->length);
} else { } else {
zlog_debug(" Unknown TLV: [type(%#.2x), length(%#.2x)]", sbuf_push(buf, indent,
"Unknown TLV: [type(%#.2x), length(%#.2x)]\n",
tlvh->type, tlvh->length); tlvh->type, tlvh->length);
} }
@ -988,87 +906,84 @@ static u_char show_vty_unknown_tlv(struct vty *vty, struct subtlv_header *tlvh)
} }
/* Main Show function */ /* 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; struct subtlv_header *tlvh = (struct subtlv_header *)subtlvs;
u_int16_t sum = 0; uint16_t sum = 0;
zlog_debug("ISIS MPLS-TE: Show database TE detail"); for (; sum < subtlv_len; tlvh = SUBTLV_HDR_NEXT(tlvh)) {
tlvh = (struct subtlv_header *)te->sub_tlvs;
for (; sum < te->sub_tlvs_length; tlvh = SUBTLV_HDR_NEXT(tlvh)) {
switch (tlvh->type) { switch (tlvh->type) {
case TE_SUBTLV_ADMIN_GRP: case TE_SUBTLV_ADMIN_GRP:
sum += show_vty_subtlv_admin_grp( sum += print_subtlv_admin_grp(buf, indent,
vty, (struct te_subtlv_admin_grp *)tlvh); (struct te_subtlv_admin_grp *)tlvh);
break; break;
case TE_SUBTLV_LLRI: case TE_SUBTLV_LLRI:
sum += show_vty_subtlv_llri( sum += print_subtlv_llri(buf, indent,
vty, (struct te_subtlv_llri *)tlvh); (struct te_subtlv_llri *)tlvh);
break; break;
case TE_SUBTLV_LOCAL_IPADDR: case TE_SUBTLV_LOCAL_IPADDR:
sum += show_vty_subtlv_local_ipaddr( sum += print_subtlv_local_ipaddr(buf, indent,
vty, (struct te_subtlv_local_ipaddr *)tlvh); (struct te_subtlv_local_ipaddr *)tlvh);
break; break;
case TE_SUBTLV_RMT_IPADDR: case TE_SUBTLV_RMT_IPADDR:
sum += show_vty_subtlv_rmt_ipaddr( sum += print_subtlv_rmt_ipaddr(buf, indent,
vty, (struct te_subtlv_rmt_ipaddr *)tlvh); (struct te_subtlv_rmt_ipaddr *)tlvh);
break; break;
case TE_SUBTLV_MAX_BW: case TE_SUBTLV_MAX_BW:
sum += show_vty_subtlv_max_bw( sum += print_subtlv_max_bw(buf, indent,
vty, (struct te_subtlv_max_bw *)tlvh); (struct te_subtlv_max_bw *)tlvh);
break; break;
case TE_SUBTLV_MAX_RSV_BW: case TE_SUBTLV_MAX_RSV_BW:
sum += show_vty_subtlv_max_rsv_bw( sum += print_subtlv_max_rsv_bw(buf, indent,
vty, (struct te_subtlv_max_rsv_bw *)tlvh); (struct te_subtlv_max_rsv_bw *)tlvh);
break; break;
case TE_SUBTLV_UNRSV_BW: case TE_SUBTLV_UNRSV_BW:
sum += show_vty_subtlv_unrsv_bw( sum += print_subtlv_unrsv_bw(buf, indent,
vty, (struct te_subtlv_unrsv_bw *)tlvh); (struct te_subtlv_unrsv_bw *)tlvh);
break; break;
case TE_SUBTLV_TE_METRIC: case TE_SUBTLV_TE_METRIC:
sum += show_vty_subtlv_te_metric( sum += print_subtlv_te_metric(buf, indent,
vty, (struct te_subtlv_te_metric *)tlvh); (struct te_subtlv_te_metric *)tlvh);
break; break;
case TE_SUBTLV_RAS: case TE_SUBTLV_RAS:
sum += show_vty_subtlv_ras( sum += print_subtlv_ras(buf, indent,
vty, (struct te_subtlv_ras *)tlvh); (struct te_subtlv_ras *)tlvh);
break; break;
case TE_SUBTLV_RIP: case TE_SUBTLV_RIP:
sum += show_vty_subtlv_rip( sum += print_subtlv_rip(buf, indent,
vty, (struct te_subtlv_rip *)tlvh); (struct te_subtlv_rip *)tlvh);
break; break;
case TE_SUBTLV_AV_DELAY: case TE_SUBTLV_AV_DELAY:
sum += show_vty_subtlv_av_delay( sum += print_subtlv_av_delay(buf, indent,
vty, (struct te_subtlv_av_delay *)tlvh); (struct te_subtlv_av_delay *)tlvh);
break; break;
case TE_SUBTLV_MM_DELAY: case TE_SUBTLV_MM_DELAY:
sum += show_vty_subtlv_mm_delay( sum += print_subtlv_mm_delay(buf, indent,
vty, (struct te_subtlv_mm_delay *)tlvh); (struct te_subtlv_mm_delay *)tlvh);
break; break;
case TE_SUBTLV_DELAY_VAR: case TE_SUBTLV_DELAY_VAR:
sum += show_vty_subtlv_delay_var( sum += print_subtlv_delay_var(buf, indent,
vty, (struct te_subtlv_delay_var *)tlvh); (struct te_subtlv_delay_var *)tlvh);
break; break;
case TE_SUBTLV_PKT_LOSS: case TE_SUBTLV_PKT_LOSS:
sum += show_vty_subtlv_pkt_loss( sum += print_subtlv_pkt_loss(buf, indent,
vty, (struct te_subtlv_pkt_loss *)tlvh); (struct te_subtlv_pkt_loss *)tlvh);
break; break;
case TE_SUBTLV_RES_BW: case TE_SUBTLV_RES_BW:
sum += show_vty_subtlv_res_bw( sum += print_subtlv_res_bw(buf, indent,
vty, (struct te_subtlv_res_bw *)tlvh); (struct te_subtlv_res_bw *)tlvh);
break; break;
case TE_SUBTLV_AVA_BW: case TE_SUBTLV_AVA_BW:
sum += show_vty_subtlv_ava_bw( sum += print_subtlv_ava_bw(buf, indent,
vty, (struct te_subtlv_ava_bw *)tlvh); (struct te_subtlv_ava_bw *)tlvh);
break; break;
case TE_SUBTLV_USE_BW: case TE_SUBTLV_USE_BW:
sum += show_vty_subtlv_use_bw( sum += print_subtlv_use_bw(buf, indent,
vty, (struct te_subtlv_use_bw *)tlvh); (struct te_subtlv_use_bw *)tlvh);
break; break;
default: default:
sum += show_vty_unknown_tlv(vty, tlvh); sum += print_unknown_tlv(buf, indent, tlvh);
break; break;
} }
} }
@ -1252,6 +1167,9 @@ DEFUN (show_isis_mpls_te_router,
static void show_mpls_te_sub(struct vty *vty, struct interface *ifp) static void show_mpls_te_sub(struct vty *vty, struct interface *ifp)
{ {
struct mpls_te_circuit *mtc; struct mpls_te_circuit *mtc;
struct sbuf buf;
sbuf_init(&buf, NULL, 0);
if ((IS_MPLS_TE(isisMplsTE)) if ((IS_MPLS_TE(isisMplsTE))
&& ((mtc = lookup_mpls_params_by_ifp(ifp)) != NULL)) { && ((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); 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) 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) 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); print_subtlv_max_bw(&buf, 4, &mtc->max_bw);
show_vty_subtlv_max_rsv_bw(vty, &mtc->max_rsv_bw); print_subtlv_max_rsv_bw(&buf, 4, &mtc->max_rsv_bw);
show_vty_subtlv_unrsv_bw(vty, &mtc->unrsv_bw); print_subtlv_unrsv_bw(&buf, 4, &mtc->unrsv_bw);
show_vty_subtlv_te_metric(vty, &mtc->te_metric); print_subtlv_te_metric(&buf, 4, &mtc->te_metric);
if (IS_INTER_AS(mtc->type)) { if (IS_INTER_AS(mtc->type)) {
if (SUBTLV_TYPE(mtc->ras) != 0) 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) 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); print_subtlv_av_delay(&buf, 4, &mtc->av_delay);
show_vty_subtlv_mm_delay(vty, &mtc->mm_delay); print_subtlv_mm_delay(&buf, 4, &mtc->mm_delay);
show_vty_subtlv_delay_var(vty, &mtc->delay_var); print_subtlv_delay_var(&buf, 4, &mtc->delay_var);
show_vty_subtlv_pkt_loss(vty, &mtc->pkt_loss); print_subtlv_pkt_loss(&buf, 4, &mtc->pkt_loss);
show_vty_subtlv_res_bw(vty, &mtc->res_bw); print_subtlv_res_bw(&buf, 4, &mtc->res_bw);
show_vty_subtlv_ava_bw(vty, &mtc->ava_bw); print_subtlv_ava_bw(&buf, 4, &mtc->ava_bw);
show_vty_subtlv_use_bw(vty, &mtc->use_bw); print_subtlv_use_bw(&buf, 4, &mtc->use_bw);
vty_multiline(vty, "", "%s", sbuf_buf(&buf));
vty_out(vty, "---------------\n\n"); vty_out(vty, "---------------\n\n");
} else { } else {
vty_out(vty, " %s: MPLS-TE is disabled on this interface\n", vty_out(vty, " %s: MPLS-TE is disabled on this interface\n",
ifp->name); ifp->name);
} }
sbuf_free(&buf);
return; return;
} }

View File

@ -81,6 +81,8 @@ struct subtlv_header {
u_char length; /* Value portion only, in byte */ 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_HDR_SIZE 2 /* (sizeof (struct sub_tlv_header)) */
#define SUBTLV_SIZE(stlvh) (SUBTLV_HDR_SIZE + (stlvh)->length) #define SUBTLV_SIZE(stlvh) (SUBTLV_HDR_SIZE + (stlvh)->length)
@ -306,12 +308,13 @@ struct mpls_te_circuit {
/* Prototypes. */ /* Prototypes. */
void isis_mpls_te_init(void); void isis_mpls_te_init(void);
struct mpls_te_circuit *mpls_te_circuit_new(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_local_ipaddr(struct mpls_te_circuit *, struct in_addr);
void set_circuitparams_rmt_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 *); uint8_t subtlvs_len(struct mpls_te_circuit *);
u_char add_te_subtlvs(u_char *, struct mpls_te_circuit *); uint8_t add_te_subtlvs(uint8_t *, struct mpls_te_circuit *);
u_char build_te_subtlvs(u_char *, struct isis_circuit *); uint8_t build_te_subtlvs(uint8_t *, struct isis_circuit *);
void isis_link_params_update(struct isis_circuit *, struct interface *); void isis_link_params_update(struct isis_circuit *, struct interface *);
void isis_mpls_te_update(struct interface *); void isis_mpls_te_update(struct interface *);
void isis_mpls_te_config_write_router(struct vty *); void isis_mpls_te_config_write_router(struct vty *);

File diff suppressed because it is too large Load Diff

View File

@ -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 */

View File

@ -42,7 +42,6 @@
#include "isisd/isis_flags.h" #include "isisd/isis_flags.h"
#include "isisd/isis_misc.h" #include "isisd/isis_misc.h"
#include "isisd/isis_circuit.h" #include "isisd/isis_circuit.h"
#include "isisd/isis_tlv.h"
#include "isisd/isisd.h" #include "isisd/isisd.h"
#include "isisd/isis_circuit.h" #include "isisd/isis_circuit.h"
#include "isisd/isis_csm.h" #include "isisd/isis_csm.h"

View File

@ -49,7 +49,6 @@
#include "isisd/isis_pdu.h" #include "isisd/isis_pdu.h"
#include "isisd/isis_misc.h" #include "isisd/isis_misc.h"
#include "isisd/isis_constants.h" #include "isisd/isis_constants.h"
#include "isisd/isis_tlv.h"
#include "isisd/isis_lsp.h" #include "isisd/isis_lsp.h"
#include "isisd/isis_spf.h" #include "isisd/isis_spf.h"
#include "isisd/isis_route.h" #include "isisd/isis_route.h"

View File

@ -67,7 +67,7 @@ int iso_csum_verify(u_char *buffer, int len, uint16_t csum, int offset)
return 1; return 1;
checksum = fletcher_checksum(buffer, len, offset); checksum = fletcher_checksum(buffer, len, offset);
if (checksum == csum) if (checksum == htons(csum))
return 0; return 0;
return 1; return 1;
} }