mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-04 10:09:25 +00:00
Merge pull request #854 from opensourcerouting/isis-parser
IS-IS: rewrite TLV deserializer/serializer
This commit is contained in:
commit
28ae32e66e
@ -8,24 +8,26 @@ LIBS = @LIBS@
|
||||
AM_CFLAGS = $(WERROR)
|
||||
|
||||
noinst_LIBRARIES = libisis.a
|
||||
sbin_PROGRAMS = isisd
|
||||
sbin_PROGRAMS = isisd
|
||||
|
||||
libisis_a_SOURCES = \
|
||||
isis_memory.c \
|
||||
isis_adjacency.c isis_lsp.c dict.c isis_circuit.c isis_pdu.c \
|
||||
isis_tlv.c isisd.c isis_misc.c isis_zebra.c isis_dr.c \
|
||||
isisd.c isis_misc.c isis_zebra.c isis_dr.c \
|
||||
isis_flags.c isis_dynhn.c iso_checksum.c isis_csm.c isis_events.c \
|
||||
isis_spf.c isis_redist.c isis_route.c isis_routemap.c isis_te.c \
|
||||
isis_vty.c isis_mt.c
|
||||
isis_vty.c isis_mt.c \
|
||||
isis_tlvs.c
|
||||
|
||||
|
||||
noinst_HEADERS = \
|
||||
isis_memory.h \
|
||||
isisd.h isis_pdu.h isis_tlv.h isis_adjacency.h isis_constants.h \
|
||||
isisd.h isis_pdu.h isis_adjacency.h isis_constants.h \
|
||||
isis_lsp.h dict.h isis_circuit.h isis_misc.h isis_network.h \
|
||||
isis_zebra.h isis_dr.h isis_flags.h isis_dynhn.h isis_common.h \
|
||||
iso_checksum.h isis_csm.h isis_events.h isis_spf.h isis_redist.h \
|
||||
isis_route.h isis_routemap.h isis_te.h isis_mt.h
|
||||
isis_route.h isis_routemap.h isis_te.h isis_mt.h \
|
||||
isis_tlvs.h
|
||||
|
||||
isisd_SOURCES = \
|
||||
isis_main.c $(libisis_a_SOURCES) \
|
||||
|
@ -43,7 +43,6 @@
|
||||
#include "isisd/isis_dr.h"
|
||||
#include "isisd/isis_dynhn.h"
|
||||
#include "isisd/isis_pdu.h"
|
||||
#include "isisd/isis_tlv.h"
|
||||
#include "isisd/isis_lsp.h"
|
||||
#include "isisd/isis_spf.h"
|
||||
#include "isisd/isis_events.h"
|
||||
@ -69,11 +68,6 @@ struct isis_adjacency *isis_new_adj(const u_char *id, const u_char *snpa,
|
||||
|
||||
adj = adj_alloc(id); /* P2P kludge */
|
||||
|
||||
if (adj == NULL) {
|
||||
zlog_err("Out of memory!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (snpa) {
|
||||
memcpy(adj->snpa, snpa, ETH_ALEN);
|
||||
} else {
|
||||
@ -137,12 +131,12 @@ void isis_delete_adj(void *arg)
|
||||
/* remove from SPF trees */
|
||||
spftree_area_adj_del(adj->circuit->area, adj);
|
||||
|
||||
if (adj->area_addrs)
|
||||
list_delete(adj->area_addrs);
|
||||
if (adj->ipv4_addrs)
|
||||
list_delete(adj->ipv4_addrs);
|
||||
if (adj->ipv6_addrs)
|
||||
list_delete(adj->ipv6_addrs);
|
||||
if (adj->area_addresses)
|
||||
XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->area_addresses);
|
||||
if (adj->ipv4_addresses)
|
||||
XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->ipv4_addresses);
|
||||
if (adj->ipv6_addresses)
|
||||
XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->ipv6_addresses);
|
||||
|
||||
adj_mt_finish(adj);
|
||||
|
||||
@ -192,7 +186,7 @@ void isis_adj_state_change(struct isis_adjacency *adj,
|
||||
|
||||
dyn = dynhn_find_by_id(adj->sysid);
|
||||
if (dyn)
|
||||
adj_name = (const char *)dyn->name.name;
|
||||
adj_name = dyn->hostname;
|
||||
else
|
||||
adj_name = sysid_print(adj->sysid);
|
||||
|
||||
@ -301,33 +295,29 @@ void isis_adj_state_change(struct isis_adjacency *adj,
|
||||
void isis_adj_print(struct isis_adjacency *adj)
|
||||
{
|
||||
struct isis_dynhn *dyn;
|
||||
struct listnode *node;
|
||||
struct in_addr *ipv4_addr;
|
||||
struct in6_addr *ipv6_addr;
|
||||
u_char ip6[INET6_ADDRSTRLEN];
|
||||
|
||||
if (!adj)
|
||||
return;
|
||||
dyn = dynhn_find_by_id(adj->sysid);
|
||||
if (dyn)
|
||||
zlog_debug("%s", dyn->name.name);
|
||||
zlog_debug("%s", dyn->hostname);
|
||||
|
||||
zlog_debug("SystemId %20s SNPA %s, level %d\nHolding Time %d",
|
||||
sysid_print(adj->sysid), snpa_print(adj->snpa), adj->level,
|
||||
adj->hold_time);
|
||||
if (adj->ipv4_addrs && listcount(adj->ipv4_addrs) > 0) {
|
||||
if (adj->ipv4_address_count) {
|
||||
zlog_debug("IPv4 Address(es):");
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(adj->ipv4_addrs, node, ipv4_addr))
|
||||
zlog_debug("%s", inet_ntoa(*ipv4_addr));
|
||||
for (unsigned int i = 0; i < adj->ipv4_address_count; i++)
|
||||
zlog_debug("%s", inet_ntoa(adj->ipv4_addresses[i]));
|
||||
}
|
||||
|
||||
if (adj->ipv6_addrs && listcount(adj->ipv6_addrs) > 0) {
|
||||
if (adj->ipv6_address_count) {
|
||||
zlog_debug("IPv6 Address(es):");
|
||||
for (ALL_LIST_ELEMENTS_RO(adj->ipv6_addrs, node, ipv6_addr)) {
|
||||
inet_ntop(AF_INET6, ipv6_addr, (char *)ip6,
|
||||
INET6_ADDRSTRLEN);
|
||||
zlog_debug("%s", ip6);
|
||||
for (unsigned int i = 0; i < adj->ipv6_address_count; i++) {
|
||||
char buf[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET6, &adj->ipv6_addresses[i], buf,
|
||||
sizeof(buf));
|
||||
zlog_debug("%s", buf);
|
||||
}
|
||||
}
|
||||
zlog_debug("Speaks: %s", nlpid2string(&adj->nlpids));
|
||||
@ -358,17 +348,13 @@ int isis_adj_expire(struct thread *thread)
|
||||
void isis_adj_print_vty(struct isis_adjacency *adj, struct vty *vty,
|
||||
char detail)
|
||||
{
|
||||
struct in6_addr *ipv6_addr;
|
||||
u_char ip6[INET6_ADDRSTRLEN];
|
||||
struct in_addr *ip_addr;
|
||||
time_t now;
|
||||
struct isis_dynhn *dyn;
|
||||
int level;
|
||||
struct listnode *node;
|
||||
|
||||
dyn = dynhn_find_by_id(adj->sysid);
|
||||
if (dyn)
|
||||
vty_out(vty, " %-20s", dyn->name.name);
|
||||
vty_out(vty, " %-20s", dyn->hostname);
|
||||
else
|
||||
vty_out(vty, " %-20s", sysid_print(adj->sysid));
|
||||
|
||||
@ -429,8 +415,7 @@ void isis_adj_print_vty(struct isis_adjacency *adj, struct vty *vty,
|
||||
&& (adj->circuit->circ_type == CIRCUIT_T_BROADCAST)) {
|
||||
dyn = dynhn_find_by_id(adj->lanid);
|
||||
if (dyn)
|
||||
vty_out(vty, ", LAN id: %s.%02x",
|
||||
dyn->name.name,
|
||||
vty_out(vty, ", LAN id: %s.%02x", dyn->hostname,
|
||||
adj->lanid[ISIS_SYS_ID_LEN]);
|
||||
else
|
||||
vty_out(vty, ", LAN id: %s.%02x",
|
||||
@ -452,28 +437,32 @@ void isis_adj_print_vty(struct isis_adjacency *adj, struct vty *vty,
|
||||
}
|
||||
vty_out(vty, "\n");
|
||||
|
||||
if (adj->area_addrs && listcount(adj->area_addrs) > 0) {
|
||||
struct area_addr *area_addr;
|
||||
if (adj->area_address_count) {
|
||||
vty_out(vty, " Area Address(es):\n");
|
||||
for (ALL_LIST_ELEMENTS_RO(adj->area_addrs, node,
|
||||
area_addr))
|
||||
for (unsigned int i = 0; i < adj->area_address_count;
|
||||
i++) {
|
||||
vty_out(vty, " %s\n",
|
||||
isonet_print(area_addr->area_addr,
|
||||
area_addr->addr_len));
|
||||
isonet_print(adj->area_addresses[i]
|
||||
.area_addr,
|
||||
adj->area_addresses[i]
|
||||
.addr_len));
|
||||
}
|
||||
}
|
||||
if (adj->ipv4_addrs && listcount(adj->ipv4_addrs) > 0) {
|
||||
if (adj->ipv4_address_count) {
|
||||
vty_out(vty, " IPv4 Address(es):\n");
|
||||
for (ALL_LIST_ELEMENTS_RO(adj->ipv4_addrs, node,
|
||||
ip_addr))
|
||||
vty_out(vty, " %s\n", inet_ntoa(*ip_addr));
|
||||
for (unsigned int i = 0; i < adj->ipv4_address_count;
|
||||
i++)
|
||||
vty_out(vty, " %s\n",
|
||||
inet_ntoa(adj->ipv4_addresses[i]));
|
||||
}
|
||||
if (adj->ipv6_addrs && listcount(adj->ipv6_addrs) > 0) {
|
||||
if (adj->ipv6_address_count) {
|
||||
vty_out(vty, " IPv6 Address(es):\n");
|
||||
for (ALL_LIST_ELEMENTS_RO(adj->ipv6_addrs, node,
|
||||
ipv6_addr)) {
|
||||
inet_ntop(AF_INET6, ipv6_addr, (char *)ip6,
|
||||
INET6_ADDRSTRLEN);
|
||||
vty_out(vty, " %s\n", ip6);
|
||||
for (unsigned int i = 0; i < adj->ipv6_address_count;
|
||||
i++) {
|
||||
char buf[INET6_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET6, &adj->ipv6_addresses[i],
|
||||
buf, sizeof(buf));
|
||||
vty_out(vty, " %s\n", buf);
|
||||
}
|
||||
}
|
||||
vty_out(vty, "\n");
|
||||
|
@ -73,13 +73,16 @@ struct isis_adjacency {
|
||||
int dischanges[ISIS_LEVELS]; /* how many DIS changes ? */
|
||||
/* an array of N levels for M records */
|
||||
struct isis_dis_record dis_record[DIS_RECORDS * ISIS_LEVELS];
|
||||
enum isis_adj_state adj_state; /* adjacencyState */
|
||||
enum isis_adj_usage adj_usage; /* adjacencyUsage */
|
||||
struct list *area_addrs; /* areaAdressesOfNeighbour */
|
||||
struct nlpids nlpids; /* protocols spoken ... */
|
||||
struct list *ipv4_addrs;
|
||||
enum isis_adj_state adj_state; /* adjacencyState */
|
||||
enum isis_adj_usage adj_usage; /* adjacencyUsage */
|
||||
struct area_addr *area_addresses; /* areaAdressesOfNeighbour */
|
||||
unsigned int area_address_count;
|
||||
struct nlpids nlpids; /* protocols spoken ... */
|
||||
struct in_addr *ipv4_addresses;
|
||||
unsigned int ipv4_address_count;
|
||||
struct in_addr router_address;
|
||||
struct list *ipv6_addrs;
|
||||
struct in6_addr *ipv6_addresses;
|
||||
unsigned int ipv6_address_count;
|
||||
struct in6_addr router_address6;
|
||||
u_char prio[ISIS_LEVELS]; /* priorityOfNeighbour for DIS */
|
||||
int circuit_t; /* from hello PDU hdr */
|
||||
|
@ -48,7 +48,6 @@
|
||||
#include "isisd/isis_common.h"
|
||||
#include "isisd/isis_flags.h"
|
||||
#include "isisd/isis_circuit.h"
|
||||
#include "isisd/isis_tlv.h"
|
||||
#include "isisd/isis_lsp.h"
|
||||
#include "isisd/isis_pdu.h"
|
||||
#include "isisd/isis_network.h"
|
||||
|
@ -46,16 +46,6 @@ struct isis_passwd {
|
||||
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
|
||||
*/
|
||||
|
@ -37,7 +37,6 @@
|
||||
#include "isisd/isis_common.h"
|
||||
#include "isisd/isis_flags.h"
|
||||
#include "isisd/isis_circuit.h"
|
||||
#include "isisd/isis_tlv.h"
|
||||
#include "isisd/isis_lsp.h"
|
||||
#include "isisd/isis_pdu.h"
|
||||
#include "isisd/isis_network.h"
|
||||
|
@ -42,7 +42,6 @@
|
||||
#include "isisd/isis_adjacency.h"
|
||||
#include "isisd/isis_constants.h"
|
||||
#include "isisd/isis_pdu.h"
|
||||
#include "isisd/isis_tlv.h"
|
||||
#include "isisd/isis_lsp.h"
|
||||
#include "isisd/isis_dr.h"
|
||||
#include "isisd/isis_events.h"
|
||||
|
@ -94,38 +94,26 @@ struct isis_dynhn *dynhn_find_by_name(const char *hostname)
|
||||
struct isis_dynhn *dyn = NULL;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(dyn_cache, node, dyn))
|
||||
if (strncmp((char *)dyn->name.name, hostname, 255) == 0)
|
||||
if (strncmp(dyn->hostname, hostname, 255) == 0)
|
||||
return dyn;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void isis_dynhn_insert(const u_char *id, struct hostname *hostname, int level)
|
||||
void isis_dynhn_insert(const u_char *id, const char *hostname, int level)
|
||||
{
|
||||
struct isis_dynhn *dyn;
|
||||
|
||||
dyn = dynhn_find_by_id(id);
|
||||
if (dyn) {
|
||||
memcpy(&dyn->name, hostname, hostname->namelen + 1);
|
||||
memcpy(dyn->id, id, ISIS_SYS_ID_LEN);
|
||||
dyn->refresh = time(NULL);
|
||||
return;
|
||||
}
|
||||
dyn = XCALLOC(MTYPE_ISIS_DYNHN, sizeof(struct isis_dynhn));
|
||||
if (!dyn) {
|
||||
zlog_warn("isis_dynhn_insert(): out of memory!");
|
||||
return;
|
||||
dyn = XCALLOC(MTYPE_ISIS_DYNHN, sizeof(struct isis_dynhn));
|
||||
memcpy(dyn->id, id, ISIS_SYS_ID_LEN);
|
||||
dyn->level = level;
|
||||
listnode_add(dyn_cache, dyn);
|
||||
}
|
||||
|
||||
/* we also copy the length */
|
||||
memcpy(&dyn->name, hostname, hostname->namelen + 1);
|
||||
memcpy(dyn->id, id, ISIS_SYS_ID_LEN);
|
||||
snprintf(dyn->hostname, sizeof(dyn->hostname), "%s", hostname);
|
||||
dyn->refresh = time(NULL);
|
||||
dyn->level = level;
|
||||
|
||||
listnode_add(dyn_cache, dyn);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void isis_dynhn_remove(const u_char *id)
|
||||
@ -137,7 +125,6 @@ void isis_dynhn_remove(const u_char *id)
|
||||
return;
|
||||
listnode_delete(dyn_cache, dyn);
|
||||
XFREE(MTYPE_ISIS_DYNHN, dyn);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -155,7 +142,7 @@ void dynhn_print_all(struct vty *vty)
|
||||
for (ALL_LIST_ELEMENTS_RO(dyn_cache, node, dyn)) {
|
||||
vty_out(vty, "%-7d", dyn->level);
|
||||
vty_out(vty, "%-15s%-15s\n", sysid_print(dyn->id),
|
||||
dyn->name.name);
|
||||
dyn->hostname);
|
||||
}
|
||||
|
||||
vty_out(vty, " * %s %s\n", sysid_print(isis->sysid),
|
||||
|
@ -25,13 +25,13 @@
|
||||
|
||||
struct isis_dynhn {
|
||||
u_char id[ISIS_SYS_ID_LEN];
|
||||
struct hostname name;
|
||||
char hostname[256];
|
||||
time_t refresh;
|
||||
int level;
|
||||
};
|
||||
|
||||
void dyn_cache_init(void);
|
||||
void isis_dynhn_insert(const u_char *id, struct hostname *hostname, int level);
|
||||
void isis_dynhn_insert(const u_char *id, const char *hostname, int level);
|
||||
void isis_dynhn_remove(const u_char *id);
|
||||
struct isis_dynhn *dynhn_find_by_id(const u_char *id);
|
||||
struct isis_dynhn *dynhn_find_by_name(const char *hostname);
|
||||
|
@ -37,7 +37,6 @@
|
||||
#include "isisd/isis_common.h"
|
||||
#include "isisd/isis_flags.h"
|
||||
#include "isisd/isis_circuit.h"
|
||||
#include "isisd/isis_tlv.h"
|
||||
#include "isisd/isis_lsp.h"
|
||||
#include "isisd/isis_pdu.h"
|
||||
#include "isisd/isis_network.h"
|
||||
|
2015
isisd/isis_lsp.c
2015
isisd/isis_lsp.c
File diff suppressed because it is too large
Load Diff
@ -24,19 +24,19 @@
|
||||
#ifndef _ZEBRA_ISIS_LSP_H
|
||||
#define _ZEBRA_ISIS_LSP_H
|
||||
|
||||
#include "isisd/isis_pdu.h"
|
||||
|
||||
/* Structure for isis_lsp, this structure will only support the fixed
|
||||
* System ID (Currently 6) (atleast for now). In order to support more
|
||||
* We will have to split the header into two parts, and for readability
|
||||
* sake it should better be avoided */
|
||||
struct isis_lsp {
|
||||
struct isis_fixed_hdr *isis_header; /* normally equals pdu */
|
||||
struct isis_link_state_hdr *lsp_header; /* pdu + isis_header_len */
|
||||
struct stream *pdu; /* full pdu lsp */
|
||||
struct isis_lsp_hdr hdr;
|
||||
struct stream *pdu; /* full pdu lsp */
|
||||
union {
|
||||
struct list *frags;
|
||||
struct isis_lsp *zero_lsp;
|
||||
} lspu;
|
||||
u_int32_t auth_tlv_offset; /* authentication TLV position in the pdu */
|
||||
u_int32_t SRMflags[ISIS_MAX_CIRCUITS];
|
||||
u_int32_t SSNflags[ISIS_MAX_CIRCUITS];
|
||||
int level; /* L1 or L2? */
|
||||
@ -47,7 +47,7 @@ struct isis_lsp {
|
||||
/* used for 60 second counting when rem_lifetime is zero */
|
||||
int age_out;
|
||||
struct isis_area *area;
|
||||
struct tlvs tlv_data; /* Simplifies TLV access */
|
||||
struct isis_tlvs *tlvs;
|
||||
};
|
||||
|
||||
dict_t *lsp_db_init(void);
|
||||
@ -59,13 +59,13 @@ int lsp_regenerate_schedule(struct isis_area *area, int level, int all_pseudo);
|
||||
int lsp_generate_pseudo(struct isis_circuit *circuit, int level);
|
||||
int lsp_regenerate_schedule_pseudo(struct isis_circuit *circuit, int level);
|
||||
|
||||
struct isis_lsp *lsp_new(struct isis_area *area, u_char *lsp_id,
|
||||
u_int16_t rem_lifetime, u_int32_t seq_num,
|
||||
u_int8_t lsp_bits, u_int16_t checksum, int level);
|
||||
struct isis_lsp *lsp_new_from_stream_ptr(struct stream *stream,
|
||||
u_int16_t pdu_len,
|
||||
struct isis_lsp *lsp0,
|
||||
struct isis_area *area, int level);
|
||||
struct isis_lsp *lsp_new(struct isis_area *area, uint8_t *lsp_id,
|
||||
uint16_t rem_lifetime, uint32_t seq_num,
|
||||
uint8_t lsp_bits, uint16_t checksum, int level);
|
||||
struct isis_lsp *lsp_new_from_recv(struct isis_lsp_hdr *hdr,
|
||||
struct isis_tlvs *tlvs,
|
||||
struct stream *stream, struct isis_lsp *lsp0,
|
||||
struct isis_area *area, int level);
|
||||
void lsp_insert(struct isis_lsp *lsp, dict_t *lspdb);
|
||||
struct isis_lsp *lsp_search(u_char *id, dict_t *lspdb);
|
||||
|
||||
@ -73,12 +73,9 @@ void lsp_build_list(u_char *start_id, u_char *stop_id, u_char num_lsps,
|
||||
struct list *list, dict_t *lspdb);
|
||||
void lsp_build_list_nonzero_ht(u_char *start_id, u_char *stop_id,
|
||||
struct list *list, dict_t *lspdb);
|
||||
void lsp_build_list_ssn(struct isis_circuit *circuit, u_char num_lsps,
|
||||
struct list *list, dict_t *lspdb);
|
||||
|
||||
void lsp_search_and_destroy(u_char *id, dict_t *lspdb);
|
||||
void lsp_purge_pseudo(u_char *id, struct isis_circuit *circuit, int level);
|
||||
void lsp_purge_non_exist(int level, struct isis_link_state_hdr *lsp_hdr,
|
||||
void lsp_purge_non_exist(int level, struct isis_lsp_hdr *hdr,
|
||||
struct isis_area *area);
|
||||
|
||||
#define LSP_EQUAL 1
|
||||
@ -92,16 +89,15 @@ void lsp_purge_non_exist(int level, struct isis_link_state_hdr *lsp_hdr,
|
||||
(I)[ISIS_SYS_ID_LEN] = 0; \
|
||||
(I)[ISIS_SYS_ID_LEN + 1] = 0
|
||||
int lsp_id_cmp(u_char *id1, u_char *id2);
|
||||
int lsp_compare(char *areatag, struct isis_lsp *lsp, u_int32_t seq_num,
|
||||
u_int16_t checksum, u_int16_t rem_lifetime);
|
||||
void lsp_update(struct isis_lsp *lsp, struct stream *stream,
|
||||
struct isis_area *area, int level);
|
||||
void lsp_inc_seqnum(struct isis_lsp *lsp, u_int32_t seq_num);
|
||||
int lsp_compare(char *areatag, struct isis_lsp *lsp, uint32_t seqno,
|
||||
uint16_t checksum, uint16_t rem_lifetime);
|
||||
void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr,
|
||||
struct isis_tlvs *tlvs, struct stream *stream,
|
||||
struct isis_area *area, int level, bool confusion);
|
||||
void lsp_inc_seqno(struct isis_lsp *lsp, uint32_t seqno);
|
||||
void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost);
|
||||
void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty, char dynhost);
|
||||
int lsp_print_all(struct vty *vty, dict_t *lspdb, char detail, char dynhost);
|
||||
const char *lsp_bits2string(u_char *);
|
||||
|
||||
/* sets SRMflags for all active circuits of an lsp */
|
||||
void lsp_set_all_srmflags(struct isis_lsp *lsp);
|
||||
|
||||
|
@ -52,7 +52,6 @@
|
||||
#include "isisd/isis_route.h"
|
||||
#include "isisd/isis_routemap.h"
|
||||
#include "isisd/isis_zebra.h"
|
||||
#include "isisd/isis_tlv.h"
|
||||
#include "isisd/isis_te.h"
|
||||
|
||||
/* Default configuration file name */
|
||||
|
@ -31,9 +31,9 @@ DEFINE_MTYPE(ISISD, ISIS_TMP, "ISIS TMP")
|
||||
DEFINE_MTYPE(ISISD, ISIS_CIRCUIT, "ISIS circuit")
|
||||
DEFINE_MTYPE(ISISD, ISIS_LSP, "ISIS LSP")
|
||||
DEFINE_MTYPE(ISISD, ISIS_ADJACENCY, "ISIS adjacency")
|
||||
DEFINE_MTYPE(ISISD, ISIS_ADJACENCY_INFO, "ISIS adjacency info")
|
||||
DEFINE_MTYPE(ISISD, ISIS_AREA, "ISIS area")
|
||||
DEFINE_MTYPE(ISISD, ISIS_AREA_ADDR, "ISIS area address")
|
||||
DEFINE_MTYPE(ISISD, ISIS_TLV, "ISIS TLV")
|
||||
DEFINE_MTYPE(ISISD, ISIS_DYNHN, "ISIS dyn hostname")
|
||||
DEFINE_MTYPE(ISISD, ISIS_SPFTREE, "ISIS SPFtree")
|
||||
DEFINE_MTYPE(ISISD, ISIS_VERTEX, "ISIS vertex")
|
||||
|
@ -30,9 +30,9 @@ DECLARE_MTYPE(ISIS_TMP)
|
||||
DECLARE_MTYPE(ISIS_CIRCUIT)
|
||||
DECLARE_MTYPE(ISIS_LSP)
|
||||
DECLARE_MTYPE(ISIS_ADJACENCY)
|
||||
DECLARE_MTYPE(ISIS_ADJACENCY_INFO)
|
||||
DECLARE_MTYPE(ISIS_AREA)
|
||||
DECLARE_MTYPE(ISIS_AREA_ADDR)
|
||||
DECLARE_MTYPE(ISIS_TLV)
|
||||
DECLARE_MTYPE(ISIS_DYNHN)
|
||||
DECLARE_MTYPE(ISIS_SPFTREE)
|
||||
DECLARE_MTYPE(ISIS_VERTEX)
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "hash.h"
|
||||
#include "if.h"
|
||||
#include "command.h"
|
||||
#include "log_int.h"
|
||||
|
||||
#include "isisd/dict.h"
|
||||
#include "isisd/isis_constants.h"
|
||||
@ -38,7 +39,6 @@
|
||||
#include "isisd/isisd.h"
|
||||
#include "isisd/isis_misc.h"
|
||||
|
||||
#include "isisd/isis_tlv.h"
|
||||
#include "isisd/isis_lsp.h"
|
||||
#include "isisd/isis_constants.h"
|
||||
#include "isisd/isis_adjacency.h"
|
||||
@ -46,15 +46,9 @@
|
||||
|
||||
/* staticly assigned vars for printing purposes */
|
||||
struct in_addr new_prefix;
|
||||
/* len of xxxx.xxxx.xxxx + place for #0 termination */
|
||||
char sysid[15];
|
||||
/* len of xxxx.xxxx.xxxx + place for #0 termination */
|
||||
char snpa[15];
|
||||
/* len of xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xx */
|
||||
char isonet[51];
|
||||
/* + place for #0 termination */
|
||||
/* len of xxxx.xxxx.xxxx.xx.xx + place for #0 termination */
|
||||
char lspid[21];
|
||||
char isonet[51];
|
||||
/* len of xxYxxMxWxdxxhxxmxxs + place for #0 termination */
|
||||
char datestring[20];
|
||||
char nlpidstring[30];
|
||||
@ -179,6 +173,26 @@ int sysid2buff(u_char *buff, const char *dotted)
|
||||
return len;
|
||||
}
|
||||
|
||||
const char *nlpid2str(uint8_t nlpid)
|
||||
{
|
||||
static char buf[4];
|
||||
switch (nlpid) {
|
||||
case NLPID_IP:
|
||||
return "IPv4";
|
||||
case NLPID_IPV6:
|
||||
return "IPv6";
|
||||
case NLPID_SNAP:
|
||||
return "SNAP";
|
||||
case NLPID_CLNP:
|
||||
return "CLNP";
|
||||
case NLPID_ESIS:
|
||||
return "ES-IS";
|
||||
default:
|
||||
snprintf(buf, sizeof(buf), "%" PRIu8, nlpid);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* converts the nlpids struct (filled by TLV #129)
|
||||
* into a string
|
||||
@ -190,26 +204,7 @@ char *nlpid2string(struct nlpids *nlpids)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nlpids->count; i++) {
|
||||
switch (nlpids->nlpids[i]) {
|
||||
case NLPID_IP:
|
||||
pos += sprintf(pos, "IPv4");
|
||||
break;
|
||||
case NLPID_IPV6:
|
||||
pos += sprintf(pos, "IPv6");
|
||||
break;
|
||||
case NLPID_SNAP:
|
||||
pos += sprintf(pos, "SNAP");
|
||||
break;
|
||||
case NLPID_CLNP:
|
||||
pos += sprintf(pos, "CLNP");
|
||||
break;
|
||||
case NLPID_ESIS:
|
||||
pos += sprintf(pos, "ES-IS");
|
||||
break;
|
||||
default:
|
||||
pos += sprintf(pos, "unknown");
|
||||
break;
|
||||
}
|
||||
pos += sprintf(pos, "%s", nlpid2str(nlpids->nlpids[i]));
|
||||
if (nlpids->count - i > 1)
|
||||
pos += sprintf(pos, ", ");
|
||||
}
|
||||
@ -219,25 +214,6 @@ char *nlpid2string(struct nlpids *nlpids)
|
||||
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
|
||||
*/
|
||||
@ -330,71 +306,53 @@ const char *syst2string(int type)
|
||||
*/
|
||||
const char *snpa_print(const u_char *from)
|
||||
{
|
||||
int i = 0;
|
||||
u_char *pos = (u_char *)snpa;
|
||||
|
||||
if (!from)
|
||||
return "unknown";
|
||||
|
||||
while (i < ETH_ALEN - 1) {
|
||||
if (i & 1) {
|
||||
sprintf((char *)pos, "%02x.", *(from + i));
|
||||
pos += 3;
|
||||
} else {
|
||||
sprintf((char *)pos, "%02x", *(from + i));
|
||||
pos += 2;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
sprintf((char *)pos, "%02x", *(from + (ISIS_SYS_ID_LEN - 1)));
|
||||
pos += 2;
|
||||
*(pos) = '\0';
|
||||
|
||||
return snpa;
|
||||
return isis_format_id(from, ISIS_SYS_ID_LEN);
|
||||
}
|
||||
|
||||
const char *sysid_print(const u_char *from)
|
||||
{
|
||||
int i = 0;
|
||||
char *pos = sysid;
|
||||
|
||||
if (!from)
|
||||
return "unknown";
|
||||
|
||||
while (i < ISIS_SYS_ID_LEN - 1) {
|
||||
if (i & 1) {
|
||||
sprintf(pos, "%02x.", *(from + i));
|
||||
pos += 3;
|
||||
} else {
|
||||
sprintf(pos, "%02x", *(from + i));
|
||||
pos += 2;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
sprintf(pos, "%02x", *(from + (ISIS_SYS_ID_LEN - 1)));
|
||||
pos += 2;
|
||||
*(pos) = '\0';
|
||||
|
||||
return sysid;
|
||||
return isis_format_id(from, ISIS_SYS_ID_LEN);
|
||||
}
|
||||
|
||||
const char *rawlspid_print(const u_char *from)
|
||||
{
|
||||
char *pos = lspid;
|
||||
if (!from)
|
||||
return "unknown";
|
||||
memcpy(pos, sysid_print(from), 15);
|
||||
pos += 14;
|
||||
sprintf(pos, ".%02x", LSP_PSEUDO_ID(from));
|
||||
pos += 3;
|
||||
sprintf(pos, "-%02x", LSP_FRAGMENT(from));
|
||||
pos += 3;
|
||||
return isis_format_id(from, 8);
|
||||
}
|
||||
|
||||
*(pos) = '\0';
|
||||
#define FORMAT_ID_SIZE sizeof("0000.0000.0000.00-00")
|
||||
const char *isis_format_id(const uint8_t *id, size_t len)
|
||||
{
|
||||
#define FORMAT_BUF_COUNT 4
|
||||
static char buf_ring[FORMAT_BUF_COUNT][FORMAT_ID_SIZE];
|
||||
static size_t cur_buf = 0;
|
||||
|
||||
return lspid;
|
||||
char *rv;
|
||||
|
||||
cur_buf++;
|
||||
if (cur_buf >= FORMAT_BUF_COUNT)
|
||||
cur_buf = 0;
|
||||
|
||||
rv = buf_ring[cur_buf];
|
||||
|
||||
if (!id) {
|
||||
snprintf(rv, FORMAT_ID_SIZE, "unknown");
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (len < 6) {
|
||||
snprintf(rv, FORMAT_ID_SIZE, "Short ID");
|
||||
return rv;
|
||||
}
|
||||
|
||||
snprintf(rv, FORMAT_ID_SIZE, "%02x%02x.%02x%02x.%02x%02x", id[0], id[1],
|
||||
id[2], id[3], id[4], id[5]);
|
||||
|
||||
if (len > 6)
|
||||
snprintf(rv + 14, FORMAT_ID_SIZE - 14, ".%02x", id[6]);
|
||||
if (len > 7)
|
||||
snprintf(rv + 17, FORMAT_ID_SIZE - 17, "-%02x", id[7]);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
const char *time2string(u_int32_t time)
|
||||
@ -508,7 +466,7 @@ const char *print_sys_hostname(const u_char *sysid)
|
||||
|
||||
dyn = dynhn_find_by_id(sysid);
|
||||
if (dyn)
|
||||
return (const char *)dyn->name.name;
|
||||
return dyn->hostname;
|
||||
|
||||
return sysid_print(sysid);
|
||||
}
|
||||
@ -572,3 +530,74 @@ void zlog_dump_data(void *data, int len)
|
||||
zlog_debug("[%8.8s] %-50.50s %s", addrstr, hexstr, charstr);
|
||||
return;
|
||||
}
|
||||
|
||||
static char *qasprintf(const char *format, va_list ap)
|
||||
{
|
||||
va_list aq;
|
||||
va_copy(aq, ap);
|
||||
|
||||
int size = 0;
|
||||
char *p = NULL;
|
||||
|
||||
size = vsnprintf(p, size, format, ap);
|
||||
|
||||
if (size < 0) {
|
||||
va_end(aq);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size++;
|
||||
p = XMALLOC(MTYPE_TMP, size);
|
||||
|
||||
size = vsnprintf(p, size, format, aq);
|
||||
va_end(aq);
|
||||
|
||||
if (size < 0) {
|
||||
XFREE(MTYPE_TMP, p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void log_multiline(int priority, const char *prefix, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *p;
|
||||
|
||||
va_start(ap, format);
|
||||
p = qasprintf(format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
char *saveptr = NULL;
|
||||
for (char *line = strtok_r(p, "\n", &saveptr); line;
|
||||
line = strtok_r(NULL, "\n", &saveptr)) {
|
||||
zlog(priority, "%s%s", prefix, line);
|
||||
}
|
||||
|
||||
XFREE(MTYPE_TMP, p);
|
||||
}
|
||||
|
||||
void vty_multiline(struct vty *vty, const char *prefix, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *p;
|
||||
|
||||
va_start(ap, format);
|
||||
p = qasprintf(format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
char *saveptr = NULL;
|
||||
for (char *line = strtok_r(p, "\n", &saveptr); line;
|
||||
line = strtok_r(NULL, "\n", &saveptr)) {
|
||||
vty_out(vty, "%s%s\n", prefix, line);
|
||||
}
|
||||
|
||||
XFREE(MTYPE_TMP, p);
|
||||
}
|
||||
|
@ -44,7 +44,9 @@ const char *isonet_print(const u_char *, int len);
|
||||
const char *sysid_print(const u_char *);
|
||||
const char *snpa_print(const u_char *);
|
||||
const char *rawlspid_print(const u_char *);
|
||||
const char *isis_format_id(const uint8_t *id, size_t len);
|
||||
const char *time2string(u_int32_t);
|
||||
const char *nlpid2str(uint8_t nlpid);
|
||||
/* typedef struct nlpids nlpids; */
|
||||
char *nlpid2string(struct nlpids *);
|
||||
const char *print_sys_hostname(const u_char *sysid);
|
||||
@ -53,7 +55,6 @@ void zlog_dump_data(void *data, int len);
|
||||
/*
|
||||
* misc functions
|
||||
*/
|
||||
int speaks(struct nlpids *nlpids, int family);
|
||||
unsigned long isis_jitter(unsigned long timer, unsigned long jitter);
|
||||
const char *unix_hostname(void);
|
||||
|
||||
@ -77,4 +78,10 @@ enum { ISIS_UI_LEVEL_BRIEF,
|
||||
ISIS_UI_LEVEL_EXTENSIVE,
|
||||
};
|
||||
|
||||
#include "lib/log.h"
|
||||
void log_multiline(int priority, const char *prefix, const char *format, ...)
|
||||
PRINTF_ATTRIBUTE(3, 4);
|
||||
struct vty;
|
||||
void vty_multiline(struct vty *vty, const char *prefix, const char *format, ...)
|
||||
PRINTF_ATTRIBUTE(3, 4);
|
||||
#endif
|
||||
|
212
isisd/isis_mt.c
212
isisd/isis_mt.c
@ -24,19 +24,14 @@
|
||||
#include "isisd/isis_memory.h"
|
||||
#include "isisd/isis_circuit.h"
|
||||
#include "isisd/isis_adjacency.h"
|
||||
#include "isisd/isis_tlv.h"
|
||||
#include "isisd/isis_misc.h"
|
||||
#include "isisd/isis_lsp.h"
|
||||
#include "isisd/isis_mt.h"
|
||||
#include "isisd/isis_tlvs.h"
|
||||
|
||||
DEFINE_MTYPE_STATIC(ISISD, MT_AREA_SETTING, "ISIS MT Area Setting")
|
||||
DEFINE_MTYPE_STATIC(ISISD, MT_CIRCUIT_SETTING, "ISIS MT Circuit Setting")
|
||||
DEFINE_MTYPE_STATIC(ISISD, MT_ADJ_INFO, "ISIS MT Adjacency Info")
|
||||
DEFINE_MTYPE_STATIC(ISISD, MT_NEIGHBORS, "ISIS MT Neighbors for TLV")
|
||||
DEFINE_MTYPE_STATIC(ISISD, MT_IPV4_REACHS,
|
||||
"ISIS MT IPv4 Reachabilities for TLV")
|
||||
DEFINE_MTYPE_STATIC(ISISD, MT_IPV6_REACHS,
|
||||
"ISIS MT IPv6 Reachabilities for TLV")
|
||||
|
||||
uint16_t isis_area_ipv6_topology(struct isis_area *area)
|
||||
{
|
||||
@ -367,7 +362,7 @@ static void adj_mt_set(struct isis_adjacency *adj, unsigned int index,
|
||||
adj->mt_set[index] = mtid;
|
||||
}
|
||||
|
||||
bool tlvs_to_adj_mt_set(struct tlvs *tlvs, bool v4_usable, bool v6_usable,
|
||||
bool tlvs_to_adj_mt_set(struct isis_tlvs *tlvs, bool v4_usable, bool v6_usable,
|
||||
struct isis_adjacency *adj)
|
||||
{
|
||||
struct isis_circuit_mt_setting **mt_settings;
|
||||
@ -388,17 +383,20 @@ bool tlvs_to_adj_mt_set(struct tlvs *tlvs, bool v4_usable, bool v6_usable,
|
||||
|
||||
mt_settings = circuit_mt_settings(adj->circuit, &circuit_mt_count);
|
||||
for (unsigned int i = 0; i < circuit_mt_count; i++) {
|
||||
if (!tlvs->mt_router_info) {
|
||||
if (!tlvs->mt_router_info.count
|
||||
&& !tlvs->mt_router_info_empty) {
|
||||
/* Other end does not have MT enabled */
|
||||
if (mt_settings[i]->mtid == ISIS_MT_IPV4_UNICAST
|
||||
&& v4_usable)
|
||||
adj_mt_set(adj, intersect_count++,
|
||||
ISIS_MT_IPV4_UNICAST);
|
||||
} else {
|
||||
struct listnode *node;
|
||||
struct mt_router_info *info;
|
||||
for (ALL_LIST_ELEMENTS_RO(tlvs->mt_router_info, node,
|
||||
info)) {
|
||||
struct isis_mt_router_info *info_head;
|
||||
|
||||
info_head = (struct isis_mt_router_info *)
|
||||
tlvs->mt_router_info.head;
|
||||
for (struct isis_mt_router_info *info = info_head; info;
|
||||
info = info->next) {
|
||||
if (mt_settings[i]->mtid == info->mtid) {
|
||||
bool usable;
|
||||
switch (info->mtid) {
|
||||
@ -456,153 +454,6 @@ void adj_mt_finish(struct isis_adjacency *adj)
|
||||
adj->mt_count = 0;
|
||||
}
|
||||
|
||||
/* TLV Router info api */
|
||||
struct mt_router_info *tlvs_lookup_mt_router_info(struct tlvs *tlvs,
|
||||
uint16_t mtid)
|
||||
{
|
||||
return lookup_mt_setting(tlvs->mt_router_info, mtid);
|
||||
}
|
||||
|
||||
/* TLV MT Neighbors api */
|
||||
struct tlv_mt_neighbors *tlvs_lookup_mt_neighbors(struct tlvs *tlvs,
|
||||
uint16_t mtid)
|
||||
{
|
||||
return lookup_mt_setting(tlvs->mt_is_neighs, mtid);
|
||||
}
|
||||
|
||||
static struct tlv_mt_neighbors *tlvs_new_mt_neighbors(uint16_t mtid)
|
||||
{
|
||||
struct tlv_mt_neighbors *rv;
|
||||
|
||||
rv = XCALLOC(MTYPE_MT_NEIGHBORS, sizeof(*rv));
|
||||
rv->mtid = mtid;
|
||||
rv->list = list_new();
|
||||
|
||||
return rv;
|
||||
};
|
||||
|
||||
static void tlvs_free_mt_neighbors(void *arg)
|
||||
{
|
||||
struct tlv_mt_neighbors *neighbors = arg;
|
||||
|
||||
if (neighbors && neighbors->list)
|
||||
list_delete(neighbors->list);
|
||||
XFREE(MTYPE_MT_NEIGHBORS, neighbors);
|
||||
}
|
||||
|
||||
static void tlvs_add_mt_neighbors(struct tlvs *tlvs,
|
||||
struct tlv_mt_neighbors *neighbors)
|
||||
{
|
||||
add_mt_setting(&tlvs->mt_is_neighs, neighbors);
|
||||
tlvs->mt_is_neighs->del = tlvs_free_mt_neighbors;
|
||||
}
|
||||
|
||||
struct tlv_mt_neighbors *tlvs_get_mt_neighbors(struct tlvs *tlvs, uint16_t mtid)
|
||||
{
|
||||
struct tlv_mt_neighbors *neighbors;
|
||||
|
||||
neighbors = tlvs_lookup_mt_neighbors(tlvs, mtid);
|
||||
if (!neighbors) {
|
||||
neighbors = tlvs_new_mt_neighbors(mtid);
|
||||
tlvs_add_mt_neighbors(tlvs, neighbors);
|
||||
}
|
||||
return neighbors;
|
||||
}
|
||||
|
||||
/* TLV MT IPv4 reach api */
|
||||
struct tlv_mt_ipv4_reachs *tlvs_lookup_mt_ipv4_reachs(struct tlvs *tlvs,
|
||||
uint16_t mtid)
|
||||
{
|
||||
return lookup_mt_setting(tlvs->mt_ipv4_reachs, mtid);
|
||||
}
|
||||
|
||||
static struct tlv_mt_ipv4_reachs *tlvs_new_mt_ipv4_reachs(uint16_t mtid)
|
||||
{
|
||||
struct tlv_mt_ipv4_reachs *rv;
|
||||
|
||||
rv = XCALLOC(MTYPE_MT_IPV4_REACHS, sizeof(*rv));
|
||||
rv->mtid = mtid;
|
||||
rv->list = list_new();
|
||||
|
||||
return rv;
|
||||
};
|
||||
|
||||
static void tlvs_free_mt_ipv4_reachs(void *arg)
|
||||
{
|
||||
struct tlv_mt_ipv4_reachs *reachs = arg;
|
||||
|
||||
if (reachs && reachs->list)
|
||||
list_delete(reachs->list);
|
||||
XFREE(MTYPE_MT_IPV4_REACHS, reachs);
|
||||
}
|
||||
|
||||
static void tlvs_add_mt_ipv4_reachs(struct tlvs *tlvs,
|
||||
struct tlv_mt_ipv4_reachs *reachs)
|
||||
{
|
||||
add_mt_setting(&tlvs->mt_ipv4_reachs, reachs);
|
||||
tlvs->mt_ipv4_reachs->del = tlvs_free_mt_ipv4_reachs;
|
||||
}
|
||||
|
||||
struct tlv_mt_ipv4_reachs *tlvs_get_mt_ipv4_reachs(struct tlvs *tlvs,
|
||||
uint16_t mtid)
|
||||
{
|
||||
struct tlv_mt_ipv4_reachs *reachs;
|
||||
|
||||
reachs = tlvs_lookup_mt_ipv4_reachs(tlvs, mtid);
|
||||
if (!reachs) {
|
||||
reachs = tlvs_new_mt_ipv4_reachs(mtid);
|
||||
tlvs_add_mt_ipv4_reachs(tlvs, reachs);
|
||||
}
|
||||
return reachs;
|
||||
}
|
||||
|
||||
/* TLV MT IPv6 reach api */
|
||||
struct tlv_mt_ipv6_reachs *tlvs_lookup_mt_ipv6_reachs(struct tlvs *tlvs,
|
||||
uint16_t mtid)
|
||||
{
|
||||
return lookup_mt_setting(tlvs->mt_ipv6_reachs, mtid);
|
||||
}
|
||||
|
||||
static struct tlv_mt_ipv6_reachs *tlvs_new_mt_ipv6_reachs(uint16_t mtid)
|
||||
{
|
||||
struct tlv_mt_ipv6_reachs *rv;
|
||||
|
||||
rv = XCALLOC(MTYPE_MT_IPV6_REACHS, sizeof(*rv));
|
||||
rv->mtid = mtid;
|
||||
rv->list = list_new();
|
||||
|
||||
return rv;
|
||||
};
|
||||
|
||||
static void tlvs_free_mt_ipv6_reachs(void *arg)
|
||||
{
|
||||
struct tlv_mt_ipv6_reachs *reachs = arg;
|
||||
|
||||
if (reachs && reachs->list)
|
||||
list_delete(reachs->list);
|
||||
XFREE(MTYPE_MT_IPV6_REACHS, reachs);
|
||||
}
|
||||
|
||||
static void tlvs_add_mt_ipv6_reachs(struct tlvs *tlvs,
|
||||
struct tlv_mt_ipv6_reachs *reachs)
|
||||
{
|
||||
add_mt_setting(&tlvs->mt_ipv6_reachs, reachs);
|
||||
tlvs->mt_ipv6_reachs->del = tlvs_free_mt_ipv6_reachs;
|
||||
}
|
||||
|
||||
struct tlv_mt_ipv6_reachs *tlvs_get_mt_ipv6_reachs(struct tlvs *tlvs,
|
||||
uint16_t mtid)
|
||||
{
|
||||
struct tlv_mt_ipv6_reachs *reachs;
|
||||
|
||||
reachs = tlvs_lookup_mt_ipv6_reachs(tlvs, mtid);
|
||||
if (!reachs) {
|
||||
reachs = tlvs_new_mt_ipv6_reachs(mtid);
|
||||
tlvs_add_mt_ipv6_reachs(tlvs, reachs);
|
||||
}
|
||||
return reachs;
|
||||
}
|
||||
|
||||
static void mt_set_add(uint16_t **mt_set, unsigned int *size,
|
||||
unsigned int *index, uint16_t mtid)
|
||||
{
|
||||
@ -647,51 +498,46 @@ static uint16_t *circuit_bcast_mt_set(struct isis_circuit *circuit, int level,
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void tlvs_add_mt_set(struct isis_area *area, struct tlvs *tlvs,
|
||||
static void tlvs_add_mt_set(struct isis_area *area, struct isis_tlvs *tlvs,
|
||||
unsigned int mt_count, uint16_t *mt_set,
|
||||
struct te_is_neigh *neigh)
|
||||
uint8_t *id, uint32_t metric, uint8_t *subtlvs,
|
||||
uint8_t subtlv_len)
|
||||
{
|
||||
for (unsigned int i = 0; i < mt_count; i++) {
|
||||
uint16_t mtid = mt_set[i];
|
||||
struct te_is_neigh *ne_copy;
|
||||
|
||||
ne_copy = XCALLOC(MTYPE_ISIS_TLV, sizeof(*ne_copy));
|
||||
memcpy(ne_copy, neigh, sizeof(*ne_copy));
|
||||
|
||||
if (mt_set[i] == ISIS_MT_IPV4_UNICAST) {
|
||||
listnode_add(tlvs->te_is_neighs, ne_copy);
|
||||
lsp_debug(
|
||||
"ISIS (%s): Adding %s.%02x as te-style neighbor",
|
||||
area->area_tag, sysid_print(ne_copy->neigh_id),
|
||||
LSP_PSEUDO_ID(ne_copy->neigh_id));
|
||||
area->area_tag, sysid_print(id),
|
||||
LSP_PSEUDO_ID(id));
|
||||
} else {
|
||||
struct tlv_mt_neighbors *neighbors;
|
||||
|
||||
neighbors = tlvs_get_mt_neighbors(tlvs, mtid);
|
||||
neighbors->list->del = free_tlv;
|
||||
listnode_add(neighbors->list, ne_copy);
|
||||
lsp_debug(
|
||||
"ISIS (%s): Adding %s.%02x as mt-style neighbor for %s",
|
||||
area->area_tag, sysid_print(ne_copy->neigh_id),
|
||||
LSP_PSEUDO_ID(ne_copy->neigh_id),
|
||||
isis_mtid2str(mtid));
|
||||
area->area_tag, sysid_print(id),
|
||||
LSP_PSEUDO_ID(id), isis_mtid2str(mtid));
|
||||
}
|
||||
isis_tlvs_add_extended_reach(tlvs, mtid, id, metric, subtlvs,
|
||||
subtlv_len);
|
||||
}
|
||||
}
|
||||
|
||||
void tlvs_add_mt_bcast(struct tlvs *tlvs, struct isis_circuit *circuit,
|
||||
int level, struct te_is_neigh *neigh)
|
||||
void tlvs_add_mt_bcast(struct isis_tlvs *tlvs, struct isis_circuit *circuit,
|
||||
int level, uint8_t *id, uint32_t metric,
|
||||
uint8_t *subtlvs, uint8_t subtlv_len)
|
||||
{
|
||||
unsigned int mt_count;
|
||||
uint16_t *mt_set = circuit_bcast_mt_set(circuit, level, &mt_count);
|
||||
|
||||
tlvs_add_mt_set(circuit->area, tlvs, mt_count, mt_set, neigh);
|
||||
tlvs_add_mt_set(circuit->area, tlvs, mt_count, mt_set, id, metric,
|
||||
subtlvs, subtlv_len);
|
||||
}
|
||||
|
||||
void tlvs_add_mt_p2p(struct tlvs *tlvs, struct isis_circuit *circuit,
|
||||
struct te_is_neigh *neigh)
|
||||
void tlvs_add_mt_p2p(struct isis_tlvs *tlvs, struct isis_circuit *circuit,
|
||||
uint8_t *id, uint32_t metric, uint8_t *subtlvs,
|
||||
uint8_t subtlv_len)
|
||||
{
|
||||
struct isis_adjacency *adj = circuit->u.p2p.neighbor;
|
||||
|
||||
tlvs_add_mt_set(circuit->area, tlvs, adj->mt_count, adj->mt_set, neigh);
|
||||
tlvs_add_mt_set(circuit->area, tlvs, adj->mt_count, adj->mt_set, id,
|
||||
metric, subtlvs, subtlv_len);
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#define ISIS_MT_MASK 0x0fff
|
||||
#define ISIS_MT_OL_MASK 0x8000
|
||||
#define ISIS_MT_AT_MASK 0x4000
|
||||
|
||||
#define ISIS_MT_IPV4_UNICAST 0
|
||||
#define ISIS_MT_IPV4_MGMT 1
|
||||
@ -64,21 +65,6 @@ struct isis_circuit_mt_setting {
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
struct tlv_mt_neighbors {
|
||||
ISIS_MT_INFO_FIELDS
|
||||
struct list *list;
|
||||
};
|
||||
|
||||
struct tlv_mt_ipv4_reachs {
|
||||
ISIS_MT_INFO_FIELDS
|
||||
struct list *list;
|
||||
};
|
||||
|
||||
struct tlv_mt_ipv6_reachs {
|
||||
ISIS_MT_INFO_FIELDS
|
||||
struct list *list;
|
||||
};
|
||||
|
||||
const char *isis_mtid2str(uint16_t mtid);
|
||||
uint16_t isis_str2mtid(const char *name);
|
||||
|
||||
@ -87,27 +73,10 @@ struct isis_area;
|
||||
struct isis_circuit;
|
||||
struct tlvs;
|
||||
struct te_is_neigh;
|
||||
struct isis_tlvs;
|
||||
|
||||
uint16_t isis_area_ipv6_topology(struct isis_area *area);
|
||||
|
||||
struct mt_router_info *tlvs_lookup_mt_router_info(struct tlvs *tlvs,
|
||||
uint16_t mtid);
|
||||
|
||||
struct tlv_mt_neighbors *tlvs_lookup_mt_neighbors(struct tlvs *tlvs,
|
||||
uint16_t mtid);
|
||||
struct tlv_mt_neighbors *tlvs_get_mt_neighbors(struct tlvs *tlvs,
|
||||
uint16_t mtid);
|
||||
|
||||
struct tlv_mt_ipv4_reachs *tlvs_lookup_mt_ipv4_reachs(struct tlvs *tlvs,
|
||||
uint16_t mtid);
|
||||
struct tlv_mt_ipv4_reachs *tlvs_get_mt_ipv4_reachs(struct tlvs *tlvs,
|
||||
uint16_t mtid);
|
||||
|
||||
struct tlv_mt_ipv6_reachs *tlvs_lookup_mt_ipv6_reachs(struct tlvs *tlvs,
|
||||
uint16_t mtid);
|
||||
struct tlv_mt_ipv6_reachs *tlvs_get_mt_ipv6_reachs(struct tlvs *tlvs,
|
||||
uint16_t mtid);
|
||||
|
||||
struct isis_area_mt_setting *area_lookup_mt_setting(struct isis_area *area,
|
||||
uint16_t mtid);
|
||||
struct isis_area_mt_setting *area_new_mt_setting(struct isis_area *area,
|
||||
@ -137,12 +106,14 @@ circuit_get_mt_setting(struct isis_circuit *circuit, uint16_t mtid);
|
||||
int circuit_write_mt_settings(struct isis_circuit *circuit, struct vty *vty);
|
||||
struct isis_circuit_mt_setting **
|
||||
circuit_mt_settings(struct isis_circuit *circuit, unsigned int *mt_count);
|
||||
bool tlvs_to_adj_mt_set(struct tlvs *tlvs, bool v4_usable, bool v6_usable,
|
||||
bool tlvs_to_adj_mt_set(struct isis_tlvs *tlvs, bool v4_usable, bool v6_usable,
|
||||
struct isis_adjacency *adj);
|
||||
bool adj_has_mt(struct isis_adjacency *adj, uint16_t mtid);
|
||||
void adj_mt_finish(struct isis_adjacency *adj);
|
||||
void tlvs_add_mt_bcast(struct tlvs *tlvs, struct isis_circuit *circuit,
|
||||
int level, struct te_is_neigh *neigh);
|
||||
void tlvs_add_mt_p2p(struct tlvs *tlvs, struct isis_circuit *circuit,
|
||||
struct te_is_neigh *neigh);
|
||||
void tlvs_add_mt_bcast(struct isis_tlvs *tlvs, struct isis_circuit *circuit,
|
||||
int level, uint8_t *id, uint32_t metric,
|
||||
uint8_t *subtlvs, uint8_t subtlv_len);
|
||||
void tlvs_add_mt_p2p(struct isis_tlvs *tlvs, struct isis_circuit *circuit,
|
||||
uint8_t *id, uint32_t metric, uint8_t *subtlvs,
|
||||
uint8_t subtlv_len);
|
||||
#endif
|
||||
|
2659
isisd/isis_pdu.c
2659
isisd/isis_pdu.c
File diff suppressed because it is too large
Load Diff
@ -65,36 +65,6 @@ struct esis_fixed_hdr {
|
||||
#define ISH_PDU 4
|
||||
#define RD_PDU 5
|
||||
|
||||
/*
|
||||
* IS to IS Fixed Header
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* | Intradomain Routeing Protocol Discriminator |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* | Length Indicator |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* | Version/Protocol ID extension |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* | R | R | R | PDU Type |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* | Version |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* | Reserved |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* | Maximum Area Addresses |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
*/
|
||||
|
||||
struct isis_fixed_hdr {
|
||||
u_char idrp;
|
||||
u_char length;
|
||||
u_char version1;
|
||||
u_char id_len;
|
||||
u_char pdu_type;
|
||||
u_char version2;
|
||||
u_char reserved;
|
||||
u_char max_area_addrs;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define ISIS_FIXED_HDR_LEN 8
|
||||
|
||||
/*
|
||||
@ -155,30 +125,14 @@ struct isis_p2p_hello_hdr {
|
||||
|
||||
#define L1_LINK_STATE 18
|
||||
#define L2_LINK_STATE 20
|
||||
/*
|
||||
* L1 and L2 IS to IS link state PDU header
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* + PDU Length + 2
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* + Remaining Lifetime + 2
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* | LSP ID | id_len + 2
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* + Sequence Number + 4
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* + Checksum + 2
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
* | P | ATT |LSPDBOL| ISTYPE |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
*/
|
||||
struct isis_link_state_hdr {
|
||||
u_int16_t pdu_len;
|
||||
u_int16_t rem_lifetime;
|
||||
u_char lsp_id[ISIS_SYS_ID_LEN + 2];
|
||||
u_int32_t seq_num;
|
||||
u_int16_t checksum;
|
||||
u_int8_t lsp_bits;
|
||||
} __attribute__((packed));
|
||||
struct isis_lsp_hdr {
|
||||
uint16_t pdu_len;
|
||||
uint16_t rem_lifetime;
|
||||
uint8_t lsp_id[ISIS_SYS_ID_LEN + 2];
|
||||
uint32_t seqno;
|
||||
uint16_t checksum;
|
||||
uint8_t lsp_bits;
|
||||
};
|
||||
#define ISIS_LSP_HDR_LEN 19
|
||||
|
||||
/*
|
||||
@ -259,9 +213,7 @@ int send_l2_csnp(struct thread *thread);
|
||||
int send_l1_psnp(struct thread *thread);
|
||||
int send_l2_psnp(struct thread *thread);
|
||||
int send_lsp(struct thread *thread);
|
||||
int ack_lsp(struct isis_link_state_hdr *hdr, struct isis_circuit *circuit,
|
||||
int level);
|
||||
void fill_fixed_hdr(struct isis_fixed_hdr *hdr, u_char pdu_type);
|
||||
void fill_fixed_hdr(uint8_t pdu_type, struct stream *stream);
|
||||
int send_hello(struct isis_circuit *circuit, int level);
|
||||
|
||||
#endif /* _ZEBRA_ISIS_PDU_H */
|
||||
|
@ -37,7 +37,6 @@
|
||||
#include "isisd/isis_flags.h"
|
||||
#include "isisd/isis_misc.h"
|
||||
#include "isisd/isis_circuit.h"
|
||||
#include "isisd/isis_tlv.h"
|
||||
#include "isisd/isisd.h"
|
||||
#include "isisd/isis_lsp.h"
|
||||
#include "isisd/isis_route.h"
|
||||
|
@ -42,7 +42,6 @@
|
||||
#include "isis_misc.h"
|
||||
#include "isis_adjacency.h"
|
||||
#include "isis_circuit.h"
|
||||
#include "isis_tlv.h"
|
||||
#include "isis_pdu.h"
|
||||
#include "isis_lsp.h"
|
||||
#include "isis_spf.h"
|
||||
@ -208,13 +207,12 @@ static void nexthops6_print(struct list *nhs6)
|
||||
static void adjinfo2nexthop(struct list *nexthops, struct isis_adjacency *adj)
|
||||
{
|
||||
struct isis_nexthop *nh;
|
||||
struct listnode *node;
|
||||
struct in_addr *ipv4_addr;
|
||||
|
||||
if (adj->ipv4_addrs == NULL)
|
||||
if (!adj->ipv4_address_count)
|
||||
return;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(adj->ipv4_addrs, node, ipv4_addr)) {
|
||||
for (unsigned int i = 0; i < adj->ipv4_address_count; i++) {
|
||||
struct in_addr *ipv4_addr = &adj->ipv4_addresses[i];
|
||||
if (!nexthoplookup(nexthops, ipv4_addr,
|
||||
adj->circuit->interface->ifindex)) {
|
||||
nh = isis_nexthop_create(
|
||||
@ -227,14 +225,13 @@ static void adjinfo2nexthop(struct list *nexthops, struct isis_adjacency *adj)
|
||||
|
||||
static void adjinfo2nexthop6(struct list *nexthops6, struct isis_adjacency *adj)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct in6_addr *ipv6_addr;
|
||||
struct isis_nexthop6 *nh6;
|
||||
|
||||
if (!adj->ipv6_addrs)
|
||||
if (!adj->ipv6_address_count)
|
||||
return;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(adj->ipv6_addrs, node, ipv6_addr)) {
|
||||
for (unsigned int i = 0; i < adj->ipv6_address_count; i++) {
|
||||
struct in6_addr *ipv6_addr = &adj->ipv6_addresses[i];
|
||||
if (!nexthop6lookup(nexthops6, ipv6_addr,
|
||||
adj->circuit->interface->ifindex)) {
|
||||
nh6 = isis_nexthop6_create(
|
||||
|
@ -42,7 +42,6 @@
|
||||
#include "isis_misc.h"
|
||||
#include "isis_adjacency.h"
|
||||
#include "isis_circuit.h"
|
||||
#include "isis_tlv.h"
|
||||
#include "isis_pdu.h"
|
||||
#include "isis_lsp.h"
|
||||
#include "isis_spf.h"
|
||||
|
242
isisd/isis_spf.c
242
isisd/isis_spf.c
@ -44,7 +44,6 @@
|
||||
#include "isis_misc.h"
|
||||
#include "isis_adjacency.h"
|
||||
#include "isis_circuit.h"
|
||||
#include "isis_tlv.h"
|
||||
#include "isis_pdu.h"
|
||||
#include "isis_lsp.h"
|
||||
#include "isis_dynhn.h"
|
||||
@ -52,9 +51,24 @@
|
||||
#include "isis_route.h"
|
||||
#include "isis_csm.h"
|
||||
#include "isis_mt.h"
|
||||
#include "isis_tlvs.h"
|
||||
|
||||
DEFINE_MTYPE_STATIC(ISISD, ISIS_SPF_RUN, "ISIS SPF Run Info");
|
||||
|
||||
/*
|
||||
* supports the given af ?
|
||||
*/
|
||||
static bool speaks(uint8_t *protocols, uint8_t count, int family)
|
||||
{
|
||||
for (uint8_t i = 0; i < count; i++) {
|
||||
if (family == AF_INET && protocols[i] == NLPID_IP)
|
||||
return true;
|
||||
if (family == AF_INET6 && protocols[i] == NLPID_IPV6)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct isis_spf_run {
|
||||
struct isis_area *area;
|
||||
int level;
|
||||
@ -340,7 +354,7 @@ static struct isis_lsp *isis_root_system_lsp(struct isis_area *area, int level,
|
||||
LSP_PSEUDO_ID(lspid) = 0;
|
||||
LSP_FRAGMENT(lspid) = 0;
|
||||
lsp = lsp_search(lspid, area->lspdb[level - 1]);
|
||||
if (lsp && lsp->lsp_header->rem_lifetime != 0)
|
||||
if (lsp && lsp->hdr.rem_lifetime != 0)
|
||||
return lsp;
|
||||
return NULL;
|
||||
}
|
||||
@ -546,6 +560,13 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype,
|
||||
|
||||
assert(spftree && parent);
|
||||
|
||||
struct prefix p;
|
||||
if (vtype >= VTYPE_IPREACH_INTERNAL) {
|
||||
prefix_copy(&p, id);
|
||||
apply_mask(&p);
|
||||
id = &p;
|
||||
}
|
||||
|
||||
/* RFC3787 section 5.1 */
|
||||
if (spftree->area->newmetric == 1) {
|
||||
if (dist > MAX_WIDE_PATH_METRIC)
|
||||
@ -632,30 +653,35 @@ static int isis_spf_process_lsp(struct isis_spftree *spftree,
|
||||
uint16_t depth, u_char *root_sysid,
|
||||
struct isis_vertex *parent)
|
||||
{
|
||||
bool pseudo_lsp = LSP_PSEUDO_ID(lsp->lsp_header->lsp_id);
|
||||
struct listnode *node, *fragnode = NULL;
|
||||
bool pseudo_lsp = LSP_PSEUDO_ID(lsp->hdr.lsp_id);
|
||||
struct listnode *fragnode = NULL;
|
||||
uint32_t dist;
|
||||
struct is_neigh *is_neigh;
|
||||
struct te_is_neigh *te_is_neigh;
|
||||
struct ipv4_reachability *ipreach;
|
||||
struct te_ipv4_reachability *te_ipv4_reach;
|
||||
enum vertextype vtype;
|
||||
struct prefix prefix;
|
||||
struct ipv6_reachability *ip6reach;
|
||||
static const u_char null_sysid[ISIS_SYS_ID_LEN];
|
||||
struct mt_router_info *mt_router_info = NULL;
|
||||
struct isis_mt_router_info *mt_router_info = NULL;
|
||||
|
||||
if (!lsp->tlvs)
|
||||
return ISIS_OK;
|
||||
|
||||
if (spftree->mtid != ISIS_MT_IPV4_UNICAST)
|
||||
mt_router_info = tlvs_lookup_mt_router_info(&lsp->tlv_data,
|
||||
spftree->mtid);
|
||||
mt_router_info = isis_tlvs_lookup_mt_router_info(lsp->tlvs,
|
||||
spftree->mtid);
|
||||
|
||||
if (!pseudo_lsp && (spftree->mtid == ISIS_MT_IPV4_UNICAST
|
||||
&& !speaks(lsp->tlv_data.nlpids, spftree->family))
|
||||
&& !speaks(lsp->tlvs->protocols_supported.protocols,
|
||||
lsp->tlvs->protocols_supported.count,
|
||||
spftree->family))
|
||||
&& !mt_router_info)
|
||||
return ISIS_OK;
|
||||
|
||||
/* RFC3787 section 4 SHOULD ignore overload bit in pseudo LSPs */
|
||||
bool no_overload = (pseudo_lsp
|
||||
|| (spftree->mtid == ISIS_MT_IPV4_UNICAST
|
||||
&& !ISIS_MASK_LSP_OL_BIT(lsp->hdr.lsp_bits))
|
||||
|| (mt_router_info && !mt_router_info->overload));
|
||||
|
||||
lspfragloop:
|
||||
if (lsp->lsp_header->seq_num == 0) {
|
||||
if (lsp->hdr.seqno == 0) {
|
||||
zlog_warn(
|
||||
"isis_spf_process_lsp(): lsp with 0 seq_num - ignore");
|
||||
return ISIS_WARNING;
|
||||
@ -663,142 +689,117 @@ lspfragloop:
|
||||
|
||||
#ifdef EXTREME_DEBUG
|
||||
zlog_debug("ISIS-Spf: process_lsp %s",
|
||||
print_sys_hostname(lsp->lsp_header->lsp_id));
|
||||
print_sys_hostname(lsp->hdr.lsp_id));
|
||||
#endif /* EXTREME_DEBUG */
|
||||
|
||||
/* RFC3787 section 4 SHOULD ignore overload bit in pseudo LSPs */
|
||||
if (pseudo_lsp || (spftree->mtid == ISIS_MT_IPV4_UNICAST
|
||||
&& !ISIS_MASK_LSP_OL_BIT(lsp->lsp_header->lsp_bits))
|
||||
|| (mt_router_info && !mt_router_info->overload))
|
||||
|
||||
{
|
||||
if (no_overload) {
|
||||
if (pseudo_lsp || spftree->mtid == ISIS_MT_IPV4_UNICAST) {
|
||||
for (ALL_LIST_ELEMENTS_RO(lsp->tlv_data.is_neighs, node,
|
||||
is_neigh)) {
|
||||
struct isis_oldstyle_reach *r;
|
||||
for (r = (struct isis_oldstyle_reach *)
|
||||
lsp->tlvs->oldstyle_reach.head;
|
||||
r; r = r->next) {
|
||||
/* C.2.6 a) */
|
||||
/* Two way connectivity */
|
||||
if (!memcmp(is_neigh->neigh_id, root_sysid,
|
||||
ISIS_SYS_ID_LEN))
|
||||
if (!memcmp(r->id, root_sysid, ISIS_SYS_ID_LEN))
|
||||
continue;
|
||||
if (!pseudo_lsp
|
||||
&& !memcmp(is_neigh->neigh_id, null_sysid,
|
||||
&& !memcmp(r->id, null_sysid,
|
||||
ISIS_SYS_ID_LEN))
|
||||
continue;
|
||||
dist = cost + is_neigh->metrics.metric_default;
|
||||
dist = cost + r->metric;
|
||||
process_N(spftree,
|
||||
LSP_PSEUDO_ID(is_neigh->neigh_id)
|
||||
LSP_PSEUDO_ID(r->id)
|
||||
? VTYPE_PSEUDO_IS
|
||||
: VTYPE_NONPSEUDO_IS,
|
||||
(void *)is_neigh->neigh_id, dist,
|
||||
depth + 1, parent);
|
||||
(void *)r->id, dist, depth + 1,
|
||||
parent);
|
||||
}
|
||||
}
|
||||
|
||||
struct list *te_is_neighs = NULL;
|
||||
if (pseudo_lsp || spftree->mtid == ISIS_MT_IPV4_UNICAST) {
|
||||
te_is_neighs = lsp->tlv_data.te_is_neighs;
|
||||
} else {
|
||||
struct tlv_mt_neighbors *mt_neighbors;
|
||||
mt_neighbors = tlvs_lookup_mt_neighbors(&lsp->tlv_data,
|
||||
spftree->mtid);
|
||||
if (mt_neighbors)
|
||||
te_is_neighs = mt_neighbors->list;
|
||||
}
|
||||
for (ALL_LIST_ELEMENTS_RO(te_is_neighs, node, te_is_neigh)) {
|
||||
if (!memcmp(te_is_neigh->neigh_id, root_sysid,
|
||||
ISIS_SYS_ID_LEN))
|
||||
struct isis_item_list *te_neighs = NULL;
|
||||
if (pseudo_lsp || spftree->mtid == ISIS_MT_IPV4_UNICAST)
|
||||
te_neighs = &lsp->tlvs->extended_reach;
|
||||
else
|
||||
te_neighs = isis_lookup_mt_items(&lsp->tlvs->mt_reach,
|
||||
spftree->mtid);
|
||||
|
||||
struct isis_extended_reach *er;
|
||||
for (er = te_neighs
|
||||
? (struct isis_extended_reach *)
|
||||
te_neighs->head
|
||||
: NULL;
|
||||
er; er = er->next) {
|
||||
if (!memcmp(er->id, root_sysid, ISIS_SYS_ID_LEN))
|
||||
continue;
|
||||
if (!pseudo_lsp
|
||||
&& !memcmp(te_is_neigh->neigh_id, null_sysid,
|
||||
ISIS_SYS_ID_LEN))
|
||||
&& !memcmp(er->id, null_sysid, ISIS_SYS_ID_LEN))
|
||||
continue;
|
||||
dist = cost + GET_TE_METRIC(te_is_neigh);
|
||||
dist = cost + er->metric;
|
||||
process_N(spftree,
|
||||
LSP_PSEUDO_ID(te_is_neigh->neigh_id)
|
||||
? VTYPE_PSEUDO_TE_IS
|
||||
: VTYPE_NONPSEUDO_TE_IS,
|
||||
(void *)te_is_neigh->neigh_id, dist,
|
||||
depth + 1, parent);
|
||||
LSP_PSEUDO_ID(er->id) ? VTYPE_PSEUDO_TE_IS
|
||||
: VTYPE_NONPSEUDO_TE_IS,
|
||||
(void *)er->id, dist, depth + 1, parent);
|
||||
}
|
||||
}
|
||||
|
||||
if (!pseudo_lsp && spftree->family == AF_INET
|
||||
&& spftree->mtid == ISIS_MT_IPV4_UNICAST) {
|
||||
struct list *reachs[] = {lsp->tlv_data.ipv4_int_reachs,
|
||||
lsp->tlv_data.ipv4_ext_reachs};
|
||||
struct isis_item_list *reachs[] = {
|
||||
&lsp->tlvs->oldstyle_ip_reach,
|
||||
&lsp->tlvs->oldstyle_ip_reach_ext};
|
||||
|
||||
prefix.family = AF_INET;
|
||||
for (unsigned int i = 0; i < array_size(reachs); i++) {
|
||||
vtype = (reachs[i] == lsp->tlv_data.ipv4_int_reachs)
|
||||
? VTYPE_IPREACH_INTERNAL
|
||||
: VTYPE_IPREACH_EXTERNAL;
|
||||
for (ALL_LIST_ELEMENTS_RO(reachs[i], node, ipreach)) {
|
||||
dist = cost + ipreach->metrics.metric_default;
|
||||
prefix.u.prefix4 = ipreach->prefix;
|
||||
prefix.prefixlen = ip_masklen(ipreach->mask);
|
||||
apply_mask(&prefix);
|
||||
process_N(spftree, vtype, (void *)&prefix, dist,
|
||||
depth + 1, parent);
|
||||
vtype = i ? VTYPE_IPREACH_EXTERNAL
|
||||
: VTYPE_IPREACH_INTERNAL;
|
||||
|
||||
struct isis_oldstyle_ip_reach *r;
|
||||
for (r = (struct isis_oldstyle_ip_reach *)reachs[i]
|
||||
->head;
|
||||
r; r = r->next) {
|
||||
dist = cost + r->metric;
|
||||
process_N(spftree, vtype, (void *)&r->prefix,
|
||||
dist, depth + 1, parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!pseudo_lsp && spftree->family == AF_INET) {
|
||||
struct list *ipv4reachs = NULL;
|
||||
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) {
|
||||
ipv4reachs = lsp->tlv_data.te_ipv4_reachs;
|
||||
} else {
|
||||
struct tlv_mt_ipv4_reachs *mt_reachs;
|
||||
mt_reachs = tlvs_lookup_mt_ipv4_reachs(&lsp->tlv_data,
|
||||
spftree->mtid);
|
||||
if (mt_reachs)
|
||||
ipv4reachs = mt_reachs->list;
|
||||
}
|
||||
|
||||
prefix.family = AF_INET;
|
||||
for (ALL_LIST_ELEMENTS_RO(ipv4reachs, node, te_ipv4_reach)) {
|
||||
assert((te_ipv4_reach->control & 0x3F)
|
||||
<= IPV4_MAX_BITLEN);
|
||||
|
||||
dist = cost + ntohl(te_ipv4_reach->te_metric);
|
||||
prefix.u.prefix4 =
|
||||
newprefix2inaddr(&te_ipv4_reach->prefix_start,
|
||||
te_ipv4_reach->control);
|
||||
prefix.prefixlen = (te_ipv4_reach->control & 0x3F);
|
||||
apply_mask(&prefix);
|
||||
process_N(spftree, VTYPE_IPREACH_TE, (void *)&prefix,
|
||||
struct isis_extended_ip_reach *r;
|
||||
for (r = ipv4_reachs
|
||||
? (struct isis_extended_ip_reach *)
|
||||
ipv4_reachs->head
|
||||
: NULL;
|
||||
r; r = r->next) {
|
||||
dist = cost + r->metric;
|
||||
process_N(spftree, VTYPE_IPREACH_TE, (void *)&r->prefix,
|
||||
dist, depth + 1, parent);
|
||||
}
|
||||
}
|
||||
|
||||
if (!pseudo_lsp && spftree->family == AF_INET6) {
|
||||
struct list *ipv6reachs = NULL;
|
||||
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) {
|
||||
ipv6reachs = lsp->tlv_data.ipv6_reachs;
|
||||
} else {
|
||||
struct tlv_mt_ipv6_reachs *mt_reachs;
|
||||
mt_reachs = tlvs_lookup_mt_ipv6_reachs(&lsp->tlv_data,
|
||||
spftree->mtid);
|
||||
if (mt_reachs)
|
||||
ipv6reachs = mt_reachs->list;
|
||||
}
|
||||
|
||||
prefix.family = AF_INET6;
|
||||
for (ALL_LIST_ELEMENTS_RO(ipv6reachs, node, ip6reach)) {
|
||||
assert(ip6reach->prefix_len <= IPV6_MAX_BITLEN);
|
||||
|
||||
dist = cost + ntohl(ip6reach->metric);
|
||||
vtype = (ip6reach->control_info
|
||||
& CTRL_INFO_DISTRIBUTION)
|
||||
? VTYPE_IP6REACH_EXTERNAL
|
||||
: VTYPE_IP6REACH_INTERNAL;
|
||||
prefix.prefixlen = ip6reach->prefix_len;
|
||||
memcpy(&prefix.u.prefix6.s6_addr, ip6reach->prefix,
|
||||
PSIZE(ip6reach->prefix_len));
|
||||
apply_mask(&prefix);
|
||||
process_N(spftree, vtype, (void *)&prefix, dist,
|
||||
struct isis_ipv6_reach *r;
|
||||
for (r = ipv6_reachs
|
||||
? (struct isis_ipv6_reach *)ipv6_reachs->head
|
||||
: NULL;
|
||||
r; r = r->next) {
|
||||
dist = cost + r->metric;
|
||||
vtype = r->external ? VTYPE_IP6REACH_EXTERNAL
|
||||
: VTYPE_IP6REACH_INTERNAL;
|
||||
process_N(spftree, vtype, (void *)&r->prefix, dist,
|
||||
depth + 1, parent);
|
||||
}
|
||||
}
|
||||
@ -893,7 +894,9 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree,
|
||||
if (!adj_has_mt(adj, spftree->mtid))
|
||||
continue;
|
||||
if (spftree->mtid == ISIS_MT_IPV4_UNICAST
|
||||
&& !speaks(&adj->nlpids, spftree->family))
|
||||
&& !speaks(adj->nlpids.nlpids,
|
||||
adj->nlpids.count,
|
||||
spftree->family))
|
||||
continue;
|
||||
switch (adj->sys_type) {
|
||||
case ISIS_SYSTYPE_ES:
|
||||
@ -928,8 +931,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree,
|
||||
->lspdb[spftree->level
|
||||
- 1]);
|
||||
if (lsp == NULL
|
||||
|| lsp->lsp_header->rem_lifetime
|
||||
== 0)
|
||||
|| lsp->hdr.rem_lifetime == 0)
|
||||
zlog_warn(
|
||||
"ISIS-Spf: No LSP %s found for IS adjacency "
|
||||
"L%d on %s (ID %u)",
|
||||
@ -979,7 +981,7 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree,
|
||||
lsp = lsp_search(
|
||||
lsp_id,
|
||||
spftree->area->lspdb[spftree->level - 1]);
|
||||
if (lsp == NULL || lsp->lsp_header->rem_lifetime == 0) {
|
||||
if (lsp == NULL || lsp->hdr.rem_lifetime == 0) {
|
||||
zlog_warn(
|
||||
"ISIS-Spf: No lsp (%p) found from root "
|
||||
"to L%d DR %s on %s (ID %d)",
|
||||
@ -1015,7 +1017,9 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree,
|
||||
LSP_PSEUDO_ID(lsp_id) = 0;
|
||||
LSP_FRAGMENT(lsp_id) = 0;
|
||||
if (spftree->mtid != ISIS_MT_IPV4_UNICAST
|
||||
|| speaks(&adj->nlpids, spftree->family))
|
||||
|| speaks(adj->nlpids.nlpids,
|
||||
adj->nlpids.count,
|
||||
spftree->family))
|
||||
isis_spf_add_local(
|
||||
spftree,
|
||||
spftree->area->oldmetric
|
||||
@ -1178,7 +1182,7 @@ static int isis_run_spf(struct isis_area *area, int level, int family,
|
||||
memcpy(lsp_id, vertex->N.id, ISIS_SYS_ID_LEN + 1);
|
||||
LSP_FRAGMENT(lsp_id) = 0;
|
||||
lsp = lsp_search(lsp_id, area->lspdb[level - 1]);
|
||||
if (lsp && lsp->lsp_header->rem_lifetime != 0) {
|
||||
if (lsp && lsp->hdr.rem_lifetime != 0) {
|
||||
isis_spf_process_lsp(spftree, lsp, vertex->d_N,
|
||||
vertex->depth, sysid,
|
||||
vertex);
|
||||
|
402
isisd/isis_te.c
402
isisd/isis_te.c
@ -41,6 +41,7 @@
|
||||
#include "md5.h"
|
||||
#include "sockunion.h"
|
||||
#include "network.h"
|
||||
#include "sbuf.h"
|
||||
|
||||
#include "isisd/dict.h"
|
||||
#include "isisd/isis_constants.h"
|
||||
@ -48,7 +49,6 @@
|
||||
#include "isisd/isis_flags.h"
|
||||
#include "isisd/isis_circuit.h"
|
||||
#include "isisd/isisd.h"
|
||||
#include "isisd/isis_tlv.h"
|
||||
#include "isisd/isis_lsp.h"
|
||||
#include "isisd/isis_pdu.h"
|
||||
#include "isisd/isis_dynhn.h"
|
||||
@ -100,9 +100,9 @@ struct mpls_te_circuit *mpls_te_circuit_new()
|
||||
/* Copy SUB TLVs parameters into a buffer - No space verification are performed
|
||||
*/
|
||||
/* Caller must verify before that there is enough free space in the buffer */
|
||||
u_char add_te_subtlvs(u_char *buf, struct mpls_te_circuit *mtc)
|
||||
uint8_t add_te_subtlvs(uint8_t *buf, struct mpls_te_circuit *mtc)
|
||||
{
|
||||
u_char size, *tlvs = buf;
|
||||
uint8_t size, *tlvs = buf;
|
||||
|
||||
zlog_debug("ISIS MPLS-TE: Add TE Sub TLVs to buffer");
|
||||
|
||||
@ -232,7 +232,7 @@ u_char add_te_subtlvs(u_char *buf, struct mpls_te_circuit *mtc)
|
||||
}
|
||||
|
||||
/* Compute total Sub-TLVs size */
|
||||
u_char subtlvs_len(struct mpls_te_circuit *mtc)
|
||||
uint8_t subtlvs_len(struct mpls_te_circuit *mtc)
|
||||
{
|
||||
int length = 0;
|
||||
|
||||
@ -306,7 +306,7 @@ u_char subtlvs_len(struct mpls_te_circuit *mtc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
mtc->length = (u_char)length;
|
||||
mtc->length = (uint8_t)length;
|
||||
|
||||
return mtc->length;
|
||||
}
|
||||
@ -546,13 +546,9 @@ void isis_link_params_update(struct isis_circuit *circuit,
|
||||
if ((SUBTLV_TYPE(mtc->rmt_ipaddr) == 0)
|
||||
&& (circuit->circ_type == CIRCUIT_T_P2P)) {
|
||||
struct isis_adjacency *adj = circuit->u.p2p.neighbor;
|
||||
if (adj->ipv4_addrs != NULL
|
||||
&& listcount(adj->ipv4_addrs) != 0) {
|
||||
struct in_addr *ip_addr;
|
||||
ip_addr = (struct in_addr *)listgetdata(
|
||||
(struct listnode *)listhead(
|
||||
adj->ipv4_addrs));
|
||||
set_circuitparams_rmt_ipaddr(mtc, *ip_addr);
|
||||
if (adj->ipv4_address_count) {
|
||||
set_circuitparams_rmt_ipaddr(
|
||||
mtc, adj->ipv4_addresses[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -670,163 +666,116 @@ void isis_mpls_te_update(struct interface *ifp)
|
||||
* Followings are vty session control functions.
|
||||
*------------------------------------------------------------------------*/
|
||||
|
||||
static u_char show_vty_subtlv_admin_grp(struct vty *vty,
|
||||
struct te_subtlv_admin_grp *tlv)
|
||||
static u_char print_subtlv_admin_grp(struct sbuf *buf, int indent,
|
||||
struct te_subtlv_admin_grp *tlv)
|
||||
{
|
||||
|
||||
if (vty != NULL)
|
||||
vty_out(vty, " Administrative Group: 0x%x\n",
|
||||
(u_int32_t)ntohl(tlv->value));
|
||||
else
|
||||
zlog_debug(" Administrative Group: 0x%x",
|
||||
(u_int32_t)ntohl(tlv->value));
|
||||
|
||||
sbuf_push(buf, indent, "Administrative Group: 0x%" PRIx32 "\n",
|
||||
ntohl(tlv->value));
|
||||
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
|
||||
}
|
||||
|
||||
static u_char show_vty_subtlv_llri(struct vty *vty, struct te_subtlv_llri *tlv)
|
||||
static u_char print_subtlv_llri(struct sbuf *buf, int indent,
|
||||
struct te_subtlv_llri *tlv)
|
||||
{
|
||||
if (vty != NULL) {
|
||||
vty_out(vty, " Link Local ID: %d\n",
|
||||
(u_int32_t)ntohl(tlv->local));
|
||||
vty_out(vty, " Link Remote ID: %d\n",
|
||||
(u_int32_t)ntohl(tlv->remote));
|
||||
} else {
|
||||
zlog_debug(" Link Local ID: %d",
|
||||
(u_int32_t)ntohl(tlv->local));
|
||||
zlog_debug(" Link Remote ID: %d",
|
||||
(u_int32_t)ntohl(tlv->remote));
|
||||
}
|
||||
sbuf_push(buf, indent, "Link Local ID: %" PRIu32 "\n",
|
||||
ntohl(tlv->local));
|
||||
sbuf_push(buf, indent, "Link Remote ID: %" PRIu32 "\n",
|
||||
ntohl(tlv->remote));
|
||||
|
||||
return (SUBTLV_HDR_SIZE + TE_SUBTLV_LLRI_SIZE);
|
||||
}
|
||||
|
||||
static u_char show_vty_subtlv_local_ipaddr(struct vty *vty,
|
||||
struct te_subtlv_local_ipaddr *tlv)
|
||||
static u_char print_subtlv_local_ipaddr(struct sbuf *buf, int indent,
|
||||
struct te_subtlv_local_ipaddr *tlv)
|
||||
{
|
||||
if (vty != NULL)
|
||||
vty_out(vty, " Local Interface IP Address(es): %s\n",
|
||||
inet_ntoa(tlv->value));
|
||||
else
|
||||
zlog_debug(" Local Interface IP Address(es): %s",
|
||||
inet_ntoa(tlv->value));
|
||||
sbuf_push(buf, indent, "Local Interface IP Address(es): %s\n",
|
||||
inet_ntoa(tlv->value));
|
||||
|
||||
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
|
||||
}
|
||||
|
||||
static u_char show_vty_subtlv_rmt_ipaddr(struct vty *vty,
|
||||
struct te_subtlv_rmt_ipaddr *tlv)
|
||||
static u_char print_subtlv_rmt_ipaddr(struct sbuf *buf, int indent,
|
||||
struct te_subtlv_rmt_ipaddr *tlv)
|
||||
{
|
||||
if (vty != NULL)
|
||||
vty_out(vty, " Remote Interface IP Address(es): %s\n",
|
||||
inet_ntoa(tlv->value));
|
||||
else
|
||||
zlog_debug(" Remote Interface IP Address(es): %s",
|
||||
inet_ntoa(tlv->value));
|
||||
sbuf_push(buf, indent, "Remote Interface IP Address(es): %s\n",
|
||||
inet_ntoa(tlv->value));
|
||||
|
||||
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
|
||||
}
|
||||
|
||||
static u_char show_vty_subtlv_max_bw(struct vty *vty,
|
||||
struct te_subtlv_max_bw *tlv)
|
||||
static u_char print_subtlv_max_bw(struct sbuf *buf, int indent,
|
||||
struct te_subtlv_max_bw *tlv)
|
||||
{
|
||||
float fval;
|
||||
|
||||
fval = ntohf(tlv->value);
|
||||
|
||||
if (vty != NULL)
|
||||
vty_out(vty, " Maximum Bandwidth: %g (Bytes/sec)\n", fval);
|
||||
else
|
||||
zlog_debug(" Maximum Bandwidth: %g (Bytes/sec)", fval);
|
||||
sbuf_push(buf, indent, "Maximum Bandwidth: %g (Bytes/sec)\n", fval);
|
||||
|
||||
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
|
||||
}
|
||||
|
||||
static u_char show_vty_subtlv_max_rsv_bw(struct vty *vty,
|
||||
struct te_subtlv_max_rsv_bw *tlv)
|
||||
static u_char print_subtlv_max_rsv_bw(struct sbuf *buf, int indent,
|
||||
struct te_subtlv_max_rsv_bw *tlv)
|
||||
{
|
||||
float fval;
|
||||
|
||||
fval = ntohf(tlv->value);
|
||||
|
||||
if (vty != NULL)
|
||||
vty_out(vty,
|
||||
" Maximum Reservable Bandwidth: %g (Bytes/sec)\n",
|
||||
fval);
|
||||
else
|
||||
zlog_debug(" Maximum Reservable Bandwidth: %g (Bytes/sec)",
|
||||
fval);
|
||||
sbuf_push(buf, indent, "Maximum Reservable Bandwidth: %g (Bytes/sec)\n", fval);
|
||||
|
||||
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
|
||||
}
|
||||
|
||||
static u_char show_vty_subtlv_unrsv_bw(struct vty *vty,
|
||||
struct te_subtlv_unrsv_bw *tlv)
|
||||
static u_char print_subtlv_unrsv_bw(struct sbuf *buf, int indent,
|
||||
struct te_subtlv_unrsv_bw *tlv)
|
||||
{
|
||||
float fval1, fval2;
|
||||
int i;
|
||||
|
||||
if (vty != NULL)
|
||||
vty_out(vty, " Unreserved Bandwidth:\n");
|
||||
else
|
||||
zlog_debug(" Unreserved Bandwidth:");
|
||||
sbuf_push(buf, indent, "Unreserved Bandwidth:\n");
|
||||
|
||||
for (i = 0; i < MAX_CLASS_TYPE; i += 2) {
|
||||
fval1 = ntohf(tlv->value[i]);
|
||||
fval2 = ntohf(tlv->value[i + 1]);
|
||||
if (vty != NULL)
|
||||
vty_out(vty,
|
||||
" [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
|
||||
i, fval1, i + 1, fval2);
|
||||
else
|
||||
zlog_debug(
|
||||
" [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)",
|
||||
i, fval1, i + 1, fval2);
|
||||
sbuf_push(buf, indent + 2, "[%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
|
||||
i, fval1, i + 1, fval2);
|
||||
}
|
||||
|
||||
return (SUBTLV_HDR_SIZE + TE_SUBTLV_UNRSV_SIZE);
|
||||
}
|
||||
|
||||
static u_char show_vty_subtlv_te_metric(struct vty *vty,
|
||||
struct te_subtlv_te_metric *tlv)
|
||||
static u_char print_subtlv_te_metric(struct sbuf *buf, int indent,
|
||||
struct te_subtlv_te_metric *tlv)
|
||||
{
|
||||
u_int32_t te_metric;
|
||||
|
||||
te_metric = tlv->value[2] | tlv->value[1] << 8 | tlv->value[0] << 16;
|
||||
if (vty != NULL)
|
||||
vty_out(vty, " Traffic Engineering Metric: %u\n", te_metric);
|
||||
else
|
||||
zlog_debug(" Traffic Engineering Metric: %u", te_metric);
|
||||
sbuf_push(buf, indent, "Traffic Engineering Metric: %u\n", te_metric);
|
||||
|
||||
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
|
||||
}
|
||||
|
||||
static u_char show_vty_subtlv_ras(struct vty *vty, struct te_subtlv_ras *tlv)
|
||||
static u_char print_subtlv_ras(struct sbuf *buf, int indent,
|
||||
struct te_subtlv_ras *tlv)
|
||||
{
|
||||
if (vty != NULL)
|
||||
vty_out(vty, " Inter-AS TE Remote AS number: %u\n",
|
||||
ntohl(tlv->value));
|
||||
else
|
||||
zlog_debug(" Inter-AS TE Remote AS number: %u",
|
||||
ntohl(tlv->value));
|
||||
sbuf_push(buf, indent, "Inter-AS TE Remote AS number: %" PRIu32 "\n",
|
||||
ntohl(tlv->value));
|
||||
|
||||
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
|
||||
}
|
||||
|
||||
static u_char show_vty_subtlv_rip(struct vty *vty, struct te_subtlv_rip *tlv)
|
||||
static u_char print_subtlv_rip(struct sbuf *buf, int indent,
|
||||
struct te_subtlv_rip *tlv)
|
||||
{
|
||||
if (vty != NULL)
|
||||
vty_out(vty, " Inter-AS TE Remote ASBR IP address: %s\n",
|
||||
inet_ntoa(tlv->value));
|
||||
else
|
||||
zlog_debug(" Inter-AS TE Remote ASBR IP address: %s",
|
||||
inet_ntoa(tlv->value));
|
||||
sbuf_push(buf, indent, "Inter-AS TE Remote ASBR IP address: %s\n",
|
||||
inet_ntoa(tlv->value));
|
||||
|
||||
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
|
||||
}
|
||||
|
||||
static u_char show_vty_subtlv_av_delay(struct vty *vty,
|
||||
struct te_subtlv_av_delay *tlv)
|
||||
static u_char print_subtlv_av_delay(struct sbuf *buf, int indent,
|
||||
struct te_subtlv_av_delay *tlv)
|
||||
{
|
||||
u_int32_t delay;
|
||||
u_int32_t A;
|
||||
@ -834,18 +783,14 @@ static u_char show_vty_subtlv_av_delay(struct vty *vty,
|
||||
delay = (u_int32_t)ntohl(tlv->value) & TE_EXT_MASK;
|
||||
A = (u_int32_t)ntohl(tlv->value) & TE_EXT_ANORMAL;
|
||||
|
||||
if (vty != NULL)
|
||||
vty_out(vty, " %s Average Link Delay: %d (micro-sec)\n",
|
||||
A ? "Anomalous" : "Normal", delay);
|
||||
else
|
||||
zlog_debug(" %s Average Link Delay: %d (micro-sec)",
|
||||
A ? "Anomalous" : "Normal", delay);
|
||||
sbuf_push(buf, indent, "%s Average Link Delay: %" PRIu32 " (micro-sec)\n",
|
||||
A ? "Anomalous" : "Normal", delay);
|
||||
|
||||
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
|
||||
}
|
||||
|
||||
static u_char show_vty_subtlv_mm_delay(struct vty *vty,
|
||||
struct te_subtlv_mm_delay *tlv)
|
||||
static u_char print_subtlv_mm_delay(struct sbuf *buf, int indent,
|
||||
struct te_subtlv_mm_delay *tlv)
|
||||
{
|
||||
u_int32_t low, high;
|
||||
u_int32_t A;
|
||||
@ -854,33 +799,26 @@ static u_char show_vty_subtlv_mm_delay(struct vty *vty,
|
||||
A = (u_int32_t)ntohl(tlv->low) & TE_EXT_ANORMAL;
|
||||
high = (u_int32_t)ntohl(tlv->high) & TE_EXT_MASK;
|
||||
|
||||
if (vty != NULL)
|
||||
vty_out(vty, " %s Min/Max Link Delay: %d / %d (micro-sec)\n",
|
||||
A ? "Anomalous" : "Normal", low, high);
|
||||
else
|
||||
zlog_debug(" %s Min/Max Link Delay: %d / %d (micro-sec)",
|
||||
A ? "Anomalous" : "Normal", low, high);
|
||||
sbuf_push(buf, indent, "%s Min/Max Link Delay: %" PRIu32 " / %" PRIu32 " (micro-sec)\n",
|
||||
A ? "Anomalous" : "Normal", low, high);
|
||||
|
||||
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
|
||||
}
|
||||
|
||||
static u_char show_vty_subtlv_delay_var(struct vty *vty,
|
||||
struct te_subtlv_delay_var *tlv)
|
||||
static u_char print_subtlv_delay_var(struct sbuf *buf, int indent,
|
||||
struct te_subtlv_delay_var *tlv)
|
||||
{
|
||||
u_int32_t jitter;
|
||||
|
||||
jitter = (u_int32_t)ntohl(tlv->value) & TE_EXT_MASK;
|
||||
|
||||
if (vty != NULL)
|
||||
vty_out(vty, " Delay Variation: %d (micro-sec)\n", jitter);
|
||||
else
|
||||
zlog_debug(" Delay Variation: %d (micro-sec)", jitter);
|
||||
sbuf_push(buf, indent, "Delay Variation: %" PRIu32 " (micro-sec)\n", jitter);
|
||||
|
||||
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
|
||||
}
|
||||
|
||||
static u_char show_vty_subtlv_pkt_loss(struct vty *vty,
|
||||
struct te_subtlv_pkt_loss *tlv)
|
||||
static u_char print_subtlv_pkt_loss(struct sbuf *buf, int indent,
|
||||
struct te_subtlv_pkt_loss *tlv)
|
||||
{
|
||||
u_int32_t loss;
|
||||
u_int32_t A;
|
||||
@ -890,189 +828,162 @@ static u_char show_vty_subtlv_pkt_loss(struct vty *vty,
|
||||
fval = (float)(loss * LOSS_PRECISION);
|
||||
A = (u_int32_t)ntohl(tlv->value) & TE_EXT_ANORMAL;
|
||||
|
||||
if (vty != NULL)
|
||||
vty_out(vty, " %s Link Packet Loss: %g (%%)\n",
|
||||
A ? "Anomalous" : "Normal", fval);
|
||||
else
|
||||
zlog_debug(" %s Link Packet Loss: %g (%%)",
|
||||
A ? "Anomalous" : "Normal", fval);
|
||||
sbuf_push(buf, indent, "%s Link Packet Loss: %g (%%)\n",
|
||||
A ? "Anomalous" : "Normal", fval);
|
||||
|
||||
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
|
||||
}
|
||||
|
||||
static u_char show_vty_subtlv_res_bw(struct vty *vty,
|
||||
struct te_subtlv_res_bw *tlv)
|
||||
static u_char print_subtlv_res_bw(struct sbuf *buf, int indent,
|
||||
struct te_subtlv_res_bw *tlv)
|
||||
{
|
||||
float fval;
|
||||
|
||||
fval = ntohf(tlv->value);
|
||||
|
||||
if (vty != NULL)
|
||||
vty_out(vty,
|
||||
" Unidirectional Residual Bandwidth: %g (Bytes/sec)\n",
|
||||
fval);
|
||||
else
|
||||
zlog_debug(
|
||||
" Unidirectional Residual Bandwidth: %g (Bytes/sec)",
|
||||
fval);
|
||||
sbuf_push(buf, indent, "Unidirectional Residual Bandwidth: %g (Bytes/sec)\n",
|
||||
fval);
|
||||
|
||||
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
|
||||
}
|
||||
|
||||
static u_char show_vty_subtlv_ava_bw(struct vty *vty,
|
||||
struct te_subtlv_ava_bw *tlv)
|
||||
static u_char print_subtlv_ava_bw(struct sbuf *buf, int indent,
|
||||
struct te_subtlv_ava_bw *tlv)
|
||||
{
|
||||
float fval;
|
||||
|
||||
fval = ntohf(tlv->value);
|
||||
|
||||
if (vty != NULL)
|
||||
vty_out(vty,
|
||||
" Unidirectional Available Bandwidth: %g (Bytes/sec)\n",
|
||||
fval);
|
||||
else
|
||||
zlog_debug(
|
||||
" Unidirectional Available Bandwidth: %g (Bytes/sec)",
|
||||
fval);
|
||||
sbuf_push(buf, indent, "Unidirectional Available Bandwidth: %g (Bytes/sec)\n",
|
||||
fval);
|
||||
|
||||
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
|
||||
}
|
||||
|
||||
static u_char show_vty_subtlv_use_bw(struct vty *vty,
|
||||
struct te_subtlv_use_bw *tlv)
|
||||
static u_char print_subtlv_use_bw(struct sbuf *buf, int indent,
|
||||
struct te_subtlv_use_bw *tlv)
|
||||
{
|
||||
float fval;
|
||||
|
||||
fval = ntohf(tlv->value);
|
||||
|
||||
if (vty != NULL)
|
||||
vty_out(vty,
|
||||
" Unidirectional Utilized Bandwidth: %g (Bytes/sec)\n",
|
||||
fval);
|
||||
else
|
||||
zlog_debug(
|
||||
" Unidirectional Utilized Bandwidth: %g (Bytes/sec)",
|
||||
fval);
|
||||
sbuf_push(buf, indent, "Unidirectional Utilized Bandwidth: %g (Bytes/sec)\n",
|
||||
fval);
|
||||
|
||||
return (SUBTLV_HDR_SIZE + SUBTLV_DEF_SIZE);
|
||||
}
|
||||
|
||||
static u_char show_vty_unknown_tlv(struct vty *vty, struct subtlv_header *tlvh)
|
||||
static u_char print_unknown_tlv(struct sbuf *buf, int indent,
|
||||
struct subtlv_header *tlvh)
|
||||
{
|
||||
int i, rtn = 1;
|
||||
u_char *v = (u_char *)tlvh;
|
||||
|
||||
if (vty != NULL) {
|
||||
if (tlvh->length != 0) {
|
||||
vty_out(vty,
|
||||
" Unknown TLV: [type(%#.2x), length(%#.2x)]\n",
|
||||
tlvh->type, tlvh->length);
|
||||
vty_out(vty, " Dump: [00]");
|
||||
rtn = 1; /* initialize end of line counter */
|
||||
for (i = 0; i < tlvh->length; i++) {
|
||||
vty_out(vty, " %#.2x", v[i]);
|
||||
if (rtn == 8) {
|
||||
vty_out(vty, "\n [%.2x]",
|
||||
i + 1);
|
||||
rtn = 1;
|
||||
} else
|
||||
rtn++;
|
||||
}
|
||||
vty_out(vty, "\n");
|
||||
} else
|
||||
vty_out(vty,
|
||||
" Unknown TLV: [type(%#.2x), length(%#.2x)]\n",
|
||||
tlvh->type, tlvh->length);
|
||||
if (tlvh->length != 0) {
|
||||
sbuf_push(buf, indent,
|
||||
"Unknown TLV: [type(%#.2x), length(%#.2x)]\n",
|
||||
tlvh->type, tlvh->length);
|
||||
sbuf_push(buf, indent + 2, "Dump: [00]");
|
||||
rtn = 1; /* initialize end of line counter */
|
||||
for (i = 0; i < tlvh->length; i++) {
|
||||
sbuf_push(buf, 0, " %#.2x", v[i]);
|
||||
if (rtn == 8) {
|
||||
sbuf_push(buf, 0, "\n");
|
||||
sbuf_push(buf, indent + 8,
|
||||
"[%.2x]", i + 1);
|
||||
rtn = 1;
|
||||
} else
|
||||
rtn++;
|
||||
}
|
||||
sbuf_push(buf, 0, "\n");
|
||||
} else {
|
||||
zlog_debug(" Unknown TLV: [type(%#.2x), length(%#.2x)]",
|
||||
tlvh->type, tlvh->length);
|
||||
sbuf_push(buf, indent,
|
||||
"Unknown TLV: [type(%#.2x), length(%#.2x)]\n",
|
||||
tlvh->type, tlvh->length);
|
||||
}
|
||||
|
||||
return SUBTLV_SIZE(tlvh);
|
||||
}
|
||||
|
||||
/* Main Show function */
|
||||
void mpls_te_print_detail(struct vty *vty, struct te_is_neigh *te)
|
||||
void mpls_te_print_detail(struct sbuf *buf, int indent,
|
||||
uint8_t *subtlvs, uint8_t subtlv_len)
|
||||
{
|
||||
struct subtlv_header *tlvh;
|
||||
u_int16_t sum = 0;
|
||||
struct subtlv_header *tlvh = (struct subtlv_header *)subtlvs;
|
||||
uint16_t sum = 0;
|
||||
|
||||
zlog_debug("ISIS MPLS-TE: Show database TE detail");
|
||||
|
||||
tlvh = (struct subtlv_header *)te->sub_tlvs;
|
||||
|
||||
for (; sum < te->sub_tlvs_length; tlvh = SUBTLV_HDR_NEXT(tlvh)) {
|
||||
for (; sum < subtlv_len; tlvh = SUBTLV_HDR_NEXT(tlvh)) {
|
||||
switch (tlvh->type) {
|
||||
case TE_SUBTLV_ADMIN_GRP:
|
||||
sum += show_vty_subtlv_admin_grp(
|
||||
vty, (struct te_subtlv_admin_grp *)tlvh);
|
||||
sum += print_subtlv_admin_grp(buf, indent,
|
||||
(struct te_subtlv_admin_grp *)tlvh);
|
||||
break;
|
||||
case TE_SUBTLV_LLRI:
|
||||
sum += show_vty_subtlv_llri(
|
||||
vty, (struct te_subtlv_llri *)tlvh);
|
||||
sum += print_subtlv_llri(buf, indent,
|
||||
(struct te_subtlv_llri *)tlvh);
|
||||
break;
|
||||
case TE_SUBTLV_LOCAL_IPADDR:
|
||||
sum += show_vty_subtlv_local_ipaddr(
|
||||
vty, (struct te_subtlv_local_ipaddr *)tlvh);
|
||||
sum += print_subtlv_local_ipaddr(buf, indent,
|
||||
(struct te_subtlv_local_ipaddr *)tlvh);
|
||||
break;
|
||||
case TE_SUBTLV_RMT_IPADDR:
|
||||
sum += show_vty_subtlv_rmt_ipaddr(
|
||||
vty, (struct te_subtlv_rmt_ipaddr *)tlvh);
|
||||
sum += print_subtlv_rmt_ipaddr(buf, indent,
|
||||
(struct te_subtlv_rmt_ipaddr *)tlvh);
|
||||
break;
|
||||
case TE_SUBTLV_MAX_BW:
|
||||
sum += show_vty_subtlv_max_bw(
|
||||
vty, (struct te_subtlv_max_bw *)tlvh);
|
||||
sum += print_subtlv_max_bw(buf, indent,
|
||||
(struct te_subtlv_max_bw *)tlvh);
|
||||
break;
|
||||
case TE_SUBTLV_MAX_RSV_BW:
|
||||
sum += show_vty_subtlv_max_rsv_bw(
|
||||
vty, (struct te_subtlv_max_rsv_bw *)tlvh);
|
||||
sum += print_subtlv_max_rsv_bw(buf, indent,
|
||||
(struct te_subtlv_max_rsv_bw *)tlvh);
|
||||
break;
|
||||
case TE_SUBTLV_UNRSV_BW:
|
||||
sum += show_vty_subtlv_unrsv_bw(
|
||||
vty, (struct te_subtlv_unrsv_bw *)tlvh);
|
||||
sum += print_subtlv_unrsv_bw(buf, indent,
|
||||
(struct te_subtlv_unrsv_bw *)tlvh);
|
||||
break;
|
||||
case TE_SUBTLV_TE_METRIC:
|
||||
sum += show_vty_subtlv_te_metric(
|
||||
vty, (struct te_subtlv_te_metric *)tlvh);
|
||||
sum += print_subtlv_te_metric(buf, indent,
|
||||
(struct te_subtlv_te_metric *)tlvh);
|
||||
break;
|
||||
case TE_SUBTLV_RAS:
|
||||
sum += show_vty_subtlv_ras(
|
||||
vty, (struct te_subtlv_ras *)tlvh);
|
||||
sum += print_subtlv_ras(buf, indent,
|
||||
(struct te_subtlv_ras *)tlvh);
|
||||
break;
|
||||
case TE_SUBTLV_RIP:
|
||||
sum += show_vty_subtlv_rip(
|
||||
vty, (struct te_subtlv_rip *)tlvh);
|
||||
sum += print_subtlv_rip(buf, indent,
|
||||
(struct te_subtlv_rip *)tlvh);
|
||||
break;
|
||||
case TE_SUBTLV_AV_DELAY:
|
||||
sum += show_vty_subtlv_av_delay(
|
||||
vty, (struct te_subtlv_av_delay *)tlvh);
|
||||
sum += print_subtlv_av_delay(buf, indent,
|
||||
(struct te_subtlv_av_delay *)tlvh);
|
||||
break;
|
||||
case TE_SUBTLV_MM_DELAY:
|
||||
sum += show_vty_subtlv_mm_delay(
|
||||
vty, (struct te_subtlv_mm_delay *)tlvh);
|
||||
sum += print_subtlv_mm_delay(buf, indent,
|
||||
(struct te_subtlv_mm_delay *)tlvh);
|
||||
break;
|
||||
case TE_SUBTLV_DELAY_VAR:
|
||||
sum += show_vty_subtlv_delay_var(
|
||||
vty, (struct te_subtlv_delay_var *)tlvh);
|
||||
sum += print_subtlv_delay_var(buf, indent,
|
||||
(struct te_subtlv_delay_var *)tlvh);
|
||||
break;
|
||||
case TE_SUBTLV_PKT_LOSS:
|
||||
sum += show_vty_subtlv_pkt_loss(
|
||||
vty, (struct te_subtlv_pkt_loss *)tlvh);
|
||||
sum += print_subtlv_pkt_loss(buf, indent,
|
||||
(struct te_subtlv_pkt_loss *)tlvh);
|
||||
break;
|
||||
case TE_SUBTLV_RES_BW:
|
||||
sum += show_vty_subtlv_res_bw(
|
||||
vty, (struct te_subtlv_res_bw *)tlvh);
|
||||
sum += print_subtlv_res_bw(buf, indent,
|
||||
(struct te_subtlv_res_bw *)tlvh);
|
||||
break;
|
||||
case TE_SUBTLV_AVA_BW:
|
||||
sum += show_vty_subtlv_ava_bw(
|
||||
vty, (struct te_subtlv_ava_bw *)tlvh);
|
||||
sum += print_subtlv_ava_bw(buf, indent,
|
||||
(struct te_subtlv_ava_bw *)tlvh);
|
||||
break;
|
||||
case TE_SUBTLV_USE_BW:
|
||||
sum += show_vty_subtlv_use_bw(
|
||||
vty, (struct te_subtlv_use_bw *)tlvh);
|
||||
sum += print_subtlv_use_bw(buf, indent,
|
||||
(struct te_subtlv_use_bw *)tlvh);
|
||||
break;
|
||||
default:
|
||||
sum += show_vty_unknown_tlv(vty, tlvh);
|
||||
sum += print_unknown_tlv(buf, indent, tlvh);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1256,6 +1167,9 @@ DEFUN (show_isis_mpls_te_router,
|
||||
static void show_mpls_te_sub(struct vty *vty, struct interface *ifp)
|
||||
{
|
||||
struct mpls_te_circuit *mtc;
|
||||
struct sbuf buf;
|
||||
|
||||
sbuf_init(&buf, NULL, 0);
|
||||
|
||||
if ((IS_MPLS_TE(isisMplsTE))
|
||||
&& ((mtc = lookup_mpls_params_by_ifp(ifp)) != NULL)) {
|
||||
@ -1280,38 +1194,42 @@ static void show_mpls_te_sub(struct vty *vty, struct interface *ifp)
|
||||
ifp->name);
|
||||
}
|
||||
|
||||
show_vty_subtlv_admin_grp(vty, &mtc->admin_grp);
|
||||
sbuf_reset(&buf);
|
||||
print_subtlv_admin_grp(&buf, 4, &mtc->admin_grp);
|
||||
|
||||
if (SUBTLV_TYPE(mtc->local_ipaddr) != 0)
|
||||
show_vty_subtlv_local_ipaddr(vty, &mtc->local_ipaddr);
|
||||
print_subtlv_local_ipaddr(&buf, 4, &mtc->local_ipaddr);
|
||||
if (SUBTLV_TYPE(mtc->rmt_ipaddr) != 0)
|
||||
show_vty_subtlv_rmt_ipaddr(vty, &mtc->rmt_ipaddr);
|
||||
print_subtlv_rmt_ipaddr(&buf, 4, &mtc->rmt_ipaddr);
|
||||
|
||||
show_vty_subtlv_max_bw(vty, &mtc->max_bw);
|
||||
show_vty_subtlv_max_rsv_bw(vty, &mtc->max_rsv_bw);
|
||||
show_vty_subtlv_unrsv_bw(vty, &mtc->unrsv_bw);
|
||||
show_vty_subtlv_te_metric(vty, &mtc->te_metric);
|
||||
print_subtlv_max_bw(&buf, 4, &mtc->max_bw);
|
||||
print_subtlv_max_rsv_bw(&buf, 4, &mtc->max_rsv_bw);
|
||||
print_subtlv_unrsv_bw(&buf, 4, &mtc->unrsv_bw);
|
||||
print_subtlv_te_metric(&buf, 4, &mtc->te_metric);
|
||||
|
||||
if (IS_INTER_AS(mtc->type)) {
|
||||
if (SUBTLV_TYPE(mtc->ras) != 0)
|
||||
show_vty_subtlv_ras(vty, &mtc->ras);
|
||||
print_subtlv_ras(&buf, 4, &mtc->ras);
|
||||
if (SUBTLV_TYPE(mtc->rip) != 0)
|
||||
show_vty_subtlv_rip(vty, &mtc->rip);
|
||||
print_subtlv_rip(&buf, 4, &mtc->rip);
|
||||
}
|
||||
|
||||
show_vty_subtlv_av_delay(vty, &mtc->av_delay);
|
||||
show_vty_subtlv_mm_delay(vty, &mtc->mm_delay);
|
||||
show_vty_subtlv_delay_var(vty, &mtc->delay_var);
|
||||
show_vty_subtlv_pkt_loss(vty, &mtc->pkt_loss);
|
||||
show_vty_subtlv_res_bw(vty, &mtc->res_bw);
|
||||
show_vty_subtlv_ava_bw(vty, &mtc->ava_bw);
|
||||
show_vty_subtlv_use_bw(vty, &mtc->use_bw);
|
||||
print_subtlv_av_delay(&buf, 4, &mtc->av_delay);
|
||||
print_subtlv_mm_delay(&buf, 4, &mtc->mm_delay);
|
||||
print_subtlv_delay_var(&buf, 4, &mtc->delay_var);
|
||||
print_subtlv_pkt_loss(&buf, 4, &mtc->pkt_loss);
|
||||
print_subtlv_res_bw(&buf, 4, &mtc->res_bw);
|
||||
print_subtlv_ava_bw(&buf, 4, &mtc->ava_bw);
|
||||
print_subtlv_use_bw(&buf, 4, &mtc->use_bw);
|
||||
|
||||
vty_multiline(vty, "", "%s", sbuf_buf(&buf));
|
||||
vty_out(vty, "---------------\n\n");
|
||||
} else {
|
||||
vty_out(vty, " %s: MPLS-TE is disabled on this interface\n",
|
||||
ifp->name);
|
||||
}
|
||||
|
||||
sbuf_free(&buf);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -81,6 +81,8 @@ struct subtlv_header {
|
||||
u_char length; /* Value portion only, in byte */
|
||||
};
|
||||
|
||||
#define MAX_SUBTLV_SIZE 256
|
||||
|
||||
#define SUBTLV_HDR_SIZE 2 /* (sizeof (struct sub_tlv_header)) */
|
||||
|
||||
#define SUBTLV_SIZE(stlvh) (SUBTLV_HDR_SIZE + (stlvh)->length)
|
||||
@ -306,12 +308,13 @@ struct mpls_te_circuit {
|
||||
/* Prototypes. */
|
||||
void isis_mpls_te_init(void);
|
||||
struct mpls_te_circuit *mpls_te_circuit_new(void);
|
||||
void mpls_te_print_detail(struct vty *, struct te_is_neigh *);
|
||||
struct sbuf;
|
||||
void mpls_te_print_detail(struct sbuf *buf, int indent, uint8_t *subtlvs, uint8_t subtlv_len);
|
||||
void set_circuitparams_local_ipaddr(struct mpls_te_circuit *, struct in_addr);
|
||||
void set_circuitparams_rmt_ipaddr(struct mpls_te_circuit *, struct in_addr);
|
||||
u_char subtlvs_len(struct mpls_te_circuit *);
|
||||
u_char add_te_subtlvs(u_char *, struct mpls_te_circuit *);
|
||||
u_char build_te_subtlvs(u_char *, struct isis_circuit *);
|
||||
uint8_t subtlvs_len(struct mpls_te_circuit *);
|
||||
uint8_t add_te_subtlvs(uint8_t *, struct mpls_te_circuit *);
|
||||
uint8_t build_te_subtlvs(uint8_t *, struct isis_circuit *);
|
||||
void isis_link_params_update(struct isis_circuit *, struct interface *);
|
||||
void isis_mpls_te_update(struct interface *);
|
||||
void isis_mpls_te_config_write_router(struct vty *);
|
||||
|
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 */
|
3090
isisd/isis_tlvs.c
Normal file
3090
isisd/isis_tlvs.c
Normal file
File diff suppressed because it is too large
Load Diff
308
isisd/isis_tlvs.h
Normal file
308
isisd/isis_tlvs.h
Normal file
@ -0,0 +1,308 @@
|
||||
/*
|
||||
* IS-IS TLV Serializer/Deserializer
|
||||
*
|
||||
* Copyright (C) 2015,2017 Christian Franke
|
||||
*
|
||||
* This file is part of FRR.
|
||||
*
|
||||
* FRR is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* FRR 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 FRR; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
#ifndef ISIS_TLVS_H
|
||||
#define ISIS_TLVS_H
|
||||
|
||||
#include "openbsd-tree.h"
|
||||
#include "prefix.h"
|
||||
#include "isisd/dict.h"
|
||||
|
||||
struct isis_subtlvs;
|
||||
|
||||
struct isis_area_address;
|
||||
struct isis_area_address {
|
||||
struct isis_area_address *next;
|
||||
|
||||
uint8_t addr[20];
|
||||
uint8_t len;
|
||||
};
|
||||
|
||||
struct isis_oldstyle_reach;
|
||||
struct isis_oldstyle_reach {
|
||||
struct isis_oldstyle_reach *next;
|
||||
|
||||
uint8_t id[7];
|
||||
uint8_t metric;
|
||||
};
|
||||
|
||||
struct isis_oldstyle_ip_reach;
|
||||
struct isis_oldstyle_ip_reach {
|
||||
struct isis_oldstyle_ip_reach *next;
|
||||
|
||||
uint8_t metric;
|
||||
struct prefix_ipv4 prefix;
|
||||
};
|
||||
|
||||
struct isis_lsp_entry;
|
||||
struct isis_lsp_entry {
|
||||
struct isis_lsp_entry *next;
|
||||
|
||||
uint16_t rem_lifetime;
|
||||
uint8_t id[8];
|
||||
uint16_t checksum;
|
||||
uint32_t seqno;
|
||||
|
||||
struct isis_lsp *lsp;
|
||||
};
|
||||
|
||||
struct isis_extended_reach;
|
||||
struct isis_extended_reach {
|
||||
struct isis_extended_reach *next;
|
||||
|
||||
uint8_t id[7];
|
||||
uint32_t metric;
|
||||
|
||||
uint8_t *subtlvs;
|
||||
uint8_t subtlv_len;
|
||||
};
|
||||
|
||||
struct isis_extended_ip_reach;
|
||||
struct isis_extended_ip_reach {
|
||||
struct isis_extended_ip_reach *next;
|
||||
|
||||
uint32_t metric;
|
||||
bool down;
|
||||
struct prefix_ipv4 prefix;
|
||||
};
|
||||
|
||||
struct isis_ipv6_reach;
|
||||
struct isis_ipv6_reach {
|
||||
struct isis_ipv6_reach *next;
|
||||
|
||||
uint32_t metric;
|
||||
bool down;
|
||||
bool external;
|
||||
|
||||
struct prefix_ipv6 prefix;
|
||||
|
||||
struct isis_subtlvs *subtlvs;
|
||||
};
|
||||
|
||||
struct isis_protocols_supported {
|
||||
uint8_t count;
|
||||
uint8_t *protocols;
|
||||
};
|
||||
|
||||
struct isis_item;
|
||||
struct isis_item {
|
||||
struct isis_item *next;
|
||||
};
|
||||
|
||||
struct isis_lan_neighbor;
|
||||
struct isis_lan_neighbor {
|
||||
struct isis_lan_neighbor *next;
|
||||
|
||||
uint8_t mac[6];
|
||||
};
|
||||
|
||||
struct isis_ipv4_address;
|
||||
struct isis_ipv4_address {
|
||||
struct isis_ipv4_address *next;
|
||||
|
||||
struct in_addr addr;
|
||||
};
|
||||
|
||||
struct isis_ipv6_address;
|
||||
struct isis_ipv6_address {
|
||||
struct isis_ipv6_address *next;
|
||||
|
||||
struct in6_addr addr;
|
||||
};
|
||||
|
||||
struct isis_mt_router_info;
|
||||
struct isis_mt_router_info {
|
||||
struct isis_mt_router_info *next;
|
||||
|
||||
bool overload;
|
||||
bool attached;
|
||||
uint16_t mtid;
|
||||
};
|
||||
|
||||
struct isis_auth;
|
||||
struct isis_auth {
|
||||
struct isis_auth *next;
|
||||
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint8_t value[256];
|
||||
|
||||
uint8_t plength;
|
||||
uint8_t passwd[256];
|
||||
|
||||
size_t offset; /* Only valid after packing */
|
||||
};
|
||||
|
||||
struct isis_item_list;
|
||||
struct isis_item_list {
|
||||
struct isis_item *head;
|
||||
struct isis_item **tail;
|
||||
|
||||
RB_ENTRY(isis_item_list) mt_tree;
|
||||
uint16_t mtid;
|
||||
unsigned int count;
|
||||
};
|
||||
|
||||
RB_HEAD(isis_mt_item_list, isis_item_list);
|
||||
|
||||
struct isis_item_list *isis_get_mt_items(struct isis_mt_item_list *m,
|
||||
uint16_t mtid);
|
||||
struct isis_item_list *isis_lookup_mt_items(struct isis_mt_item_list *m,
|
||||
uint16_t mtid);
|
||||
|
||||
struct isis_tlvs {
|
||||
struct isis_item_list isis_auth;
|
||||
struct isis_item_list area_addresses;
|
||||
struct isis_item_list oldstyle_reach;
|
||||
struct isis_item_list lan_neighbor;
|
||||
struct isis_item_list lsp_entries;
|
||||
struct isis_item_list extended_reach;
|
||||
struct isis_mt_item_list mt_reach;
|
||||
struct isis_item_list oldstyle_ip_reach;
|
||||
struct isis_protocols_supported protocols_supported;
|
||||
struct isis_item_list oldstyle_ip_reach_ext;
|
||||
struct isis_item_list ipv4_address;
|
||||
struct isis_item_list ipv6_address;
|
||||
struct isis_item_list mt_router_info;
|
||||
bool mt_router_info_empty;
|
||||
struct in_addr *te_router_id;
|
||||
struct isis_item_list extended_ip_reach;
|
||||
struct isis_mt_item_list mt_ip_reach;
|
||||
char *hostname;
|
||||
struct isis_item_list ipv6_reach;
|
||||
struct isis_mt_item_list mt_ipv6_reach;
|
||||
};
|
||||
|
||||
struct isis_subtlvs {
|
||||
/* draft-baker-ipv6-isis-dst-src-routing-06 */
|
||||
struct prefix_ipv6 *source_prefix;
|
||||
};
|
||||
|
||||
enum isis_tlv_context {
|
||||
ISIS_CONTEXT_LSP,
|
||||
ISIS_CONTEXT_SUBTLV_NE_REACH,
|
||||
ISIS_CONTEXT_SUBTLV_IP_REACH,
|
||||
ISIS_CONTEXT_SUBTLV_IPV6_REACH,
|
||||
ISIS_CONTEXT_MAX
|
||||
};
|
||||
|
||||
enum isis_tlv_type {
|
||||
ISIS_TLV_AREA_ADDRESSES = 1,
|
||||
ISIS_TLV_OLDSTYLE_REACH = 2,
|
||||
ISIS_TLV_LAN_NEIGHBORS = 6,
|
||||
ISIS_TLV_PADDING = 8,
|
||||
ISIS_TLV_LSP_ENTRY = 9,
|
||||
ISIS_TLV_AUTH = 10,
|
||||
ISIS_TLV_EXTENDED_REACH = 22,
|
||||
|
||||
ISIS_TLV_OLDSTYLE_IP_REACH = 128,
|
||||
ISIS_TLV_PROTOCOLS_SUPPORTED = 129,
|
||||
ISIS_TLV_OLDSTYLE_IP_REACH_EXT = 130,
|
||||
ISIS_TLV_IPV4_ADDRESS = 132,
|
||||
ISIS_TLV_TE_ROUTER_ID = 134,
|
||||
ISIS_TLV_EXTENDED_IP_REACH = 135,
|
||||
ISIS_TLV_DYNAMIC_HOSTNAME = 137,
|
||||
ISIS_TLV_MT_REACH = 222,
|
||||
ISIS_TLV_MT_ROUTER_INFO = 229,
|
||||
ISIS_TLV_IPV6_ADDRESS = 232,
|
||||
ISIS_TLV_MT_IP_REACH = 235,
|
||||
ISIS_TLV_IPV6_REACH = 236,
|
||||
ISIS_TLV_MT_IPV6_REACH = 237,
|
||||
ISIS_TLV_MAX = 256,
|
||||
|
||||
ISIS_SUBTLV_IPV6_SOURCE_PREFIX = 22
|
||||
};
|
||||
|
||||
#define IS_COMPAT_MT_TLV(tlv_type) \
|
||||
((tlv_type == ISIS_TLV_MT_REACH) || (tlv_type == ISIS_TLV_MT_IP_REACH) \
|
||||
|| (tlv_type == ISIS_TLV_MT_IPV6_REACH))
|
||||
|
||||
struct stream;
|
||||
int isis_pack_tlvs(struct isis_tlvs *tlvs, struct stream *stream,
|
||||
size_t len_pointer, bool pad, bool is_lsp);
|
||||
void isis_free_tlvs(struct isis_tlvs *tlvs);
|
||||
struct isis_tlvs *isis_alloc_tlvs(void);
|
||||
int isis_unpack_tlvs(size_t avail_len, struct stream *stream,
|
||||
struct isis_tlvs **dest, const char **error_log);
|
||||
const char *isis_format_tlvs(struct isis_tlvs *tlvs);
|
||||
struct isis_tlvs *isis_copy_tlvs(struct isis_tlvs *tlvs);
|
||||
struct list *isis_fragment_tlvs(struct isis_tlvs *tlvs, size_t size);
|
||||
|
||||
#define ISIS_EXTENDED_IP_REACH_DOWN 0x80
|
||||
#define ISIS_EXTENDED_IP_REACH_SUBTLV 0x40
|
||||
|
||||
#define ISIS_IPV6_REACH_DOWN 0x80
|
||||
#define ISIS_IPV6_REACH_EXTERNAL 0x40
|
||||
#define ISIS_IPV6_REACH_SUBTLV 0x20
|
||||
|
||||
#ifndef ISIS_MT_MASK
|
||||
#define ISIS_MT_MASK 0x0fff
|
||||
#define ISIS_MT_OL_MASK 0x8000
|
||||
#define ISIS_MT_AT_MASK 0x4000
|
||||
#endif
|
||||
|
||||
|
||||
void isis_tlvs_add_auth(struct isis_tlvs *tlvs, struct isis_passwd *passwd);
|
||||
void isis_tlvs_add_area_addresses(struct isis_tlvs *tlvs,
|
||||
struct list *addresses);
|
||||
void isis_tlvs_add_lan_neighbors(struct isis_tlvs *tlvs,
|
||||
struct list *neighbors);
|
||||
void isis_tlvs_set_protocols_supported(struct isis_tlvs *tlvs,
|
||||
struct nlpids *nlpids);
|
||||
void isis_tlvs_add_mt_router_info(struct isis_tlvs *tlvs, uint16_t mtid,
|
||||
bool overload, bool attached);
|
||||
void isis_tlvs_add_ipv4_address(struct isis_tlvs *tlvs, struct in_addr *addr);
|
||||
void isis_tlvs_add_ipv4_addresses(struct isis_tlvs *tlvs,
|
||||
struct list *addresses);
|
||||
void isis_tlvs_add_ipv6_addresses(struct isis_tlvs *tlvs,
|
||||
struct list *addresses);
|
||||
bool isis_tlvs_auth_is_valid(struct isis_tlvs *tlvs, struct isis_passwd *passwd,
|
||||
struct stream *stream, bool is_lsp);
|
||||
bool isis_tlvs_area_addresses_match(struct isis_tlvs *tlvs,
|
||||
struct list *addresses);
|
||||
struct isis_adjacency;
|
||||
void isis_tlvs_to_adj(struct isis_tlvs *tlvs, struct isis_adjacency *adj,
|
||||
bool *changed);
|
||||
bool isis_tlvs_own_snpa_found(struct isis_tlvs *tlvs, uint8_t *snpa);
|
||||
void isis_tlvs_add_lsp_entry(struct isis_tlvs *tlvs, struct isis_lsp *lsp);
|
||||
void isis_tlvs_add_csnp_entries(struct isis_tlvs *tlvs, uint8_t *start_id,
|
||||
uint8_t *stop_id, uint16_t num_lsps,
|
||||
dict_t *lspdb, struct isis_lsp **last_lsp);
|
||||
void isis_tlvs_set_dynamic_hostname(struct isis_tlvs *tlvs,
|
||||
const char *hostname);
|
||||
void isis_tlvs_set_te_router_id(struct isis_tlvs *tlvs,
|
||||
const struct in_addr *id);
|
||||
void isis_tlvs_add_oldstyle_ip_reach(struct isis_tlvs *tlvs,
|
||||
struct prefix_ipv4 *dest, uint8_t metric);
|
||||
void isis_tlvs_add_extended_ip_reach(struct isis_tlvs *tlvs,
|
||||
struct prefix_ipv4 *dest, uint32_t metric);
|
||||
void isis_tlvs_add_ipv6_reach(struct isis_tlvs *tlvs, uint16_t mtid,
|
||||
struct prefix_ipv6 *dest, uint32_t metric);
|
||||
void isis_tlvs_add_oldstyle_reach(struct isis_tlvs *tlvs, uint8_t *id,
|
||||
uint8_t metric);
|
||||
void isis_tlvs_add_extended_reach(struct isis_tlvs *tlvs, uint16_t mtid,
|
||||
uint8_t *id, uint32_t metric,
|
||||
uint8_t *subtlvs, uint8_t subtlv_len);
|
||||
|
||||
struct isis_mt_router_info *
|
||||
isis_tlvs_lookup_mt_router_info(struct isis_tlvs *tlvs, uint16_t mtid);
|
||||
#endif
|
@ -42,7 +42,6 @@
|
||||
#include "isisd/isis_flags.h"
|
||||
#include "isisd/isis_misc.h"
|
||||
#include "isisd/isis_circuit.h"
|
||||
#include "isisd/isis_tlv.h"
|
||||
#include "isisd/isisd.h"
|
||||
#include "isisd/isis_circuit.h"
|
||||
#include "isisd/isis_csm.h"
|
||||
|
@ -49,7 +49,6 @@
|
||||
#include "isisd/isis_pdu.h"
|
||||
#include "isisd/isis_misc.h"
|
||||
#include "isisd/isis_constants.h"
|
||||
#include "isisd/isis_tlv.h"
|
||||
#include "isisd/isis_lsp.h"
|
||||
#include "isisd/isis_spf.h"
|
||||
#include "isisd/isis_route.h"
|
||||
|
@ -67,7 +67,7 @@ int iso_csum_verify(u_char *buffer, int len, uint16_t csum, int offset)
|
||||
return 1;
|
||||
|
||||
checksum = fletcher_checksum(buffer, len, offset);
|
||||
if (checksum == csum)
|
||||
if (checksum == htons(csum))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
107
lib/sbuf.c
Normal file
107
lib/sbuf.c
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Simple string buffer
|
||||
*
|
||||
* Copyright (C) 2017 Christian Franke
|
||||
*
|
||||
* This file is part of FRR.
|
||||
*
|
||||
* FRR is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* FRR 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 FRR; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
#include <zebra.h>
|
||||
|
||||
#include "sbuf.h"
|
||||
#include "memory.h"
|
||||
|
||||
void sbuf_init(struct sbuf *dest, char *buf, size_t size)
|
||||
{
|
||||
dest->fixed = (size > 0);
|
||||
if (dest->fixed) {
|
||||
dest->buf = buf;
|
||||
dest->size = size;
|
||||
} else {
|
||||
dest->buf = XMALLOC(MTYPE_TMP, 4096);
|
||||
dest->size = 4096;
|
||||
}
|
||||
|
||||
dest->pos = 0;
|
||||
dest->buf[0] = '\0';
|
||||
}
|
||||
|
||||
void sbuf_reset(struct sbuf *dest)
|
||||
{
|
||||
dest->pos = 0;
|
||||
dest->buf[0] = '\0';
|
||||
}
|
||||
|
||||
const char *sbuf_buf(struct sbuf *buf)
|
||||
{
|
||||
return buf->buf;
|
||||
}
|
||||
|
||||
void sbuf_free(struct sbuf *buf)
|
||||
{
|
||||
if (!buf->fixed)
|
||||
XFREE(MTYPE_TMP, buf->buf);
|
||||
}
|
||||
|
||||
void sbuf_push(struct sbuf *buf, int indent, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
int written;
|
||||
|
||||
if (!buf->fixed) {
|
||||
char dummy;
|
||||
int written1, written2;
|
||||
size_t new_size;
|
||||
|
||||
written1 = snprintf(&dummy, 0, "%*s", indent, "");
|
||||
va_start(args, format);
|
||||
written2 = vsnprintf(&dummy, 0, format, args);
|
||||
va_end(args);
|
||||
|
||||
new_size = buf->size;
|
||||
if (written1 >= 0 && written2 >= 0) {
|
||||
while (buf->pos + written1 + written2 >= new_size)
|
||||
new_size *= 2;
|
||||
if (new_size > buf->size) {
|
||||
buf->buf =
|
||||
XREALLOC(MTYPE_TMP, buf->buf, new_size);
|
||||
buf->size = new_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
written = snprintf(buf->buf + buf->pos, buf->size - buf->pos, "%*s",
|
||||
indent, "");
|
||||
|
||||
if (written >= 0)
|
||||
buf->pos += written;
|
||||
if (buf->pos > buf->size)
|
||||
buf->pos = buf->size;
|
||||
|
||||
va_start(args, format);
|
||||
written = vsnprintf(buf->buf + buf->pos, buf->size - buf->pos, format,
|
||||
args);
|
||||
va_end(args);
|
||||
|
||||
if (written >= 0)
|
||||
buf->pos += written;
|
||||
if (buf->pos > buf->size)
|
||||
buf->pos = buf->size;
|
||||
|
||||
if (buf->pos == buf->size)
|
||||
assert(!"Buffer filled up!");
|
||||
}
|
77
lib/sbuf.h
Normal file
77
lib/sbuf.h
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Simple string buffer
|
||||
*
|
||||
* Copyright (C) 2017 Christian Franke
|
||||
*
|
||||
* This file is part of FRR.
|
||||
*
|
||||
* FRR is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* FRR 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 FRR; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
#ifndef SBUF_H
|
||||
#define SBUF_H
|
||||
|
||||
/*
|
||||
* sbuf provides a simple string buffer. One application where this comes
|
||||
* in handy is the parsing of binary data: If there is an error in the parsing
|
||||
* process due to invalid input data, printing an error message explaining what
|
||||
* went wrong is definitely useful. However, just printing the actual error,
|
||||
* without any information about the previous parsing steps, is usually not very
|
||||
* helpful.
|
||||
* Using sbuf, the parser can log the whole parsing process into a buffer using
|
||||
* a printf like API. When an error ocurrs, all the information about previous
|
||||
* parsing steps is there in the log, without any need for backtracking, and can
|
||||
* be used to give a detailed and useful error description.
|
||||
* When parsing completes successfully without any error, the log can just be
|
||||
* discarded unless debugging is turned on, to not spam the log.
|
||||
*
|
||||
* For the described usecase, the code would look something like this:
|
||||
*
|
||||
* int sbuf_example(..., char **parser_log)
|
||||
* {
|
||||
* struct sbuf logbuf;
|
||||
*
|
||||
* sbuf_init(&logbuf, NULL, 0);
|
||||
* sbuf_push(&logbuf, 0, "Starting parser\n");
|
||||
*
|
||||
* int rv = do_parse(&logbuf, ...);
|
||||
*
|
||||
* *parser_log = sbuf_buf(&logbuf);
|
||||
*
|
||||
* return 1;
|
||||
* }
|
||||
*
|
||||
* In this case, sbuf_example uses a string buffer with undefined size, which will
|
||||
* be allocated on the heap by sbuf. The caller of sbuf_example is expected to free
|
||||
* the string returned in parser_log.
|
||||
*/
|
||||
|
||||
struct sbuf {
|
||||
bool fixed;
|
||||
char *buf;
|
||||
size_t size;
|
||||
size_t pos;
|
||||
int indent;
|
||||
};
|
||||
|
||||
void sbuf_init(struct sbuf *dest, char *buf, size_t size);
|
||||
void sbuf_reset(struct sbuf *buf);
|
||||
const char *sbuf_buf(struct sbuf *buf);
|
||||
void sbuf_free(struct sbuf *buf);
|
||||
#include "lib/log.h"
|
||||
void sbuf_push(struct sbuf *buf, int indent, const char *format, ...)
|
||||
PRINTF_ATTRIBUTE(3, 4);
|
||||
|
||||
#endif
|
@ -51,6 +51,7 @@ lib_libfrr_la_SOURCES = \
|
||||
lib/ptm_lib.c \
|
||||
lib/qobj.c \
|
||||
lib/routemap.c \
|
||||
lib/sbuf.c \
|
||||
lib/sha256.c \
|
||||
lib/sigevent.c \
|
||||
lib/skiplist.c \
|
||||
@ -125,6 +126,7 @@ pkginclude_HEADERS += \
|
||||
lib/qobj.h \
|
||||
lib/route_types.h \
|
||||
lib/routemap.h \
|
||||
lib/sbuf.h \
|
||||
lib/sha256.h \
|
||||
lib/sigevent.h \
|
||||
lib/skiplist.h \
|
||||
|
2
tests/.gitignore
vendored
2
tests/.gitignore
vendored
@ -25,6 +25,8 @@ __pycache__
|
||||
/bgpd/test_ecommunity
|
||||
/bgpd/test_mp_attr
|
||||
/bgpd/test_mpath
|
||||
/isisd/test_fuzz_isis_tlv
|
||||
/isisd/test_fuzz_isis_tlv_tests.h
|
||||
/lib/cli/test_cli
|
||||
/lib/cli/test_commands
|
||||
/lib/cli/test_commands_defun.c
|
||||
|
@ -24,6 +24,13 @@ else
|
||||
TESTS_BGPD =
|
||||
endif
|
||||
|
||||
if ISISD
|
||||
TESTS_ISISD = \
|
||||
isisd/test_fuzz_isis_tlv
|
||||
else
|
||||
TESTS_ISISD =
|
||||
endif
|
||||
|
||||
if OSPF6D
|
||||
TESTS_OSPF6D = \
|
||||
ospf6d/test_lsdb \
|
||||
@ -61,6 +68,7 @@ check_PROGRAMS = \
|
||||
lib/cli/test_cli \
|
||||
lib/cli/test_commands \
|
||||
$(TESTS_BGPD) \
|
||||
$(TESTS_ISISD) \
|
||||
$(TESTS_OSPF6D) \
|
||||
# end
|
||||
|
||||
@ -75,7 +83,12 @@ lib/cli/test_commands_defun.c: ../vtysh/vtysh_cmd.c
|
||||
< ../vtysh/vtysh_cmd.c \
|
||||
> "$@"
|
||||
|
||||
BUILT_SOURCES = lib/cli/test_commands_defun.c
|
||||
isisd/test_fuzz_isis_tlv_tests.h: $(top_srcdir)/tests/isisd/test_fuzz_isis_tlv_tests.h.gz
|
||||
gzip -d < $(top_srcdir)/tests/isisd/test_fuzz_isis_tlv_tests.h.gz > "$@"
|
||||
|
||||
BUILT_SOURCES = \
|
||||
lib/cli/test_commands_defun.c \
|
||||
isisd/test_fuzz_isis_tlv_tests.h
|
||||
|
||||
noinst_HEADERS = \
|
||||
./helpers/c/prng.h \
|
||||
@ -110,11 +123,14 @@ bgpd_test_capability_SOURCES = bgpd/test_capability.c
|
||||
bgpd_test_ecommunity_SOURCES = bgpd/test_ecommunity.c
|
||||
bgpd_test_mp_attr_SOURCES = bgpd/test_mp_attr.c
|
||||
bgpd_test_mpath_SOURCES = bgpd/test_mpath.c
|
||||
isisd_test_fuzz_isis_tlv_SOURCES = isisd/test_fuzz_isis_tlv.c
|
||||
isisd_test_fuzz_isis_tlv_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)/tests/isisd
|
||||
|
||||
ospf6d_test_lsdb_SOURCES = ospf6d/test_lsdb.c lib/cli/common_cli.c
|
||||
|
||||
ALL_TESTS_LDADD = ../lib/libfrr.la @LIBCAP@
|
||||
BGP_TEST_LDADD = ../bgpd/libbgp.a $(BGP_VNC_RFP_LIB) $(ALL_TESTS_LDADD) -lm
|
||||
ISISD_TEST_LDADD = ../isisd/libisis.a $(ALL_TESTS_LDADD)
|
||||
OSPF6_TEST_LDADD = ../ospf6d/libospf6.a $(ALL_TESTS_LDADD)
|
||||
|
||||
lib_test_buffer_LDADD = $(ALL_TESTS_LDADD)
|
||||
@ -140,6 +156,7 @@ bgpd_test_capability_LDADD = $(BGP_TEST_LDADD)
|
||||
bgpd_test_ecommunity_LDADD = $(BGP_TEST_LDADD)
|
||||
bgpd_test_mp_attr_LDADD = $(BGP_TEST_LDADD)
|
||||
bgpd_test_mpath_LDADD = $(BGP_TEST_LDADD)
|
||||
isisd_test_fuzz_isis_tlv_LDADD = $(ISISD_TEST_LDADD)
|
||||
ospf6d_test_lsdb_LDADD = $(OSPF6_TEST_LDADD)
|
||||
|
||||
EXTRA_DIST = \
|
||||
@ -151,6 +168,8 @@ EXTRA_DIST = \
|
||||
bgpd/test_mpath.py \
|
||||
helpers/python/frrsix.py \
|
||||
helpers/python/frrtest.py \
|
||||
isisd/test_fuzz_isis_tlv.py \
|
||||
isisd/test_fuzz_isis_tlv_tests.h.gz \
|
||||
lib/cli/test_commands.in \
|
||||
lib/cli/test_commands.py \
|
||||
lib/cli/test_commands.refout \
|
||||
|
1
tests/isisd/.gitignore
vendored
Normal file
1
tests/isisd/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/*_afl/*
|
188
tests/isisd/test_fuzz_isis_tlv.c
Normal file
188
tests/isisd/test_fuzz_isis_tlv.c
Normal file
@ -0,0 +1,188 @@
|
||||
#include "test_fuzz_isis_tlv_tests.h"
|
||||
|
||||
#include <zebra.h>
|
||||
|
||||
#include "memory.h"
|
||||
#include "sbuf.h"
|
||||
#include "stream.h"
|
||||
#include "thread.h"
|
||||
|
||||
#include "isisd/isis_circuit.h"
|
||||
#include "isisd/isis_tlvs.h"
|
||||
|
||||
#define TEST_STREAM_SIZE 1500
|
||||
|
||||
struct thread_master *master;
|
||||
int isis_sock_init(struct isis_circuit *circuit);
|
||||
int isis_sock_init(struct isis_circuit *circuit)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool atexit_registered;
|
||||
|
||||
static void show_meminfo_at_exit(void)
|
||||
{
|
||||
log_memstats_stderr("isis fuzztest");
|
||||
}
|
||||
|
||||
static int comp_line(const void *p1, const void *p2)
|
||||
{
|
||||
return strcmp(*(char * const *)p1, *(char * const *)p2);
|
||||
}
|
||||
|
||||
static char *sortlines(char *in)
|
||||
{
|
||||
size_t line_count = 1;
|
||||
size_t rv_len = strlen(in) + 1;
|
||||
size_t rv_pos = 0;
|
||||
char *rv = XMALLOC(MTYPE_TMP, rv_len);
|
||||
|
||||
for (char *c = in; *c; c++) {
|
||||
if (*c == '\n')
|
||||
line_count++;
|
||||
}
|
||||
|
||||
if (line_count == 1) {
|
||||
strncpy(rv, in, rv_len);
|
||||
return rv;
|
||||
}
|
||||
|
||||
char **lines = XCALLOC(MTYPE_TMP, sizeof(char *)*line_count);
|
||||
char *saveptr = NULL;
|
||||
size_t i = 0;
|
||||
|
||||
for (char *line = strtok_r(in, "\n", &saveptr); line;
|
||||
line = strtok_r(NULL, "\n", &saveptr)) {
|
||||
lines[i++] = line;
|
||||
assert(i <= line_count);
|
||||
}
|
||||
|
||||
line_count = i;
|
||||
|
||||
qsort(lines, line_count, sizeof(char *), comp_line);
|
||||
|
||||
for (i = 0; i < line_count; i++) {
|
||||
int printf_rv = snprintf(rv + rv_pos, rv_len - rv_pos, "%s\n", lines[i]);
|
||||
assert(printf_rv >= 0);
|
||||
rv_pos += printf_rv;
|
||||
}
|
||||
|
||||
XFREE(MTYPE_TMP, lines);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int test(FILE *input, FILE *output)
|
||||
{
|
||||
struct stream *s = stream_new(TEST_STREAM_SIZE);
|
||||
char buf[TEST_STREAM_SIZE];
|
||||
size_t bytes_read = 0;
|
||||
|
||||
if (!atexit_registered) {
|
||||
atexit(show_meminfo_at_exit);
|
||||
atexit_registered = true;
|
||||
}
|
||||
|
||||
while (STREAM_WRITEABLE(s) && !feof(input)) {
|
||||
bytes_read = fread(buf, 1, STREAM_WRITEABLE(s), input);
|
||||
if (bytes_read == 0)
|
||||
break;
|
||||
stream_put(s, buf, bytes_read);
|
||||
}
|
||||
|
||||
if (bytes_read && !feof(input)) {
|
||||
fprintf(output, "Too much input data.\n");
|
||||
stream_free(s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
stream_set_getp(s, 0);
|
||||
struct isis_tlvs *tlvs;
|
||||
const char *log;
|
||||
int rv = isis_unpack_tlvs(STREAM_READABLE(s), s, &tlvs, &log);
|
||||
|
||||
if (rv) {
|
||||
fprintf(output, "Could not unpack TLVs:\n%s\n", log);
|
||||
isis_free_tlvs(tlvs);
|
||||
stream_free(s);
|
||||
return 2;
|
||||
}
|
||||
|
||||
fprintf(output, "Unpack log:\n%s", log);
|
||||
const char *s_tlvs = isis_format_tlvs(tlvs);
|
||||
fprintf(output, "Unpacked TLVs:\n%s", s_tlvs);
|
||||
|
||||
struct isis_tlvs *tlv_copy = isis_copy_tlvs(tlvs);
|
||||
isis_free_tlvs(tlvs);
|
||||
|
||||
struct stream *s2 = stream_new(TEST_STREAM_SIZE);
|
||||
|
||||
if (isis_pack_tlvs(tlv_copy, s2, (size_t)-1, false, false)) {
|
||||
fprintf(output, "Could not pack TLVs.\n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
stream_set_getp(s2, 0);
|
||||
rv = isis_unpack_tlvs(STREAM_READABLE(s2), s2, &tlvs, &log);
|
||||
if (rv) {
|
||||
fprintf(output, "Could not unpack own TLVs:\n%s\n", log);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
char *orig_tlvs = XSTRDUP(MTYPE_TMP, s_tlvs);
|
||||
s_tlvs = isis_format_tlvs(tlvs);
|
||||
|
||||
if (strcmp(orig_tlvs, s_tlvs)) {
|
||||
fprintf(output,
|
||||
"Deserialized and Serialized LSP seem to differ.\n");
|
||||
fprintf(output, "Re-Unpacked TLVs:\n%s", s_tlvs);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
isis_free_tlvs(tlv_copy);
|
||||
stream_free(s);
|
||||
stream_free(s2);
|
||||
|
||||
struct list *fragments = isis_fragment_tlvs(tlvs, 550);
|
||||
isis_free_tlvs(tlvs);
|
||||
if (!fragments) {
|
||||
XFREE(MTYPE_TMP, orig_tlvs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
s = stream_new(550);
|
||||
|
||||
struct sbuf fragment_format;
|
||||
sbuf_init(&fragment_format, NULL, 0);
|
||||
|
||||
struct listnode *node;
|
||||
for (ALL_LIST_ELEMENTS_RO(fragments, node, tlvs)) {
|
||||
stream_reset(s);
|
||||
int rv = isis_pack_tlvs(tlvs, s, (size_t)-1, false, false);
|
||||
if (rv) {
|
||||
fprintf(output, "Could not pack fragment, too large.\n");
|
||||
assert(0);
|
||||
}
|
||||
sbuf_push(&fragment_format, 0, "%s", isis_format_tlvs(tlvs));
|
||||
isis_free_tlvs(tlvs);
|
||||
}
|
||||
list_delete(fragments);
|
||||
stream_free(s);
|
||||
|
||||
char *fragment_content = sortlines((char *)sbuf_buf(&fragment_format));
|
||||
sbuf_free(&fragment_format);
|
||||
char *orig_tlv_content = sortlines(orig_tlvs);
|
||||
XFREE(MTYPE_TMP, orig_tlvs);
|
||||
|
||||
if (strcmp(fragment_content, orig_tlv_content)) {
|
||||
fprintf(output, "Fragmented and unfragmented LSP seem to differ.\n");
|
||||
fprintf(output, "Original:\n%s\nFragmented:\n%s\n",
|
||||
orig_tlv_content, fragment_content);
|
||||
assert(0);
|
||||
}
|
||||
|
||||
XFREE(MTYPE_TMP, fragment_content);
|
||||
XFREE(MTYPE_TMP, orig_tlv_content);
|
||||
|
||||
return 0;
|
||||
}
|
6
tests/isisd/test_fuzz_isis_tlv.py
Normal file
6
tests/isisd/test_fuzz_isis_tlv.py
Normal file
@ -0,0 +1,6 @@
|
||||
import frrtest
|
||||
|
||||
class TestFuzzIsisTLV(frrtest.TestMultiOut):
|
||||
program = './test_fuzz_isis_tlv'
|
||||
|
||||
TestFuzzIsisTLV.exit_cleanly()
|
BIN
tests/isisd/test_fuzz_isis_tlv_tests.h.gz
Normal file
BIN
tests/isisd/test_fuzz_isis_tlv_tests.h.gz
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user