mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 13:27:53 +00:00
isisd: send/receive LSPs with new parser
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
This commit is contained in:
parent
17c9dcd5f1
commit
af8ac8f98f
@ -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 \
|
||||||
|
@ -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",
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
@ -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),
|
||||||
|
@ -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);
|
||||||
|
@ -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"
|
||||||
|
1929
isisd/isis_lsp.c
1929
isisd/isis_lsp.c
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
199
isisd/isis_mt.c
199
isisd/isis_mt.c
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
486
isisd/isis_pdu.c
486
isisd/isis_pdu.c
@ -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;
|
|
||||||
}
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
223
isisd/isis_spf.c
223
isisd/isis_spf.c
@ -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);
|
||||||
|
320
isisd/isis_te.c
320
isisd/isis_te.c
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 *);
|
||||||
|
1453
isisd/isis_tlv.c
1453
isisd/isis_tlv.c
File diff suppressed because it is too large
Load Diff
340
isisd/isis_tlv.h
340
isisd/isis_tlv.h
@ -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 */
|
|
@ -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"
|
||||||
|
@ -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"
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user