mirror of
https://git.proxmox.com/git/mirror_frr
synced 2026-02-01 18:56:52 +00:00
Indentation only. No any functional changes.
This commit is contained in:
parent
f3f27f60fd
commit
f390d2c783
1990
isisd/dict.c
1990
isisd/dict.c
File diff suppressed because it is too large
Load Diff
126
isisd/dict.h
126
isisd/dict.h
@ -14,7 +14,7 @@
|
||||
* into proprietary software; there is no requirement for such software to
|
||||
* contain a copyright notice related to this source.
|
||||
*
|
||||
* $Id: dict.h,v 1.1 2003/12/23 08:09:48 jardin Exp $
|
||||
* $Id: dict.h,v 1.2 2004/09/10 20:48:21 hasso Exp $
|
||||
* $Name: $
|
||||
*/
|
||||
|
||||
@ -31,37 +31,41 @@
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef unsigned long dictcount_t;
|
||||
typedef unsigned long dictcount_t;
|
||||
#define DICTCOUNT_T_MAX ULONG_MAX
|
||||
|
||||
/*
|
||||
* The dictionary is implemented as a red-black tree
|
||||
*/
|
||||
|
||||
typedef enum { dnode_red, dnode_black } dnode_color_t;
|
||||
typedef enum
|
||||
{ dnode_red, dnode_black } dnode_color_t;
|
||||
|
||||
typedef struct dnode_t {
|
||||
#if defined(DICT_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG)
|
||||
typedef struct dnode_t
|
||||
{
|
||||
#if defined(DICT_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG)
|
||||
struct dnode_t *dict_left;
|
||||
struct dnode_t *dict_right;
|
||||
struct dnode_t *dict_parent;
|
||||
dnode_color_t dict_color;
|
||||
const void *dict_key;
|
||||
void *dict_data;
|
||||
#else
|
||||
#else
|
||||
int dict_dummy;
|
||||
#endif
|
||||
} dnode_t;
|
||||
#endif
|
||||
} dnode_t;
|
||||
|
||||
typedef int (*dict_comp_t)(const void *, const void *);
|
||||
typedef dnode_t *(*dnode_alloc_t)(void *);
|
||||
typedef void (*dnode_free_t)(dnode_t *, void *);
|
||||
typedef int (*dict_comp_t) (const void *, const void *);
|
||||
typedef dnode_t *(*dnode_alloc_t) (void *);
|
||||
typedef void (*dnode_free_t) (dnode_t *, void *);
|
||||
|
||||
typedef struct dict_t {
|
||||
#if defined(DICT_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG)
|
||||
typedef struct dict_t
|
||||
{
|
||||
#if defined(DICT_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG)
|
||||
dnode_t dict_nilnode;
|
||||
dictcount_t dict_nodecount;
|
||||
dictcount_t dict_maxcount;
|
||||
@ -70,59 +74,61 @@ typedef struct dict_t {
|
||||
dnode_free_t dict_freenode;
|
||||
void *dict_context;
|
||||
int dict_dupes;
|
||||
#else
|
||||
#else
|
||||
int dict_dummmy;
|
||||
#endif
|
||||
} dict_t;
|
||||
#endif
|
||||
} dict_t;
|
||||
|
||||
typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *);
|
||||
typedef void (*dnode_process_t) (dict_t *, dnode_t *, void *);
|
||||
|
||||
typedef struct dict_load_t {
|
||||
#if defined(DICT_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG)
|
||||
typedef struct dict_load_t
|
||||
{
|
||||
#if defined(DICT_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG)
|
||||
dict_t *dict_dictptr;
|
||||
dnode_t dict_nilnode;
|
||||
#else
|
||||
#else
|
||||
int dict_dummmy;
|
||||
#endif
|
||||
} dict_load_t;
|
||||
#endif
|
||||
} dict_load_t;
|
||||
|
||||
extern dict_t *dict_create(dictcount_t, dict_comp_t);
|
||||
extern void dict_set_allocator(dict_t *, dnode_alloc_t, dnode_free_t, void *);
|
||||
extern void dict_destroy(dict_t *);
|
||||
extern void dict_free_nodes(dict_t *);
|
||||
extern void dict_free(dict_t *);
|
||||
extern dict_t *dict_init(dict_t *, dictcount_t, dict_comp_t);
|
||||
extern void dict_init_like(dict_t *, const dict_t *);
|
||||
extern int dict_verify(dict_t *);
|
||||
extern int dict_similar(const dict_t *, const dict_t *);
|
||||
extern dnode_t *dict_lookup(dict_t *, const void *);
|
||||
extern dnode_t *dict_lower_bound(dict_t *, const void *);
|
||||
extern dnode_t *dict_upper_bound(dict_t *, const void *);
|
||||
extern void dict_insert(dict_t *, dnode_t *, const void *);
|
||||
extern dnode_t *dict_delete(dict_t *, dnode_t *);
|
||||
extern int dict_alloc_insert(dict_t *, const void *, void *);
|
||||
extern void dict_delete_free(dict_t *, dnode_t *);
|
||||
extern dnode_t *dict_first(dict_t *);
|
||||
extern dnode_t *dict_last(dict_t *);
|
||||
extern dnode_t *dict_next(dict_t *, dnode_t *);
|
||||
extern dnode_t *dict_prev(dict_t *, dnode_t *);
|
||||
extern dictcount_t dict_count(dict_t *);
|
||||
extern int dict_isempty(dict_t *);
|
||||
extern int dict_isfull(dict_t *);
|
||||
extern int dict_contains(dict_t *, dnode_t *);
|
||||
extern void dict_allow_dupes(dict_t *);
|
||||
extern int dnode_is_in_a_dict(dnode_t *);
|
||||
extern dnode_t *dnode_create(void *);
|
||||
extern dnode_t *dnode_init(dnode_t *, void *);
|
||||
extern void dnode_destroy(dnode_t *);
|
||||
extern void *dnode_get(dnode_t *);
|
||||
extern const void *dnode_getkey(dnode_t *);
|
||||
extern void dnode_put(dnode_t *, void *);
|
||||
extern void dict_process(dict_t *, void *, dnode_process_t);
|
||||
extern void dict_load_begin(dict_load_t *, dict_t *);
|
||||
extern void dict_load_next(dict_load_t *, dnode_t *, const void *);
|
||||
extern void dict_load_end(dict_load_t *);
|
||||
extern void dict_merge(dict_t *, dict_t *);
|
||||
extern dict_t *dict_create (dictcount_t, dict_comp_t);
|
||||
extern void dict_set_allocator (dict_t *, dnode_alloc_t, dnode_free_t,
|
||||
void *);
|
||||
extern void dict_destroy (dict_t *);
|
||||
extern void dict_free_nodes (dict_t *);
|
||||
extern void dict_free (dict_t *);
|
||||
extern dict_t *dict_init (dict_t *, dictcount_t, dict_comp_t);
|
||||
extern void dict_init_like (dict_t *, const dict_t *);
|
||||
extern int dict_verify (dict_t *);
|
||||
extern int dict_similar (const dict_t *, const dict_t *);
|
||||
extern dnode_t *dict_lookup (dict_t *, const void *);
|
||||
extern dnode_t *dict_lower_bound (dict_t *, const void *);
|
||||
extern dnode_t *dict_upper_bound (dict_t *, const void *);
|
||||
extern void dict_insert (dict_t *, dnode_t *, const void *);
|
||||
extern dnode_t *dict_delete (dict_t *, dnode_t *);
|
||||
extern int dict_alloc_insert (dict_t *, const void *, void *);
|
||||
extern void dict_delete_free (dict_t *, dnode_t *);
|
||||
extern dnode_t *dict_first (dict_t *);
|
||||
extern dnode_t *dict_last (dict_t *);
|
||||
extern dnode_t *dict_next (dict_t *, dnode_t *);
|
||||
extern dnode_t *dict_prev (dict_t *, dnode_t *);
|
||||
extern dictcount_t dict_count (dict_t *);
|
||||
extern int dict_isempty (dict_t *);
|
||||
extern int dict_isfull (dict_t *);
|
||||
extern int dict_contains (dict_t *, dnode_t *);
|
||||
extern void dict_allow_dupes (dict_t *);
|
||||
extern int dnode_is_in_a_dict (dnode_t *);
|
||||
extern dnode_t *dnode_create (void *);
|
||||
extern dnode_t *dnode_init (dnode_t *, void *);
|
||||
extern void dnode_destroy (dnode_t *);
|
||||
extern void *dnode_get (dnode_t *);
|
||||
extern const void *dnode_getkey (dnode_t *);
|
||||
extern void dnode_put (dnode_t *, void *);
|
||||
extern void dict_process (dict_t *, void *, dnode_process_t);
|
||||
extern void dict_load_begin (dict_load_t *, dict_t *);
|
||||
extern void dict_load_next (dict_load_t *, dnode_t *, const void *);
|
||||
extern void dict_load_end (dict_load_t *);
|
||||
extern void dict_merge (dict_t *, dict_t *);
|
||||
|
||||
#if defined(DICT_IMPLEMENTATION) || !defined(KAZLIB_OPAQUE_DEBUG)
|
||||
#ifdef KAZLIB_SIDEEFFECT_DEBUG
|
||||
|
||||
@ -47,172 +47,180 @@
|
||||
#include "isisd/isis_dynhn.h"
|
||||
#include "isisd/isis_pdu.h"
|
||||
|
||||
|
||||
extern struct isis *isis;
|
||||
|
||||
|
||||
struct isis_adjacency *
|
||||
adj_alloc (u_char *id)
|
||||
adj_alloc (u_char * id)
|
||||
{
|
||||
struct isis_adjacency *adj;
|
||||
struct isis_adjacency *adj;
|
||||
|
||||
adj = XMALLOC (MTYPE_ISIS_ADJACENCY, sizeof (struct isis_adjacency));
|
||||
memset (adj, 0, sizeof (struct isis_adjacency));
|
||||
memcpy (adj->sysid, id, ISIS_SYS_ID_LEN);
|
||||
|
||||
return adj;
|
||||
adj = XMALLOC (MTYPE_ISIS_ADJACENCY, sizeof (struct isis_adjacency));
|
||||
memset (adj, 0, sizeof (struct isis_adjacency));
|
||||
memcpy (adj->sysid, id, ISIS_SYS_ID_LEN);
|
||||
|
||||
return adj;
|
||||
}
|
||||
|
||||
struct isis_adjacency *
|
||||
isis_new_adj (u_char *id, u_char *snpa, int level,
|
||||
isis_new_adj (u_char * id, u_char * snpa, int level,
|
||||
struct isis_circuit *circuit)
|
||||
{
|
||||
|
||||
struct isis_adjacency *adj;
|
||||
int i;
|
||||
int i;
|
||||
|
||||
adj = adj_alloc (id); /* P2P kludge */
|
||||
|
||||
if (adj == NULL){
|
||||
zlog_err ("Out of memory!");
|
||||
return NULL;
|
||||
}
|
||||
adj = adj_alloc (id); /* P2P kludge */
|
||||
|
||||
if (adj == NULL)
|
||||
{
|
||||
zlog_err ("Out of memory!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy (adj->snpa, snpa, 6);
|
||||
adj->circuit = circuit;
|
||||
adj->level = level;
|
||||
adj->flaps = 0;
|
||||
adj->last_flap = time (NULL);
|
||||
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
|
||||
listnode_add (circuit->u.bc.adjdb[level-1], adj);
|
||||
adj->dischanges[level - 1] = 0;
|
||||
for (i = 0; i < DIS_RECORDS; i++) /* clear N DIS state change records */
|
||||
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
|
||||
{
|
||||
listnode_add (circuit->u.bc.adjdb[level - 1], adj);
|
||||
adj->dischanges[level - 1] = 0;
|
||||
for (i = 0; i < DIS_RECORDS; i++) /* clear N DIS state change records */
|
||||
{
|
||||
adj->dis_record[(i * ISIS_LEVELS) + level - 1].dis
|
||||
adj->dis_record[(i * ISIS_LEVELS) + level - 1].dis
|
||||
= ISIS_UNKNOWN_DIS;
|
||||
adj->dis_record[(i * ISIS_LEVELS) + level - 1].last_dis_change
|
||||
= time (NULL);
|
||||
adj->dis_record[(i * ISIS_LEVELS) + level - 1].last_dis_change
|
||||
= time (NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return adj;
|
||||
}
|
||||
|
||||
struct isis_adjacency *
|
||||
isis_adj_lookup (u_char *sysid, struct list *adjdb)
|
||||
isis_adj_lookup (u_char * sysid, struct list *adjdb)
|
||||
{
|
||||
struct isis_adjacency *adj;
|
||||
struct listnode *node;
|
||||
|
||||
for (node = listhead (adjdb); node; nextnode (node)) {
|
||||
adj = getdata (node);
|
||||
if (memcmp (adj->sysid, sysid, ISIS_SYS_ID_LEN) == 0)
|
||||
return adj;
|
||||
}
|
||||
|
||||
for (node = listhead (adjdb); node; nextnode (node))
|
||||
{
|
||||
adj = getdata (node);
|
||||
if (memcmp (adj->sysid, sysid, ISIS_SYS_ID_LEN) == 0)
|
||||
return adj;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
struct isis_adjacency *
|
||||
isis_adj_lookup_snpa (u_char *ssnpa, struct list *adjdb)
|
||||
isis_adj_lookup_snpa (u_char * ssnpa, struct list *adjdb)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct isis_adjacency *adj;
|
||||
|
||||
for (node = listhead (adjdb); node; nextnode (node)) {
|
||||
adj = getdata (node);
|
||||
if (memcmp (adj->snpa, ssnpa, ETH_ALEN) == 0)
|
||||
return adj;
|
||||
}
|
||||
|
||||
for (node = listhead (adjdb); node; nextnode (node))
|
||||
{
|
||||
adj = getdata (node);
|
||||
if (memcmp (adj->snpa, ssnpa, ETH_ALEN) == 0)
|
||||
return adj;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* When we recieve a NULL list, we will know its p2p
|
||||
*/
|
||||
void
|
||||
void
|
||||
isis_delete_adj (struct isis_adjacency *adj, struct list *adjdb)
|
||||
{
|
||||
struct isis_adjacency *adj2;
|
||||
struct listnode *node;
|
||||
|
||||
if (adjdb) {
|
||||
for (node = listhead (adjdb); node; nextnode (node)) {
|
||||
adj2 = getdata (node);
|
||||
if (adj2 == adj)
|
||||
break;
|
||||
|
||||
if (adjdb)
|
||||
{
|
||||
for (node = listhead (adjdb); node; nextnode (node))
|
||||
{
|
||||
adj2 = getdata (node);
|
||||
if (adj2 == adj)
|
||||
break;
|
||||
}
|
||||
listnode_delete (adjdb, adj);
|
||||
}
|
||||
listnode_delete (adjdb, adj);
|
||||
}
|
||||
|
||||
|
||||
if (adj->ipv4_addrs)
|
||||
list_delete (adj->ipv4_addrs);
|
||||
#ifdef HAVE_IPV6
|
||||
if (adj->ipv6_addrs)
|
||||
list_delete (adj->ipv6_addrs);
|
||||
#endif
|
||||
if (adj) {
|
||||
XFREE (MTYPE_ISIS_ADJACENCY,adj);
|
||||
} else {
|
||||
zlog_info ("tried to delete a non-existent adjacency");
|
||||
}
|
||||
|
||||
|
||||
if (adj)
|
||||
{
|
||||
XFREE (MTYPE_ISIS_ADJACENCY, adj);
|
||||
}
|
||||
else
|
||||
{
|
||||
zlog_info ("tried to delete a non-existent adjacency");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
isis_adj_state_change (struct isis_adjacency *adj, enum isis_adj_state state,
|
||||
char *reason)
|
||||
|
||||
void
|
||||
isis_adj_state_change (struct isis_adjacency *adj, enum isis_adj_state state,
|
||||
char *reason)
|
||||
{
|
||||
int old_state;
|
||||
int level = adj->level;
|
||||
struct isis_circuit *circuit;
|
||||
|
||||
|
||||
old_state = adj->adj_state;
|
||||
adj->adj_state = state;
|
||||
|
||||
circuit = adj->circuit;
|
||||
|
||||
if (isis->debugs & DEBUG_ADJ_PACKETS) {
|
||||
zlog_info ("ISIS-Adj (%s): Adjacency state change %d->%d: %s",
|
||||
circuit->area->area_tag,
|
||||
old_state,
|
||||
state,
|
||||
reason ? reason : "unspecified");
|
||||
}
|
||||
|
||||
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
|
||||
if (state == ISIS_ADJ_UP)
|
||||
circuit->upadjcount[level-1]++;
|
||||
if (state == ISIS_ADJ_DOWN) {
|
||||
isis_delete_adj (adj, adj->circuit->u.bc.adjdb[level - 1]);
|
||||
circuit->upadjcount[level-1]--;
|
||||
if (isis->debugs & DEBUG_ADJ_PACKETS)
|
||||
{
|
||||
zlog_info ("ISIS-Adj (%s): Adjacency state change %d->%d: %s",
|
||||
circuit->area->area_tag,
|
||||
old_state, state, reason ? reason : "unspecified");
|
||||
}
|
||||
|
||||
list_delete_all_node (circuit->u.bc.lan_neighs[level - 1]);
|
||||
isis_adj_build_neigh_list (circuit->u.bc.adjdb[level - 1],
|
||||
circuit->u.bc.lan_neighs[level - 1]);
|
||||
} else if (state == ISIS_ADJ_UP) { /* p2p interface */
|
||||
if (adj->sys_type == ISIS_SYSTYPE_UNKNOWN)
|
||||
send_hello (circuit, 1);
|
||||
|
||||
/* update counter & timers for debugging purposes */
|
||||
adj->last_flap = time(NULL);
|
||||
adj->flaps++;
|
||||
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
|
||||
{
|
||||
if (state == ISIS_ADJ_UP)
|
||||
circuit->upadjcount[level - 1]++;
|
||||
if (state == ISIS_ADJ_DOWN)
|
||||
{
|
||||
isis_delete_adj (adj, adj->circuit->u.bc.adjdb[level - 1]);
|
||||
circuit->upadjcount[level - 1]--;
|
||||
}
|
||||
|
||||
/* 7.3.17 - going up on P2P -> send CSNP */
|
||||
/* FIXME: yup, I know its wrong... but i will do it! (for now) */
|
||||
send_csnp (circuit,1);
|
||||
send_csnp (circuit,2);
|
||||
} else if (state == ISIS_ADJ_DOWN) { /* p2p interface */
|
||||
adj->circuit->u.p2p.neighbor = NULL;
|
||||
isis_delete_adj (adj, NULL);
|
||||
}
|
||||
list_delete_all_node (circuit->u.bc.lan_neighs[level - 1]);
|
||||
isis_adj_build_neigh_list (circuit->u.bc.adjdb[level - 1],
|
||||
circuit->u.bc.lan_neighs[level - 1]);
|
||||
}
|
||||
else if (state == ISIS_ADJ_UP)
|
||||
{ /* p2p interface */
|
||||
if (adj->sys_type == ISIS_SYSTYPE_UNKNOWN)
|
||||
send_hello (circuit, 1);
|
||||
|
||||
/* update counter & timers for debugging purposes */
|
||||
adj->last_flap = time (NULL);
|
||||
adj->flaps++;
|
||||
|
||||
/* 7.3.17 - going up on P2P -> send CSNP */
|
||||
/* FIXME: yup, I know its wrong... but i will do it! (for now) */
|
||||
send_csnp (circuit, 1);
|
||||
send_csnp (circuit, 2);
|
||||
}
|
||||
else if (state == ISIS_ADJ_DOWN)
|
||||
{ /* p2p interface */
|
||||
adj->circuit->u.p2p.neighbor = NULL;
|
||||
isis_delete_adj (adj, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -223,47 +231,49 @@ isis_adj_print (struct isis_adjacency *adj)
|
||||
struct isis_dynhn *dyn;
|
||||
struct listnode *node;
|
||||
struct in_addr *ipv4_addr;
|
||||
#ifdef HAVE_IPV6
|
||||
#ifdef HAVE_IPV6
|
||||
struct in6_addr *ipv6_addr;
|
||||
u_char ip6 [INET6_ADDRSTRLEN];
|
||||
u_char ip6[INET6_ADDRSTRLEN];
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
if(!adj)
|
||||
|
||||
if (!adj)
|
||||
return;
|
||||
dyn = dynhn_find_by_id (adj->sysid);
|
||||
if (dyn)
|
||||
zlog_info ("%s", dyn->name.name);
|
||||
|
||||
zlog_info ("SystemId %20s SNPA %s, level %d\nHolding Time %d",
|
||||
adj->sysid ? sysid_print (adj->sysid) : "unknown" ,
|
||||
snpa_print (adj->snpa),
|
||||
adj->level, adj->hold_time);
|
||||
if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0) {
|
||||
zlog_info ("IPv4 Addresses:");
|
||||
|
||||
for (node = listhead (adj->ipv4_addrs); node; nextnode (node)) {
|
||||
ipv4_addr = getdata (node);
|
||||
zlog_info ("%s", inet_ntoa(*ipv4_addr));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0) {
|
||||
zlog_info ("IPv6 Addresses:");
|
||||
for (node = listhead (adj->ipv6_addrs); node; nextnode (node)) {
|
||||
ipv6_addr = getdata (node);
|
||||
inet_ntop (AF_INET6, ipv6_addr, ip6, INET6_ADDRSTRLEN);
|
||||
zlog_info ("%s", ip6);
|
||||
zlog_info ("SystemId %20s SNPA %s, level %d\nHolding Time %d",
|
||||
adj->sysid ? sysid_print (adj->sysid) : "unknown",
|
||||
snpa_print (adj->snpa), adj->level, adj->hold_time);
|
||||
if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0)
|
||||
{
|
||||
zlog_info ("IPv4 Addresses:");
|
||||
|
||||
for (node = listhead (adj->ipv4_addrs); node; nextnode (node))
|
||||
{
|
||||
ipv4_addr = getdata (node);
|
||||
zlog_info ("%s", inet_ntoa (*ipv4_addr));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0)
|
||||
{
|
||||
zlog_info ("IPv6 Addresses:");
|
||||
for (node = listhead (adj->ipv6_addrs); node; nextnode (node))
|
||||
{
|
||||
ipv6_addr = getdata (node);
|
||||
inet_ntop (AF_INET6, ipv6_addr, ip6, INET6_ADDRSTRLEN);
|
||||
zlog_info ("%s", ip6);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
zlog_info ("Speaks: %s", nlpid2string(&adj->nlpids));
|
||||
|
||||
zlog_info ("Speaks: %s", nlpid2string (&adj->nlpids));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
isis_adj_expire (struct thread *thread)
|
||||
{
|
||||
struct isis_adjacency *adj;
|
||||
@ -286,19 +296,20 @@ isis_adj_expire (struct thread *thread)
|
||||
const char *
|
||||
adj_state2string (int state)
|
||||
{
|
||||
|
||||
switch (state) {
|
||||
case ISIS_ADJ_INITIALIZING:
|
||||
return "Initializing";
|
||||
case ISIS_ADJ_UP:
|
||||
return "Up";
|
||||
case ISIS_ADJ_DOWN:
|
||||
return "Down";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
return NULL; /* not reached */
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case ISIS_ADJ_INITIALIZING:
|
||||
return "Initializing";
|
||||
case ISIS_ADJ_UP:
|
||||
return "Up";
|
||||
case ISIS_ADJ_DOWN:
|
||||
return "Down";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
return NULL; /* not reached */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -310,7 +321,7 @@ isis_adj_print_vty2 (struct isis_adjacency *adj, struct vty *vty, char detail)
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
struct in6_addr *ipv6_addr;
|
||||
u_char ip6 [INET6_ADDRSTRLEN];
|
||||
u_char ip6[INET6_ADDRSTRLEN];
|
||||
#endif /* HAVE_IPV6 */
|
||||
struct in_addr *ip_addr;
|
||||
time_t now;
|
||||
@ -321,111 +332,112 @@ isis_adj_print_vty2 (struct isis_adjacency *adj, struct vty *vty, char detail)
|
||||
dyn = dynhn_find_by_id (adj->sysid);
|
||||
if (dyn)
|
||||
vty_out (vty, " %-20s", dyn->name.name);
|
||||
else if (adj->sysid){
|
||||
vty_out (vty, " %-20s", sysid_print (adj->sysid));
|
||||
} else {
|
||||
vty_out (vty, " unknown ");
|
||||
}
|
||||
|
||||
if (detail == ISIS_UI_LEVEL_BRIEF) {
|
||||
if (adj->circuit)
|
||||
vty_out (vty, "%-12s",adj->circuit->interface->name);
|
||||
else
|
||||
vty_out (vty, "NULL circuit!");
|
||||
vty_out (vty, "%-3u", adj->level); /* level */
|
||||
vty_out (vty, "%-13s", adj_state2string (adj->adj_state));
|
||||
now = time (NULL);
|
||||
if (adj->last_upd)
|
||||
vty_out (vty, "%-9lu", adj->last_upd + adj->hold_time - now);
|
||||
else
|
||||
vty_out (vty, "- ");
|
||||
vty_out (vty, "%-10s", snpa_print (adj->snpa));
|
||||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
}
|
||||
|
||||
if (detail == ISIS_UI_LEVEL_DETAIL) {
|
||||
level = adj->level;
|
||||
if (adj->circuit)
|
||||
vty_out (vty, "%s Interface: %s",
|
||||
VTY_NEWLINE,
|
||||
adj->circuit->interface->name); /* interface name */
|
||||
else
|
||||
vty_out (vty, "NULL circuit!%s", VTY_NEWLINE);
|
||||
vty_out (vty, ", Level: %u", adj->level); /* level */
|
||||
vty_out (vty, ", State: %s", adj_state2string (adj->adj_state));
|
||||
now = time (NULL);
|
||||
if (adj->last_upd)
|
||||
vty_out (vty, ", Expires in %s",
|
||||
time2string (adj->last_upd + adj->hold_time - now));
|
||||
else
|
||||
vty_out (vty, ", Expires in %s",
|
||||
time2string (adj->hold_time));
|
||||
vty_out (vty, "%s Adjacency flaps: %u",
|
||||
VTY_NEWLINE,
|
||||
adj->flaps);
|
||||
vty_out (vty, ", Last: %s ago", time2string(now - adj->last_flap));
|
||||
vty_out (vty, "%s Circuit type: %s",
|
||||
VTY_NEWLINE,
|
||||
circuit_t2string(adj->circuit_t));
|
||||
vty_out (vty, ", Speaks: %s", nlpid2string(&adj->nlpids));
|
||||
vty_out (vty, "%s SNPA: %s",
|
||||
VTY_NEWLINE,
|
||||
snpa_print (adj->snpa));
|
||||
dyn = dynhn_find_by_id (adj->lanid);
|
||||
if (dyn)
|
||||
vty_out (vty, ", LAN id: %s.%02x",
|
||||
dyn->name.name,
|
||||
adj->lanid[ISIS_SYS_ID_LEN]);
|
||||
else
|
||||
vty_out (vty, ", LAN id: %s.%02x",
|
||||
sysid_print (adj->lanid),
|
||||
adj->lanid[ISIS_SYS_ID_LEN]);
|
||||
|
||||
vty_out (vty, "%s Priority: %u",
|
||||
VTY_NEWLINE,
|
||||
adj->prio[adj->level-1]);
|
||||
|
||||
vty_out (vty, ", %s, DIS flaps: %u, Last: %s ago%s",
|
||||
isis_disflag2string(adj->dis_record[ISIS_LEVELS+level-1].dis),
|
||||
adj->dischanges[level-1],
|
||||
time2string (now -
|
||||
(adj->dis_record[ISIS_LEVELS + level - 1].last_dis_change)),
|
||||
VTY_NEWLINE);
|
||||
|
||||
if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0) {
|
||||
vty_out (vty, " IPv4 Addresses:%s", VTY_NEWLINE);
|
||||
for (node = listhead (adj->ipv4_addrs);node; nextnode (node)) {
|
||||
ip_addr = getdata (node);
|
||||
vty_out (vty, " %s%s", inet_ntoa(*ip_addr), VTY_NEWLINE);
|
||||
}
|
||||
else if (adj->sysid)
|
||||
{
|
||||
vty_out (vty, " %-20s", sysid_print (adj->sysid));
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0) {
|
||||
vty_out (vty, " IPv6 Addresses:%s", VTY_NEWLINE);
|
||||
for (node = listhead (adj->ipv6_addrs); node; nextnode (node)) {
|
||||
ipv6_addr = getdata (node);
|
||||
inet_ntop (AF_INET6, ipv6_addr, ip6, INET6_ADDRSTRLEN);
|
||||
vty_out (vty, " %s%s", ip6, VTY_NEWLINE);
|
||||
}
|
||||
else
|
||||
{
|
||||
vty_out (vty, " unknown ");
|
||||
}
|
||||
|
||||
if (detail == ISIS_UI_LEVEL_BRIEF)
|
||||
{
|
||||
if (adj->circuit)
|
||||
vty_out (vty, "%-12s", adj->circuit->interface->name);
|
||||
else
|
||||
vty_out (vty, "NULL circuit!");
|
||||
vty_out (vty, "%-3u", adj->level); /* level */
|
||||
vty_out (vty, "%-13s", adj_state2string (adj->adj_state));
|
||||
now = time (NULL);
|
||||
if (adj->last_upd)
|
||||
vty_out (vty, "%-9lu", adj->last_upd + adj->hold_time - now);
|
||||
else
|
||||
vty_out (vty, "- ");
|
||||
vty_out (vty, "%-10s", snpa_print (adj->snpa));
|
||||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
}
|
||||
|
||||
if (detail == ISIS_UI_LEVEL_DETAIL)
|
||||
{
|
||||
level = adj->level;
|
||||
if (adj->circuit)
|
||||
vty_out (vty, "%s Interface: %s", VTY_NEWLINE, adj->circuit->interface->name); /* interface name */
|
||||
else
|
||||
vty_out (vty, "NULL circuit!%s", VTY_NEWLINE);
|
||||
vty_out (vty, ", Level: %u", adj->level); /* level */
|
||||
vty_out (vty, ", State: %s", adj_state2string (adj->adj_state));
|
||||
now = time (NULL);
|
||||
if (adj->last_upd)
|
||||
vty_out (vty, ", Expires in %s",
|
||||
time2string (adj->last_upd + adj->hold_time - now));
|
||||
else
|
||||
vty_out (vty, ", Expires in %s", time2string (adj->hold_time));
|
||||
vty_out (vty, "%s Adjacency flaps: %u", VTY_NEWLINE, adj->flaps);
|
||||
vty_out (vty, ", Last: %s ago", time2string (now - adj->last_flap));
|
||||
vty_out (vty, "%s Circuit type: %s",
|
||||
VTY_NEWLINE, circuit_t2string (adj->circuit_t));
|
||||
vty_out (vty, ", Speaks: %s", nlpid2string (&adj->nlpids));
|
||||
vty_out (vty, "%s SNPA: %s", VTY_NEWLINE, snpa_print (adj->snpa));
|
||||
dyn = dynhn_find_by_id (adj->lanid);
|
||||
if (dyn)
|
||||
vty_out (vty, ", LAN id: %s.%02x",
|
||||
dyn->name.name, adj->lanid[ISIS_SYS_ID_LEN]);
|
||||
else
|
||||
vty_out (vty, ", LAN id: %s.%02x",
|
||||
sysid_print (adj->lanid), adj->lanid[ISIS_SYS_ID_LEN]);
|
||||
|
||||
vty_out (vty, "%s Priority: %u",
|
||||
VTY_NEWLINE, adj->prio[adj->level - 1]);
|
||||
|
||||
vty_out (vty, ", %s, DIS flaps: %u, Last: %s ago%s",
|
||||
isis_disflag2string (adj->dis_record[ISIS_LEVELS + level - 1].
|
||||
dis), adj->dischanges[level - 1],
|
||||
time2string (now -
|
||||
(adj->dis_record[ISIS_LEVELS + level - 1].
|
||||
last_dis_change)), VTY_NEWLINE);
|
||||
|
||||
if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0)
|
||||
{
|
||||
vty_out (vty, " IPv4 Addresses:%s", VTY_NEWLINE);
|
||||
for (node = listhead (adj->ipv4_addrs); node; nextnode (node))
|
||||
{
|
||||
ip_addr = getdata (node);
|
||||
vty_out (vty, " %s%s", inet_ntoa (*ip_addr), VTY_NEWLINE);
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0)
|
||||
{
|
||||
vty_out (vty, " IPv6 Addresses:%s", VTY_NEWLINE);
|
||||
for (node = listhead (adj->ipv6_addrs); node; nextnode (node))
|
||||
{
|
||||
ipv6_addr = getdata (node);
|
||||
inet_ntop (AF_INET6, ipv6_addr, ip6, INET6_ADDRSTRLEN);
|
||||
vty_out (vty, " %s%s", ip6, VTY_NEWLINE);
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
}
|
||||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
isis_adj_print_vty (struct isis_adjacency *adj, struct vty *vty) {
|
||||
isis_adj_print_vty (struct isis_adjacency *adj, struct vty *vty)
|
||||
{
|
||||
isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_BRIEF);
|
||||
}
|
||||
|
||||
void
|
||||
isis_adj_print_vty_detail (struct isis_adjacency *adj, struct vty *vty) {
|
||||
isis_adj_print_vty_detail (struct isis_adjacency *adj, struct vty *vty)
|
||||
{
|
||||
isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_DETAIL);
|
||||
}
|
||||
|
||||
void
|
||||
isis_adj_print_vty_extensive (struct isis_adjacency *adj, struct vty *vty) {
|
||||
isis_adj_print_vty_extensive (struct isis_adjacency *adj, struct vty *vty)
|
||||
{
|
||||
isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_EXTENSIVE);
|
||||
}
|
||||
|
||||
@ -435,54 +447,56 @@ isis_adj_p2p_print_vty (struct isis_adjacency *adj, struct vty *vty)
|
||||
isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_BRIEF);
|
||||
}
|
||||
|
||||
void
|
||||
isis_adj_p2p_print_vty_detail (struct isis_adjacency *adj, struct vty *vty)
|
||||
void
|
||||
isis_adj_p2p_print_vty_detail (struct isis_adjacency *adj, struct vty *vty)
|
||||
{
|
||||
isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_DETAIL);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
isis_adj_p2p_print_vty_extensive (struct isis_adjacency *adj, struct vty *vty)
|
||||
{
|
||||
isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_EXTENSIVE);
|
||||
}
|
||||
|
||||
void
|
||||
isis_adjdb_iterate (struct list *adjdb, void (*func)(struct isis_adjacency*,
|
||||
void *), void *arg)
|
||||
isis_adjdb_iterate (struct list *adjdb, void (*func) (struct isis_adjacency *,
|
||||
void *), void *arg)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct isis_adjacency *adj;
|
||||
for (node = listhead (adjdb); node; nextnode (node)) {
|
||||
adj = getdata (node);
|
||||
(*func)(adj, arg);
|
||||
}
|
||||
for (node = listhead (adjdb); node; nextnode (node))
|
||||
{
|
||||
adj = getdata (node);
|
||||
(*func) (adj, arg);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
isis_adj_build_neigh_list (struct list *adjdb, struct list *list)
|
||||
|
||||
{
|
||||
struct isis_adjacency *adj;
|
||||
struct listnode *node;
|
||||
|
||||
|
||||
if (!list) {
|
||||
zlog_warn ("isis_adj_build_neigh_list(): NULL list");
|
||||
return;
|
||||
}
|
||||
|
||||
for (node = listhead (adjdb); node; nextnode (node)) {
|
||||
adj = getdata (node);
|
||||
if (!adj) {
|
||||
zlog_warn ("isis_adj_build_neigh_list(): NULL adj");
|
||||
|
||||
if (!list)
|
||||
{
|
||||
zlog_warn ("isis_adj_build_neigh_list(): NULL list");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((adj->adj_state == ISIS_ADJ_UP ||
|
||||
adj->adj_state == ISIS_ADJ_INITIALIZING))
|
||||
listnode_add (list, adj->snpa);
|
||||
}
|
||||
|
||||
for (node = listhead (adjdb); node; nextnode (node))
|
||||
{
|
||||
adj = getdata (node);
|
||||
if (!adj)
|
||||
{
|
||||
zlog_warn ("isis_adj_build_neigh_list(): NULL adj");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((adj->adj_state == ISIS_ADJ_UP ||
|
||||
adj->adj_state == ISIS_ADJ_INITIALIZING))
|
||||
listnode_add (list, adj->snpa);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -492,23 +506,25 @@ isis_adj_build_up_list (struct list *adjdb, struct list *list)
|
||||
struct isis_adjacency *adj;
|
||||
struct listnode *node;
|
||||
|
||||
if (!list) {
|
||||
zlog_warn ("isis_adj_build_up_list(): NULL list");
|
||||
return;
|
||||
}
|
||||
|
||||
for (node = listhead (adjdb); node; nextnode (node)) {
|
||||
adj = getdata (node);
|
||||
|
||||
if (!adj) {
|
||||
zlog_warn ("isis_adj_build_up_list(): NULL adj");
|
||||
if (!list)
|
||||
{
|
||||
zlog_warn ("isis_adj_build_up_list(): NULL list");
|
||||
return;
|
||||
}
|
||||
|
||||
if (adj->adj_state == ISIS_ADJ_UP)
|
||||
listnode_add (list, adj);
|
||||
}
|
||||
|
||||
for (node = listhead (adjdb); node; nextnode (node))
|
||||
{
|
||||
adj = getdata (node);
|
||||
|
||||
if (!adj)
|
||||
{
|
||||
zlog_warn ("isis_adj_build_up_list(): NULL adj");
|
||||
return;
|
||||
}
|
||||
|
||||
if (adj->adj_state == ISIS_ADJ_UP)
|
||||
listnode_add (list, adj);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ enum isis_adj_usage
|
||||
ISIS_ADJ_LEVEL1AND2
|
||||
};
|
||||
|
||||
enum isis_system_type
|
||||
enum isis_system_type
|
||||
{
|
||||
ISIS_SYSTYPE_UNKNOWN,
|
||||
ISIS_SYSTYPE_ES,
|
||||
@ -42,7 +42,7 @@ enum isis_system_type
|
||||
ISIS_SYSTYPE_L2_IS
|
||||
};
|
||||
|
||||
enum isis_adj_state
|
||||
enum isis_adj_state
|
||||
{
|
||||
ISIS_ADJ_INITIALIZING,
|
||||
ISIS_ADJ_UP,
|
||||
@ -62,65 +62,66 @@ enum isis_adj_updown_reason
|
||||
ISIS_ADJ_REASON_CHECKSUM_FAILED
|
||||
};
|
||||
|
||||
#define DIS_RECORDS 8 /* keep the last 8 DIS state changes on record */
|
||||
#define DIS_RECORDS 8 /* keep the last 8 DIS state changes on record */
|
||||
|
||||
struct isis_dis_record {
|
||||
int dis; /* is our neighbor the DIS ? */ time_t last_dis_change; /* timestamp for last dis change */
|
||||
struct isis_dis_record
|
||||
{
|
||||
int dis; /* is our neighbor the DIS ? */
|
||||
time_t last_dis_change; /* timestamp for last dis change */
|
||||
};
|
||||
|
||||
struct isis_adjacency{
|
||||
u_char snpa[ETH_ALEN]; /* NeighbourSNPAAddress */
|
||||
u_char sysid[ISIS_SYS_ID_LEN]; /* neighbourSystemIdentifier */
|
||||
u_char lanid[ISIS_SYS_ID_LEN+1]; /* LAN id on bcast circuits */
|
||||
int dischanges[ISIS_LEVELS]; /* how many DIS changes ?*/
|
||||
struct isis_adjacency
|
||||
{
|
||||
u_char snpa[ETH_ALEN]; /* NeighbourSNPAAddress */
|
||||
u_char sysid[ISIS_SYS_ID_LEN]; /* neighbourSystemIdentifier */
|
||||
u_char lanid[ISIS_SYS_ID_LEN + 1]; /* LAN id on bcast circuits */
|
||||
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 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;
|
||||
#ifdef HAVE_IPV6
|
||||
struct list *ipv6_addrs;
|
||||
#endif /* HAVE_IPV6 */
|
||||
u_char prio[ISIS_LEVELS]; /* priorityOfNeighbour for DIS*/
|
||||
int circuit_t; /* from hello PDU hdr */
|
||||
int level; /* level (1 or 2) */
|
||||
enum isis_system_type sys_type; /* neighbourSystemType */
|
||||
u_int16_t hold_time; /* entryRemainingTime */
|
||||
#endif /* HAVE_IPV6 */
|
||||
u_char prio[ISIS_LEVELS]; /* priorityOfNeighbour for DIS */
|
||||
int circuit_t; /* from hello PDU hdr */
|
||||
int level; /* level (1 or 2) */
|
||||
enum isis_system_type sys_type; /* neighbourSystemType */
|
||||
u_int16_t hold_time; /* entryRemainingTime */
|
||||
u_int32_t last_upd;
|
||||
u_int32_t last_flap; /* last time the adj flapped */
|
||||
int flaps; /* number of adjacency flaps */
|
||||
struct thread *t_expire; /* expire after hold_time */
|
||||
struct isis_circuit *circuit; /* back pointer */
|
||||
u_int32_t last_flap; /* last time the adj flapped */
|
||||
int flaps; /* number of adjacency flaps */
|
||||
struct thread *t_expire; /* expire after hold_time */
|
||||
struct isis_circuit *circuit; /* back pointer */
|
||||
};
|
||||
|
||||
|
||||
struct isis_adjacency *isis_adj_lookup (u_char *sysid, struct list *adjdb);
|
||||
struct isis_adjacency *isis_adj_lookup_snpa (u_char *ssnpa,
|
||||
struct isis_adjacency *isis_adj_lookup (u_char * sysid, struct list *adjdb);
|
||||
struct isis_adjacency *isis_adj_lookup_snpa (u_char * ssnpa,
|
||||
struct list *adjdb);
|
||||
struct isis_adjacency *isis_new_adj (u_char *id, u_char *snpa, int level,
|
||||
struct isis_circuit *circuit);
|
||||
void isis_delete_adj (struct isis_adjacency *adj, struct list *adjdb);
|
||||
void isis_adj_state_change (struct isis_adjacency *adj,
|
||||
enum isis_adj_state state, char *reason);
|
||||
void isis_adj_print (struct isis_adjacency *adj);
|
||||
int isis_adj_expire (struct thread *thread);
|
||||
struct isis_adjacency *isis_new_adj (u_char * id, u_char * snpa, int level,
|
||||
struct isis_circuit *circuit);
|
||||
void isis_delete_adj (struct isis_adjacency *adj, struct list *adjdb);
|
||||
void isis_adj_state_change (struct isis_adjacency *adj,
|
||||
enum isis_adj_state state, char *reason);
|
||||
void isis_adj_print (struct isis_adjacency *adj);
|
||||
int isis_adj_expire (struct thread *thread);
|
||||
void isis_adj_print_vty (struct isis_adjacency *adj, struct vty *vty);
|
||||
void isis_adj_print_vty_detail (struct isis_adjacency *adj, struct vty *vty);
|
||||
void isis_adj_print_vty_extensive (struct isis_adjacency *adj,
|
||||
struct vty *vty);
|
||||
void isis_adj_print_vty_extensive (struct isis_adjacency *adj,
|
||||
struct vty *vty);
|
||||
void isis_adj_p2p_print_vty (struct isis_adjacency *adj, struct vty *vty);
|
||||
void isis_adj_p2p_print_vty_detail (struct isis_adjacency *adj,
|
||||
struct vty *vty);
|
||||
void isis_adj_p2p_print_vty_extensive (struct isis_adjacency *adj,
|
||||
struct vty *vty);
|
||||
void isis_adj_p2p_print_vty_detail (struct isis_adjacency *adj,
|
||||
struct vty *vty);
|
||||
void isis_adj_p2p_print_vty_extensive (struct isis_adjacency *adj,
|
||||
struct vty *vty);
|
||||
|
||||
void isis_adj_build_neigh_list (struct list *adjdb, struct list *list);
|
||||
void isis_adj_build_up_list (struct list *adjdb, struct list *list);
|
||||
void isis_adjdb_iterate (struct list *adjdb,
|
||||
void (*func)(struct isis_adjacency*,
|
||||
void *), void *arg);
|
||||
void isis_adjdb_iterate (struct list *adjdb,
|
||||
void (*func) (struct isis_adjacency *,
|
||||
void *), void *arg);
|
||||
|
||||
#endif /* ISIS_ADJACENCY_H */
|
||||
|
||||
|
||||
1830
isisd/isis_circuit.c
1830
isisd/isis_circuit.c
File diff suppressed because it is too large
Load Diff
@ -25,134 +25,139 @@
|
||||
|
||||
#define CIRCUIT_MAX 255
|
||||
|
||||
struct password {
|
||||
struct password
|
||||
{
|
||||
struct password *next;
|
||||
int len;
|
||||
u_char *pass;
|
||||
int len;
|
||||
u_char *pass;
|
||||
};
|
||||
|
||||
struct metric {
|
||||
struct metric
|
||||
{
|
||||
u_char metric_default;
|
||||
u_char metric_error;
|
||||
u_char metric_expense;
|
||||
u_char metric_delay;
|
||||
};
|
||||
|
||||
struct isis_bcast_info {
|
||||
u_char snpa [ETH_ALEN]; /* SNPA of this circuit */
|
||||
char run_dr_elect[2]; /* Should we run dr election ? */
|
||||
struct thread *t_run_dr[2]; /* DR election thread */
|
||||
struct thread *t_send_lan_hello[2]; /* send LAN IIHs in this thread */
|
||||
struct list *adjdb[2]; /* adjacency dbs */
|
||||
struct list *lan_neighs[2]; /* list of lx neigh snpa */
|
||||
char is_dr[2]; /* Are we level x DR ? */
|
||||
u_char l1_desig_is[ISIS_SYS_ID_LEN + 1]; /* level-1 DR */
|
||||
u_char l2_desig_is[ISIS_SYS_ID_LEN + 1]; /* level-2 DR */
|
||||
struct thread *t_refresh_pseudo_lsp[2]; /* refresh pseudo-node LSPs */
|
||||
int pad_hellos; /* add padding to Hello PDUs ? */
|
||||
u_char priority[2]; /* l1/2 IS Priority */
|
||||
struct isis_bcast_info
|
||||
{
|
||||
u_char snpa[ETH_ALEN]; /* SNPA of this circuit */
|
||||
char run_dr_elect[2]; /* Should we run dr election ? */
|
||||
struct thread *t_run_dr[2]; /* DR election thread */
|
||||
struct thread *t_send_lan_hello[2]; /* send LAN IIHs in this thread */
|
||||
struct list *adjdb[2]; /* adjacency dbs */
|
||||
struct list *lan_neighs[2]; /* list of lx neigh snpa */
|
||||
char is_dr[2]; /* Are we level x DR ? */
|
||||
u_char l1_desig_is[ISIS_SYS_ID_LEN + 1]; /* level-1 DR */
|
||||
u_char l2_desig_is[ISIS_SYS_ID_LEN + 1]; /* level-2 DR */
|
||||
struct thread *t_refresh_pseudo_lsp[2]; /* refresh pseudo-node LSPs */
|
||||
int pad_hellos; /* add padding to Hello PDUs ? */
|
||||
u_char priority[2]; /* l1/2 IS Priority */
|
||||
};
|
||||
|
||||
struct isis_p2p_info {
|
||||
struct isis_adjacency *neighbor;
|
||||
struct thread *t_send_p2p_hello; /* send P2P IIHs in this thread */
|
||||
struct isis_p2p_info
|
||||
{
|
||||
struct isis_adjacency *neighbor;
|
||||
struct thread *t_send_p2p_hello; /* send P2P IIHs in this thread */
|
||||
};
|
||||
|
||||
struct isis_circuit {
|
||||
struct isis_circuit
|
||||
{
|
||||
int state;
|
||||
u_char circuit_id; /* l1/l2 p2p/bcast CircuitID */
|
||||
struct isis_area *area; /* back pointer to the area */
|
||||
struct interface *interface; /* interface info from z */
|
||||
int fd; /* IS-IS l1/2 socket */
|
||||
struct nlpids nlpids;
|
||||
u_char circuit_id; /* l1/l2 p2p/bcast CircuitID */
|
||||
struct isis_area *area; /* back pointer to the area */
|
||||
struct interface *interface; /* interface info from z */
|
||||
int fd; /* IS-IS l1/2 socket */
|
||||
struct nlpids nlpids;
|
||||
/*
|
||||
* Threads
|
||||
*/
|
||||
struct thread *t_read;
|
||||
struct thread *t_send_csnp[2];
|
||||
struct thread *t_send_psnp[2];
|
||||
struct list *lsp_queue; /* LSPs to be txed (both levels) */
|
||||
struct list *lsp_queue; /* LSPs to be txed (both levels) */
|
||||
/* there is no real point in two streams, just for programming kicker */
|
||||
int (* rx) (struct isis_circuit *circuit, u_char *ssnpa);
|
||||
struct stream *rcv_stream; /* Stream for receiving */
|
||||
int (* tx) (struct isis_circuit *circuit, int level);
|
||||
struct stream *snd_stream; /* Stream for sending */
|
||||
int idx; /* idx in S[RM|SN] flags */
|
||||
#define CIRCUIT_T_BROADCAST 0
|
||||
int (*rx) (struct isis_circuit * circuit, u_char * ssnpa);
|
||||
struct stream *rcv_stream; /* Stream for receiving */
|
||||
int (*tx) (struct isis_circuit * circuit, int level);
|
||||
struct stream *snd_stream; /* Stream for sending */
|
||||
int idx; /* idx in S[RM|SN] flags */
|
||||
#define CIRCUIT_T_BROADCAST 0
|
||||
#define CIRCUIT_T_P2P 1
|
||||
#define CIRCUIT_T_STATIC_IN 2
|
||||
#define CIRCUIT_T_STATIC_OUT 3
|
||||
#define CIRCUIT_T_DA 4
|
||||
int circ_type; /* type of the physical interface */
|
||||
union {
|
||||
int circ_type; /* type of the physical interface */
|
||||
union
|
||||
{
|
||||
struct isis_bcast_info bc;
|
||||
struct isis_p2p_info p2p;
|
||||
} u;
|
||||
char ext_domain; /* externalDomain (boolean) */
|
||||
char ext_domain; /* externalDomain (boolean) */
|
||||
/*
|
||||
* Configurables
|
||||
*/
|
||||
struct isis_passwd passwd; /* Circuit rx/tx password */
|
||||
long lsp_interval;
|
||||
int manual_l2_only; /* manualL2OnlyMode (boolean) */
|
||||
int circuit_is_type; /* circuit is type == level of circuit
|
||||
* diffrenciated from circuit type (media) */
|
||||
u_int32_t hello_interval[2]; /* l1HelloInterval in msecs */
|
||||
u_int16_t hello_multiplier[2]; /* l1HelloMultiplier */
|
||||
u_int16_t csnp_interval[2]; /* level-1 csnp-interval in seconds */
|
||||
u_int16_t psnp_interval[2]; /* level-1 psnp-interval in seconds */
|
||||
struct metric metrics[2]; /* l1XxxMetric */
|
||||
struct password *c_rx_passwds; /* circuitReceivePasswords */
|
||||
struct password *c_tc_passwd; /* circuitTransmitPassword */
|
||||
int ip_router; /* Route IP ? */
|
||||
struct list *ip_addrs; /* our IP addresses */
|
||||
struct isis_passwd passwd; /* Circuit rx/tx password */
|
||||
long lsp_interval;
|
||||
int manual_l2_only; /* manualL2OnlyMode (boolean) */
|
||||
int circuit_is_type; /* circuit is type == level of circuit
|
||||
* diffrenciated from circuit type (media) */
|
||||
u_int32_t hello_interval[2]; /* l1HelloInterval in msecs */
|
||||
u_int16_t hello_multiplier[2]; /* l1HelloMultiplier */
|
||||
u_int16_t csnp_interval[2]; /* level-1 csnp-interval in seconds */
|
||||
u_int16_t psnp_interval[2]; /* level-1 psnp-interval in seconds */
|
||||
struct metric metrics[2]; /* l1XxxMetric */
|
||||
struct password *c_rx_passwds; /* circuitReceivePasswords */
|
||||
struct password *c_tc_passwd; /* circuitTransmitPassword */
|
||||
int ip_router; /* Route IP ? */
|
||||
struct list *ip_addrs; /* our IP addresses */
|
||||
#ifdef HAVE_IPV6
|
||||
int ipv6_router; /* Route IPv6 ? */
|
||||
struct list *ipv6_link; /* our link local IPv6 addresses */
|
||||
struct list *ipv6_non_link; /* our non-link local IPv6 addresses */
|
||||
#endif /* HAVE_IPV6 */
|
||||
int ipv6_router; /* Route IPv6 ? */
|
||||
struct list *ipv6_link; /* our link local IPv6 addresses */
|
||||
struct list *ipv6_non_link; /* our non-link local IPv6 addresses */
|
||||
#endif /* HAVE_IPV6 */
|
||||
/*
|
||||
* RFC 2973 IS-IS Mesh Groups
|
||||
*/
|
||||
#define MESH_INACTIVE 0
|
||||
#define MESH_BLOCKED 1
|
||||
#define MESH_SET 2
|
||||
int mesh_enabled; /* meshGroupEnabled */
|
||||
u_int16_t mesh_group; /* meshGroup */
|
||||
int mesh_enabled; /* meshGroupEnabled */
|
||||
u_int16_t mesh_group; /* meshGroup */
|
||||
u_int16_t upadjcount[2];
|
||||
/*
|
||||
* Counters as in 10589--11.2.5.9
|
||||
*/
|
||||
u_int32_t adj_state_changes; /* changesInAdjacencyState */
|
||||
u_int32_t init_failures; /* intialisationFailures */
|
||||
u_int32_t ctrl_pdus_rxed; /* controlPDUsReceived */
|
||||
u_int32_t ctrl_pdus_txed; /* controlPDUsSent */
|
||||
u_int32_t desig_changes[2]; /* lanLxDesignatedIntermediateSystemChanges*/
|
||||
u_int32_t rej_adjacencies; /* rejectedAdjacencies */
|
||||
u_int32_t adj_state_changes; /* changesInAdjacencyState */
|
||||
u_int32_t init_failures; /* intialisationFailures */
|
||||
u_int32_t ctrl_pdus_rxed; /* controlPDUsReceived */
|
||||
u_int32_t ctrl_pdus_txed; /* controlPDUsSent */
|
||||
u_int32_t desig_changes[2]; /* lanLxDesignatedIntermediateSystemChanges */
|
||||
u_int32_t rej_adjacencies; /* rejectedAdjacencies */
|
||||
};
|
||||
|
||||
void isis_circuit_init (void);
|
||||
struct isis_circuit *isis_circuit_new (void);
|
||||
struct isis_circuit *circuit_lookup_by_ifp (struct interface *ifp,
|
||||
struct list *list);
|
||||
struct isis_circuit *circuit_scan_by_ifp (struct interface *ifp);
|
||||
void isis_circuit_del (struct isis_circuit *circuit);
|
||||
void isis_circuit_configure (struct isis_circuit *circuit,
|
||||
struct isis_area *area);
|
||||
void isis_circuit_up (struct isis_circuit *circuit);
|
||||
void isis_circuit_deconfigure (struct isis_circuit *circuit,
|
||||
struct isis_area *area);
|
||||
|
||||
void isis_circuit_init (void);
|
||||
struct isis_circuit *isis_circuit_new (void);
|
||||
struct isis_circuit *circuit_lookup_by_ifp (struct interface *ifp,
|
||||
struct list *list);
|
||||
struct isis_circuit *circuit_scan_by_ifp (struct interface *ifp);
|
||||
void isis_circuit_del (struct isis_circuit *circuit);
|
||||
void isis_circuit_configure (struct isis_circuit *circuit,
|
||||
struct isis_area *area);
|
||||
void isis_circuit_up (struct isis_circuit *circuit);
|
||||
void isis_circuit_deconfigure (struct isis_circuit *circuit,
|
||||
struct isis_area *area);
|
||||
|
||||
int isis_circuit_destroy (struct isis_circuit *circuit);
|
||||
void isis_circuit_if_add (struct isis_circuit *circuit,
|
||||
struct interface *ifp);
|
||||
void isis_circuit_if_del (struct isis_circuit *circuit);
|
||||
void circuit_update_nlpids (struct isis_circuit *circuit);
|
||||
void isis_circuit_update_params (struct isis_circuit *circuit,
|
||||
struct interface *ifp);
|
||||
void isis_circuit_add_addr (struct isis_circuit *circuit,
|
||||
struct connected *conn);
|
||||
void isis_circuit_del_addr (struct isis_circuit *circuit,
|
||||
struct connected *conn);
|
||||
int isis_circuit_destroy (struct isis_circuit *circuit);
|
||||
void isis_circuit_if_add (struct isis_circuit *circuit,
|
||||
struct interface *ifp);
|
||||
void isis_circuit_if_del (struct isis_circuit *circuit);
|
||||
void circuit_update_nlpids (struct isis_circuit *circuit);
|
||||
void isis_circuit_update_params (struct isis_circuit *circuit,
|
||||
struct interface *ifp);
|
||||
void isis_circuit_add_addr (struct isis_circuit *circuit,
|
||||
struct connected *conn);
|
||||
void isis_circuit_del_addr (struct isis_circuit *circuit,
|
||||
struct connected *conn);
|
||||
#endif /* _ZEBRA_ISIS_CIRCUIT_H */
|
||||
|
||||
@ -23,13 +23,15 @@
|
||||
|
||||
/*
|
||||
* Area Address
|
||||
*/
|
||||
struct area_addr {
|
||||
u_char addr_len;
|
||||
u_char area_addr[20];
|
||||
*/
|
||||
struct area_addr
|
||||
{
|
||||
u_char addr_len;
|
||||
u_char area_addr[20];
|
||||
};
|
||||
|
||||
struct isis_passwd {
|
||||
struct isis_passwd
|
||||
{
|
||||
u_char len;
|
||||
#define ISIS_PASSWD_TYPE_UNUSED 0
|
||||
#define ISIS_PASSWD_TYPE_CLEARTXT 1
|
||||
@ -43,7 +45,8 @@ struct isis_passwd {
|
||||
* one struct for cache list
|
||||
* one struct for LSP TLV
|
||||
*/
|
||||
struct hostname {
|
||||
struct hostname
|
||||
{
|
||||
u_char namelen;
|
||||
u_char name[255];
|
||||
};
|
||||
@ -51,15 +54,17 @@ struct hostname {
|
||||
/*
|
||||
* Supported Protocol IDs
|
||||
*/
|
||||
struct nlpids {
|
||||
struct nlpids
|
||||
{
|
||||
u_char count;
|
||||
u_char nlpids[4]; /* FIXME: enough ? */
|
||||
u_char nlpids[4]; /* FIXME: enough ? */
|
||||
};
|
||||
|
||||
/*
|
||||
* Flags structure for SSN and SRM flags
|
||||
*/
|
||||
struct flags {
|
||||
*/
|
||||
struct flags
|
||||
{
|
||||
int maxindex;
|
||||
struct list *free_idcs;
|
||||
};
|
||||
|
||||
@ -25,9 +25,9 @@
|
||||
|
||||
/*
|
||||
* Architectural constant values from p. 35 of ISO/IEC 10589
|
||||
*/
|
||||
*/
|
||||
|
||||
#define MAX_LINK_METRIC 63
|
||||
#define MAX_LINK_METRIC 63
|
||||
#define MAX_PATH_METRIC 1023
|
||||
#define ISO_SAP 0xFE
|
||||
#define INTRADOMAIN_ROUTEING_SELECTOR 0
|
||||
@ -38,11 +38,11 @@
|
||||
* implementation specific jitter values
|
||||
*/
|
||||
|
||||
#define IIH_JITTER 25 /* % */
|
||||
#define MAX_AGE_JITTER 5 /* % */
|
||||
#define MAX_LSP_GEN_JITTER 5 /* % */
|
||||
#define CSNP_JITTER 10 /* % */
|
||||
#define PSNP_JITTER 10 /* % */
|
||||
#define IIH_JITTER 25 /* % */
|
||||
#define MAX_AGE_JITTER 5 /* % */
|
||||
#define MAX_LSP_GEN_JITTER 5 /* % */
|
||||
#define CSNP_JITTER 10 /* % */
|
||||
#define PSNP_JITTER 10 /* % */
|
||||
|
||||
#define RANDOM_SPREAD 100000.0
|
||||
|
||||
@ -70,12 +70,12 @@
|
||||
#define HELLO_MULTIPLIER 3
|
||||
#define DEFAULT_PRIORITY 64
|
||||
/* different vendors implement different values 5-10 on average */
|
||||
#define LSP_GEN_INTERVAL_DEFAULT 10
|
||||
#define LSP_INTERVAL 33 /* msecs */
|
||||
#define LSP_GEN_INTERVAL_DEFAULT 10
|
||||
#define LSP_INTERVAL 33 /* msecs */
|
||||
#define DEFAULT_CIRCUIT_METRICS 10
|
||||
#define METRICS_UNSUPPORTED 0x80
|
||||
#define PERIODIC_SPF_INTERVAL 60 /* at the top of my head */
|
||||
#define MINIMUM_SPF_INTERVAL 5 /* .. same here */
|
||||
#define PERIODIC_SPF_INTERVAL 60 /* at the top of my head */
|
||||
#define MINIMUM_SPF_INTERVAL 5 /* .. same here */
|
||||
|
||||
/*
|
||||
* NLPID values
|
||||
@ -143,12 +143,4 @@
|
||||
#define ETH_ALEN 6
|
||||
#endif
|
||||
|
||||
#endif /* ISIS_CONSTANTS_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* ISIS_CONSTANTS_H */
|
||||
|
||||
204
isisd/isis_csm.c
204
isisd/isis_csm.c
@ -52,8 +52,7 @@
|
||||
|
||||
extern struct isis *isis;
|
||||
|
||||
static char *csm_statestr[] =
|
||||
{
|
||||
static char *csm_statestr[] = {
|
||||
"C_STATE_NA",
|
||||
"C_STATE_INIT",
|
||||
"C_STATE_CONF",
|
||||
@ -62,8 +61,7 @@ static char *csm_statestr[] =
|
||||
|
||||
#define STATE2STR(S) csm_statestr[S]
|
||||
|
||||
static char *csm_eventstr[] =
|
||||
{
|
||||
static char *csm_eventstr[] = {
|
||||
"NO_STATE",
|
||||
"ISIS_ENABLE",
|
||||
"IF_UP_FROM_Z",
|
||||
@ -73,113 +71,113 @@ static char *csm_eventstr[] =
|
||||
|
||||
#define EVENT2STR(E) csm_eventstr[E]
|
||||
|
||||
|
||||
struct isis_circuit*
|
||||
isis_csm_state_change (int event, struct isis_circuit *circuit,
|
||||
void *arg)
|
||||
struct isis_circuit *
|
||||
isis_csm_state_change (int event, struct isis_circuit *circuit, void *arg)
|
||||
{
|
||||
int old_state;
|
||||
|
||||
old_state = circuit ? circuit->state : C_STATE_NA;
|
||||
|
||||
zlog_info ("CSM_EVENT: %s", EVENT2STR(event));
|
||||
|
||||
switch (old_state) {
|
||||
case C_STATE_NA:
|
||||
if (circuit)
|
||||
zlog_warn ("Non-null circuit while state C_STATE_NA");
|
||||
switch (event) {
|
||||
case ISIS_ENABLE:
|
||||
circuit = isis_circuit_new ();
|
||||
isis_circuit_configure (circuit, (struct isis_area *)arg);
|
||||
circuit->state = C_STATE_CONF;
|
||||
|
||||
zlog_info ("CSM_EVENT: %s", EVENT2STR (event));
|
||||
|
||||
switch (old_state)
|
||||
{
|
||||
case C_STATE_NA:
|
||||
if (circuit)
|
||||
zlog_warn ("Non-null circuit while state C_STATE_NA");
|
||||
switch (event)
|
||||
{
|
||||
case ISIS_ENABLE:
|
||||
circuit = isis_circuit_new ();
|
||||
isis_circuit_configure (circuit, (struct isis_area *) arg);
|
||||
circuit->state = C_STATE_CONF;
|
||||
break;
|
||||
case IF_UP_FROM_Z:
|
||||
circuit = isis_circuit_new ();
|
||||
isis_circuit_if_add (circuit, (struct interface *) arg);
|
||||
listnode_add (isis->init_circ_list, circuit);
|
||||
circuit->state = C_STATE_INIT;
|
||||
break;
|
||||
case ISIS_DISABLE:
|
||||
zlog_warn ("circuit already disabled");
|
||||
case IF_DOWN_FROM_Z:
|
||||
zlog_warn ("circuit already disconnected");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case IF_UP_FROM_Z:
|
||||
circuit = isis_circuit_new ();
|
||||
isis_circuit_if_add (circuit, (struct interface *)arg);
|
||||
listnode_add (isis->init_circ_list, circuit);
|
||||
circuit->state = C_STATE_INIT;
|
||||
case C_STATE_INIT:
|
||||
switch (event)
|
||||
{
|
||||
case ISIS_ENABLE:
|
||||
isis_circuit_configure (circuit, (struct isis_area *) arg);
|
||||
isis_circuit_up (circuit);
|
||||
circuit->state = C_STATE_UP;
|
||||
isis_event_circuit_state_change (circuit, 1);
|
||||
listnode_delete (isis->init_circ_list, circuit);
|
||||
break;
|
||||
case IF_UP_FROM_Z:
|
||||
zlog_warn ("circuit already connected");
|
||||
break;
|
||||
case ISIS_DISABLE:
|
||||
zlog_warn ("circuit already disabled");
|
||||
break;
|
||||
case IF_DOWN_FROM_Z:
|
||||
isis_circuit_if_del (circuit);
|
||||
listnode_delete (isis->init_circ_list, circuit);
|
||||
isis_circuit_del (circuit);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ISIS_DISABLE:
|
||||
zlog_warn ("circuit already disabled");
|
||||
case IF_DOWN_FROM_Z:
|
||||
zlog_warn ("circuit already disconnected");
|
||||
case C_STATE_CONF:
|
||||
switch (event)
|
||||
{
|
||||
case ISIS_ENABLE:
|
||||
zlog_warn ("circuit already enabled");
|
||||
break;
|
||||
case IF_UP_FROM_Z:
|
||||
isis_circuit_if_add (circuit, (struct interface *) arg);
|
||||
isis_circuit_up (circuit);
|
||||
circuit->state = C_STATE_UP;
|
||||
isis_event_circuit_state_change (circuit, 1);
|
||||
break;
|
||||
case ISIS_DISABLE:
|
||||
isis_circuit_deconfigure (circuit, (struct isis_area *) arg);
|
||||
isis_circuit_del (circuit);
|
||||
break;
|
||||
case IF_DOWN_FROM_Z:
|
||||
zlog_warn ("circuit already disconnected");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case C_STATE_UP:
|
||||
switch (event)
|
||||
{
|
||||
case ISIS_ENABLE:
|
||||
zlog_warn ("circuit already configured");
|
||||
break;
|
||||
case IF_UP_FROM_Z:
|
||||
zlog_warn ("circuit already connected");
|
||||
break;
|
||||
case ISIS_DISABLE:
|
||||
isis_circuit_deconfigure (circuit, (struct isis_area *) arg);
|
||||
listnode_add (isis->init_circ_list, circuit);
|
||||
circuit->state = C_STATE_INIT;
|
||||
isis_event_circuit_state_change (circuit, 0);
|
||||
break;
|
||||
case IF_DOWN_FROM_Z:
|
||||
isis_circuit_if_del (circuit);
|
||||
circuit->state = C_STATE_CONF;
|
||||
isis_event_circuit_state_change (circuit, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
zlog_warn ("Invalid circuit state %d", old_state);
|
||||
}
|
||||
break;
|
||||
case C_STATE_INIT:
|
||||
switch (event) {
|
||||
case ISIS_ENABLE:
|
||||
isis_circuit_configure (circuit, (struct isis_area *)arg);
|
||||
isis_circuit_up (circuit);
|
||||
circuit->state = C_STATE_UP;
|
||||
isis_event_circuit_state_change (circuit, 1);
|
||||
listnode_delete (isis->init_circ_list, circuit);
|
||||
break;
|
||||
case IF_UP_FROM_Z:
|
||||
zlog_warn ("circuit already connected");
|
||||
break;
|
||||
case ISIS_DISABLE:
|
||||
zlog_warn ("circuit already disabled");
|
||||
break;
|
||||
case IF_DOWN_FROM_Z:
|
||||
isis_circuit_if_del (circuit);
|
||||
listnode_delete (isis->init_circ_list, circuit);
|
||||
isis_circuit_del (circuit);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case C_STATE_CONF:
|
||||
switch (event) {
|
||||
case ISIS_ENABLE:
|
||||
zlog_warn ("circuit already enabled");
|
||||
break;
|
||||
case IF_UP_FROM_Z:
|
||||
isis_circuit_if_add (circuit, (struct interface *)arg);
|
||||
isis_circuit_up (circuit);
|
||||
circuit->state = C_STATE_UP;
|
||||
isis_event_circuit_state_change (circuit, 1);
|
||||
break;
|
||||
case ISIS_DISABLE:
|
||||
isis_circuit_deconfigure (circuit, (struct isis_area *)arg);
|
||||
isis_circuit_del (circuit);
|
||||
break;
|
||||
case IF_DOWN_FROM_Z:
|
||||
zlog_warn ("circuit already disconnected");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case C_STATE_UP:
|
||||
switch (event) {
|
||||
case ISIS_ENABLE:
|
||||
zlog_warn ("circuit already configured");
|
||||
break;
|
||||
case IF_UP_FROM_Z:
|
||||
zlog_warn ("circuit already connected");
|
||||
break;
|
||||
case ISIS_DISABLE:
|
||||
isis_circuit_deconfigure (circuit, (struct isis_area *)arg);
|
||||
listnode_add (isis->init_circ_list, circuit);
|
||||
circuit->state = C_STATE_INIT;
|
||||
isis_event_circuit_state_change (circuit, 0);
|
||||
break;
|
||||
case IF_DOWN_FROM_Z:
|
||||
isis_circuit_if_del (circuit);
|
||||
circuit->state = C_STATE_CONF;
|
||||
isis_event_circuit_state_change (circuit, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
zlog_warn ("Invalid circuit state %d", old_state);
|
||||
}
|
||||
|
||||
zlog_info ("CSM_STATE_CHANGE: %s -> %s ", STATE2STR (old_state),
|
||||
circuit ? STATE2STR (circuit->state) : STATE2STR (C_STATE_NA));
|
||||
|
||||
zlog_info ("CSM_STATE_CHANGE: %s -> %s ", STATE2STR (old_state),
|
||||
circuit ? STATE2STR (circuit->state) : STATE2STR (C_STATE_NA));
|
||||
|
||||
return circuit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -28,9 +28,9 @@
|
||||
* Circuit states
|
||||
*/
|
||||
#define C_STATE_NA 0
|
||||
#define C_STATE_INIT 1 /* Connected to interface */
|
||||
#define C_STATE_CONF 2 /* Configured for ISIS */
|
||||
#define C_STATE_UP 3 /* CONN | CONF */
|
||||
#define C_STATE_INIT 1 /* Connected to interface */
|
||||
#define C_STATE_CONF 2 /* Configured for ISIS */
|
||||
#define C_STATE_UP 3 /* CONN | CONF */
|
||||
|
||||
/*
|
||||
* Circuit events
|
||||
@ -40,8 +40,8 @@
|
||||
#define ISIS_DISABLE 3
|
||||
#define IF_DOWN_FROM_Z 4
|
||||
|
||||
struct isis_circuit *isis_csm_state_change (int event,
|
||||
struct isis_circuit *circuit,
|
||||
void *arg);
|
||||
struct isis_circuit *isis_csm_state_change (int event,
|
||||
struct isis_circuit *circuit,
|
||||
void *arg);
|
||||
|
||||
#endif /* _ZEBRA_ISIS_CSM_H */
|
||||
|
||||
394
isisd/isis_dr.c
394
isisd/isis_dr.c
@ -51,37 +51,37 @@ extern struct isis *isis;
|
||||
extern struct thread_master *master;
|
||||
|
||||
char *
|
||||
isis_disflag2string (int disflag) {
|
||||
isis_disflag2string (int disflag)
|
||||
{
|
||||
|
||||
switch (disflag) {
|
||||
switch (disflag)
|
||||
{
|
||||
case ISIS_IS_NOT_DIS:
|
||||
return "is not DIS";
|
||||
case ISIS_IS_DIS:
|
||||
return "is DIS";
|
||||
case ISIS_WAS_DIS:
|
||||
return "was DIS";
|
||||
default:
|
||||
return "unknown DIS state";
|
||||
}
|
||||
return NULL; /* not reached */
|
||||
default:
|
||||
return "unknown DIS state";
|
||||
}
|
||||
return NULL; /* not reached */
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
isis_run_dr_l1 (struct thread *thread)
|
||||
{
|
||||
struct isis_circuit *circuit;
|
||||
|
||||
|
||||
circuit = THREAD_ARG (thread);
|
||||
assert (circuit);
|
||||
|
||||
if (circuit->u.bc.run_dr_elect[0])
|
||||
zlog_warn ("isis_run_dr(): run_dr_elect already set for l1");
|
||||
|
||||
|
||||
circuit->u.bc.t_run_dr[0] = NULL;
|
||||
circuit->u.bc.run_dr_elect[0] = 1;
|
||||
|
||||
|
||||
return ISIS_OK;
|
||||
}
|
||||
|
||||
@ -89,17 +89,17 @@ int
|
||||
isis_run_dr_l2 (struct thread *thread)
|
||||
{
|
||||
struct isis_circuit *circuit;
|
||||
|
||||
|
||||
circuit = THREAD_ARG (thread);
|
||||
assert (circuit);
|
||||
|
||||
if (circuit->u.bc.run_dr_elect[1])
|
||||
zlog_warn ("isis_run_dr(): run_dr_elect already set for l2");
|
||||
|
||||
|
||||
circuit->u.bc.t_run_dr[1] = NULL;
|
||||
|
||||
|
||||
circuit->u.bc.t_run_dr[1] = NULL;
|
||||
circuit->u.bc.run_dr_elect[1] = 1;
|
||||
|
||||
|
||||
return ISIS_OK;
|
||||
}
|
||||
|
||||
@ -108,24 +108,25 @@ isis_check_dr_change (struct isis_adjacency *adj, int level)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( adj->dis_record[level-1].dis !=
|
||||
adj->dis_record[(1*ISIS_LEVELS) + level - 1].dis)
|
||||
/* was there a DIS state transition ? */
|
||||
if (adj->dis_record[level - 1].dis !=
|
||||
adj->dis_record[(1 * ISIS_LEVELS) + level - 1].dis)
|
||||
/* was there a DIS state transition ? */
|
||||
{
|
||||
adj->dischanges[level-1]++;
|
||||
adj->dischanges[level - 1]++;
|
||||
/* ok rotate the history list through */
|
||||
for (i = DIS_RECORDS - 1; i > 0; i--)
|
||||
for (i = DIS_RECORDS - 1; i > 0; i--)
|
||||
{
|
||||
adj->dis_record[(i * ISIS_LEVELS) + level - 1].dis =
|
||||
adj->dis_record[((i-1) * ISIS_LEVELS) + level - 1].dis;
|
||||
adj->dis_record[(i * ISIS_LEVELS) + level - 1].last_dis_change =
|
||||
adj->dis_record[((i-1) * ISIS_LEVELS) + level - 1].last_dis_change;
|
||||
adj->dis_record[(i * ISIS_LEVELS) + level - 1].dis =
|
||||
adj->dis_record[((i - 1) * ISIS_LEVELS) + level - 1].dis;
|
||||
adj->dis_record[(i * ISIS_LEVELS) + level - 1].last_dis_change =
|
||||
adj->dis_record[((i - 1) * ISIS_LEVELS) + level -
|
||||
1].last_dis_change;
|
||||
}
|
||||
}
|
||||
return ISIS_OK;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
isis_dr_elect (struct isis_circuit *circuit, int level)
|
||||
{
|
||||
struct list *adjdb;
|
||||
@ -135,213 +136,242 @@ isis_dr_elect (struct isis_circuit *circuit, int level)
|
||||
u_char own_prio;
|
||||
int biggest_prio = -1;
|
||||
int cmp_res, retval = ISIS_OK;
|
||||
|
||||
|
||||
own_prio = circuit->u.bc.priority[level - 1];
|
||||
adjdb = circuit->u.bc.adjdb[level - 1];
|
||||
|
||||
if (!adjdb) {
|
||||
zlog_warn ("isis_dr_elect() adjdb == NULL");
|
||||
retval = ISIS_WARNING;
|
||||
list_delete (list);
|
||||
goto out;
|
||||
}
|
||||
if (!adjdb)
|
||||
{
|
||||
zlog_warn ("isis_dr_elect() adjdb == NULL");
|
||||
retval = ISIS_WARNING;
|
||||
list_delete (list);
|
||||
goto out;
|
||||
}
|
||||
isis_adj_build_up_list (adjdb, list);
|
||||
|
||||
/*
|
||||
* Loop the adjacencies and find the one with the biggest priority
|
||||
*/
|
||||
for (node = listhead (list); node; nextnode (node)) {
|
||||
adj = getdata (node);
|
||||
/* clear flag for show output */
|
||||
adj->dis_record[level-1].dis = ISIS_IS_NOT_DIS;
|
||||
adj->dis_record[level-1].last_dis_change = time (NULL);
|
||||
for (node = listhead (list); node; nextnode (node))
|
||||
{
|
||||
adj = getdata (node);
|
||||
/* clear flag for show output */
|
||||
adj->dis_record[level - 1].dis = ISIS_IS_NOT_DIS;
|
||||
adj->dis_record[level - 1].last_dis_change = time (NULL);
|
||||
|
||||
if (adj->prio[level-1] > biggest_prio) {
|
||||
biggest_prio = adj->prio[level-1];
|
||||
adj_dr = adj;
|
||||
} else if (adj->prio[level-1] == biggest_prio) {
|
||||
/*
|
||||
* Comparison of MACs breaks a tie
|
||||
*/
|
||||
if (adj_dr) {
|
||||
cmp_res = memcmp (adj_dr->snpa, adj->snpa, ETH_ALEN);
|
||||
if (cmp_res < 0) {
|
||||
adj_dr = adj;
|
||||
if (adj->prio[level - 1] > biggest_prio)
|
||||
{
|
||||
biggest_prio = adj->prio[level - 1];
|
||||
adj_dr = adj;
|
||||
}
|
||||
else if (adj->prio[level - 1] == biggest_prio)
|
||||
{
|
||||
/*
|
||||
* Comparison of MACs breaks a tie
|
||||
*/
|
||||
if (adj_dr)
|
||||
{
|
||||
cmp_res = memcmp (adj_dr->snpa, adj->snpa, ETH_ALEN);
|
||||
if (cmp_res < 0)
|
||||
{
|
||||
adj_dr = adj;
|
||||
}
|
||||
if (cmp_res == 0)
|
||||
zlog_warn
|
||||
("isis_dr_elect(): multiple adjacencies with same SNPA");
|
||||
}
|
||||
else
|
||||
{
|
||||
adj_dr = adj;
|
||||
}
|
||||
}
|
||||
if (cmp_res == 0)
|
||||
zlog_warn ("isis_dr_elect(): multiple adjacencies with same SNPA");
|
||||
} else {
|
||||
adj_dr = adj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!adj_dr) {
|
||||
/*
|
||||
* Could not find the DR - means we are alone and thus the DR
|
||||
*/
|
||||
if ( !circuit->u.bc.is_dr[level - 1]) {
|
||||
list_delete (list);
|
||||
list = NULL;
|
||||
return isis_dr_commence (circuit, level);
|
||||
|
||||
if (!adj_dr)
|
||||
{
|
||||
/*
|
||||
* Could not find the DR - means we are alone and thus the DR
|
||||
*/
|
||||
if (!circuit->u.bc.is_dr[level - 1])
|
||||
{
|
||||
list_delete (list);
|
||||
list = NULL;
|
||||
return isis_dr_commence (circuit, level);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we have the DR adjacency, compare it to self
|
||||
*/
|
||||
if (adj_dr->prio[level-1] < own_prio || (adj_dr->prio[level-1] == own_prio &&
|
||||
memcmp (adj_dr->snpa, circuit->u.bc.snpa,
|
||||
ETH_ALEN) < 0)) {
|
||||
if (!circuit->u.bc.is_dr[level - 1]) {
|
||||
/*
|
||||
* We are the DR -> commence
|
||||
if (adj_dr->prio[level - 1] < own_prio
|
||||
|| (adj_dr->prio[level - 1] == own_prio
|
||||
&& memcmp (adj_dr->snpa, circuit->u.bc.snpa, ETH_ALEN) < 0))
|
||||
{
|
||||
if (!circuit->u.bc.is_dr[level - 1])
|
||||
{
|
||||
/*
|
||||
* We are the DR -> commence
|
||||
*/
|
||||
list_delete (list);
|
||||
return isis_dr_commence (circuit, level);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* ok we have found the DIS - lets mark the adjacency */
|
||||
/* set flag for show output */
|
||||
adj_dr->dis_record[level - 1].dis = ISIS_IS_DIS;
|
||||
adj_dr->dis_record[level - 1].last_dis_change = time (NULL);
|
||||
|
||||
/* now loop through a second time to check if there has been a DIS change
|
||||
* if yes rotate the history log
|
||||
*/
|
||||
list_delete (list);
|
||||
return isis_dr_commence (circuit, level);
|
||||
|
||||
for (node = listhead (list); node; nextnode (node))
|
||||
{
|
||||
adj = getdata (node);
|
||||
isis_check_dr_change (adj, level);
|
||||
}
|
||||
|
||||
/*
|
||||
* We are not DR - if we were -> resign
|
||||
*/
|
||||
|
||||
if (circuit->u.bc.is_dr[level - 1])
|
||||
{
|
||||
list_delete (list);
|
||||
return isis_dr_resign (circuit, level);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
/* ok we have found the DIS - lets mark the adjacency */
|
||||
/* set flag for show output */
|
||||
adj_dr->dis_record[level - 1].dis = ISIS_IS_DIS;
|
||||
adj_dr->dis_record[level - 1].last_dis_change = time(NULL);
|
||||
|
||||
/* now loop through a second time to check if there has been a DIS change
|
||||
* if yes rotate the history log
|
||||
*/
|
||||
|
||||
for (node = listhead (list); node; nextnode (node)) {
|
||||
adj = getdata (node);
|
||||
isis_check_dr_change(adj, level);
|
||||
}
|
||||
|
||||
/*
|
||||
* We are not DR - if we were -> resign
|
||||
*/
|
||||
|
||||
if (circuit->u.bc.is_dr[level - 1]) {
|
||||
list_delete (list);
|
||||
return isis_dr_resign (circuit, level);
|
||||
}
|
||||
}
|
||||
out:
|
||||
out:
|
||||
if (list)
|
||||
list_delete (list);
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
isis_dr_resign (struct isis_circuit *circuit, int level)
|
||||
{
|
||||
u_char id[ISIS_SYS_ID_LEN + 2];
|
||||
|
||||
|
||||
zlog_info ("isis_dr_resign l%d", level);
|
||||
|
||||
circuit->u.bc.is_dr[level - 1] = 0;
|
||||
circuit->u.bc.run_dr_elect[level - 1] = 0;
|
||||
THREAD_TIMER_OFF(circuit->u.bc.t_run_dr[level - 1]);
|
||||
THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
|
||||
|
||||
circuit->u.bc.run_dr_elect[level - 1] = 0;
|
||||
THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[level - 1]);
|
||||
THREAD_TIMER_OFF (circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
|
||||
|
||||
memcpy (id, isis->sysid, ISIS_SYS_ID_LEN);
|
||||
LSP_PSEUDO_ID(id) = circuit->circuit_id;
|
||||
LSP_FRAGMENT(id) = 0;
|
||||
LSP_PSEUDO_ID (id) = circuit->circuit_id;
|
||||
LSP_FRAGMENT (id) = 0;
|
||||
lsp_purge_dr (id, circuit, level);
|
||||
|
||||
if (level == 1) {
|
||||
memset (circuit->u.bc.l1_desig_is, 0, ISIS_SYS_ID_LEN + 1);
|
||||
|
||||
THREAD_TIMER_OFF(circuit->t_send_csnp[0]);
|
||||
|
||||
THREAD_TIMER_ON(master, circuit->u.bc.t_run_dr[0], isis_run_dr_l1,
|
||||
circuit, 2 * circuit->hello_interval[1]);
|
||||
|
||||
THREAD_TIMER_ON(master, circuit->t_send_psnp[0], send_l1_psnp, circuit,
|
||||
isis_jitter (circuit->psnp_interval[level - 1], PSNP_JITTER));
|
||||
} else {
|
||||
memset (circuit->u.bc.l2_desig_is, 0, ISIS_SYS_ID_LEN + 1);
|
||||
if (level == 1)
|
||||
{
|
||||
memset (circuit->u.bc.l1_desig_is, 0, ISIS_SYS_ID_LEN + 1);
|
||||
|
||||
THREAD_TIMER_OFF(circuit->t_send_csnp[1]);
|
||||
THREAD_TIMER_OFF (circuit->t_send_csnp[0]);
|
||||
|
||||
THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[0], isis_run_dr_l1,
|
||||
circuit, 2 * circuit->hello_interval[1]);
|
||||
|
||||
THREAD_TIMER_ON (master, circuit->t_send_psnp[0], send_l1_psnp, circuit,
|
||||
isis_jitter (circuit->psnp_interval[level - 1],
|
||||
PSNP_JITTER));
|
||||
}
|
||||
else
|
||||
{
|
||||
memset (circuit->u.bc.l2_desig_is, 0, ISIS_SYS_ID_LEN + 1);
|
||||
|
||||
THREAD_TIMER_OFF (circuit->t_send_csnp[1]);
|
||||
|
||||
THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[1], isis_run_dr_l2,
|
||||
circuit, 2 * circuit->hello_interval[1]);
|
||||
|
||||
THREAD_TIMER_ON (master, circuit->t_send_psnp[1], send_l2_psnp, circuit,
|
||||
isis_jitter (circuit->psnp_interval[level - 1],
|
||||
PSNP_JITTER));
|
||||
}
|
||||
|
||||
THREAD_TIMER_ON(master, circuit->u.bc.t_run_dr[1], isis_run_dr_l2,
|
||||
circuit, 2 * circuit->hello_interval[1]);
|
||||
|
||||
THREAD_TIMER_ON(master, circuit->t_send_psnp[1], send_l2_psnp, circuit,
|
||||
isis_jitter (circuit->psnp_interval[level - 1], PSNP_JITTER));
|
||||
}
|
||||
|
||||
thread_add_event (master, isis_event_dis_status_change, circuit, 0);
|
||||
|
||||
return ISIS_OK;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
isis_dr_commence (struct isis_circuit *circuit, int level)
|
||||
{
|
||||
u_char old_dr[ISIS_SYS_ID_LEN + 2];
|
||||
|
||||
|
||||
zlog_info ("isis_dr_commence l%d", level);
|
||||
|
||||
/* Lets keep a pause in DR election */
|
||||
circuit->u.bc.run_dr_elect[level - 1] = 0;
|
||||
if (level == 1)
|
||||
THREAD_TIMER_ON(master, circuit->u.bc.t_run_dr[0], isis_run_dr_l1,
|
||||
circuit, 2 * circuit->hello_multiplier[0] *
|
||||
circuit->hello_interval[0]);
|
||||
else
|
||||
THREAD_TIMER_ON(master, circuit->u.bc.t_run_dr[1], isis_run_dr_l2,
|
||||
circuit, 2 * circuit->hello_multiplier[1] *
|
||||
circuit->hello_interval[1]);
|
||||
if (level == 1)
|
||||
THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[0], isis_run_dr_l1,
|
||||
circuit, 2 * circuit->hello_multiplier[0] *
|
||||
circuit->hello_interval[0]);
|
||||
else
|
||||
THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[1], isis_run_dr_l2,
|
||||
circuit, 2 * circuit->hello_multiplier[1] *
|
||||
circuit->hello_interval[1]);
|
||||
circuit->u.bc.is_dr[level - 1] = 1;
|
||||
|
||||
if (level == 1) {
|
||||
memcpy (old_dr, circuit->u.bc.l1_desig_is, ISIS_SYS_ID_LEN + 1);
|
||||
LSP_FRAGMENT (old_dr) = 0;
|
||||
if (LSP_PSEUDO_ID(old_dr)) {
|
||||
/* there was a dr elected, purge its LSPs from the db */
|
||||
lsp_purge_dr (old_dr, circuit, level);
|
||||
}
|
||||
memcpy (circuit->u.bc.l1_desig_is, isis->sysid, ISIS_SYS_ID_LEN);
|
||||
*(circuit->u.bc.l1_desig_is + ISIS_SYS_ID_LEN) = circuit->circuit_id;
|
||||
|
||||
assert (circuit->circuit_id); /* must be non-zero */
|
||||
/* if (circuit->t_send_l1_psnp)
|
||||
thread_cancel (circuit->t_send_l1_psnp); */
|
||||
lsp_l1_pseudo_generate (circuit);
|
||||
if (level == 1)
|
||||
{
|
||||
memcpy (old_dr, circuit->u.bc.l1_desig_is, ISIS_SYS_ID_LEN + 1);
|
||||
LSP_FRAGMENT (old_dr) = 0;
|
||||
if (LSP_PSEUDO_ID (old_dr))
|
||||
{
|
||||
/* there was a dr elected, purge its LSPs from the db */
|
||||
lsp_purge_dr (old_dr, circuit, level);
|
||||
}
|
||||
memcpy (circuit->u.bc.l1_desig_is, isis->sysid, ISIS_SYS_ID_LEN);
|
||||
*(circuit->u.bc.l1_desig_is + ISIS_SYS_ID_LEN) = circuit->circuit_id;
|
||||
|
||||
THREAD_TIMER_OFF(circuit->u.bc.t_run_dr[0]);
|
||||
THREAD_TIMER_ON(master, circuit->u.bc.t_run_dr[0], isis_run_dr_l1,
|
||||
circuit, 2 * circuit->hello_interval[0]);
|
||||
|
||||
THREAD_TIMER_ON(master, circuit->t_send_csnp[0], send_l1_csnp, circuit,
|
||||
isis_jitter(circuit->csnp_interval[level-1], CSNP_JITTER));
|
||||
|
||||
} else {
|
||||
memcpy (old_dr, circuit->u.bc.l2_desig_is, ISIS_SYS_ID_LEN + 1);
|
||||
LSP_FRAGMENT (old_dr) = 0;
|
||||
if (LSP_PSEUDO_ID(old_dr)) {
|
||||
/* there was a dr elected, purge its LSPs from the db */
|
||||
lsp_purge_dr (old_dr, circuit, level);
|
||||
}
|
||||
memcpy (circuit->u.bc.l2_desig_is, isis->sysid, ISIS_SYS_ID_LEN);
|
||||
*(circuit->u.bc.l2_desig_is + ISIS_SYS_ID_LEN) = circuit->circuit_id;
|
||||
|
||||
assert (circuit->circuit_id); /* must be non-zero */
|
||||
/* if (circuit->t_send_l1_psnp)
|
||||
thread_cancel (circuit->t_send_l1_psnp); */
|
||||
lsp_l2_pseudo_generate (circuit);
|
||||
assert (circuit->circuit_id); /* must be non-zero */
|
||||
/* if (circuit->t_send_l1_psnp)
|
||||
thread_cancel (circuit->t_send_l1_psnp); */
|
||||
lsp_l1_pseudo_generate (circuit);
|
||||
|
||||
THREAD_TIMER_OFF(circuit->u.bc.t_run_dr[1]);
|
||||
THREAD_TIMER_ON(master, circuit->u.bc.t_run_dr[1], isis_run_dr_l2,
|
||||
circuit, 2 * circuit->hello_interval[1]);
|
||||
|
||||
THREAD_TIMER_ON(master, circuit->t_send_csnp[1], send_l2_csnp, circuit,
|
||||
isis_jitter (circuit->csnp_interval[level-1], CSNP_JITTER));
|
||||
}
|
||||
THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[0]);
|
||||
THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[0], isis_run_dr_l1,
|
||||
circuit, 2 * circuit->hello_interval[0]);
|
||||
|
||||
THREAD_TIMER_ON (master, circuit->t_send_csnp[0], send_l1_csnp, circuit,
|
||||
isis_jitter (circuit->csnp_interval[level - 1],
|
||||
CSNP_JITTER));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (old_dr, circuit->u.bc.l2_desig_is, ISIS_SYS_ID_LEN + 1);
|
||||
LSP_FRAGMENT (old_dr) = 0;
|
||||
if (LSP_PSEUDO_ID (old_dr))
|
||||
{
|
||||
/* there was a dr elected, purge its LSPs from the db */
|
||||
lsp_purge_dr (old_dr, circuit, level);
|
||||
}
|
||||
memcpy (circuit->u.bc.l2_desig_is, isis->sysid, ISIS_SYS_ID_LEN);
|
||||
*(circuit->u.bc.l2_desig_is + ISIS_SYS_ID_LEN) = circuit->circuit_id;
|
||||
|
||||
assert (circuit->circuit_id); /* must be non-zero */
|
||||
/* if (circuit->t_send_l1_psnp)
|
||||
thread_cancel (circuit->t_send_l1_psnp); */
|
||||
lsp_l2_pseudo_generate (circuit);
|
||||
|
||||
THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[1]);
|
||||
THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[1], isis_run_dr_l2,
|
||||
circuit, 2 * circuit->hello_interval[1]);
|
||||
|
||||
THREAD_TIMER_ON (master, circuit->t_send_csnp[1], send_l2_csnp, circuit,
|
||||
isis_jitter (circuit->csnp_interval[level - 1],
|
||||
CSNP_JITTER));
|
||||
}
|
||||
|
||||
thread_add_event (master, isis_event_dis_status_change, circuit, 0);
|
||||
|
||||
|
||||
return ISIS_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -31,7 +31,8 @@ int isis_dr_resign (struct isis_circuit *circuit, int level);
|
||||
int isis_dr_commence (struct isis_circuit *circuit, int level);
|
||||
char *isis_disflag2string (int disflag);
|
||||
|
||||
enum isis_dis_state {
|
||||
enum isis_dis_state
|
||||
{
|
||||
ISIS_IS_NOT_DIS,
|
||||
ISIS_IS_DIS,
|
||||
ISIS_WAS_DIS,
|
||||
@ -39,4 +40,3 @@ enum isis_dis_state {
|
||||
};
|
||||
|
||||
#endif /* _ZEBRA_ISIS_DR_H */
|
||||
|
||||
|
||||
@ -50,48 +50,52 @@ void
|
||||
dyn_cache_init (void)
|
||||
{
|
||||
dyn_cache = list_new ();
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
struct isis_dynhn *dynhn_find_by_id (u_char * id)
|
||||
struct isis_dynhn *
|
||||
dynhn_find_by_id (u_char * id)
|
||||
{
|
||||
struct listnode *node = NULL;
|
||||
struct isis_dynhn *dyn = NULL;
|
||||
|
||||
for (node = listhead (dyn_cache); node; nextnode (node)) {
|
||||
dyn = getdata (node);
|
||||
if (memcmp (dyn->id, id, ISIS_SYS_ID_LEN) == 0)
|
||||
return dyn;
|
||||
}
|
||||
|
||||
for (node = listhead (dyn_cache); node; nextnode (node))
|
||||
{
|
||||
dyn = getdata (node);
|
||||
if (memcmp (dyn->id, id, ISIS_SYS_ID_LEN) == 0)
|
||||
return dyn;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
isis_dynhn_insert (u_char *id, struct hostname *hostname, int level)
|
||||
isis_dynhn_insert (u_char * id, struct hostname *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;
|
||||
}
|
||||
if (dyn)
|
||||
{
|
||||
memcpy (&dyn->name, hostname, hostname->namelen + 1);
|
||||
memcpy (dyn->id, id, ISIS_SYS_ID_LEN);
|
||||
dyn->refresh = time (NULL);
|
||||
return;
|
||||
}
|
||||
dyn = XMALLOC (MTYPE_ISIS_DYNHN, sizeof (struct isis_dynhn));
|
||||
if (!dyn) {
|
||||
zlog_warn ("isis_dynhn_insert(): out of memory!");
|
||||
return;
|
||||
}
|
||||
memset (dyn,0,sizeof(struct isis_dynhn));
|
||||
if (!dyn)
|
||||
{
|
||||
zlog_warn ("isis_dynhn_insert(): out of memory!");
|
||||
return;
|
||||
}
|
||||
memset (dyn, 0, sizeof (struct isis_dynhn));
|
||||
/* we also copy the length */
|
||||
memcpy (&dyn->name, hostname, hostname->namelen + 1);
|
||||
memcpy (&dyn->name, hostname, hostname->namelen + 1);
|
||||
memcpy (dyn->id, id, ISIS_SYS_ID_LEN);
|
||||
dyn->refresh = time (NULL);
|
||||
dyn->level = level;
|
||||
|
||||
|
||||
listnode_add (dyn_cache, dyn);
|
||||
|
||||
return;
|
||||
@ -103,21 +107,22 @@ isis_dynhn_insert (u_char *id, struct hostname *hostname, int level)
|
||||
* 2 0000.0000.0002 bar-gw
|
||||
* * 0000.0000.0004 this-gw
|
||||
*/
|
||||
void dynhn_print_all (struct vty *vty)
|
||||
void
|
||||
dynhn_print_all (struct vty *vty)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct isis_dynhn *dyn;
|
||||
|
||||
vty_out (vty, "Level System ID Dynamic Hostname%s", VTY_NEWLINE);
|
||||
for (node = listhead (dyn_cache); node; nextnode (node)) {
|
||||
dyn = getdata (node);
|
||||
vty_out (vty, "%-7d", dyn->level);
|
||||
vty_out (vty, "%-15s%-15s%s", sysid_print (dyn->id), dyn->name.name,
|
||||
VTY_NEWLINE);
|
||||
}
|
||||
|
||||
vty_out (vty, " * %s %s%s", sysid_print (isis->sysid), unix_hostname(),
|
||||
for (node = listhead (dyn_cache); node; nextnode (node))
|
||||
{
|
||||
dyn = getdata (node);
|
||||
vty_out (vty, "%-7d", dyn->level);
|
||||
vty_out (vty, "%-15s%-15s%s", sysid_print (dyn->id), dyn->name.name,
|
||||
VTY_NEWLINE);
|
||||
}
|
||||
|
||||
vty_out (vty, " * %s %s%s", sysid_print (isis->sysid), unix_hostname (),
|
||||
VTY_NEWLINE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -23,7 +23,8 @@
|
||||
#ifndef _ZEBRA_ISIS_DYNHN_H
|
||||
#define _ZEBRA_ISIS_DYNHN_H
|
||||
|
||||
struct isis_dynhn {
|
||||
struct isis_dynhn
|
||||
{
|
||||
u_char id[ISIS_SYS_ID_LEN];
|
||||
struct hostname name;
|
||||
time_t refresh;
|
||||
@ -31,12 +32,8 @@ struct isis_dynhn {
|
||||
};
|
||||
|
||||
void dyn_cache_init (void);
|
||||
void isis_dynhn_insert (u_char *id, struct hostname *hostname, int level);
|
||||
void isis_dynhn_insert (u_char * id, struct hostname *hostname, int level);
|
||||
struct isis_dynhn *dynhn_find_by_id (u_char * id);
|
||||
void dynhn_print_all (struct vty *vty);
|
||||
void dynhn_print_all (struct vty *vty);
|
||||
|
||||
#endif /* _ZEBRA_ISIS_DYNHN_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -64,19 +64,19 @@ extern struct isis *isis;
|
||||
4w5d: ISIS-Spf (tlt): L2 SPF needed, periodic SPF, from 0x6091C844
|
||||
*/
|
||||
|
||||
void
|
||||
void
|
||||
isis_event_circuit_state_change (struct isis_circuit *circuit, int up)
|
||||
{
|
||||
struct isis_area *area;
|
||||
|
||||
|
||||
area = circuit->area;
|
||||
assert (area);
|
||||
area->circuit_state_changes++;
|
||||
|
||||
if (isis->debugs & DEBUG_EVENTS)
|
||||
zlog_info ("ISIS-Evt (%s) circuit %s", circuit->area->area_tag,
|
||||
|
||||
if (isis->debugs & DEBUG_EVENTS)
|
||||
zlog_info ("ISIS-Evt (%s) circuit %s", circuit->area->area_tag,
|
||||
up ? "up" : "down");
|
||||
|
||||
|
||||
/*
|
||||
* Regenerate LSPs this affects
|
||||
*/
|
||||
@ -85,47 +85,51 @@ isis_event_circuit_state_change (struct isis_circuit *circuit, int up)
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
isis_event_system_type_change (struct isis_area *area, int newtype)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct isis_circuit *circuit;
|
||||
|
||||
if (isis->debugs & DEBUG_EVENTS)
|
||||
zlog_info ("ISIS-Evt (%s) system type change %s -> %s", area->area_tag,
|
||||
if (isis->debugs & DEBUG_EVENTS)
|
||||
zlog_info ("ISIS-Evt (%s) system type change %s -> %s", area->area_tag,
|
||||
circuit_t2string (area->is_type), circuit_t2string (newtype));
|
||||
|
||||
|
||||
if (area->is_type == newtype)
|
||||
return; /* No change */
|
||||
|
||||
switch (area->is_type) {
|
||||
case IS_LEVEL_1:
|
||||
if (area->lspdb[1] == NULL)
|
||||
area->lspdb[1] = lsp_db_init ();
|
||||
lsp_l2_generate (area);
|
||||
break;
|
||||
case IS_LEVEL_1_AND_2:
|
||||
if (newtype == IS_LEVEL_1) {
|
||||
lsp_db_destroy (area->lspdb[1]);
|
||||
}
|
||||
else {
|
||||
lsp_db_destroy (area->lspdb[0]);
|
||||
}
|
||||
break;
|
||||
case IS_LEVEL_2:
|
||||
if (area->lspdb[0] == NULL)
|
||||
area->lspdb[0] = lsp_db_init ();
|
||||
lsp_l1_generate (area);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return; /* No change */
|
||||
|
||||
switch (area->is_type)
|
||||
{
|
||||
case IS_LEVEL_1:
|
||||
if (area->lspdb[1] == NULL)
|
||||
area->lspdb[1] = lsp_db_init ();
|
||||
lsp_l2_generate (area);
|
||||
break;
|
||||
case IS_LEVEL_1_AND_2:
|
||||
if (newtype == IS_LEVEL_1)
|
||||
{
|
||||
lsp_db_destroy (area->lspdb[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
lsp_db_destroy (area->lspdb[0]);
|
||||
}
|
||||
break;
|
||||
case IS_LEVEL_2:
|
||||
if (area->lspdb[0] == NULL)
|
||||
area->lspdb[0] = lsp_db_init ();
|
||||
lsp_l1_generate (area);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
area->is_type = newtype;
|
||||
for (node = listhead (area->circuit_list); node; nextnode (node)) {
|
||||
circuit = getdata (node);
|
||||
isis_event_circuit_type_change (circuit, newtype);
|
||||
}
|
||||
for (node = listhead (area->circuit_list); node; nextnode (node))
|
||||
{
|
||||
circuit = getdata (node);
|
||||
isis_event_circuit_type_change (circuit, newtype);
|
||||
}
|
||||
|
||||
spftree_area_init (area);
|
||||
lsp_regenerate_schedule (area);
|
||||
@ -133,9 +137,7 @@ isis_event_system_type_change (struct isis_area *area, int newtype)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
void
|
||||
isis_event_area_addr_change (struct isis_area *area)
|
||||
{
|
||||
|
||||
@ -146,40 +148,49 @@ circuit_commence_level (struct isis_circuit *circuit, int level)
|
||||
{
|
||||
uint32_t interval;
|
||||
|
||||
if (level == 1) {
|
||||
THREAD_TIMER_ON(master, circuit->t_send_psnp[0], send_l1_psnp, circuit,
|
||||
isis_jitter(circuit->psnp_interval[0], PSNP_JITTER));
|
||||
if (level == 1)
|
||||
{
|
||||
THREAD_TIMER_ON (master, circuit->t_send_psnp[0], send_l1_psnp, circuit,
|
||||
isis_jitter (circuit->psnp_interval[0], PSNP_JITTER));
|
||||
|
||||
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
|
||||
interval = circuit->hello_multiplier[0] * (circuit->hello_interval[0]);
|
||||
|
||||
THREAD_TIMER_ON(master, circuit->u.bc.t_run_dr[0], isis_run_dr_l1,
|
||||
circuit, interval);
|
||||
|
||||
THREAD_TIMER_ON(master, circuit->u.bc.t_send_lan_hello[0],
|
||||
send_lan_l1_hello, circuit,
|
||||
isis_jitter(circuit->hello_interval[0], IIH_JITTER));
|
||||
|
||||
circuit->u.bc.lan_neighs[0] = list_new ();
|
||||
}
|
||||
} else {
|
||||
THREAD_TIMER_ON(master, circuit->t_send_psnp[1], send_l2_psnp, circuit,
|
||||
isis_jitter(circuit->psnp_interval[1], PSNP_JITTER));
|
||||
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
|
||||
{
|
||||
interval =
|
||||
circuit->hello_multiplier[0] * (circuit->hello_interval[0]);
|
||||
|
||||
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
|
||||
interval = circuit->hello_multiplier[1] * (circuit->hello_interval[1]);
|
||||
|
||||
THREAD_TIMER_ON(master, circuit->u.bc.t_run_dr[1], isis_run_dr_l2,
|
||||
circuit, interval);
|
||||
|
||||
THREAD_TIMER_ON(master, circuit->u.bc.t_send_lan_hello[1],
|
||||
send_lan_l2_hello, circuit,
|
||||
isis_jitter(circuit->hello_interval[1], IIH_JITTER));
|
||||
|
||||
circuit->u.bc.lan_neighs[1] = list_new ();
|
||||
THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[0], isis_run_dr_l1,
|
||||
circuit, interval);
|
||||
|
||||
THREAD_TIMER_ON (master, circuit->u.bc.t_send_lan_hello[0],
|
||||
send_lan_l1_hello, circuit,
|
||||
isis_jitter (circuit->hello_interval[0],
|
||||
IIH_JITTER));
|
||||
|
||||
circuit->u.bc.lan_neighs[0] = list_new ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
THREAD_TIMER_ON (master, circuit->t_send_psnp[1], send_l2_psnp, circuit,
|
||||
isis_jitter (circuit->psnp_interval[1], PSNP_JITTER));
|
||||
|
||||
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
|
||||
{
|
||||
interval =
|
||||
circuit->hello_multiplier[1] * (circuit->hello_interval[1]);
|
||||
|
||||
THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[1], isis_run_dr_l2,
|
||||
circuit, interval);
|
||||
|
||||
THREAD_TIMER_ON (master, circuit->u.bc.t_send_lan_hello[1],
|
||||
send_lan_l2_hello, circuit,
|
||||
isis_jitter (circuit->hello_interval[1],
|
||||
IIH_JITTER));
|
||||
|
||||
circuit->u.bc.lan_neighs[1] = list_new ();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -187,61 +198,64 @@ void
|
||||
circuit_resign_level (struct isis_circuit *circuit, int level)
|
||||
{
|
||||
int idx = level - 1;
|
||||
|
||||
THREAD_TIMER_OFF(circuit->t_send_csnp[idx]);
|
||||
THREAD_TIMER_OFF(circuit->t_send_psnp[idx]);
|
||||
|
||||
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
|
||||
THREAD_TIMER_OFF(circuit->u.bc.t_send_lan_hello[idx]);
|
||||
THREAD_TIMER_OFF(circuit->u.bc.t_run_dr[idx]);
|
||||
circuit->u.bc.run_dr_elect[idx] = 0;
|
||||
}
|
||||
|
||||
THREAD_TIMER_OFF (circuit->t_send_csnp[idx]);
|
||||
THREAD_TIMER_OFF (circuit->t_send_psnp[idx]);
|
||||
|
||||
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
|
||||
{
|
||||
THREAD_TIMER_OFF (circuit->u.bc.t_send_lan_hello[idx]);
|
||||
THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[idx]);
|
||||
circuit->u.bc.run_dr_elect[idx] = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
isis_event_circuit_type_change (struct isis_circuit *circuit, int newtype)
|
||||
void
|
||||
isis_event_circuit_type_change (struct isis_circuit *circuit, int newtype)
|
||||
{
|
||||
|
||||
if (isis->debugs & DEBUG_EVENTS)
|
||||
zlog_info ("ISIS-Evt (%s) circuit type change %s -> %s",
|
||||
circuit->area->area_tag,
|
||||
circuit_t2string (circuit->circuit_is_type),
|
||||
|
||||
if (isis->debugs & DEBUG_EVENTS)
|
||||
zlog_info ("ISIS-Evt (%s) circuit type change %s -> %s",
|
||||
circuit->area->area_tag,
|
||||
circuit_t2string (circuit->circuit_is_type),
|
||||
circuit_t2string (newtype));
|
||||
|
||||
if (circuit->circuit_is_type == newtype)
|
||||
return; /* No change */
|
||||
return; /* No change */
|
||||
|
||||
if (!(newtype & circuit->area->is_type))
|
||||
{
|
||||
zlog_err ("ISIS-Evt (%s) circuit type change - invalid level %s because"
|
||||
" area is %s", circuit->area->area_tag,
|
||||
circuit_t2string (newtype),
|
||||
circuit_t2string (circuit->area->is_type));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (circuit->circuit_is_type)
|
||||
{
|
||||
case IS_LEVEL_1:
|
||||
if (newtype == IS_LEVEL_2)
|
||||
circuit_resign_level (circuit, 1);
|
||||
circuit_commence_level (circuit, 2);
|
||||
break;
|
||||
case IS_LEVEL_1_AND_2:
|
||||
if (newtype == IS_LEVEL_1)
|
||||
circuit_resign_level (circuit, 2);
|
||||
else
|
||||
circuit_resign_level (circuit, 1);
|
||||
break;
|
||||
case IS_LEVEL_2:
|
||||
if (newtype == IS_LEVEL_1)
|
||||
circuit_resign_level (circuit, 2);
|
||||
circuit_commence_level (circuit, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(newtype & circuit->area->is_type)) {
|
||||
zlog_err ("ISIS-Evt (%s) circuit type change - invalid level %s because"
|
||||
" area is %s", circuit->area->area_tag,
|
||||
circuit_t2string (newtype),
|
||||
circuit_t2string (circuit->area->is_type));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (circuit->circuit_is_type) {
|
||||
case IS_LEVEL_1:
|
||||
if (newtype == IS_LEVEL_2)
|
||||
circuit_resign_level (circuit, 1);
|
||||
circuit_commence_level (circuit, 2);
|
||||
break;
|
||||
case IS_LEVEL_1_AND_2:
|
||||
if (newtype == IS_LEVEL_1)
|
||||
circuit_resign_level (circuit, 2);
|
||||
else
|
||||
circuit_resign_level (circuit, 1);
|
||||
break;
|
||||
case IS_LEVEL_2:
|
||||
if (newtype == IS_LEVEL_1)
|
||||
circuit_resign_level (circuit, 2);
|
||||
circuit_commence_level (circuit, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
circuit->circuit_is_type = newtype;
|
||||
lsp_regenerate_schedule (circuit->area);
|
||||
|
||||
@ -270,18 +284,19 @@ isis_event_circuit_type_change (struct isis_circuit *circuit, int newtype)
|
||||
*
|
||||
* ***********************************************************************/
|
||||
|
||||
void
|
||||
void
|
||||
isis_event_adjacency_state_change (struct isis_adjacency *adj, int newstate)
|
||||
{
|
||||
/* adjacency state change event.
|
||||
* - the only proto-type was supported */
|
||||
|
||||
/* invalid arguments */
|
||||
if ( !adj || !adj->circuit || !adj->circuit->area ) return;
|
||||
|
||||
zlog_info ("ISIS-Evt (%s) Adjacency State change",
|
||||
adj->circuit->area->area_tag );
|
||||
|
||||
|
||||
/* invalid arguments */
|
||||
if (!adj || !adj->circuit || !adj->circuit->area)
|
||||
return;
|
||||
|
||||
zlog_info ("ISIS-Evt (%s) Adjacency State change",
|
||||
adj->circuit->area->area_tag);
|
||||
|
||||
/* LSP generation again */
|
||||
lsp_regenerate_schedule (adj->circuit->area);
|
||||
|
||||
@ -294,27 +309,26 @@ int
|
||||
isis_event_dis_status_change (struct thread *thread)
|
||||
{
|
||||
struct isis_circuit *circuit;
|
||||
|
||||
|
||||
circuit = THREAD_ARG (thread);
|
||||
|
||||
|
||||
/* invalid arguments */
|
||||
if (!circuit || !circuit->area) return 0;
|
||||
|
||||
if (!circuit || !circuit->area)
|
||||
return 0;
|
||||
|
||||
zlog_info ("ISIS-Evt (%s) DIS status change", circuit->area->area_tag);
|
||||
|
||||
/* LSP generation again */
|
||||
lsp_regenerate_schedule (circuit->area);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
isis_event_auth_failure (char *area_tag, char *error_string, char *sysid)
|
||||
void
|
||||
isis_event_auth_failure (char *area_tag, char *error_string, char *sysid)
|
||||
{
|
||||
zlog_info ("ISIS-Evt (%s) Authentication failure %s from %s",
|
||||
area_tag, error_string, sysid_print (sysid));
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -31,14 +31,15 @@ void isis_event_area_addr_change (struct isis_area *area);
|
||||
/*
|
||||
* Events related to circuit
|
||||
*/
|
||||
void isis_event_circuit_state_change (struct isis_circuit *circuit, int state);
|
||||
void isis_event_circuit_type_change (struct isis_circuit *circuit,
|
||||
int newtype);
|
||||
void isis_event_circuit_state_change (struct isis_circuit *circuit,
|
||||
int state);
|
||||
void isis_event_circuit_type_change (struct isis_circuit *circuit,
|
||||
int newtype);
|
||||
/*
|
||||
* Events related to adjacencies
|
||||
*/
|
||||
void isis_event_adjacency_state_change(struct isis_adjacency *adj,
|
||||
int newstate);
|
||||
void isis_event_adjacency_state_change (struct isis_adjacency *adj,
|
||||
int newstate);
|
||||
|
||||
int isis_event_dis_status_change (struct thread *thread);
|
||||
|
||||
@ -48,7 +49,7 @@ int isis_event_dis_status_change (struct thread *thread);
|
||||
#define AUTH_ERROR_TYPE_LSP 3
|
||||
#define AUTH_ERROR_TYPE_SNP 2
|
||||
#define AUTH_ERROR_TYPE_HELLO 1
|
||||
void isis_event_auth_failure (char *area_tag, char *error_string, char *sysid);
|
||||
void isis_event_auth_failure (char *area_tag, char *error_string,
|
||||
char *sysid);
|
||||
|
||||
#endif /* _ZEBRA_ISIS_EVENTS_H */
|
||||
|
||||
|
||||
@ -21,7 +21,6 @@
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include <zebra.h>
|
||||
#include "log.h"
|
||||
#include "linklist.h"
|
||||
@ -31,41 +30,44 @@
|
||||
#include "isisd/isis_flags.h"
|
||||
|
||||
int
|
||||
flags_get_index (struct flags *flags)
|
||||
flags_get_index (struct flags *flags)
|
||||
{
|
||||
struct listnode *node;
|
||||
int index;
|
||||
|
||||
if (flags->free_idcs == NULL || flags->free_idcs->count == 0) {
|
||||
flags->maxindex++;
|
||||
index = flags->maxindex;
|
||||
} else {
|
||||
node = listhead (flags->free_idcs);
|
||||
index = (int) getdata (node);
|
||||
listnode_delete (flags->free_idcs, (void *)index);
|
||||
}
|
||||
|
||||
if (flags->free_idcs == NULL || flags->free_idcs->count == 0)
|
||||
{
|
||||
flags->maxindex++;
|
||||
index = flags->maxindex;
|
||||
}
|
||||
else
|
||||
{
|
||||
node = listhead (flags->free_idcs);
|
||||
index = (int) getdata (node);
|
||||
listnode_delete (flags->free_idcs, (void *) index);
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
void
|
||||
flags_free_index (struct flags *flags, int index)
|
||||
void
|
||||
flags_free_index (struct flags *flags, int index)
|
||||
{
|
||||
if (flags->free_idcs == NULL) {
|
||||
flags->free_idcs = list_new ();
|
||||
}
|
||||
|
||||
listnode_add (flags->free_idcs, (void *)index);
|
||||
|
||||
if (flags->free_idcs == NULL)
|
||||
{
|
||||
flags->free_idcs = list_new ();
|
||||
}
|
||||
|
||||
listnode_add (flags->free_idcs, (void *) index);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
flags_any_set (u_int32_t *flags)
|
||||
int
|
||||
flags_any_set (u_int32_t * flags)
|
||||
{
|
||||
u_int32_t zero[ISIS_MAX_CIRCUITS];
|
||||
memset (zero, 0x00, ISIS_MAX_CIRCUITS * 4);
|
||||
|
||||
u_int32_t zero[ISIS_MAX_CIRCUITS];
|
||||
memset (zero, 0x00, ISIS_MAX_CIRCUITS*4);
|
||||
|
||||
return bcmp(flags, zero, ISIS_MAX_CIRCUITS*4);
|
||||
return bcmp (flags, zero, ISIS_MAX_CIRCUITS * 4);
|
||||
}
|
||||
|
||||
@ -26,13 +26,13 @@
|
||||
|
||||
/* The grand plan is to support 1024 circuits so we have 32*32 bit flags
|
||||
* the support will be achived using the newest drafts */
|
||||
#define ISIS_MAX_CIRCUITS 32 /* = 1024 */ /*FIXME:defined in lsp.h as well*/
|
||||
#define ISIS_MAX_CIRCUITS 32 /* = 1024 */ /*FIXME:defined in lsp.h as well */
|
||||
|
||||
struct flags *new_flags (int size);
|
||||
int flags_get_index (struct flags *flags);
|
||||
void flags_free_index (struct flags *flags, int index);
|
||||
struct flags *new_flags (int size);
|
||||
int flags_get_index (struct flags *flags);
|
||||
void flags_free_index (struct flags *flags, int index);
|
||||
|
||||
int flags_any_set (u_int32_t *flags);
|
||||
int flags_any_set (u_int32_t * flags);
|
||||
|
||||
#define ISIS_SET_FLAG(F,C) \
|
||||
F[C->idx>>5] |= (1<<(C->idx & 0x1F));
|
||||
@ -50,9 +50,3 @@ int flags_any_set (u_int32_t *flags);
|
||||
memset(FLAGS,0x00,ISIS_MAX_CIRCUITS*4);
|
||||
|
||||
#endif /* _ZEBRA_ISIS_FLAGS_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
2669
isisd/isis_lsp.c
2669
isisd/isis_lsp.c
File diff suppressed because it is too large
Load Diff
@ -26,7 +26,7 @@
|
||||
|
||||
/* The grand plan is to support 1024 circuits so we have 32*32 bit flags
|
||||
* the support will be achived using the newest drafts */
|
||||
#define ISIS_MAX_CIRCUITS 32 /* = 1024 */ /*FIXME:defined in flags.h as well*/
|
||||
#define ISIS_MAX_CIRCUITS 32 /* = 1024 - FIXME:defined in flags.h as well */
|
||||
|
||||
/* Structure for isis_lsp, this structure will only support the fixed
|
||||
* System ID (Currently 6) (atleast for now). In order to support more
|
||||
@ -34,19 +34,20 @@
|
||||
* 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 */
|
||||
union {
|
||||
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 */
|
||||
union
|
||||
{
|
||||
struct list *frags;
|
||||
struct isis_lsp *zero_lsp;
|
||||
} lspu;
|
||||
u_int32_t SRMflags[ISIS_MAX_CIRCUITS];
|
||||
u_int32_t SSNflags[ISIS_MAX_CIRCUITS];
|
||||
u_int32_t rexmit_queue[ISIS_MAX_CIRCUITS];
|
||||
int level; /* L1 or L2? */
|
||||
int purged; /* have purged this one */
|
||||
int scheduled; /* scheduled for sending */
|
||||
int level; /* L1 or L2? */
|
||||
int purged; /* have purged this one */
|
||||
int scheduled; /* scheduled for sending */
|
||||
time_t installed;
|
||||
time_t last_generated;
|
||||
time_t last_sent;
|
||||
@ -56,13 +57,13 @@ struct isis_lsp
|
||||
struct thread *t_lsp_top_ref;
|
||||
#endif
|
||||
/* used for 60 second counting when rem_lifetime is zero */
|
||||
int age_out;
|
||||
int age_out;
|
||||
struct isis_adjacency *adj;
|
||||
struct tlvs tlv_data; /* Simplifies TLV access */
|
||||
struct tlvs tlv_data; /* Simplifies TLV access */
|
||||
};
|
||||
|
||||
dict_t *lsp_db_init (void);
|
||||
void lsp_db_destroy (dict_t *lspdb);
|
||||
void lsp_db_destroy (dict_t * lspdb);
|
||||
int lsp_tick (struct thread *thread);
|
||||
|
||||
int lsp_l1_generate (struct isis_area *area);
|
||||
@ -73,31 +74,31 @@ int lsp_regenerate_schedule (struct isis_area *area);
|
||||
|
||||
int lsp_l1_pseudo_generate (struct isis_circuit *circuit);
|
||||
int lsp_l2_pseudo_generate (struct isis_circuit *circuit);
|
||||
int lsp_l1_refresh_pseudo (struct thread *thread);
|
||||
int lsp_l2_refresh_pseudo (struct thread *thread);
|
||||
int lsp_l1_refresh_pseudo (struct thread *thread);
|
||||
int lsp_l2_refresh_pseudo (struct thread *thread);
|
||||
int isis_lsp_authinfo_check (struct stream *stream, struct isis_area *area,
|
||||
int pdulen, struct isis_passwd *passwd);
|
||||
struct isis_lsp *lsp_new (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);
|
||||
void lsp_insert (struct isis_lsp *lsp, dict_t *lspdb);
|
||||
struct isis_lsp *lsp_search (u_char *id, dict_t *lspdb);
|
||||
int pdulen, struct isis_passwd *passwd);
|
||||
struct isis_lsp *lsp_new (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);
|
||||
void lsp_insert (struct isis_lsp *lsp, dict_t * lspdb);
|
||||
struct isis_lsp *lsp_search (u_char * id, dict_t * lspdb);
|
||||
|
||||
void lsp_build_list (u_char *start_id, u_char *stop_id,
|
||||
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, struct list *list,
|
||||
dict_t *lspdb);
|
||||
void lsp_build_list (u_char * start_id, u_char * stop_id,
|
||||
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, struct list *list,
|
||||
dict_t * lspdb);
|
||||
|
||||
void lsp_search_and_destroy (u_char *id, dict_t *lspdb);
|
||||
void lsp_purge_dr (u_char *id, struct isis_circuit *circuit, int level);
|
||||
void lsp_purge_non_exist (struct isis_link_state_hdr *lsp_hdr,
|
||||
struct isis_area *area);
|
||||
void lsp_search_and_destroy (u_char * id, dict_t * lspdb);
|
||||
void lsp_purge_dr (u_char * id, struct isis_circuit *circuit, int level);
|
||||
void lsp_purge_non_exist (struct isis_link_state_hdr *lsp_hdr,
|
||||
struct isis_area *area);
|
||||
|
||||
#define LSP_EQUAL 1
|
||||
#define LSP_NEWER 2
|
||||
@ -109,24 +110,24 @@ void lsp_purge_non_exist (struct isis_link_state_hdr *lsp_hdr,
|
||||
memcpy ((I), isis->sysid, ISIS_SYS_ID_LEN);\
|
||||
(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);
|
||||
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 isis_link_state_hdr *lsp_hdr,
|
||||
struct stream *stream, struct isis_area *area);
|
||||
struct stream *stream, struct isis_area *area);
|
||||
void lsp_inc_seqnum (struct isis_lsp *lsp, u_int32_t seq_num);
|
||||
int lsp_print_all (struct vty *vty, dict_t *lspdb, char detail, char dynhost);
|
||||
int lsp_print_all (struct vty *vty, dict_t * lspdb, char detail,
|
||||
char dynhost);
|
||||
char *lsp_bits2string (u_char *);
|
||||
|
||||
/* staticly assigned vars for printing purposes */
|
||||
char lsp_bits_string[200]; /* FIXME: enough ? */
|
||||
char lsp_bits_string[200]; /* FIXME: enough ? */
|
||||
|
||||
#ifdef TOPOLOGY_GENERATE
|
||||
void generate_topology_lsps (struct isis_area *area);
|
||||
void remove_topology_lsps (struct isis_area *area);
|
||||
void build_topology_lsp_data (struct isis_lsp *lsp,
|
||||
struct isis_area *area, int lsp_top_num);
|
||||
struct isis_area *area, int lsp_top_num);
|
||||
#endif /* TOPOLOGY_GENERATE */
|
||||
|
||||
#endif /* ISIS_LSP */
|
||||
|
||||
|
||||
@ -50,14 +50,12 @@
|
||||
#define ISISD_VTY_PORT 2608
|
||||
|
||||
/* isisd privileges */
|
||||
zebra_capabilities_t _caps_p [] =
|
||||
{
|
||||
zebra_capabilities_t _caps_p[] = {
|
||||
ZCAP_RAW,
|
||||
ZCAP_BIND
|
||||
};
|
||||
|
||||
struct zebra_privs_t isisd_privs =
|
||||
{
|
||||
struct zebra_privs_t isisd_privs = {
|
||||
#if defined(QUAGGA_USER)
|
||||
.user = QUAGGA_USER,
|
||||
#endif
|
||||
@ -73,17 +71,16 @@ struct zebra_privs_t isisd_privs =
|
||||
};
|
||||
|
||||
/* isisd options */
|
||||
struct option longopts[] =
|
||||
{
|
||||
{ "daemon", no_argument, NULL, 'd'},
|
||||
{ "config_file", required_argument, NULL, 'f'},
|
||||
{ "pid_file", required_argument, NULL, 'i'},
|
||||
{ "vty_addr", required_argument, NULL, 'A'},
|
||||
{ "vty_port", required_argument, NULL, 'P'},
|
||||
{ "user", required_argument, NULL, 'u'},
|
||||
{ "version", no_argument, NULL, 'v'},
|
||||
{ "help", no_argument, NULL, 'h'},
|
||||
{ 0 }
|
||||
struct option longopts[] = {
|
||||
{"daemon", no_argument, NULL, 'd'},
|
||||
{"config_file", required_argument, NULL, 'f'},
|
||||
{"pid_file", required_argument, NULL, 'i'},
|
||||
{"vty_addr", required_argument, NULL, 'A'},
|
||||
{"vty_port", required_argument, NULL, 'P'},
|
||||
{"user", required_argument, NULL, 'u'},
|
||||
{"version", no_argument, NULL, 'v'},
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{0}
|
||||
};
|
||||
|
||||
/* Configuration file and directory. */
|
||||
@ -108,7 +105,6 @@ int _argc;
|
||||
char **_argv;
|
||||
char **_envp;
|
||||
|
||||
|
||||
/* Help information display. */
|
||||
static void
|
||||
usage (int status)
|
||||
@ -116,7 +112,7 @@ usage (int status)
|
||||
if (status != 0)
|
||||
fprintf (stderr, "Try `%s --help' for more information.\n", progname);
|
||||
else
|
||||
{
|
||||
{
|
||||
printf ("Usage : %s [OPTION...]\n\n\
|
||||
Daemon which manages IS-IS routing\n\n\
|
||||
-d, --daemon Runs in daemon mode\n\
|
||||
@ -154,7 +150,7 @@ terminate (int i)
|
||||
* Signal handlers
|
||||
*/
|
||||
|
||||
void
|
||||
void
|
||||
sighup (void)
|
||||
{
|
||||
zlog_info ("SIGHUP received");
|
||||
@ -168,7 +164,7 @@ sigint (void)
|
||||
{
|
||||
zlog_info ("SIGINT received");
|
||||
terminate (0);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -187,29 +183,29 @@ sigusr1 (void)
|
||||
}
|
||||
|
||||
struct quagga_signal_t isisd_signals[] =
|
||||
{
|
||||
{
|
||||
.signal = SIGHUP,
|
||||
.handler = &sighup,
|
||||
},
|
||||
{
|
||||
{
|
||||
.signal = SIGUSR1,
|
||||
.handler = &sigusr1,
|
||||
},
|
||||
.signal = SIGHUP,
|
||||
.handler = &sighup,
|
||||
},
|
||||
{
|
||||
.signal = SIGINT,
|
||||
.handler = &sigint,
|
||||
},
|
||||
.signal = SIGUSR1,
|
||||
.handler = &sigusr1,
|
||||
},
|
||||
{
|
||||
.signal = SIGTERM,
|
||||
.handler = &sigterm,
|
||||
},
|
||||
.signal = SIGINT,
|
||||
.handler = &sigint,
|
||||
},
|
||||
{
|
||||
.signal = SIGTERM,
|
||||
.handler = &sigterm,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Main routine of isisd. Parse arguments and handle IS-IS state machine.
|
||||
*/
|
||||
int
|
||||
int
|
||||
main (int argc, char **argv, char **envp)
|
||||
{
|
||||
char *p;
|
||||
@ -222,9 +218,8 @@ main (int argc, char **argv, char **envp)
|
||||
progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
|
||||
|
||||
zlog_default = openzlog (progname, ZLOG_NOLOG, ZLOG_ISIS,
|
||||
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
|
||||
LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
|
||||
|
||||
|
||||
/* for reload */
|
||||
_argc = argc;
|
||||
_argv = argv;
|
||||
@ -234,73 +229,73 @@ main (int argc, char **argv, char **envp)
|
||||
snprintf (_progpath, sizeof (_progpath), "%s/%s", _cwd, _argv[0]);
|
||||
else
|
||||
snprintf (_progpath, sizeof (_progpath), "%s", argv[0]);
|
||||
|
||||
|
||||
/* Command line argument treatment. */
|
||||
while (1)
|
||||
while (1)
|
||||
{
|
||||
opt = getopt_long (argc, argv, "df:i:hA:p:P:u:v", longopts, 0);
|
||||
|
||||
if (opt == EOF)
|
||||
break;
|
||||
|
||||
switch (opt)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 'd':
|
||||
daemon_mode = 1;
|
||||
break;
|
||||
case 'f':
|
||||
config_file = optarg;
|
||||
break;
|
||||
case 'i':
|
||||
pid_file = optarg;
|
||||
break;
|
||||
case 'A':
|
||||
vty_addr = optarg;
|
||||
break;
|
||||
case 'P':
|
||||
/* Deal with atoi() returning 0 on failure, and isisd not
|
||||
listening on isisd port... */
|
||||
if (strcmp(optarg, "0") == 0)
|
||||
{
|
||||
vty_port = 0;
|
||||
break;
|
||||
}
|
||||
vty_port = atoi (optarg);
|
||||
vty_port = (vty_port ? vty_port : ISISD_VTY_PORT);
|
||||
if (opt == EOF)
|
||||
break;
|
||||
|
||||
switch (opt)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 'u':
|
||||
isisd_privs.user = isisd_privs.group = optarg;
|
||||
break;
|
||||
break;
|
||||
case 'v':
|
||||
printf("ISISd version %s\n", ISISD_VERSION);
|
||||
printf("Copyright (c) 2001-2002 Sampo Saaristo,"
|
||||
" Ofer Wald and Hannes Gredler\n");
|
||||
print_version ("Zebra");
|
||||
exit (0);
|
||||
break;
|
||||
case 'h':
|
||||
usage (0);
|
||||
break;
|
||||
default:
|
||||
usage (1);
|
||||
break;
|
||||
}
|
||||
case 'd':
|
||||
daemon_mode = 1;
|
||||
break;
|
||||
case 'f':
|
||||
config_file = optarg;
|
||||
break;
|
||||
case 'i':
|
||||
pid_file = optarg;
|
||||
break;
|
||||
case 'A':
|
||||
vty_addr = optarg;
|
||||
break;
|
||||
case 'P':
|
||||
/* Deal with atoi() returning 0 on failure, and isisd not
|
||||
listening on isisd port... */
|
||||
if (strcmp (optarg, "0") == 0)
|
||||
{
|
||||
vty_port = 0;
|
||||
break;
|
||||
}
|
||||
vty_port = atoi (optarg);
|
||||
vty_port = (vty_port ? vty_port : ISISD_VTY_PORT);
|
||||
break;
|
||||
case 'u':
|
||||
isisd_privs.user = isisd_privs.group = optarg;
|
||||
break;
|
||||
break;
|
||||
case 'v':
|
||||
printf ("ISISd version %s\n", ISISD_VERSION);
|
||||
printf ("Copyright (c) 2001-2002 Sampo Saaristo,"
|
||||
" Ofer Wald and Hannes Gredler\n");
|
||||
print_version ("Zebra");
|
||||
exit (0);
|
||||
break;
|
||||
case 'h':
|
||||
usage (0);
|
||||
break;
|
||||
default:
|
||||
usage (1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* thread master */
|
||||
master = thread_master_create ();
|
||||
|
||||
/* random seed from time */
|
||||
srand(time(NULL));
|
||||
srand (time (NULL));
|
||||
|
||||
/*
|
||||
* initializations
|
||||
*/
|
||||
zprivs_init (&isisd_privs);
|
||||
signal_init (master, Q_SIGC(isisd_signals), isisd_signals);
|
||||
signal_init (master, Q_SIGC (isisd_signals), isisd_signals);
|
||||
cmd_init (1);
|
||||
vty_init (master);
|
||||
memory_init ();
|
||||
@ -308,7 +303,7 @@ main (int argc, char **argv, char **envp)
|
||||
dyn_cache_init ();
|
||||
sort_node ();
|
||||
|
||||
/* parse config file */
|
||||
/* parse config file */
|
||||
/* this is needed three times! because we have interfaces before the areas */
|
||||
vty_read_config (config_file, config_default);
|
||||
vty_read_config (config_file, config_default);
|
||||
@ -323,7 +318,7 @@ main (int argc, char **argv, char **envp)
|
||||
|
||||
/* Make isis vty socket. */
|
||||
vty_serv_sock (vty_addr, vty_port, ISIS_VTYSH_PATH);
|
||||
|
||||
|
||||
/* Print banner. */
|
||||
#if defined(ZEBRA_VERSION)
|
||||
zlog_info ("ISISd %s starting: vty@%d", ZEBRA_VERSION, vty_port);
|
||||
@ -340,13 +335,3 @@ main (int argc, char **argv, char **envp)
|
||||
/* Not reached. */
|
||||
exit (0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -21,7 +21,6 @@
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
@ -50,28 +49,37 @@
|
||||
/*
|
||||
* This converts the isonet to its printable format
|
||||
*/
|
||||
char * isonet_print (u_char *from, int len) {
|
||||
char *
|
||||
isonet_print (u_char * from, int len)
|
||||
{
|
||||
int i = 0;
|
||||
char *pos = isonet;
|
||||
|
||||
if(!from)
|
||||
if (!from)
|
||||
return "unknown";
|
||||
|
||||
while (i < len) {
|
||||
if (i & 1) {
|
||||
sprintf ( pos, "%02x", *(from + i));
|
||||
pos += 2;
|
||||
} else {
|
||||
if (i == (len - 1)) { /* No dot at the end of address */
|
||||
sprintf ( pos, "%02x", *(from + i));
|
||||
pos += 2;
|
||||
} else {
|
||||
sprintf ( pos, "%02x.", *(from + i));
|
||||
pos += 3;
|
||||
}
|
||||
while (i < len)
|
||||
{
|
||||
if (i & 1)
|
||||
{
|
||||
sprintf (pos, "%02x", *(from + i));
|
||||
pos += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i == (len - 1))
|
||||
{ /* No dot at the end of address */
|
||||
sprintf (pos, "%02x", *(from + i));
|
||||
pos += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf (pos, "%02x.", *(from + i));
|
||||
pos += 3;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
*(pos) = '\0';
|
||||
return isonet;
|
||||
}
|
||||
@ -81,7 +89,7 @@ char * isonet_print (u_char *from, int len) {
|
||||
* extract dot from the dotted str, and insert all the number in a buff
|
||||
*/
|
||||
int
|
||||
dotformat2buff (u_char *buff, u_char *dotted)
|
||||
dotformat2buff (u_char * buff, u_char * dotted)
|
||||
{
|
||||
int dotlen, len = 0;
|
||||
u_char *pos = dotted;
|
||||
@ -89,80 +97,96 @@ dotformat2buff (u_char *buff, u_char *dotted)
|
||||
int nextdotpos = 2;
|
||||
|
||||
number[2] = '\0';
|
||||
dotlen = strlen(dotted);
|
||||
if (dotlen > 50) {
|
||||
/* this can't be an iso net, its too long */
|
||||
return 0;
|
||||
}
|
||||
|
||||
while ( (pos - dotted) < dotlen && len < 20 ) {
|
||||
if (*pos == '.') {
|
||||
/* we expect the . at 2, and than every 5 */
|
||||
if ((pos - dotted) != nextdotpos) {
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
nextdotpos += 5;
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
/* we must have at least two chars left here */
|
||||
if (dotlen - (pos - dotted) < 2) {
|
||||
len = 0;
|
||||
break;
|
||||
dotlen = strlen (dotted);
|
||||
if (dotlen > 50)
|
||||
{
|
||||
/* this can't be an iso net, its too long */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((isxdigit((int)*pos)) && (isxdigit((int)*(pos+1)))){
|
||||
memcpy (number, pos ,2);
|
||||
pos+=2;
|
||||
} else {
|
||||
len = 0;
|
||||
break;
|
||||
while ((pos - dotted) < dotlen && len < 20)
|
||||
{
|
||||
if (*pos == '.')
|
||||
{
|
||||
/* we expect the . at 2, and than every 5 */
|
||||
if ((pos - dotted) != nextdotpos)
|
||||
{
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
nextdotpos += 5;
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
/* we must have at least two chars left here */
|
||||
if (dotlen - (pos - dotted) < 2)
|
||||
{
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((isxdigit ((int) *pos)) && (isxdigit ((int) *(pos + 1))))
|
||||
{
|
||||
memcpy (number, pos, 2);
|
||||
pos += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
*(buff + len) = (char) strtol (number, NULL, 16);
|
||||
len++;
|
||||
}
|
||||
|
||||
*(buff + len) = (char)strtol(number, NULL, 16);
|
||||
len++;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* conversion of XXXX.XXXX.XXXX to memory
|
||||
*/
|
||||
int
|
||||
sysid2buff (u_char *buff, u_char *dotted)
|
||||
{
|
||||
sysid2buff (u_char * buff, u_char * dotted)
|
||||
{
|
||||
int len = 0;
|
||||
u_char *pos = dotted;
|
||||
u_char number[3];
|
||||
|
||||
number[2] = '\0';
|
||||
// surely not a sysid_string if not 14 length
|
||||
if (strlen(dotted) != 14) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while ( len < ISIS_SYS_ID_LEN ) {
|
||||
if (*pos == '.') {
|
||||
/* the . is not positioned correctly */
|
||||
if (((pos - dotted) !=4) && ((pos - dotted) != 9)) {
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
if ((isxdigit((int)*pos)) && (isxdigit((int)*(pos+1)))){
|
||||
memcpy (number, pos ,2);
|
||||
pos+=2;
|
||||
} else {
|
||||
len = 0;
|
||||
break;
|
||||
if (strlen (dotted) != 14)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
*(buff + len) = (char)strtol(number, NULL, 16);
|
||||
len++;
|
||||
}
|
||||
while (len < ISIS_SYS_ID_LEN)
|
||||
{
|
||||
if (*pos == '.')
|
||||
{
|
||||
/* the . is not positioned correctly */
|
||||
if (((pos - dotted) != 4) && ((pos - dotted) != 9))
|
||||
{
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
continue;
|
||||
}
|
||||
if ((isxdigit ((int) *pos)) && (isxdigit ((int) *(pos + 1))))
|
||||
{
|
||||
memcpy (number, pos, 2);
|
||||
pos += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
*(buff + len) = (char) strtol (number, NULL, 16);
|
||||
len++;
|
||||
}
|
||||
|
||||
return len;
|
||||
|
||||
@ -174,79 +198,82 @@ sysid2buff (u_char *buff, u_char *dotted)
|
||||
*/
|
||||
|
||||
char *
|
||||
nlpid2string (struct nlpids *nlpids) {
|
||||
nlpid2string (struct nlpids *nlpids)
|
||||
{
|
||||
char *pos = nlpidstring;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
if (nlpids->count - i > 1)
|
||||
pos += sprintf (pos, ", ");
|
||||
|
||||
}
|
||||
if (nlpids->count-i>1)
|
||||
pos += sprintf (pos, ", ");
|
||||
|
||||
}
|
||||
|
||||
*(pos) = '\0';
|
||||
|
||||
|
||||
return nlpidstring;
|
||||
}
|
||||
|
||||
/*
|
||||
* supports the given af ?
|
||||
*/
|
||||
int
|
||||
int
|
||||
speaks (struct nlpids *nlpids, int family)
|
||||
{
|
||||
int i, speaks = 0;
|
||||
|
||||
if (nlpids == (struct nlpids*)NULL)
|
||||
|
||||
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;
|
||||
}
|
||||
for (i = 0; i < nlpids->count; i++)
|
||||
{
|
||||
if (family == AF_INET && nlpids->nlpids[i] == NLPID_IP)
|
||||
speaks = 1;
|
||||
if (family == AF_INET6 && nlpids->nlpids[i] == NLPID_IPV6)
|
||||
speaks = 1;
|
||||
}
|
||||
|
||||
return speaks;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns 0 on error, IS-IS Circuit Type on ok
|
||||
*/
|
||||
int
|
||||
string2circuit_t (u_char *str)
|
||||
int
|
||||
string2circuit_t (u_char * str)
|
||||
{
|
||||
|
||||
|
||||
if (!str)
|
||||
return 0;
|
||||
|
||||
if (!strcmp(str,"level-1"))
|
||||
|
||||
if (!strcmp (str, "level-1"))
|
||||
return IS_LEVEL_1;
|
||||
|
||||
if (!strcmp(str,"level-2-only") || !strcmp(str,"level-2"))
|
||||
if (!strcmp (str, "level-2-only") || !strcmp (str, "level-2"))
|
||||
return IS_LEVEL_2;
|
||||
|
||||
if (!strcmp(str,"level-1-2"))
|
||||
|
||||
if (!strcmp (str, "level-1-2"))
|
||||
return IS_LEVEL_1_AND_2;
|
||||
|
||||
return 0;
|
||||
@ -255,62 +282,68 @@ string2circuit_t (u_char *str)
|
||||
const char *
|
||||
circuit_t2string (int circuit_t)
|
||||
{
|
||||
switch (circuit_t) {
|
||||
case IS_LEVEL_1:
|
||||
return "L1";
|
||||
case IS_LEVEL_2:
|
||||
return "L2";
|
||||
case IS_LEVEL_1_AND_2:
|
||||
return "L1L2";
|
||||
default:
|
||||
return "??";
|
||||
}
|
||||
switch (circuit_t)
|
||||
{
|
||||
case IS_LEVEL_1:
|
||||
return "L1";
|
||||
case IS_LEVEL_2:
|
||||
return "L2";
|
||||
case IS_LEVEL_1_AND_2:
|
||||
return "L1L2";
|
||||
default:
|
||||
return "??";
|
||||
}
|
||||
|
||||
return NULL; /* not reached */
|
||||
return NULL; /* not reached */
|
||||
}
|
||||
|
||||
const char *
|
||||
syst2string (int type)
|
||||
{
|
||||
switch (type) {
|
||||
case ISIS_SYSTYPE_ES:
|
||||
return "ES";
|
||||
case ISIS_SYSTYPE_IS:
|
||||
return "IS";
|
||||
case ISIS_SYSTYPE_L1_IS:
|
||||
return "1";
|
||||
case ISIS_SYSTYPE_L2_IS:
|
||||
return "2";
|
||||
default:
|
||||
return "??";
|
||||
}
|
||||
switch (type)
|
||||
{
|
||||
case ISIS_SYSTYPE_ES:
|
||||
return "ES";
|
||||
case ISIS_SYSTYPE_IS:
|
||||
return "IS";
|
||||
case ISIS_SYSTYPE_L1_IS:
|
||||
return "1";
|
||||
case ISIS_SYSTYPE_L2_IS:
|
||||
return "2";
|
||||
default:
|
||||
return "??";
|
||||
}
|
||||
|
||||
return NULL; /* not reached */
|
||||
return NULL; /* not reached */
|
||||
}
|
||||
|
||||
/*
|
||||
* Print functions - we print to static vars
|
||||
*/
|
||||
char *
|
||||
snpa_print (u_char *from)
|
||||
snpa_print (u_char * from)
|
||||
{
|
||||
int i = 0;
|
||||
u_char *pos = snpa;
|
||||
|
||||
if(!from)
|
||||
if (!from)
|
||||
return "unknown";
|
||||
|
||||
while (i < ETH_ALEN - 1) {
|
||||
if (i & 1) {
|
||||
sprintf ( pos, "%02x.", *(from + i));
|
||||
pos += 3;
|
||||
} else {
|
||||
sprintf ( pos, "%02x", *(from + i));
|
||||
pos += 2;
|
||||
|
||||
while (i < ETH_ALEN - 1)
|
||||
{
|
||||
if (i & 1)
|
||||
{
|
||||
sprintf (pos, "%02x.", *(from + i));
|
||||
pos += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf (pos, "%02x", *(from + i));
|
||||
pos += 2;
|
||||
|
||||
}
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
sprintf (pos, "%02x", *(from + (ISIS_SYS_ID_LEN - 1)));
|
||||
pos += 2;
|
||||
@ -320,44 +353,48 @@ snpa_print (u_char *from)
|
||||
}
|
||||
|
||||
char *
|
||||
sysid_print (u_char *from)
|
||||
sysid_print (u_char * from)
|
||||
{
|
||||
int i = 0;
|
||||
char *pos = sysid;
|
||||
|
||||
if(!from)
|
||||
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++;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
char *
|
||||
rawlspid_print (u_char *from)
|
||||
rawlspid_print (u_char * from)
|
||||
{
|
||||
char *pos = lspid;
|
||||
if(!from)
|
||||
if (!from)
|
||||
return "unknown";
|
||||
memcpy(pos, sysid_print(from), 15);
|
||||
memcpy (pos, sysid_print (from), 15);
|
||||
pos += 14;
|
||||
sprintf (pos, ".%02x", LSP_PSEUDO_ID(from));
|
||||
sprintf (pos, ".%02x", LSP_PSEUDO_ID (from));
|
||||
pos += 3;
|
||||
sprintf (pos, "-%02x", LSP_FRAGMENT(from));
|
||||
sprintf (pos, "-%02x", LSP_FRAGMENT (from));
|
||||
pos += 3;
|
||||
|
||||
*(pos) = '\0';
|
||||
@ -366,34 +403,35 @@ rawlspid_print (u_char *from)
|
||||
}
|
||||
|
||||
char *
|
||||
time2string (u_int32_t time) {
|
||||
char *pos = datestring;
|
||||
time2string (u_int32_t time)
|
||||
{
|
||||
char *pos = datestring;
|
||||
u_int32_t rest;
|
||||
|
||||
if (time==0)
|
||||
if (time == 0)
|
||||
return "-";
|
||||
|
||||
if(time/SECS_PER_YEAR)
|
||||
pos += sprintf (pos, "%uY",time/SECS_PER_YEAR);
|
||||
rest=time%SECS_PER_YEAR;
|
||||
if(rest/SECS_PER_MONTH)
|
||||
pos += sprintf (pos, "%uM",rest/SECS_PER_MONTH);
|
||||
rest=rest%SECS_PER_MONTH;
|
||||
if(rest/SECS_PER_WEEK)
|
||||
pos += sprintf (pos, "%uw",rest/SECS_PER_WEEK);
|
||||
rest=rest%SECS_PER_WEEK;
|
||||
if(rest/SECS_PER_DAY)
|
||||
pos += sprintf (pos, "%ud",rest/SECS_PER_DAY);
|
||||
rest=rest%SECS_PER_DAY;
|
||||
if(rest/SECS_PER_HOUR)
|
||||
pos += sprintf (pos, "%uh",rest/SECS_PER_HOUR);
|
||||
rest=rest%SECS_PER_HOUR;
|
||||
if(rest/SECS_PER_MINUTE)
|
||||
pos += sprintf (pos, "%um",rest/SECS_PER_MINUTE);
|
||||
rest=rest%SECS_PER_MINUTE;
|
||||
if(rest)
|
||||
pos += sprintf (pos, "%us",rest);
|
||||
|
||||
if (time / SECS_PER_YEAR)
|
||||
pos += sprintf (pos, "%uY", time / SECS_PER_YEAR);
|
||||
rest = time % SECS_PER_YEAR;
|
||||
if (rest / SECS_PER_MONTH)
|
||||
pos += sprintf (pos, "%uM", rest / SECS_PER_MONTH);
|
||||
rest = rest % SECS_PER_MONTH;
|
||||
if (rest / SECS_PER_WEEK)
|
||||
pos += sprintf (pos, "%uw", rest / SECS_PER_WEEK);
|
||||
rest = rest % SECS_PER_WEEK;
|
||||
if (rest / SECS_PER_DAY)
|
||||
pos += sprintf (pos, "%ud", rest / SECS_PER_DAY);
|
||||
rest = rest % SECS_PER_DAY;
|
||||
if (rest / SECS_PER_HOUR)
|
||||
pos += sprintf (pos, "%uh", rest / SECS_PER_HOUR);
|
||||
rest = rest % SECS_PER_HOUR;
|
||||
if (rest / SECS_PER_MINUTE)
|
||||
pos += sprintf (pos, "%um", rest / SECS_PER_MINUTE);
|
||||
rest = rest % SECS_PER_MINUTE;
|
||||
if (rest)
|
||||
pos += sprintf (pos, "%us", rest);
|
||||
|
||||
*(pos) = 0;
|
||||
|
||||
return datestring;
|
||||
@ -406,12 +444,12 @@ time2string (u_int32_t time) {
|
||||
* first argument is the timer and the second is
|
||||
* the jitter
|
||||
*/
|
||||
unsigned long
|
||||
unsigned long
|
||||
isis_jitter (unsigned long timer, unsigned long jitter)
|
||||
{
|
||||
int j,k;
|
||||
int j, k;
|
||||
|
||||
if (jitter>=100)
|
||||
if (jitter >= 100)
|
||||
return timer;
|
||||
|
||||
if (timer == 1)
|
||||
@ -423,9 +461,9 @@ isis_jitter (unsigned long timer, unsigned long jitter)
|
||||
* most IS-IS timers are no longer than 16 bit
|
||||
*/
|
||||
|
||||
j = 1 + (int) ((RANDOM_SPREAD * rand()) / (RAND_MAX + 1.0 ));
|
||||
j = 1 + (int) ((RANDOM_SPREAD * rand ()) / (RAND_MAX + 1.0));
|
||||
|
||||
k = timer - (timer * (100 - jitter))/100;
|
||||
k = timer - (timer * (100 - jitter)) / 100;
|
||||
|
||||
timer = timer - (k * j / RANDOM_SPREAD);
|
||||
|
||||
@ -433,11 +471,11 @@ isis_jitter (unsigned long timer, unsigned long jitter)
|
||||
}
|
||||
|
||||
struct in_addr
|
||||
newprefix2inaddr (u_char *prefix_start, u_char prefix_masklen)
|
||||
newprefix2inaddr (u_char * prefix_start, u_char prefix_masklen)
|
||||
{
|
||||
memset(&new_prefix, 0, sizeof (new_prefix));
|
||||
memcpy(&new_prefix, prefix_start, (prefix_masklen & 0x3F) ?
|
||||
((((prefix_masklen & 0x3F)-1)>>3)+1) : 0);
|
||||
memset (&new_prefix, 0, sizeof (new_prefix));
|
||||
memcpy (&new_prefix, prefix_start, (prefix_masklen & 0x3F) ?
|
||||
((((prefix_masklen & 0x3F) - 1) >> 3) + 1) : 0);
|
||||
return new_prefix;
|
||||
}
|
||||
|
||||
@ -446,17 +484,18 @@ newprefix2inaddr (u_char *prefix_start, u_char prefix_masklen)
|
||||
* it returns the system hostname.
|
||||
*/
|
||||
const char *
|
||||
unix_hostname(void)
|
||||
unix_hostname (void)
|
||||
{
|
||||
static struct utsname names;
|
||||
const char *hostname;
|
||||
extern struct host host;
|
||||
|
||||
hostname = host.name;
|
||||
if (!hostname) {
|
||||
uname(&names);
|
||||
hostname = names.nodename;
|
||||
}
|
||||
if (!hostname)
|
||||
{
|
||||
uname (&names);
|
||||
hostname = names.nodename;
|
||||
}
|
||||
|
||||
return hostname;
|
||||
}
|
||||
|
||||
@ -28,7 +28,8 @@ int dotformat2buff (u_char *, u_char *);
|
||||
int string2circuit_t (u_char *);
|
||||
const char *circuit_t2string (int);
|
||||
const char *syst2string (int);
|
||||
struct in_addr newprefix2inaddr (u_char *prefix_start, u_char prefix_masklen);
|
||||
struct in_addr newprefix2inaddr (u_char * prefix_start,
|
||||
u_char prefix_masklen);
|
||||
/*
|
||||
* Converting input to memory stored format
|
||||
* return value of 0 indicates wrong input
|
||||
@ -41,41 +42,38 @@ int sysid2buff (u_char *, u_char *);
|
||||
*/
|
||||
char *isonet_print (u_char *, int len);
|
||||
char *sysid_print (u_char *);
|
||||
char *snpa_print (u_char *);
|
||||
char *snpa_print (u_char *);
|
||||
char *rawlspid_print (u_char *);
|
||||
char *time2string (u_int32_t);
|
||||
/* typedef struct nlpids nlpids; */
|
||||
char *nlpid2string (struct nlpids *);
|
||||
|
||||
|
||||
/*
|
||||
* misc functions
|
||||
*/
|
||||
int speaks (struct nlpids *nlpids, int family);
|
||||
int speaks (struct nlpids *nlpids, int family);
|
||||
unsigned long isis_jitter (unsigned long timer, unsigned long jitter);
|
||||
const char * unix_hostname(void);
|
||||
|
||||
const char *unix_hostname (void);
|
||||
|
||||
/*
|
||||
* macros
|
||||
*/
|
||||
#define GETSYSID(A,L) (A->area_addr + (A->addr_len - (L + 1)))
|
||||
|
||||
|
||||
/* staticly assigned vars for printing purposes */
|
||||
struct in_addr new_prefix;
|
||||
struct in_addr new_prefix;
|
||||
/* len of xxxx.xxxx.xxxx + place for #0 termination */
|
||||
char sysid[15];
|
||||
char sysid[15];
|
||||
/* len of xxxx.xxxx.xxxx + place for #0 termination */
|
||||
char snpa[15];
|
||||
char snpa[15];
|
||||
/* len of xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xx */
|
||||
char isonet[51];
|
||||
char isonet[51];
|
||||
/* + place for #0 termination */
|
||||
/* len of xxxx.xxxx.xxxx.xx.xx + place for #0 termination */
|
||||
char lspid[21];
|
||||
char lspid[21];
|
||||
/* len of xxYxxMxWxdxxhxxmxxs + place for #0 termination */
|
||||
char datestring[20];
|
||||
char nlpidstring[30];
|
||||
char datestring[20];
|
||||
char nlpidstring[30];
|
||||
|
||||
/* used for calculating nice string representation instead of plain seconds */
|
||||
|
||||
@ -86,11 +84,11 @@ char nlpidstring[30];
|
||||
#define SECS_PER_MONTH 2628000
|
||||
#define SECS_PER_YEAR 31536000
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
ISIS_UI_LEVEL_BRIEF,
|
||||
ISIS_UI_LEVEL_DETAIL,
|
||||
ISIS_UI_LEVEL_EXTENSIVE,
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -25,18 +25,16 @@
|
||||
#include <errno.h>
|
||||
#include <zebra.h>
|
||||
#ifdef GNU_LINUX
|
||||
#include <net/ethernet.h> /* the L2 protocols */
|
||||
#include <net/ethernet.h> /* the L2 protocols */
|
||||
#else
|
||||
#include <net/if.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "log.h"
|
||||
#include "stream.h"
|
||||
#include "if.h"
|
||||
|
||||
|
||||
#include "isisd/dict.h"
|
||||
#include "isisd/include-netbsd/iso.h"
|
||||
#include "isisd/isis_constants.h"
|
||||
@ -59,19 +57,19 @@ extern struct zebra_privs_t isisd_privs;
|
||||
*/
|
||||
#ifdef GNU_LINUX
|
||||
#include <netpacket/packet.h>
|
||||
#else
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/bpf.h>
|
||||
struct bpf_insn llcfilter[] = {
|
||||
BPF_STMT(BPF_LD+BPF_B+BPF_ABS, ETHER_HDR_LEN), /* check first byte */
|
||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ISO_SAP, 0, 5),
|
||||
BPF_STMT(BPF_LD+BPF_B+BPF_ABS, ETHER_HDR_LEN+1),
|
||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ISO_SAP, 0, 3), /* check second byte */
|
||||
BPF_STMT(BPF_LD+BPF_B+BPF_ABS, ETHER_HDR_LEN+2),
|
||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x03, 0, 1), /* check third byte */
|
||||
BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
|
||||
BPF_STMT(BPF_RET+BPF_K, 0)
|
||||
BPF_STMT (BPF_LD + BPF_B + BPF_ABS, ETHER_HDR_LEN), /* check first byte */
|
||||
BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ISO_SAP, 0, 5),
|
||||
BPF_STMT (BPF_LD + BPF_B + BPF_ABS, ETHER_HDR_LEN + 1),
|
||||
BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ISO_SAP, 0, 3), /* check second byte */
|
||||
BPF_STMT (BPF_LD + BPF_B + BPF_ABS, ETHER_HDR_LEN + 2),
|
||||
BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 0x03, 0, 1), /* check third byte */
|
||||
BPF_STMT (BPF_RET + BPF_K, (u_int) - 1),
|
||||
BPF_STMT (BPF_RET + BPF_K, 0)
|
||||
};
|
||||
int readblen = 0;
|
||||
u_char *readbuff = NULL;
|
||||
@ -82,10 +80,10 @@ u_char *readbuff = NULL;
|
||||
* ISO 10589 - 8.4.8
|
||||
*/
|
||||
|
||||
u_char ALL_L1_ISS[6] = {0x01, 0x80, 0xC2, 0x00, 0x00, 0x14};
|
||||
u_char ALL_L2_ISS[6] = {0x01, 0x80, 0xC2, 0x00, 0x00, 0x15};
|
||||
u_char ALL_ISS[6] = {0x09, 0x00, 0x2B, 0x00, 0x00, 0x05};
|
||||
u_char ALL_ESS[6] = {0x09, 0x00, 0x2B, 0x00, 0x00, 0x04};
|
||||
u_char ALL_L1_ISS[6] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x14 };
|
||||
u_char ALL_L2_ISS[6] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x15 };
|
||||
u_char ALL_ISS[6] = { 0x09, 0x00, 0x2B, 0x00, 0x00, 0x05 };
|
||||
u_char ALL_ESS[6] = { 0x09, 0x00, 0x2B, 0x00, 0x00, 0x04 };
|
||||
|
||||
#ifdef GNU_LINUX
|
||||
static char discard_buff[8192];
|
||||
@ -102,89 +100,101 @@ isis_multicast_join (int fd, int registerto, int if_num)
|
||||
{
|
||||
struct packet_mreq mreq;
|
||||
|
||||
memset(&mreq, 0, sizeof(mreq));
|
||||
memset (&mreq, 0, sizeof (mreq));
|
||||
mreq.mr_ifindex = if_num;
|
||||
if (registerto) {
|
||||
mreq.mr_type = PACKET_MR_MULTICAST;
|
||||
mreq.mr_alen = ETH_ALEN;
|
||||
if (registerto == 1)
|
||||
memcpy (&mreq.mr_address, ALL_L1_ISS, ETH_ALEN);
|
||||
else if (registerto == 2)
|
||||
memcpy (&mreq.mr_address, ALL_L2_ISS, ETH_ALEN);
|
||||
else if (registerto == 3)
|
||||
memcpy (&mreq.mr_address, ALL_ISS, ETH_ALEN);
|
||||
else
|
||||
memcpy (&mreq.mr_address, ALL_ESS, ETH_ALEN);
|
||||
if (registerto)
|
||||
{
|
||||
mreq.mr_type = PACKET_MR_MULTICAST;
|
||||
mreq.mr_alen = ETH_ALEN;
|
||||
if (registerto == 1)
|
||||
memcpy (&mreq.mr_address, ALL_L1_ISS, ETH_ALEN);
|
||||
else if (registerto == 2)
|
||||
memcpy (&mreq.mr_address, ALL_L2_ISS, ETH_ALEN);
|
||||
else if (registerto == 3)
|
||||
memcpy (&mreq.mr_address, ALL_ISS, ETH_ALEN);
|
||||
else
|
||||
memcpy (&mreq.mr_address, ALL_ESS, ETH_ALEN);
|
||||
|
||||
} else {
|
||||
mreq.mr_type = PACKET_MR_ALLMULTI;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mreq.mr_type = PACKET_MR_ALLMULTI;
|
||||
}
|
||||
#ifdef EXTREME_DEBUG
|
||||
zlog_info ("isis_multicast_join(): fd=%d, reg_to=%d, if_num=%d, "
|
||||
"address = %02x:%02x:%02x:%02x:%02x:%02x",
|
||||
fd, registerto, if_num, mreq.mr_address[0], mreq.mr_address[1],
|
||||
mreq.mr_address[2], mreq.mr_address[3],mreq.mr_address[4],
|
||||
mreq.mr_address[5]);
|
||||
"address = %02x:%02x:%02x:%02x:%02x:%02x",
|
||||
fd, registerto, if_num, mreq.mr_address[0], mreq.mr_address[1],
|
||||
mreq.mr_address[2], mreq.mr_address[3], mreq.mr_address[4],
|
||||
mreq.mr_address[5]);
|
||||
#endif /* EXTREME_DEBUG */
|
||||
if (setsockopt (fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq,
|
||||
sizeof (struct packet_mreq))) {
|
||||
zlog_warn ("isis_multicast_join(): setsockopt(): %s", strerror (errno));
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
|
||||
if (setsockopt (fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq,
|
||||
sizeof (struct packet_mreq)))
|
||||
{
|
||||
zlog_warn ("isis_multicast_join(): setsockopt(): %s", strerror (errno));
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
|
||||
return ISIS_OK;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
open_packet_socket (struct isis_circuit *circuit)
|
||||
{
|
||||
struct sockaddr_ll s_addr;
|
||||
int fd, retval = ISIS_OK;
|
||||
|
||||
|
||||
fd = socket (PF_PACKET, SOCK_DGRAM, htons (ETH_P_ALL));
|
||||
if (fd < 0) {
|
||||
zlog_warn ("open_packet_socket(): socket() failed %s", strerror (errno));
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
if (fd < 0)
|
||||
{
|
||||
zlog_warn ("open_packet_socket(): socket() failed %s",
|
||||
strerror (errno));
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bind to the physical interface
|
||||
*/
|
||||
memset(&s_addr, 0, sizeof (struct sockaddr_ll));
|
||||
memset (&s_addr, 0, sizeof (struct sockaddr_ll));
|
||||
s_addr.sll_family = AF_PACKET;
|
||||
s_addr.sll_protocol = htons (ETH_P_ALL);
|
||||
s_addr.sll_ifindex = circuit->interface->ifindex;
|
||||
|
||||
if (bind (fd, (struct sockaddr*) (&s_addr),
|
||||
sizeof(struct sockaddr_ll)) < 0) {
|
||||
zlog_warn ("open_packet_socket(): bind() failed: %s", strerror(errno));
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
|
||||
|
||||
if (bind (fd, (struct sockaddr *) (&s_addr),
|
||||
sizeof (struct sockaddr_ll)) < 0)
|
||||
{
|
||||
zlog_warn ("open_packet_socket(): bind() failed: %s", strerror (errno));
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
|
||||
circuit->fd = fd;
|
||||
|
||||
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
|
||||
/*
|
||||
* Join to multicast groups
|
||||
* according to
|
||||
* 8.4.2 - Broadcast subnetwork IIH PDUs
|
||||
* FIXME: is there a case only one will fail??
|
||||
*/
|
||||
if (circuit->circuit_is_type & IS_LEVEL_1) {
|
||||
/* joining ALL_L1_ISS */
|
||||
retval = isis_multicast_join (circuit->fd, 1,
|
||||
circuit->interface->ifindex);
|
||||
/* joining ALL_ISS */
|
||||
retval = isis_multicast_join (circuit->fd, 3,
|
||||
circuit->interface->ifindex);
|
||||
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
|
||||
{
|
||||
/*
|
||||
* Join to multicast groups
|
||||
* according to
|
||||
* 8.4.2 - Broadcast subnetwork IIH PDUs
|
||||
* FIXME: is there a case only one will fail??
|
||||
*/
|
||||
if (circuit->circuit_is_type & IS_LEVEL_1)
|
||||
{
|
||||
/* joining ALL_L1_ISS */
|
||||
retval = isis_multicast_join (circuit->fd, 1,
|
||||
circuit->interface->ifindex);
|
||||
/* joining ALL_ISS */
|
||||
retval = isis_multicast_join (circuit->fd, 3,
|
||||
circuit->interface->ifindex);
|
||||
}
|
||||
if (circuit->circuit_is_type & IS_LEVEL_2)
|
||||
/* joining ALL_L2_ISS */
|
||||
retval = isis_multicast_join (circuit->fd, 2,
|
||||
circuit->interface->ifindex);
|
||||
}
|
||||
else
|
||||
{
|
||||
retval =
|
||||
isis_multicast_join (circuit->fd, 0, circuit->interface->ifindex);
|
||||
}
|
||||
if (circuit->circuit_is_type & IS_LEVEL_2)
|
||||
/* joining ALL_L2_ISS */
|
||||
retval = isis_multicast_join (circuit->fd, 2,
|
||||
circuit->interface->ifindex);
|
||||
} else {
|
||||
retval = isis_multicast_join (circuit->fd, 0, circuit->interface->ifindex);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -201,101 +211,110 @@ open_bpf_dev (struct isis_circuit *circuit)
|
||||
int true = 1, false = 0;
|
||||
struct timeval timeout;
|
||||
struct bpf_program bpf_prog;
|
||||
|
||||
do {
|
||||
(void)snprintf(bpfdev, sizeof(bpfdev), "/dev/bpf%d", i++);
|
||||
fd = open(bpfdev, O_RDWR);
|
||||
} while (fd < 0 && errno == EBUSY);
|
||||
|
||||
if (fd < 0) {
|
||||
zlog_warn ("open_bpf_dev(): failed to create bpf socket: %s",
|
||||
strerror (errno));
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
(void) snprintf (bpfdev, sizeof (bpfdev), "/dev/bpf%d", i++);
|
||||
fd = open (bpfdev, O_RDWR);
|
||||
}
|
||||
while (fd < 0 && errno == EBUSY);
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
zlog_warn ("open_bpf_dev(): failed to create bpf socket: %s",
|
||||
strerror (errno));
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
|
||||
zlog_info ("Opened BPF device %s", bpfdev);
|
||||
|
||||
memcpy (ifr.ifr_name, circuit->interface->name, sizeof(ifr.ifr_name));
|
||||
if (ioctl (fd, BIOCSETIF, (caddr_t)&ifr) < 0 ) {
|
||||
zlog_warn ("open_bpf_dev(): failed to bind to interface: %s",
|
||||
strerror (errno));
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
memcpy (ifr.ifr_name, circuit->interface->name, sizeof (ifr.ifr_name));
|
||||
if (ioctl (fd, BIOCSETIF, (caddr_t) & ifr) < 0)
|
||||
{
|
||||
zlog_warn ("open_bpf_dev(): failed to bind to interface: %s",
|
||||
strerror (errno));
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
|
||||
if (ioctl (fd, BIOCGBLEN, (caddr_t) & blen) < 0)
|
||||
{
|
||||
zlog_warn ("failed to get BPF buffer len");
|
||||
blen = circuit->interface->mtu;
|
||||
}
|
||||
|
||||
if (ioctl (fd, BIOCGBLEN, (caddr_t)&blen) < 0) {
|
||||
zlog_warn ("failed to get BPF buffer len");
|
||||
blen = circuit->interface->mtu;
|
||||
}
|
||||
|
||||
readblen = blen;
|
||||
|
||||
if (readbuff == NULL)
|
||||
readbuff = malloc (blen);
|
||||
|
||||
|
||||
zlog_info ("BPF buffer len = %u", blen);
|
||||
|
||||
/* BPF(4): reads return immediately upon packet reception.
|
||||
* Otherwise, a read will block until either the kernel
|
||||
* buffer becomes full or a timeout occurs.
|
||||
*/
|
||||
if (ioctl (fd, BIOCIMMEDIATE, (caddr_t)&true) < 0) {
|
||||
zlog_warn ("failed to set BPF dev to immediate mode");
|
||||
}
|
||||
if (ioctl (fd, BIOCIMMEDIATE, (caddr_t) & true) < 0)
|
||||
{
|
||||
zlog_warn ("failed to set BPF dev to immediate mode");
|
||||
}
|
||||
|
||||
#ifdef BIOCSSEESENT
|
||||
/*
|
||||
* We want to see only incoming packets
|
||||
*/
|
||||
if (ioctl (fd, BIOCSSEESENT, (caddr_t)&false) < 0) {
|
||||
zlog_warn ("failed to set BPF dev to incoming only mode");
|
||||
}
|
||||
if (ioctl (fd, BIOCSSEESENT, (caddr_t) & false) < 0)
|
||||
{
|
||||
zlog_warn ("failed to set BPF dev to incoming only mode");
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ...but all of them
|
||||
*/
|
||||
if (ioctl (fd, BIOCPROMISC, (caddr_t)&true) < 0) {
|
||||
zlog_warn ("failed to set BPF dev to promiscuous mode");
|
||||
}
|
||||
|
||||
if (ioctl (fd, BIOCPROMISC, (caddr_t) & true) < 0)
|
||||
{
|
||||
zlog_warn ("failed to set BPF dev to promiscuous mode");
|
||||
}
|
||||
|
||||
/*
|
||||
* If the buffer length is smaller than our mtu, lets try to increase it
|
||||
*/
|
||||
if (blen < circuit->interface->mtu) {
|
||||
if (ioctl (fd, BIOCSBLEN, &circuit->interface->mtu) < 0) {
|
||||
zlog_warn ("failed to set BPF buffer len (%u to %u)", blen,
|
||||
circuit->interface->mtu);
|
||||
if (blen < circuit->interface->mtu)
|
||||
{
|
||||
if (ioctl (fd, BIOCSBLEN, &circuit->interface->mtu) < 0)
|
||||
{
|
||||
zlog_warn ("failed to set BPF buffer len (%u to %u)", blen,
|
||||
circuit->interface->mtu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a timeout parameter - hope this helps select()
|
||||
*/
|
||||
timeout.tv_sec = 600;
|
||||
timeout.tv_usec = 0;
|
||||
if (ioctl (fd, BIOCSRTIMEOUT, (caddr_t)&timeout) < 0) {
|
||||
zlog_warn ("failed to set BPF device timeout");
|
||||
}
|
||||
|
||||
if (ioctl (fd, BIOCSRTIMEOUT, (caddr_t) & timeout) < 0)
|
||||
{
|
||||
zlog_warn ("failed to set BPF device timeout");
|
||||
}
|
||||
|
||||
/*
|
||||
* And set the filter
|
||||
*/
|
||||
memset (&bpf_prog, 0, sizeof (struct bpf_program));
|
||||
bpf_prog.bf_len = 8;
|
||||
bpf_prog.bf_insns = &(llcfilter[0]);
|
||||
if (ioctl (fd, BIOCSETF, (caddr_t)&bpf_prog) < 0) {
|
||||
zlog_warn ("open_bpf_dev(): failed to install filter: %s",
|
||||
strerror (errno));
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
|
||||
if (ioctl (fd, BIOCSETF, (caddr_t) & bpf_prog) < 0)
|
||||
{
|
||||
zlog_warn ("open_bpf_dev(): failed to install filter: %s",
|
||||
strerror (errno));
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
|
||||
assert (fd > 0);
|
||||
|
||||
circuit->fd = fd;
|
||||
|
||||
|
||||
return ISIS_OK;
|
||||
}
|
||||
|
||||
@ -309,9 +328,8 @@ isis_sock_init (struct isis_circuit *circuit)
|
||||
{
|
||||
int retval = ISIS_OK;
|
||||
|
||||
if ( isisd_privs.change (ZPRIVS_RAISE) )
|
||||
zlog_err ("%s: could not raise privs, %s", __func__,
|
||||
strerror (errno) );
|
||||
if (isisd_privs.change (ZPRIVS_RAISE))
|
||||
zlog_err ("%s: could not raise privs, %s", __func__, strerror (errno));
|
||||
|
||||
#ifdef GNU_LINUX
|
||||
retval = open_packet_socket (circuit);
|
||||
@ -319,46 +337,48 @@ isis_sock_init (struct isis_circuit *circuit)
|
||||
retval = open_bpf_dev (circuit);
|
||||
#endif
|
||||
|
||||
if (retval != ISIS_OK) {
|
||||
zlog_warn("%s: could not initialize the socket",
|
||||
__func__);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
|
||||
circuit->tx = isis_send_pdu_bcast;
|
||||
circuit->rx = isis_recv_pdu_bcast;
|
||||
} else if (circuit->circ_type == CIRCUIT_T_P2P) {
|
||||
circuit->tx = isis_send_pdu_p2p;
|
||||
circuit->rx = isis_recv_pdu_p2p;
|
||||
} else {
|
||||
zlog_warn ("isis_sock_init(): unknown circuit type");
|
||||
retval = ISIS_WARNING;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (retval != ISIS_OK)
|
||||
{
|
||||
zlog_warn ("%s: could not initialize the socket", __func__);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
|
||||
{
|
||||
circuit->tx = isis_send_pdu_bcast;
|
||||
circuit->rx = isis_recv_pdu_bcast;
|
||||
}
|
||||
else if (circuit->circ_type == CIRCUIT_T_P2P)
|
||||
{
|
||||
circuit->tx = isis_send_pdu_p2p;
|
||||
circuit->rx = isis_recv_pdu_p2p;
|
||||
}
|
||||
else
|
||||
{
|
||||
zlog_warn ("isis_sock_init(): unknown circuit type");
|
||||
retval = ISIS_WARNING;
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
if ( isisd_privs.change (ZPRIVS_LOWER) )
|
||||
zlog_err ("%s: could not lower privs, %s", __func__,
|
||||
strerror (errno) );
|
||||
if (isisd_privs.change (ZPRIVS_LOWER))
|
||||
zlog_err ("%s: could not lower privs, %s", __func__, strerror (errno));
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
static inline int
|
||||
llc_check (u_char *llc)
|
||||
static inline int
|
||||
llc_check (u_char * llc)
|
||||
{
|
||||
|
||||
if(*llc != ISO_SAP || *(llc + 1) != ISO_SAP || *(llc +2) != 3)
|
||||
if (*llc != ISO_SAP || *(llc + 1) != ISO_SAP || *(llc + 2) != 3)
|
||||
return 0;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef GNU_LINUX
|
||||
int
|
||||
isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char *ssnpa)
|
||||
isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char * ssnpa)
|
||||
{
|
||||
int bytesread, addr_len;
|
||||
struct sockaddr_ll s_addr;
|
||||
@ -368,50 +388,51 @@ isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char *ssnpa)
|
||||
|
||||
memset (&s_addr, 0, sizeof (struct sockaddr_ll));
|
||||
|
||||
bytesread = recvfrom (circuit->fd, (void *)&llc,
|
||||
LLC_LEN, MSG_PEEK,
|
||||
(struct sockaddr *)&s_addr, &addr_len);
|
||||
bytesread = recvfrom (circuit->fd, (void *) &llc,
|
||||
LLC_LEN, MSG_PEEK,
|
||||
(struct sockaddr *) &s_addr, &addr_len);
|
||||
|
||||
if (bytesread < 0) {
|
||||
zlog_warn ("isis_recv_packet_bcast(): fd %d, recvfrom (): %s",
|
||||
circuit->fd, strerror (errno));
|
||||
zlog_warn ("circuit is %s", circuit->interface->name);
|
||||
zlog_warn ("circuit fd %d", circuit->fd);
|
||||
zlog_warn ("bytesread %d", bytesread);
|
||||
/* get rid of the packet */
|
||||
bytesread = read (circuit->fd, discard_buff, sizeof (discard_buff));
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
if (bytesread < 0)
|
||||
{
|
||||
zlog_warn ("isis_recv_packet_bcast(): fd %d, recvfrom (): %s",
|
||||
circuit->fd, strerror (errno));
|
||||
zlog_warn ("circuit is %s", circuit->interface->name);
|
||||
zlog_warn ("circuit fd %d", circuit->fd);
|
||||
zlog_warn ("bytesread %d", bytesread);
|
||||
/* get rid of the packet */
|
||||
bytesread = read (circuit->fd, discard_buff, sizeof (discard_buff));
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
/*
|
||||
* Filtering by llc field, discard packets sent by this host (other circuit)
|
||||
*/
|
||||
if (!llc_check (llc) || s_addr.sll_pkttype == PACKET_OUTGOING) {
|
||||
/* Read the packet into discard buff */
|
||||
bytesread = read (circuit->fd, discard_buff, sizeof (discard_buff));
|
||||
if (bytesread < 0)
|
||||
zlog_warn ("isis_recv_pdu_bcast(): read() failed");
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
|
||||
if (!llc_check (llc) || s_addr.sll_pkttype == PACKET_OUTGOING)
|
||||
{
|
||||
/* Read the packet into discard buff */
|
||||
bytesread = read (circuit->fd, discard_buff, sizeof (discard_buff));
|
||||
if (bytesread < 0)
|
||||
zlog_warn ("isis_recv_pdu_bcast(): read() failed");
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
|
||||
/* on lan we have to read to the static buff first */
|
||||
bytesread = recvfrom (circuit->fd, sock_buff, circuit->interface->mtu, 0,
|
||||
(struct sockaddr *)&s_addr, &addr_len);
|
||||
|
||||
(struct sockaddr *) &s_addr, &addr_len);
|
||||
|
||||
/* then we lose the LLC */
|
||||
memcpy (STREAM_DATA (circuit->rcv_stream),
|
||||
sock_buff + LLC_LEN, bytesread - LLC_LEN);
|
||||
memcpy (STREAM_DATA (circuit->rcv_stream),
|
||||
sock_buff + LLC_LEN, bytesread - LLC_LEN);
|
||||
circuit->rcv_stream->putp = bytesread - LLC_LEN;
|
||||
circuit->rcv_stream->endp = bytesread - LLC_LEN;
|
||||
|
||||
memcpy (ssnpa, &s_addr.sll_addr, s_addr.sll_halen);
|
||||
|
||||
|
||||
memcpy (ssnpa, &s_addr.sll_addr, s_addr.sll_halen);
|
||||
|
||||
return ISIS_OK;
|
||||
}
|
||||
|
||||
int
|
||||
isis_recv_pdu_p2p (struct isis_circuit *circuit, u_char *ssnpa)
|
||||
isis_recv_pdu_p2p (struct isis_circuit *circuit, u_char * ssnpa)
|
||||
{
|
||||
|
||||
int bytesread, addr_len;
|
||||
struct sockaddr_ll s_addr;
|
||||
|
||||
@ -420,16 +441,17 @@ isis_recv_pdu_p2p (struct isis_circuit *circuit, u_char *ssnpa)
|
||||
|
||||
/* we can read directly to the stream */
|
||||
bytesread = recvfrom (circuit->fd, STREAM_DATA (circuit->rcv_stream),
|
||||
circuit->interface->mtu, 0,
|
||||
(struct sockaddr *)&s_addr, &addr_len);
|
||||
circuit->interface->mtu, 0,
|
||||
(struct sockaddr *) &s_addr, &addr_len);
|
||||
|
||||
if(s_addr.sll_pkttype == PACKET_OUTGOING) {
|
||||
/* Read the packet into discard buff */
|
||||
bytesread = read (circuit->fd, discard_buff, sizeof (discard_buff));
|
||||
if (bytesread < 0)
|
||||
zlog_warn ("isis_recv_pdu_p2p(): read() failed");
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
if (s_addr.sll_pkttype == PACKET_OUTGOING)
|
||||
{
|
||||
/* Read the packet into discard buff */
|
||||
bytesread = read (circuit->fd, discard_buff, sizeof (discard_buff));
|
||||
if (bytesread < 0)
|
||||
zlog_warn ("isis_recv_pdu_p2p(): read() failed");
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
|
||||
circuit->rcv_stream->putp = bytesread;
|
||||
circuit->rcv_stream->endp = bytesread;
|
||||
@ -437,32 +459,31 @@ isis_recv_pdu_p2p (struct isis_circuit *circuit, u_char *ssnpa)
|
||||
/* If we don't have protocol type 0x00FE which is
|
||||
* ISO over GRE we exit with pain :)
|
||||
*/
|
||||
if (ntohs(s_addr.sll_protocol) != 0x00FE) {
|
||||
zlog_warn ("isis_recv_pdu_p2p(): protocol mismatch(): %X",
|
||||
ntohs(s_addr.sll_protocol));
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
|
||||
memcpy (ssnpa, &s_addr.sll_addr, s_addr.sll_halen);
|
||||
|
||||
if (ntohs (s_addr.sll_protocol) != 0x00FE)
|
||||
{
|
||||
zlog_warn ("isis_recv_pdu_p2p(): protocol mismatch(): %X",
|
||||
ntohs (s_addr.sll_protocol));
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
|
||||
memcpy (ssnpa, &s_addr.sll_addr, s_addr.sll_halen);
|
||||
|
||||
return ISIS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
int
|
||||
isis_send_pdu_bcast (struct isis_circuit *circuit, int level)
|
||||
{
|
||||
/* we need to do the LLC in here because of P2P circuits, which will
|
||||
* not need it
|
||||
*/
|
||||
int written = 1;
|
||||
int written = 1;
|
||||
struct sockaddr_ll sa;
|
||||
|
||||
stream_set_getp (circuit->snd_stream, 0);
|
||||
memset (&sa, 0, sizeof (struct sockaddr_ll));
|
||||
sa.sll_family = AF_PACKET;
|
||||
sa.sll_protocol = htons (stream_get_endp(circuit->snd_stream)+LLC_LEN);
|
||||
sa.sll_protocol = htons (stream_get_endp (circuit->snd_stream) + LLC_LEN);
|
||||
sa.sll_ifindex = circuit->interface->ifindex;
|
||||
sa.sll_halen = ETH_ALEN;
|
||||
if (level == 1)
|
||||
@ -477,29 +498,28 @@ isis_send_pdu_bcast (struct isis_circuit *circuit, int level)
|
||||
sock_buff[2] = 0x03;
|
||||
|
||||
/* then we copy the data */
|
||||
memcpy (sock_buff + LLC_LEN, circuit->snd_stream->data,
|
||||
stream_get_endp (circuit->snd_stream));
|
||||
memcpy (sock_buff + LLC_LEN, circuit->snd_stream->data,
|
||||
stream_get_endp (circuit->snd_stream));
|
||||
|
||||
/* now we can send this */
|
||||
written = sendto (circuit->fd, sock_buff,
|
||||
circuit->snd_stream->putp + LLC_LEN, 0,
|
||||
(struct sockaddr *)&sa, sizeof (struct sockaddr_ll));
|
||||
|
||||
circuit->snd_stream->putp + LLC_LEN, 0,
|
||||
(struct sockaddr *) &sa, sizeof (struct sockaddr_ll));
|
||||
|
||||
return ISIS_OK;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
isis_send_pdu_p2p (struct isis_circuit *circuit, int level)
|
||||
{
|
||||
|
||||
int written = 1;
|
||||
int written = 1;
|
||||
struct sockaddr_ll sa;
|
||||
|
||||
stream_set_getp (circuit->snd_stream, 0);
|
||||
memset (&sa, 0, sizeof (struct sockaddr_ll));
|
||||
sa.sll_family = AF_PACKET;
|
||||
sa.sll_protocol = htons (stream_get_endp(circuit->snd_stream)+LLC_LEN);
|
||||
sa.sll_protocol = htons (stream_get_endp (circuit->snd_stream) + LLC_LEN);
|
||||
sa.sll_ifindex = circuit->interface->ifindex;
|
||||
sa.sll_halen = ETH_ALEN;
|
||||
if (level == 1)
|
||||
@ -509,86 +529,87 @@ isis_send_pdu_p2p (struct isis_circuit *circuit, int level)
|
||||
|
||||
|
||||
/* lets try correcting the protocol */
|
||||
sa.sll_protocol = htons(0x00FE);
|
||||
written = sendto (circuit->fd, circuit->snd_stream->data,
|
||||
circuit->snd_stream->putp, 0, (struct sockaddr *)&sa,
|
||||
sizeof (struct sockaddr_ll));
|
||||
|
||||
sa.sll_protocol = htons (0x00FE);
|
||||
written = sendto (circuit->fd, circuit->snd_stream->data,
|
||||
circuit->snd_stream->putp, 0, (struct sockaddr *) &sa,
|
||||
sizeof (struct sockaddr_ll));
|
||||
|
||||
return ISIS_OK;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
int
|
||||
isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char *ssnpa)
|
||||
isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char * ssnpa)
|
||||
{
|
||||
int bytesread = 0, bytestoread, offset, one = 1;
|
||||
struct bpf_hdr *bpf_hdr;
|
||||
|
||||
assert (circuit->fd > 0);
|
||||
|
||||
if (ioctl (circuit->fd, FIONREAD, (caddr_t)&bytestoread) < 0 ) {
|
||||
zlog_warn ("ioctl() FIONREAD failed: %s", strerror (errno));
|
||||
}
|
||||
if (ioctl (circuit->fd, FIONREAD, (caddr_t) & bytestoread) < 0)
|
||||
{
|
||||
zlog_warn ("ioctl() FIONREAD failed: %s", strerror (errno));
|
||||
}
|
||||
|
||||
if (bytestoread) {
|
||||
bytesread = read (circuit->fd, readbuff, readblen);
|
||||
}
|
||||
if (bytesread < 0) {
|
||||
zlog_warn ("isis_recv_pdu_bcast(): read() failed: %s", strerror (errno));
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
if (bytestoread)
|
||||
{
|
||||
bytesread = read (circuit->fd, readbuff, readblen);
|
||||
}
|
||||
if (bytesread < 0)
|
||||
{
|
||||
zlog_warn ("isis_recv_pdu_bcast(): read() failed: %s",
|
||||
strerror (errno));
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
|
||||
if (bytesread == 0)
|
||||
return ISIS_WARNING;
|
||||
|
||||
bpf_hdr = (struct bpf_hdr*)readbuff;
|
||||
bpf_hdr = (struct bpf_hdr *) readbuff;
|
||||
|
||||
assert (bpf_hdr->bh_caplen == bpf_hdr->bh_datalen);
|
||||
|
||||
|
||||
offset = bpf_hdr->bh_hdrlen + LLC_LEN + ETHER_HDR_LEN;
|
||||
|
||||
|
||||
/* then we lose the BPF, LLC and ethernet headers */
|
||||
memcpy (STREAM_DATA (circuit->rcv_stream),
|
||||
readbuff + offset,
|
||||
bpf_hdr->bh_caplen - LLC_LEN - ETHER_HDR_LEN);
|
||||
memcpy (STREAM_DATA (circuit->rcv_stream),
|
||||
readbuff + offset, bpf_hdr->bh_caplen - LLC_LEN - ETHER_HDR_LEN);
|
||||
|
||||
circuit->rcv_stream->putp = bpf_hdr->bh_caplen - LLC_LEN - ETHER_HDR_LEN;
|
||||
circuit->rcv_stream->endp = bpf_hdr->bh_caplen - LLC_LEN - ETHER_HDR_LEN;
|
||||
circuit->rcv_stream->getp = 0;
|
||||
|
||||
memcpy (ssnpa, readbuff + bpf_hdr->bh_hdrlen + ETHER_ADDR_LEN,
|
||||
ETHER_ADDR_LEN);
|
||||
|
||||
memcpy (ssnpa, readbuff + bpf_hdr->bh_hdrlen + ETHER_ADDR_LEN,
|
||||
ETHER_ADDR_LEN);
|
||||
|
||||
if (ioctl (circuit->fd, BIOCFLUSH, &one) < 0)
|
||||
zlog_warn ("Flushing failed: %s", strerror (errno));
|
||||
|
||||
|
||||
return ISIS_OK;
|
||||
}
|
||||
|
||||
int
|
||||
isis_recv_pdu_p2p (struct isis_circuit *circuit, u_char *ssnpa)
|
||||
isis_recv_pdu_p2p (struct isis_circuit *circuit, u_char * ssnpa)
|
||||
{
|
||||
int bytesread;
|
||||
|
||||
bytesread = read (circuit->fd, STREAM_DATA(circuit->rcv_stream),
|
||||
circuit->interface->mtu);
|
||||
|
||||
if (bytesread < 0) {
|
||||
zlog_warn ("isis_recv_pdu_p2p(): read () failed: %s", strerror (errno));
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
bytesread = read (circuit->fd, STREAM_DATA (circuit->rcv_stream),
|
||||
circuit->interface->mtu);
|
||||
|
||||
if (bytesread < 0)
|
||||
{
|
||||
zlog_warn ("isis_recv_pdu_p2p(): read () failed: %s", strerror (errno));
|
||||
return ISIS_WARNING;
|
||||
}
|
||||
|
||||
circuit->rcv_stream->putp = bytesread;
|
||||
circuit->rcv_stream->endp = bytesread;
|
||||
|
||||
|
||||
return ISIS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
int
|
||||
isis_send_pdu_bcast (struct isis_circuit *circuit, int level)
|
||||
{
|
||||
struct ether_header *eth;
|
||||
@ -599,7 +620,7 @@ isis_send_pdu_bcast (struct isis_circuit *circuit, int level)
|
||||
/*
|
||||
* First the eth header
|
||||
*/
|
||||
eth = (struct ether_header *)sock_buff;
|
||||
eth = (struct ether_header *) sock_buff;
|
||||
if (level == 1)
|
||||
memcpy (eth->ether_dhost, ALL_L1_ISS, ETHER_ADDR_LEN);
|
||||
else
|
||||
@ -610,36 +631,25 @@ isis_send_pdu_bcast (struct isis_circuit *circuit, int level)
|
||||
/*
|
||||
* Then the LLC
|
||||
*/
|
||||
sock_buff[ETHER_HDR_LEN] = ISO_SAP;
|
||||
sock_buff[ETHER_HDR_LEN + 1] = ISO_SAP;
|
||||
sock_buff[ETHER_HDR_LEN + 2] = 0x03;
|
||||
sock_buff[ETHER_HDR_LEN] = ISO_SAP;
|
||||
sock_buff[ETHER_HDR_LEN + 1] = ISO_SAP;
|
||||
sock_buff[ETHER_HDR_LEN + 2] = 0x03;
|
||||
|
||||
/* then we copy the data */
|
||||
memcpy (sock_buff + (LLC_LEN + ETHER_HDR_LEN), circuit->snd_stream->data,
|
||||
stream_get_endp (circuit->snd_stream));
|
||||
memcpy (sock_buff + (LLC_LEN + ETHER_HDR_LEN), circuit->snd_stream->data,
|
||||
stream_get_endp (circuit->snd_stream));
|
||||
|
||||
/* now we can send this */
|
||||
written = write (circuit->fd, sock_buff,
|
||||
circuit->snd_stream->putp + LLC_LEN + ETHER_HDR_LEN);
|
||||
|
||||
circuit->snd_stream->putp + LLC_LEN + ETHER_HDR_LEN);
|
||||
|
||||
return ISIS_OK;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
isis_send_pdu_p2p (struct isis_circuit *circuit, int level)
|
||||
{
|
||||
|
||||
|
||||
return ISIS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* GNU_LINUX */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -29,8 +29,8 @@ extern u_char ALL_L2_ISYSTEMS[];
|
||||
|
||||
int isis_sock_init (struct isis_circuit *circuit);
|
||||
|
||||
int isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char *ssnpa);
|
||||
int isis_recv_pdu_p2p (struct isis_circuit *circuit, u_char *ssnpa);
|
||||
int isis_recv_pdu_bcast (struct isis_circuit *circuit, u_char * ssnpa);
|
||||
int isis_recv_pdu_p2p (struct isis_circuit *circuit, u_char * ssnpa);
|
||||
int isis_send_pdu_bcast (struct isis_circuit *circuit, int level);
|
||||
int isis_send_pdu_p2p (struct isis_circuit *circuit, int level);
|
||||
|
||||
|
||||
2888
isisd/isis_pdu.c
2888
isisd/isis_pdu.c
File diff suppressed because it is too large
Load Diff
@ -54,7 +54,7 @@ struct esis_fixed_hdr
|
||||
u_char pdu_type;
|
||||
u_int16_t holdtime;
|
||||
u_int16_t checksum;
|
||||
} __attribute__((packed));
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define ESIS_FIXED_HDR_LEN 9
|
||||
|
||||
@ -81,7 +81,7 @@ struct esis_fixed_hdr
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
*/
|
||||
|
||||
struct isis_fixed_hdr
|
||||
struct isis_fixed_hdr
|
||||
{
|
||||
u_char idrp;
|
||||
u_char length;
|
||||
@ -117,14 +117,15 @@ struct isis_fixed_hdr
|
||||
* | LAN ID | id_len + 1
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
*/
|
||||
struct isis_lan_hello_hdr {
|
||||
u_char circuit_t;
|
||||
u_char source_id[ISIS_SYS_ID_LEN];
|
||||
u_int16_t hold_time;
|
||||
u_int16_t pdu_len;
|
||||
u_char prio;
|
||||
u_char lan_id[ISIS_SYS_ID_LEN + 1];
|
||||
} __attribute__((packed));
|
||||
struct isis_lan_hello_hdr
|
||||
{
|
||||
u_char circuit_t;
|
||||
u_char source_id[ISIS_SYS_ID_LEN];
|
||||
u_int16_t hold_time;
|
||||
u_int16_t pdu_len;
|
||||
u_char prio;
|
||||
u_char lan_id[ISIS_SYS_ID_LEN + 1];
|
||||
} __attribute__ ((packed));
|
||||
#define ISIS_LANHELLO_HDRLEN 19
|
||||
|
||||
#define P2P_HELLO 17
|
||||
@ -142,13 +143,14 @@ struct isis_lan_hello_hdr {
|
||||
* | Local Circuit ID | 1
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
*/
|
||||
struct isis_p2p_hello_hdr {
|
||||
u_char circuit_t;
|
||||
u_char source_id[ISIS_SYS_ID_LEN];
|
||||
u_int16_t hold_time;
|
||||
u_int16_t pdu_len;
|
||||
struct isis_p2p_hello_hdr
|
||||
{
|
||||
u_char circuit_t;
|
||||
u_char source_id[ISIS_SYS_ID_LEN];
|
||||
u_int16_t hold_time;
|
||||
u_int16_t pdu_len;
|
||||
u_char local_id;
|
||||
} __attribute__((packed));
|
||||
} __attribute__ ((packed));
|
||||
#define ISIS_P2PHELLO_HDRLEN 12
|
||||
|
||||
#define L1_LINK_STATE 18
|
||||
@ -169,14 +171,15 @@ struct isis_p2p_hello_hdr {
|
||||
* | P | ATT |LSPDBOL| ISTYPE |
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
*/
|
||||
struct isis_link_state_hdr {
|
||||
u_int16_t pdu_len;
|
||||
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_char lsp_id[ISIS_SYS_ID_LEN + 2];
|
||||
u_int32_t seq_num;
|
||||
u_int16_t checksum;
|
||||
u_int8_t lsp_bits;
|
||||
} __attribute__((packed));
|
||||
u_int8_t lsp_bits;
|
||||
} __attribute__ ((packed));
|
||||
#define ISIS_LSP_HDR_LEN 19
|
||||
|
||||
#define L1_COMPLETE_SEQ_NUM 24
|
||||
@ -193,11 +196,12 @@ struct isis_link_state_hdr {
|
||||
* + End LSP ID + id_len + 2
|
||||
* +-------+-------+-------+-------+-------+-------+-------+-------+
|
||||
*/
|
||||
struct isis_complete_seqnum_hdr {
|
||||
struct isis_complete_seqnum_hdr
|
||||
{
|
||||
u_int16_t pdu_len;
|
||||
u_char source_id[ISIS_SYS_ID_LEN + 1];
|
||||
u_char start_lsp_id[ISIS_SYS_ID_LEN + 2];
|
||||
u_char stop_lsp_id[ISIS_SYS_ID_LEN + 2];
|
||||
u_char source_id[ISIS_SYS_ID_LEN + 1];
|
||||
u_char start_lsp_id[ISIS_SYS_ID_LEN + 2];
|
||||
u_char stop_lsp_id[ISIS_SYS_ID_LEN + 2];
|
||||
};
|
||||
#define ISIS_CSNP_HDRLEN 25
|
||||
|
||||
@ -211,9 +215,10 @@ struct isis_complete_seqnum_hdr {
|
||||
* + Source ID + id_len + 1
|
||||
* +---------------------------------------------------------------+
|
||||
*/
|
||||
struct isis_partial_seqnum_hdr {
|
||||
struct isis_partial_seqnum_hdr
|
||||
{
|
||||
u_int16_t pdu_len;
|
||||
u_char source_id[ISIS_SYS_ID_LEN + 1];
|
||||
u_char source_id[ISIS_SYS_ID_LEN + 1];
|
||||
};
|
||||
#define ISIS_PSNP_HDRLEN 9
|
||||
|
||||
@ -231,27 +236,22 @@ int isis_receive (struct thread *thread);
|
||||
/*
|
||||
* Sending functions
|
||||
*/
|
||||
int send_lan_l1_hello (struct thread *thread);
|
||||
int send_lan_l2_hello (struct thread *thread);
|
||||
int send_p2p_hello (struct thread *thread);
|
||||
int send_csnp (struct isis_circuit *circuit, int level);
|
||||
int send_l1_csnp (struct thread *thread);
|
||||
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);
|
||||
int send_hello (struct isis_circuit *circuit, int level);
|
||||
int send_lan_l1_hello (struct thread *thread);
|
||||
int send_lan_l2_hello (struct thread *thread);
|
||||
int send_p2p_hello (struct thread *thread);
|
||||
int send_csnp (struct isis_circuit *circuit, int level);
|
||||
int send_l1_csnp (struct thread *thread);
|
||||
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);
|
||||
int send_hello (struct isis_circuit *circuit, int level);
|
||||
|
||||
|
||||
int authentication_check (struct isis_passwd *one,
|
||||
int authentication_check (struct isis_passwd *one,
|
||||
struct isis_passwd *theother);
|
||||
|
||||
#endif /* _ZEBRA_ISIS_PDU_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -55,27 +55,28 @@ extern struct thread_master *master;
|
||||
|
||||
struct isis_nexthop *
|
||||
isis_nexthop_create (struct in_addr *ip, unsigned int ifindex)
|
||||
|
||||
{
|
||||
struct listnode *node;
|
||||
struct isis_nexthop *nexthop;
|
||||
|
||||
for (node = listhead (isis->nexthops); node; nextnode (node)) {
|
||||
nexthop = getdata (node);
|
||||
if (nexthop->ifindex != ifindex)
|
||||
continue;
|
||||
if (ip && memcmp (&nexthop->ip, ip, sizeof (struct in_addr)) != 0)
|
||||
continue;
|
||||
|
||||
nexthop->lock++;
|
||||
return nexthop;
|
||||
}
|
||||
|
||||
for (node = listhead (isis->nexthops); node; nextnode (node))
|
||||
{
|
||||
nexthop = getdata (node);
|
||||
if (nexthop->ifindex != ifindex)
|
||||
continue;
|
||||
if (ip && memcmp (&nexthop->ip, ip, sizeof (struct in_addr)) != 0)
|
||||
continue;
|
||||
|
||||
nexthop->lock++;
|
||||
return nexthop;
|
||||
}
|
||||
|
||||
nexthop = XMALLOC (MTYPE_ISIS_NEXTHOP, sizeof (struct isis_nexthop));
|
||||
if (!nexthop) {
|
||||
zlog_err ("ISIS-Rte: isis_nexthop_create: out of memory!");
|
||||
}
|
||||
|
||||
if (!nexthop)
|
||||
{
|
||||
zlog_err ("ISIS-Rte: isis_nexthop_create: out of memory!");
|
||||
}
|
||||
|
||||
memset (nexthop, 0, sizeof (struct isis_nexthop));
|
||||
nexthop->ifindex = ifindex;
|
||||
memcpy (&nexthop->ip, ip, sizeof (struct in_addr));
|
||||
@ -85,32 +86,33 @@ isis_nexthop_create (struct in_addr *ip, unsigned int ifindex)
|
||||
return nexthop;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
isis_nexthop_delete (struct isis_nexthop *nexthop)
|
||||
{
|
||||
nexthop->lock--;
|
||||
if (nexthop->lock == 0) {
|
||||
listnode_delete (isis->nexthops, nexthop);
|
||||
XFREE (MTYPE_ISIS_NEXTHOP, nexthop);
|
||||
}
|
||||
|
||||
if (nexthop->lock == 0)
|
||||
{
|
||||
listnode_delete (isis->nexthops, nexthop);
|
||||
XFREE (MTYPE_ISIS_NEXTHOP, nexthop);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
nexthoplookup (struct list *nexthops, struct in_addr *ip,
|
||||
unsigned int ifindex)
|
||||
nexthoplookup (struct list *nexthops, struct in_addr *ip,
|
||||
unsigned int ifindex)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct isis_nexthop *nh;
|
||||
|
||||
for (node = listhead (nexthops); node; nextnode (node)) {
|
||||
nh = getdata (node);
|
||||
if (!(memcmp (ip, &nh->ip, sizeof (struct in_addr))) &&
|
||||
ifindex == nh->ifindex)
|
||||
return 1;
|
||||
}
|
||||
for (node = listhead (nexthops); node; nextnode (node))
|
||||
{
|
||||
nh = getdata (node);
|
||||
if (!(memcmp (ip, &nh->ip, sizeof (struct in_addr))) &&
|
||||
ifindex == nh->ifindex)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -119,9 +121,9 @@ void
|
||||
nexthop_print (struct isis_nexthop *nh)
|
||||
{
|
||||
u_char buf[BUFSIZ];
|
||||
|
||||
|
||||
inet_ntop (AF_INET, &nh->ip, buf, BUFSIZ);
|
||||
|
||||
|
||||
zlog_info (" %s %u", buf, nh->ifindex);
|
||||
}
|
||||
|
||||
@ -129,24 +131,25 @@ void
|
||||
nexthops_print (struct list *nhs)
|
||||
{
|
||||
struct listnode *node;
|
||||
|
||||
for (node = listhead(nhs); node; nextnode (node))
|
||||
|
||||
for (node = listhead (nhs); node; nextnode (node))
|
||||
nexthop_print (getdata (node));
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
|
||||
struct isis_nexthop6 *
|
||||
isis_nexthop6_new (struct in6_addr *ip6, unsigned int ifindex)
|
||||
isis_nexthop6_new (struct in6_addr *ip6, unsigned int ifindex)
|
||||
{
|
||||
|
||||
|
||||
struct isis_nexthop6 *nexthop6;
|
||||
|
||||
|
||||
nexthop6 = XMALLOC (MTYPE_ISIS_NEXTHOP6, sizeof (struct isis_nexthop6));
|
||||
if (!nexthop6) {
|
||||
zlog_err ("ISIS-Rte: isis_nexthop_create6: out of memory!");
|
||||
}
|
||||
|
||||
if (!nexthop6)
|
||||
{
|
||||
zlog_err ("ISIS-Rte: isis_nexthop_create6: out of memory!");
|
||||
}
|
||||
|
||||
memset (nexthop6, 0, sizeof (struct isis_nexthop6));
|
||||
nexthop6->ifindex = ifindex;
|
||||
memcpy (&nexthop6->ip6, ip6, sizeof (struct in6_addr));
|
||||
@ -157,54 +160,55 @@ isis_nexthop6_new (struct in6_addr *ip6, unsigned int ifindex)
|
||||
|
||||
struct isis_nexthop6 *
|
||||
isis_nexthop6_create (struct in6_addr *ip6, unsigned int ifindex)
|
||||
|
||||
{
|
||||
struct listnode *node;
|
||||
struct isis_nexthop6 *nexthop6;
|
||||
|
||||
for (node = listhead (isis->nexthops6); node; nextnode (node)) {
|
||||
nexthop6 = getdata (node);
|
||||
if (nexthop6->ifindex != ifindex)
|
||||
continue;
|
||||
if (ip6 && memcmp (&nexthop6->ip6, ip6, sizeof (struct in6_addr)) != 0)
|
||||
continue;
|
||||
|
||||
nexthop6->lock++;
|
||||
return nexthop6;
|
||||
}
|
||||
|
||||
for (node = listhead (isis->nexthops6); node; nextnode (node))
|
||||
{
|
||||
nexthop6 = getdata (node);
|
||||
if (nexthop6->ifindex != ifindex)
|
||||
continue;
|
||||
if (ip6 && memcmp (&nexthop6->ip6, ip6, sizeof (struct in6_addr)) != 0)
|
||||
continue;
|
||||
|
||||
nexthop6->lock++;
|
||||
return nexthop6;
|
||||
}
|
||||
|
||||
nexthop6 = isis_nexthop6_new (ip6, ifindex);
|
||||
|
||||
return nexthop6;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
isis_nexthop6_delete (struct isis_nexthop6 *nexthop6)
|
||||
{
|
||||
|
||||
nexthop6->lock--;
|
||||
if (nexthop6->lock == 0) {
|
||||
listnode_delete (isis->nexthops6, nexthop6);
|
||||
XFREE (MTYPE_ISIS_NEXTHOP6, nexthop6);
|
||||
}
|
||||
|
||||
if (nexthop6->lock == 0)
|
||||
{
|
||||
listnode_delete (isis->nexthops6, nexthop6);
|
||||
XFREE (MTYPE_ISIS_NEXTHOP6, nexthop6);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
nexthop6lookup (struct list *nexthops6, struct in6_addr *ip6,
|
||||
unsigned int ifindex)
|
||||
nexthop6lookup (struct list *nexthops6, struct in6_addr *ip6,
|
||||
unsigned int ifindex)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct isis_nexthop6 *nh6;
|
||||
|
||||
for (node = listhead (nexthops6); node; nextnode (node)) {
|
||||
nh6 = getdata (node);
|
||||
if (!(memcmp (ip6, &nh6->ip6, sizeof (struct in6_addr))) &&
|
||||
ifindex == nh6->ifindex)
|
||||
return 1;
|
||||
}
|
||||
for (node = listhead (nexthops6); node; nextnode (node))
|
||||
{
|
||||
nh6 = getdata (node);
|
||||
if (!(memcmp (ip6, &nh6->ip6, sizeof (struct in6_addr))) &&
|
||||
ifindex == nh6->ifindex)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -213,9 +217,9 @@ void
|
||||
nexthop6_print (struct isis_nexthop6 *nh6)
|
||||
{
|
||||
u_char buf[BUFSIZ];
|
||||
|
||||
|
||||
inet_ntop (AF_INET6, &nh6->ip6, buf, BUFSIZ);
|
||||
|
||||
|
||||
zlog_info (" %s %u", buf, nh6->ifindex);
|
||||
}
|
||||
|
||||
@ -223,8 +227,8 @@ void
|
||||
nexthops6_print (struct list *nhs6)
|
||||
{
|
||||
struct listnode *node;
|
||||
|
||||
for (node = listhead(nhs6); node; nextnode (node))
|
||||
|
||||
for (node = listhead (nhs6); node; nextnode (node))
|
||||
nexthop6_print (getdata (node));
|
||||
}
|
||||
|
||||
@ -240,15 +244,17 @@ adjinfo2nexthop (struct list *nexthops, struct isis_adjacency *adj)
|
||||
|
||||
if (adj->ipv4_addrs == NULL)
|
||||
return;
|
||||
for (node = listhead (adj->ipv4_addrs); node; nextnode (node)) {
|
||||
ipv4_addr = getdata (node);
|
||||
if (!nexthoplookup (nexthops, ipv4_addr,
|
||||
adj->circuit->interface->ifindex)) {
|
||||
nh = isis_nexthop_create (ipv4_addr,
|
||||
adj->circuit->interface->ifindex);
|
||||
listnode_add (nexthops, nh);
|
||||
for (node = listhead (adj->ipv4_addrs); node; nextnode (node))
|
||||
{
|
||||
ipv4_addr = getdata (node);
|
||||
if (!nexthoplookup (nexthops, ipv4_addr,
|
||||
adj->circuit->interface->ifindex))
|
||||
{
|
||||
nh = isis_nexthop_create (ipv4_addr,
|
||||
adj->circuit->interface->ifindex);
|
||||
listnode_add (nexthops, nh);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
@ -258,156 +264,170 @@ adjinfo2nexthop6 (struct list *nexthops6, struct isis_adjacency *adj)
|
||||
struct listnode *node;
|
||||
struct in6_addr *ipv6_addr;
|
||||
struct isis_nexthop6 *nh6;
|
||||
|
||||
|
||||
if (!adj->ipv6_addrs)
|
||||
return;
|
||||
|
||||
for (node = listhead (adj->ipv6_addrs); node; nextnode (node)) {
|
||||
ipv6_addr = getdata (node);
|
||||
if (!nexthop6lookup (nexthops6, ipv6_addr,
|
||||
adj->circuit->interface->ifindex)) {
|
||||
nh6 = isis_nexthop6_create (ipv6_addr,
|
||||
adj->circuit->interface->ifindex);
|
||||
listnode_add (nexthops6, nh6);
|
||||
for (node = listhead (adj->ipv6_addrs); node; nextnode (node))
|
||||
{
|
||||
ipv6_addr = getdata (node);
|
||||
if (!nexthop6lookup (nexthops6, ipv6_addr,
|
||||
adj->circuit->interface->ifindex))
|
||||
{
|
||||
nh6 = isis_nexthop6_create (ipv6_addr,
|
||||
adj->circuit->interface->ifindex);
|
||||
listnode_add (nexthops6, nh6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
struct isis_route_info *
|
||||
isis_route_info_new (uint32_t cost, uint32_t depth, u_char family,
|
||||
struct list *adjacencies)
|
||||
isis_route_info_new (uint32_t cost, uint32_t depth, u_char family,
|
||||
struct list *adjacencies)
|
||||
{
|
||||
struct isis_route_info *rinfo;
|
||||
struct isis_adjacency *adj;
|
||||
struct listnode *node;
|
||||
|
||||
|
||||
rinfo = XMALLOC (MTYPE_ISIS_ROUTE_INFO, sizeof (struct isis_route_info));
|
||||
if (!rinfo) {
|
||||
zlog_err ("ISIS-Rte: isis_route_info_new: out of memory!");
|
||||
return NULL;
|
||||
}
|
||||
if (!rinfo)
|
||||
{
|
||||
zlog_err ("ISIS-Rte: isis_route_info_new: out of memory!");
|
||||
return NULL;
|
||||
}
|
||||
memset (rinfo, 0, sizeof (struct isis_route_info));
|
||||
|
||||
if (family == AF_INET) {
|
||||
rinfo->nexthops = list_new ();
|
||||
for (node = listhead (adjacencies); node; nextnode (node)) {
|
||||
adj = getdata (node);
|
||||
adjinfo2nexthop (rinfo->nexthops, adj);
|
||||
if (family == AF_INET)
|
||||
{
|
||||
rinfo->nexthops = list_new ();
|
||||
for (node = listhead (adjacencies); node; nextnode (node))
|
||||
{
|
||||
adj = getdata (node);
|
||||
adjinfo2nexthop (rinfo->nexthops, adj);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
if (family == AF_INET6) {
|
||||
rinfo->nexthops6 = list_new ();
|
||||
for (node = listhead (adjacencies); node; nextnode (node)) {
|
||||
adj =getdata (node);
|
||||
adjinfo2nexthop6 (rinfo->nexthops6, adj);
|
||||
if (family == AF_INET6)
|
||||
{
|
||||
rinfo->nexthops6 = list_new ();
|
||||
for (node = listhead (adjacencies); node; nextnode (node))
|
||||
{
|
||||
adj = getdata (node);
|
||||
adjinfo2nexthop6 (rinfo->nexthops6, adj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
rinfo->cost = cost;
|
||||
rinfo->depth = depth;
|
||||
|
||||
|
||||
return rinfo;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
isis_route_info_delete (struct isis_route_info *route_info)
|
||||
{
|
||||
|
||||
if (route_info->nexthops) {
|
||||
route_info->nexthops->del = (void *)isis_nexthop_delete;
|
||||
list_delete (route_info->nexthops);
|
||||
}
|
||||
|
||||
if (route_info->nexthops)
|
||||
{
|
||||
route_info->nexthops->del = (void *) isis_nexthop_delete;
|
||||
list_delete (route_info->nexthops);
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
if (route_info->nexthops6) {
|
||||
route_info->nexthops6->del = (void *)isis_nexthop6_delete;
|
||||
if (route_info->nexthops6)
|
||||
{
|
||||
route_info->nexthops6->del = (void *) isis_nexthop6_delete;
|
||||
list_delete (route_info->nexthops6);
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
|
||||
XFREE (MTYPE_ISIS_ROUTE_INFO, route_info);
|
||||
}
|
||||
|
||||
int
|
||||
isis_route_info_same_attrib (struct isis_route_info *new,
|
||||
struct isis_route_info *old)
|
||||
isis_route_info_same_attrib (struct isis_route_info *new,
|
||||
struct isis_route_info *old)
|
||||
{
|
||||
if (new->cost != old->cost)
|
||||
return 0;
|
||||
if (new->depth != old->depth)
|
||||
return 0;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
isis_route_info_same (struct isis_route_info *new, struct isis_route_info *old,
|
||||
u_char family)
|
||||
isis_route_info_same (struct isis_route_info *new,
|
||||
struct isis_route_info *old, u_char family)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct listnode *node;
|
||||
struct isis_nexthop *nexthop;
|
||||
#ifdef HAVE_IPV6
|
||||
struct isis_nexthop6 *nexthop6;
|
||||
#endif /* HAVE_IPV6 */
|
||||
if (!isis_route_info_same_attrib (new, old))
|
||||
return 0;
|
||||
|
||||
if (family == AF_INET) {
|
||||
for (node = listhead (new->nexthops); node; nextnode (node)) {
|
||||
nexthop = (struct isis_nexthop *) getdata (node);
|
||||
if (nexthoplookup (old->nexthops, &nexthop->ip, nexthop->ifindex) == 0)
|
||||
return 0;
|
||||
|
||||
if (family == AF_INET)
|
||||
{
|
||||
for (node = listhead (new->nexthops); node; nextnode (node))
|
||||
{
|
||||
nexthop = (struct isis_nexthop *) getdata (node);
|
||||
if (nexthoplookup (old->nexthops, &nexthop->ip, nexthop->ifindex) ==
|
||||
0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (node = listhead (old->nexthops); node; nextnode (node))
|
||||
{
|
||||
nexthop = (struct isis_nexthop *) getdata (node);
|
||||
if (nexthoplookup (new->nexthops, &nexthop->ip, nexthop->ifindex) ==
|
||||
0)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (node = listhead (old->nexthops); node; nextnode (node)) {
|
||||
nexthop = (struct isis_nexthop *) getdata (node);
|
||||
if (nexthoplookup (new->nexthops, &nexthop->ip, nexthop->ifindex) == 0)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else if (family == AF_INET6) {
|
||||
for (node = listhead (new->nexthops6); node; nextnode (node)) {
|
||||
nexthop6 = (struct isis_nexthop6 *) getdata (node);
|
||||
if (nexthop6lookup (old->nexthops6, &nexthop6->ip6,
|
||||
nexthop6->ifindex) == 0)
|
||||
return 0;
|
||||
else if (family == AF_INET6)
|
||||
{
|
||||
for (node = listhead (new->nexthops6); node; nextnode (node))
|
||||
{
|
||||
nexthop6 = (struct isis_nexthop6 *) getdata (node);
|
||||
if (nexthop6lookup (old->nexthops6, &nexthop6->ip6,
|
||||
nexthop6->ifindex) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (node = listhead (old->nexthops6); node; nextnode (node))
|
||||
{
|
||||
nexthop6 = (struct isis_nexthop6 *) getdata (node);
|
||||
if (nexthop6lookup (new->nexthops6, &nexthop6->ip6,
|
||||
nexthop6->ifindex) == 0)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (node = listhead (old->nexthops6); node; nextnode (node)) {
|
||||
nexthop6 = (struct isis_nexthop6 *) getdata (node);
|
||||
if (nexthop6lookup (new->nexthops6, &nexthop6->ip6,
|
||||
nexthop6->ifindex) == 0)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
isis_nexthops_merge (struct list *new, struct list *old)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct isis_nexthop *nexthop;
|
||||
|
||||
for (node = listhead (new); node; nextnode (node)) {
|
||||
nexthop = (struct isis_nexthop *) getdata (node);
|
||||
if (nexthoplookup (old, &nexthop->ip, nexthop->ifindex))
|
||||
continue;
|
||||
listnode_add (old, nexthop);
|
||||
nexthop->lock++;
|
||||
}
|
||||
for (node = listhead (new); node; nextnode (node))
|
||||
{
|
||||
nexthop = (struct isis_nexthop *) getdata (node);
|
||||
if (nexthoplookup (old, &nexthop->ip, nexthop->ifindex))
|
||||
continue;
|
||||
listnode_add (old, nexthop);
|
||||
nexthop->lock++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
void
|
||||
isis_nexthops6_merge (struct list *new, struct list *old)
|
||||
@ -415,123 +435,133 @@ isis_nexthops6_merge (struct list *new, struct list *old)
|
||||
struct listnode *node;
|
||||
struct isis_nexthop6 *nexthop6;
|
||||
|
||||
for (node = listhead (new); node; nextnode (node)) {
|
||||
nexthop6 = (struct isis_nexthop6 *) getdata (node);
|
||||
if (nexthop6lookup (old, &nexthop6->ip6, nexthop6->ifindex))
|
||||
continue;
|
||||
listnode_add (old, nexthop6);
|
||||
nexthop6->lock++;
|
||||
}
|
||||
for (node = listhead (new); node; nextnode (node))
|
||||
{
|
||||
nexthop6 = (struct isis_nexthop6 *) getdata (node);
|
||||
if (nexthop6lookup (old, &nexthop6->ip6, nexthop6->ifindex))
|
||||
continue;
|
||||
listnode_add (old, nexthop6);
|
||||
nexthop6->lock++;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
void
|
||||
isis_route_info_merge (struct isis_route_info *new,
|
||||
struct isis_route_info *old, u_char family)
|
||||
isis_route_info_merge (struct isis_route_info *new,
|
||||
struct isis_route_info *old, u_char family)
|
||||
{
|
||||
|
||||
if (family == AF_INET)
|
||||
if (family == AF_INET)
|
||||
isis_nexthops_merge (new->nexthops, old->nexthops);
|
||||
#ifdef HAVE_IPV6
|
||||
else if (family == AF_INET6)
|
||||
else if (family == AF_INET6)
|
||||
isis_nexthops6_merge (new->nexthops6, old->nexthops6);
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
isis_route_info_prefer_new (struct isis_route_info *new,
|
||||
struct isis_route_info *old)
|
||||
isis_route_info_prefer_new (struct isis_route_info *new,
|
||||
struct isis_route_info *old)
|
||||
{
|
||||
|
||||
if (!CHECK_FLAG (old->flag, ISIS_ROUTE_FLAG_ACTIVE))
|
||||
return 1;
|
||||
|
||||
if (new->cost < old->cost)
|
||||
return 1;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct isis_route_info *
|
||||
isis_route_create (struct prefix *prefix, u_int32_t cost, u_int32_t depth,
|
||||
struct list *adjacencies, struct isis_area *area)
|
||||
struct list *adjacencies, struct isis_area *area)
|
||||
{
|
||||
struct route_node *route_node;
|
||||
struct isis_route_info *rinfo_new, *rinfo_old, *route_info = NULL;
|
||||
u_char buff[BUFSIZ];
|
||||
u_char family;
|
||||
|
||||
|
||||
family = prefix->family;
|
||||
/* for debugs */
|
||||
prefix2str (prefix, buff, BUFSIZ);
|
||||
|
||||
|
||||
rinfo_new = isis_route_info_new (cost, depth, family, adjacencies);
|
||||
if (!rinfo_new) {
|
||||
zlog_err ("ISIS-Rte (%s): isis_route_create: out of memory!",
|
||||
area->area_tag);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!rinfo_new)
|
||||
{
|
||||
zlog_err ("ISIS-Rte (%s): isis_route_create: out of memory!",
|
||||
area->area_tag);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (family == AF_INET)
|
||||
route_node = route_node_get (area->route_table, prefix);
|
||||
route_node = route_node_get (area->route_table, prefix);
|
||||
#ifdef HAVE_IPV6
|
||||
else if (family == AF_INET6)
|
||||
route_node = route_node_get (area->route_table6, prefix);
|
||||
route_node = route_node_get (area->route_table6, prefix);
|
||||
#endif /* HAVE_IPV6 */
|
||||
else
|
||||
else
|
||||
return NULL;
|
||||
rinfo_old = route_node->info;
|
||||
if (!rinfo_old) {
|
||||
if (isis->debugs & DEBUG_RTE_EVENTS)
|
||||
zlog_info ("ISIS-Rte (%s) route created: %s", area->area_tag, buff);
|
||||
SET_FLAG(rinfo_new->flag, ISIS_ROUTE_FLAG_ACTIVE);
|
||||
route_node->info = rinfo_new;
|
||||
return rinfo_new;
|
||||
}
|
||||
|
||||
rinfo_old = route_node->info;
|
||||
if (!rinfo_old)
|
||||
{
|
||||
if (isis->debugs & DEBUG_RTE_EVENTS)
|
||||
zlog_info ("ISIS-Rte (%s) route created: %s", area->area_tag, buff);
|
||||
SET_FLAG (rinfo_new->flag, ISIS_ROUTE_FLAG_ACTIVE);
|
||||
route_node->info = rinfo_new;
|
||||
return rinfo_new;
|
||||
}
|
||||
|
||||
if (isis->debugs & DEBUG_RTE_EVENTS)
|
||||
zlog_info ("ISIS-Rte (%s) route already exists: %s", area->area_tag, buff);
|
||||
|
||||
if (isis_route_info_same (rinfo_new, rinfo_old, family)) {
|
||||
if (isis->debugs & DEBUG_RTE_EVENTS)
|
||||
zlog_info ("ISIS-Rte (%s) route unchanged: %s", area->area_tag, buff);
|
||||
isis_route_info_delete (rinfo_new);
|
||||
route_info = rinfo_old;
|
||||
} else if (isis_route_info_same_attrib (rinfo_new, rinfo_old)) {
|
||||
/* merge the nexthop lists */
|
||||
if (isis->debugs & DEBUG_RTE_EVENTS)
|
||||
zlog_info ("ISIS-Rte (%s) route changed (same attribs): %s",
|
||||
area->area_tag, buff);
|
||||
#ifdef EXTREME_DEBUG
|
||||
zlog_info ("Old nexthops");
|
||||
nexthops6_print (rinfo_old->nexthops6);
|
||||
zlog_info ("New nexthops");
|
||||
nexthops6_print (rinfo_new->nexthops6);
|
||||
#endif /* EXTREME_DEBUG */
|
||||
isis_route_info_merge (rinfo_new, rinfo_old, family);
|
||||
isis_route_info_delete (rinfo_new);
|
||||
route_info = rinfo_old;
|
||||
} else {
|
||||
if (isis_route_info_prefer_new (rinfo_new, rinfo_old)) {
|
||||
zlog_info ("ISIS-Rte (%s) route already exists: %s", area->area_tag,
|
||||
buff);
|
||||
|
||||
if (isis_route_info_same (rinfo_new, rinfo_old, family))
|
||||
{
|
||||
if (isis->debugs & DEBUG_RTE_EVENTS)
|
||||
zlog_info ("ISIS-Rte (%s) route changed: %s", area->area_tag, buff);
|
||||
isis_route_info_delete (rinfo_old);
|
||||
route_info = rinfo_new;
|
||||
} else {
|
||||
if (isis->debugs & DEBUG_RTE_EVENTS)
|
||||
zlog_info ("ISIS-Rte (%s) route rejected: %s", area->area_tag, buff);
|
||||
zlog_info ("ISIS-Rte (%s) route unchanged: %s", area->area_tag, buff);
|
||||
isis_route_info_delete (rinfo_new);
|
||||
route_info = rinfo_old;
|
||||
}
|
||||
}
|
||||
|
||||
else if (isis_route_info_same_attrib (rinfo_new, rinfo_old))
|
||||
{
|
||||
/* merge the nexthop lists */
|
||||
if (isis->debugs & DEBUG_RTE_EVENTS)
|
||||
zlog_info ("ISIS-Rte (%s) route changed (same attribs): %s",
|
||||
area->area_tag, buff);
|
||||
#ifdef EXTREME_DEBUG
|
||||
zlog_info ("Old nexthops");
|
||||
nexthops6_print (rinfo_old->nexthops6);
|
||||
zlog_info ("New nexthops");
|
||||
nexthops6_print (rinfo_new->nexthops6);
|
||||
#endif /* EXTREME_DEBUG */
|
||||
isis_route_info_merge (rinfo_new, rinfo_old, family);
|
||||
isis_route_info_delete (rinfo_new);
|
||||
route_info = rinfo_old;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isis_route_info_prefer_new (rinfo_new, rinfo_old))
|
||||
{
|
||||
if (isis->debugs & DEBUG_RTE_EVENTS)
|
||||
zlog_info ("ISIS-Rte (%s) route changed: %s", area->area_tag,
|
||||
buff);
|
||||
isis_route_info_delete (rinfo_old);
|
||||
route_info = rinfo_new;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isis->debugs & DEBUG_RTE_EVENTS)
|
||||
zlog_info ("ISIS-Rte (%s) route rejected: %s", area->area_tag,
|
||||
buff);
|
||||
isis_route_info_delete (rinfo_new);
|
||||
route_info = rinfo_old;
|
||||
}
|
||||
}
|
||||
|
||||
SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE);
|
||||
route_node->info = route_info;
|
||||
|
||||
|
||||
return route_info;
|
||||
}
|
||||
|
||||
@ -549,21 +579,23 @@ isis_route_delete (struct prefix *prefix, struct route_table *table)
|
||||
rode = route_node_get (table, prefix);
|
||||
rinfo = rode->info;
|
||||
|
||||
if (rinfo == NULL) {
|
||||
if (isis->debugs & DEBUG_RTE_EVENTS)
|
||||
zlog_info ("ISIS-Rte: tried to delete non-existant route %s", buff);
|
||||
return;
|
||||
}
|
||||
if (rinfo == NULL)
|
||||
{
|
||||
if (isis->debugs & DEBUG_RTE_EVENTS)
|
||||
zlog_info ("ISIS-Rte: tried to delete non-existant route %s", buff);
|
||||
return;
|
||||
}
|
||||
|
||||
if (CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC)) {
|
||||
UNSET_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE);
|
||||
if (isis->debugs & DEBUG_RTE_EVENTS)
|
||||
zlog_info ("ISIS-Rte: route delete %s", buff);
|
||||
isis_zebra_route_update (prefix, rinfo);
|
||||
}
|
||||
if (CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC))
|
||||
{
|
||||
UNSET_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE);
|
||||
if (isis->debugs & DEBUG_RTE_EVENTS)
|
||||
zlog_info ("ISIS-Rte: route delete %s", buff);
|
||||
isis_zebra_route_update (prefix, rinfo);
|
||||
}
|
||||
isis_route_info_delete (rinfo);
|
||||
rode->info = NULL;
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -581,27 +613,29 @@ isis_route_validate (struct thread *thread)
|
||||
area = THREAD_ARG (thread);
|
||||
table = area->route_table;
|
||||
#ifdef HAVE_IPV6
|
||||
again:
|
||||
again:
|
||||
#endif
|
||||
for (rode = route_top (table); rode; rode = route_next (rode)) {
|
||||
if (rode->info == NULL)
|
||||
continue;
|
||||
rinfo = rode->info;
|
||||
|
||||
if (isis->debugs & DEBUG_RTE_EVENTS) {
|
||||
prefix2str (&rode->p, buff, BUFSIZ);
|
||||
zlog_info ("ISIS-Rte (%s): route validate: %s %s %s",
|
||||
area->area_tag,
|
||||
(CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC) ?
|
||||
"sync'ed": "nosync"),
|
||||
(CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE) ?
|
||||
"active": "inactive"), buff);
|
||||
for (rode = route_top (table); rode; rode = route_next (rode))
|
||||
{
|
||||
if (rode->info == NULL)
|
||||
continue;
|
||||
rinfo = rode->info;
|
||||
|
||||
if (isis->debugs & DEBUG_RTE_EVENTS)
|
||||
{
|
||||
prefix2str (&rode->p, buff, BUFSIZ);
|
||||
zlog_info ("ISIS-Rte (%s): route validate: %s %s %s",
|
||||
area->area_tag,
|
||||
(CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC) ?
|
||||
"sync'ed" : "nosync"),
|
||||
(CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE) ?
|
||||
"active" : "inactive"), buff);
|
||||
}
|
||||
|
||||
isis_zebra_route_update (&rode->p, rinfo);
|
||||
if (!CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE))
|
||||
isis_route_delete (&rode->p, area->route_table);
|
||||
}
|
||||
|
||||
isis_zebra_route_update (&rode->p, rinfo);
|
||||
if (!CHECK_FLAG (rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE))
|
||||
isis_route_delete (&rode->p, area->route_table);
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
if (v6done)
|
||||
return ISIS_OK;
|
||||
|
||||
@ -26,35 +26,38 @@
|
||||
#define _ZEBRA_ISIS_ROUTE_H
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
struct isis_nexthop6 {
|
||||
struct isis_nexthop6
|
||||
{
|
||||
unsigned int ifindex;
|
||||
struct in6_addr ip6;
|
||||
unsigned int lock;
|
||||
};
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
struct isis_nexthop {
|
||||
struct isis_nexthop
|
||||
{
|
||||
unsigned int ifindex;
|
||||
struct in_addr ip;
|
||||
unsigned int lock;
|
||||
};
|
||||
|
||||
struct isis_route_info {
|
||||
struct isis_route_info
|
||||
{
|
||||
#define ISIS_ROUTE_FLAG_ZEBRA_SYNC 0x01
|
||||
#define ISIS_ROUTE_FLAG_ACTIVE 0x02
|
||||
u_char flag;
|
||||
u_char flag;
|
||||
u_int32_t cost;
|
||||
u_int32_t depth;
|
||||
struct list *nexthops;
|
||||
#ifdef HAVE_IPV6
|
||||
struct list *nexthops6;
|
||||
#endif /* HAVE_IPV6 */
|
||||
#endif /* HAVE_IPV6 */
|
||||
};
|
||||
|
||||
struct isis_route_info *isis_route_create (struct prefix *prefix,
|
||||
u_int32_t cost, u_int32_t depth,
|
||||
struct list *adjacencies,
|
||||
struct isis_area *area);
|
||||
struct isis_route_info *isis_route_create (struct prefix *prefix,
|
||||
u_int32_t cost, u_int32_t depth,
|
||||
struct list *adjacencies,
|
||||
struct isis_area *area);
|
||||
|
||||
int isis_route_validate (struct thread *thread);
|
||||
|
||||
|
||||
@ -52,48 +52,49 @@
|
||||
extern struct isis *isis;
|
||||
|
||||
void
|
||||
isis_route_map_upd()
|
||||
isis_route_map_upd ()
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
|
||||
if (!isis)
|
||||
return;
|
||||
|
||||
for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) {
|
||||
if (isis->rmap[i].name)
|
||||
isis->rmap[i].map = isis->rmap[i].map =
|
||||
route_map_lookup_by_name (isis->rmap[i].name);
|
||||
else
|
||||
isis->rmap[i].map = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
|
||||
{
|
||||
if (isis->rmap[i].name)
|
||||
isis->rmap[i].map = isis->rmap[i].map =
|
||||
route_map_lookup_by_name (isis->rmap[i].name);
|
||||
else
|
||||
isis->rmap[i].map = NULL;
|
||||
}
|
||||
/* FIXME: do the address family sub-mode AF_INET6 here ? */
|
||||
}
|
||||
|
||||
void
|
||||
isis_route_map_event(route_map_event_t event, char *name)
|
||||
isis_route_map_event (route_map_event_t event, char *name)
|
||||
{
|
||||
int type;
|
||||
|
||||
if (!isis)
|
||||
return;
|
||||
|
||||
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
|
||||
if (isis->rmap[type].name && isis->rmap[type].map &&
|
||||
!strcmp (isis->rmap[type].name, name)) {
|
||||
isis_distribute_list_update (type);
|
||||
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
|
||||
{
|
||||
if (isis->rmap[type].name && isis->rmap[type].map &&
|
||||
!strcmp (isis->rmap[type].name, name))
|
||||
{
|
||||
isis_distribute_list_update (type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
isis_route_map_init (void)
|
||||
{
|
||||
route_map_init ();
|
||||
route_map_init_vty ();
|
||||
|
||||
|
||||
route_map_add_hook (isis_route_map_upd);
|
||||
route_map_delete_hook (isis_route_map_upd);
|
||||
route_map_event_hook (isis_route_map_event);
|
||||
|
||||
}
|
||||
|
||||
1625
isisd/isis_spf.c
1625
isisd/isis_spf.c
File diff suppressed because it is too large
Load Diff
@ -24,17 +24,18 @@
|
||||
#ifndef _ZEBRA_ISIS_SPF_H
|
||||
#define _ZEBRA_ISIS_SPF_H
|
||||
|
||||
enum vertextype {
|
||||
enum vertextype
|
||||
{
|
||||
VTYPE_PSEUDO_IS = 1,
|
||||
VTYPE_NONPSEUDO_IS,
|
||||
VTYPE_ES,
|
||||
VTYPE_IPREACH_INTERNAL,
|
||||
VTYPE_IPREACH_EXTERNAL
|
||||
#ifdef HAVE_IPV6
|
||||
,
|
||||
,
|
||||
VTYPE_IP6REACH_INTERNAL,
|
||||
VTYPE_IP6REACH_EXTERNAL
|
||||
#endif /* HAVE_IPV6 */
|
||||
#endif /* HAVE_IPV6 */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -44,28 +45,28 @@ struct isis_vertex
|
||||
{
|
||||
enum vertextype type;
|
||||
|
||||
union {
|
||||
u_char id [ISIS_SYS_ID_LEN + 1];
|
||||
union
|
||||
{
|
||||
u_char id[ISIS_SYS_ID_LEN + 1];
|
||||
struct prefix prefix;
|
||||
} N;
|
||||
|
||||
|
||||
struct isis_lsp *lsp;
|
||||
u_int32_t d_N; /* d(N) Distance from this IS */
|
||||
u_int16_t depth; /* The depth in the imaginary tree */
|
||||
|
||||
struct list *Adj_N; /* {Adj(N)} */
|
||||
};
|
||||
u_int32_t d_N; /* d(N) Distance from this IS */
|
||||
u_int16_t depth; /* The depth in the imaginary tree */
|
||||
|
||||
struct list *Adj_N; /* {Adj(N)} */
|
||||
};
|
||||
|
||||
struct isis_spftree
|
||||
{
|
||||
struct thread *t_spf_periodic; /* periodic spf threads */
|
||||
time_t lastrun; /* for scheduling */
|
||||
int pending; /* already scheduled */
|
||||
struct list *paths; /* the SPT */
|
||||
struct list *tents; /* TENT */
|
||||
struct thread *t_spf_periodic; /* periodic spf threads */
|
||||
time_t lastrun; /* for scheduling */
|
||||
int pending; /* already scheduled */
|
||||
struct list *paths; /* the SPT */
|
||||
struct list *tents; /* TENT */
|
||||
|
||||
u_int32_t timerun; /* statistics */
|
||||
u_int32_t timerun; /* statistics */
|
||||
};
|
||||
|
||||
void spftree_area_init (struct isis_area *area);
|
||||
@ -75,11 +76,3 @@ void isis_spf_cmds_init (void);
|
||||
int isis_spf_schedule6 (struct isis_area *area, int level);
|
||||
#endif
|
||||
#endif /* _ZEBRA_ISIS_SPF_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1527
isisd/isis_tlv.c
1527
isisd/isis_tlv.c
File diff suppressed because it is too large
Load Diff
168
isisd/isis_tlv.h
168
isisd/isis_tlv.h
@ -95,86 +95,98 @@
|
||||
|
||||
#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 LSP_ENTRIES_LEN (10 + ISIS_SYS_ID_LEN) /* FIXME: should be entry */
|
||||
#define IPV4_REACH_LEN 12
|
||||
#define IPV6_REACH_LEN 22
|
||||
|
||||
/* struct for neighbor */
|
||||
struct is_neigh{
|
||||
struct metric metrics;
|
||||
u_char neigh_id[ISIS_SYS_ID_LEN + 1];
|
||||
struct is_neigh
|
||||
{
|
||||
struct metric metrics;
|
||||
u_char neigh_id[ISIS_SYS_ID_LEN + 1];
|
||||
};
|
||||
|
||||
/* struct for te is neighbor */
|
||||
struct te_is_neigh{
|
||||
u_char neigh_id[ISIS_SYS_ID_LEN + 1];
|
||||
u_char te_metric[3];
|
||||
u_char sub_tlvs_length;
|
||||
struct te_is_neigh
|
||||
{
|
||||
u_char neigh_id[ISIS_SYS_ID_LEN + 1];
|
||||
u_char te_metric[3];
|
||||
u_char sub_tlvs_length;
|
||||
};
|
||||
|
||||
/* struct for es neighbors */
|
||||
struct es_neigh{
|
||||
struct metric metrics;
|
||||
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];
|
||||
|
||||
u_char first_es_neigh[ISIS_SYS_ID_LEN];
|
||||
|
||||
};
|
||||
|
||||
struct partition_desig_level2_is{
|
||||
struct list *isis_system_ids;
|
||||
struct partition_desig_level2_is
|
||||
{
|
||||
struct list *isis_system_ids;
|
||||
};
|
||||
|
||||
/* struct for lan neighbors */
|
||||
struct lan_neigh{
|
||||
u_char LAN_addr[6];
|
||||
struct lan_neigh
|
||||
{
|
||||
u_char LAN_addr[6];
|
||||
};
|
||||
|
||||
/* 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));
|
||||
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));
|
||||
|
||||
/* struct for checksum */
|
||||
struct checksum {
|
||||
struct checksum
|
||||
{
|
||||
u_int16_t checksum;
|
||||
};
|
||||
|
||||
/* ipv4 reachability */
|
||||
struct ipv4_reachability {
|
||||
struct ipv4_reachability
|
||||
{
|
||||
struct metric metrics;
|
||||
struct in_addr prefix;
|
||||
struct in_addr mask;
|
||||
struct in_addr mask;
|
||||
};
|
||||
|
||||
/* te router id */
|
||||
struct te_router_id {
|
||||
struct in_addr 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 */
|
||||
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 */
|
||||
|
||||
|
||||
|
||||
struct idrp_info {
|
||||
struct idrp_info
|
||||
{
|
||||
u_char len;
|
||||
u_char *value;
|
||||
};
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
struct ipv6_reachability {
|
||||
u_int32_t metric;
|
||||
u_char control_info;
|
||||
u_char prefix_len;
|
||||
u_char prefix[16];
|
||||
struct ipv6_reachability
|
||||
{
|
||||
u_int32_t metric;
|
||||
u_char control_info;
|
||||
u_char prefix_len;
|
||||
u_char prefix[16];
|
||||
};
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
@ -190,27 +202,28 @@ struct ipv6_reachability {
|
||||
/*
|
||||
* Pointer to each tlv type, filled by parse_tlvs()
|
||||
*/
|
||||
struct tlvs {
|
||||
struct list *area_addrs;
|
||||
struct list *is_neighs;
|
||||
struct list *te_is_neighs;
|
||||
struct list *es_neighs;
|
||||
struct list *lsp_entries;
|
||||
struct list *prefix_neighs;
|
||||
struct list *lan_neighs;
|
||||
struct checksum *checksum;
|
||||
struct nlpids *nlpids;
|
||||
struct list *ipv4_addrs;
|
||||
struct list *ipv4_int_reachs;
|
||||
struct list *ipv4_ext_reachs;
|
||||
struct list *te_ipv4_reachs;
|
||||
struct hostname *hostname;
|
||||
struct te_router_id *router_id;
|
||||
struct tlvs
|
||||
{
|
||||
struct list *area_addrs;
|
||||
struct list *is_neighs;
|
||||
struct list *te_is_neighs;
|
||||
struct list *es_neighs;
|
||||
struct list *lsp_entries;
|
||||
struct list *prefix_neighs;
|
||||
struct list *lan_neighs;
|
||||
struct checksum *checksum;
|
||||
struct nlpids *nlpids;
|
||||
struct list *ipv4_addrs;
|
||||
struct list *ipv4_int_reachs;
|
||||
struct list *ipv4_ext_reachs;
|
||||
struct list *te_ipv4_reachs;
|
||||
struct hostname *hostname;
|
||||
struct te_router_id *router_id;
|
||||
#ifdef HAVE_IPV6
|
||||
struct list *ipv6_addrs;
|
||||
struct list *ipv6_reachs;
|
||||
struct list *ipv6_addrs;
|
||||
struct list *ipv6_reachs;
|
||||
#endif
|
||||
struct isis_passwd auth_info;
|
||||
struct isis_passwd auth_info;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -240,32 +253,29 @@ struct tlvs {
|
||||
#define TLVFLAG_CHECKSUM (1<<20)
|
||||
#define TLVFLAG_GRACEFUL_RESTART (1<<21)
|
||||
|
||||
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);
|
||||
void free_tlv (void *val);
|
||||
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);
|
||||
void free_tlv (void *val);
|
||||
|
||||
int tlv_add_area_addrs (struct list *area_addrs, struct stream *stream);
|
||||
int tlv_add_is_neighs (struct list *is_neighs, struct stream *stream);
|
||||
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,
|
||||
int tlv_add_area_addrs (struct list *area_addrs, struct stream *stream);
|
||||
int tlv_add_is_neighs (struct list *is_neighs, struct stream *stream);
|
||||
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 (char auth_type, char authlen, char *auth_value,
|
||||
struct stream *stream);
|
||||
int tlv_add_ip_addrs (struct list *ip_addrs, struct stream *stream);
|
||||
int tlv_add_dynamic_hostname (struct hostname *hostname,
|
||||
struct stream *stream);
|
||||
int tlv_add_authinfo (char auth_type, char authlen, char *auth_value,
|
||||
struct stream *stream);
|
||||
int tlv_add_ip_addrs (struct list *ip_addrs, struct stream *stream);
|
||||
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_reachs (struct list *ipv4_reachs, struct stream *stream);
|
||||
int tlv_add_lsp_entries (struct list *lsps, struct stream *stream);
|
||||
int tlv_add_ipv4_reachs (struct list *ipv4_reachs, struct stream *stream);
|
||||
#ifdef HAVE_IPV6
|
||||
int tlv_add_ipv6_addrs (struct list *ipv6_addrs, struct stream *stream);
|
||||
int tlv_add_ipv6_reachs (struct list *ipv6_reachs, struct stream *stream);
|
||||
int tlv_add_ipv6_addrs (struct list *ipv6_addrs, struct stream *stream);
|
||||
int tlv_add_ipv6_reachs (struct list *ipv6_reachs, struct stream *stream);
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
int tlv_add_padding (struct stream *stream);
|
||||
int tlv_add_padding (struct stream *stream);
|
||||
|
||||
#endif /* _ZEBRA_ISIS_TLV_H */
|
||||
|
||||
|
||||
|
||||
|
||||
@ -44,20 +44,20 @@ struct zclient *zclient = NULL;
|
||||
|
||||
extern struct thread_master *master;
|
||||
|
||||
int
|
||||
int
|
||||
isis_zebra_if_add (int command, struct zclient *zclient, zebra_size_t length)
|
||||
{
|
||||
struct interface *ifp;
|
||||
|
||||
ifp = zebra_interface_add_read (zclient->ibuf);
|
||||
|
||||
|
||||
|
||||
zlog_info ("Zebra I/F add: %s index %d flags %ld metric %d mtu %d",
|
||||
ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
|
||||
|
||||
|
||||
if (if_is_up (ifp))
|
||||
isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -69,19 +69,19 @@ isis_zebra_if_del (int command, struct zclient *zclient, zebra_size_t length)
|
||||
|
||||
s = zclient->ibuf;
|
||||
ifp = zebra_interface_state_read (s);
|
||||
|
||||
|
||||
if (!ifp)
|
||||
return 0;
|
||||
|
||||
if (if_is_up (ifp))
|
||||
zlog_warn ("Zebra: got delete of %s, but interface is still up",
|
||||
ifp->name);
|
||||
ifp->name);
|
||||
|
||||
zlog_info ("Zebra I/F delete: %s index %d flags %ld metric %d mtu %d",
|
||||
ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
|
||||
|
||||
if_delete (ifp);
|
||||
|
||||
|
||||
isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
|
||||
|
||||
return 0;
|
||||
@ -120,103 +120,104 @@ zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
|
||||
}
|
||||
|
||||
int
|
||||
isis_zebra_if_state_up (int command, struct zclient *zclient,
|
||||
isis_zebra_if_state_up (int command, struct zclient *zclient,
|
||||
zebra_size_t length)
|
||||
{
|
||||
struct interface *ifp;
|
||||
|
||||
|
||||
ifp = zebra_interface_if_lookup (zclient->ibuf);
|
||||
|
||||
|
||||
if (!ifp)
|
||||
return 0;
|
||||
|
||||
if (if_is_up (ifp)) {
|
||||
zebra_interface_if_set_value (zclient->ibuf, ifp);
|
||||
isis_circuit_update_params (circuit_scan_by_ifp (ifp), ifp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (if_is_up (ifp))
|
||||
{
|
||||
zebra_interface_if_set_value (zclient->ibuf, ifp);
|
||||
isis_circuit_update_params (circuit_scan_by_ifp (ifp), ifp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
zebra_interface_if_set_value (zclient->ibuf, ifp);
|
||||
isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
isis_zebra_if_state_down (int command, struct zclient *zclient,
|
||||
isis_zebra_if_state_down (int command, struct zclient *zclient,
|
||||
zebra_size_t length)
|
||||
{
|
||||
struct interface *ifp;
|
||||
|
||||
|
||||
ifp = zebra_interface_if_lookup (zclient->ibuf);
|
||||
|
||||
|
||||
if (ifp == NULL)
|
||||
return 0;
|
||||
|
||||
if (if_is_up (ifp)) {
|
||||
zebra_interface_if_set_value (zclient->ibuf, ifp);
|
||||
isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
|
||||
}
|
||||
|
||||
|
||||
if (if_is_up (ifp))
|
||||
{
|
||||
zebra_interface_if_set_value (zclient->ibuf, ifp);
|
||||
isis_csm_state_change (IF_DOWN_FROM_Z, circuit_scan_by_ifp (ifp), ifp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
isis_zebra_if_address_add (int command, struct zclient *zclient,
|
||||
zebra_size_t length)
|
||||
isis_zebra_if_address_add (int command, struct zclient *zclient,
|
||||
zebra_size_t length)
|
||||
{
|
||||
struct connected *c;
|
||||
struct prefix *p;
|
||||
u_char buf[BUFSIZ];
|
||||
|
||||
c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
|
||||
zclient->ibuf);
|
||||
|
||||
c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
|
||||
zclient->ibuf);
|
||||
|
||||
if (c == NULL)
|
||||
return 0;
|
||||
|
||||
|
||||
p = c->address;
|
||||
|
||||
|
||||
prefix2str (p, buf, BUFSIZ);
|
||||
#ifdef EXTREME_DEBUG
|
||||
if (p->family == AF_INET)
|
||||
if (p->family == AF_INET)
|
||||
zlog_info ("connected IP address %s", buf);
|
||||
#ifdef HAVE_IPV6
|
||||
if (p->family == AF_INET6)
|
||||
zlog_info ("connected IPv6 address %s", buf);
|
||||
#endif /* HAVE_IPV6 */
|
||||
#endif /* EXTREME_DEBUG */
|
||||
isis_circuit_add_addr (circuit_scan_by_ifp (c->ifp), c);
|
||||
isis_circuit_add_addr (circuit_scan_by_ifp (c->ifp), c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
isis_zebra_if_address_del (int command, struct zclient *client,
|
||||
zebra_size_t length)
|
||||
isis_zebra_if_address_del (int command, struct zclient *client,
|
||||
zebra_size_t length)
|
||||
{
|
||||
struct connected *c;
|
||||
struct interface *ifp;
|
||||
|
||||
c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
|
||||
zclient->ibuf);
|
||||
|
||||
c = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
|
||||
zclient->ibuf);
|
||||
|
||||
if (c == NULL)
|
||||
return 0;
|
||||
|
||||
|
||||
ifp = c->ifp;
|
||||
|
||||
|
||||
connected_free (c);
|
||||
|
||||
|
||||
isis_circuit_del_addr (circuit_scan_by_ifp (ifp), c);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
isis_zebra_route_add_ipv4 (struct prefix *prefix,
|
||||
struct isis_route_info *route_info)
|
||||
isis_zebra_route_add_ipv4 (struct prefix *prefix,
|
||||
struct isis_route_info *route_info)
|
||||
{
|
||||
u_char message, flags;
|
||||
int psize;
|
||||
@ -227,83 +228,89 @@ isis_zebra_route_add_ipv4 (struct prefix *prefix,
|
||||
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC))
|
||||
return;
|
||||
|
||||
if (zclient->redist[ZEBRA_ROUTE_ISIS]) {
|
||||
message = 0;
|
||||
flags = 0;
|
||||
|
||||
SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
|
||||
SET_FLAG (message, ZAPI_MESSAGE_METRIC);
|
||||
#if 0
|
||||
SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
|
||||
#endif
|
||||
|
||||
stream = zclient->obuf;
|
||||
stream_reset (stream);
|
||||
/* Length place holder. */
|
||||
stream_putw (stream, 0);
|
||||
/* command */
|
||||
stream_putc (stream, ZEBRA_IPV4_ROUTE_ADD);
|
||||
/* type */
|
||||
stream_putc (stream, ZEBRA_ROUTE_ISIS);
|
||||
/* flags */
|
||||
stream_putc (stream, flags);
|
||||
/* message */
|
||||
stream_putc (stream, message);
|
||||
/* prefix information */
|
||||
psize = PSIZE (prefix->prefixlen);
|
||||
stream_putc (stream, prefix->prefixlen);
|
||||
stream_write (stream, (u_char *)&prefix->u.prefix4, psize);
|
||||
if (zclient->redist[ZEBRA_ROUTE_ISIS])
|
||||
{
|
||||
message = 0;
|
||||
flags = 0;
|
||||
|
||||
stream_putc (stream, listcount (route_info->nexthops));
|
||||
|
||||
/* Nexthop, ifindex, distance and metric information */
|
||||
for (node = listhead (route_info->nexthops); node; nextnode (node)) {
|
||||
nexthop = getdata (node);
|
||||
/* FIXME: can it be ? */
|
||||
if (nexthop->ip.s_addr != INADDR_ANY) {
|
||||
stream_putc (stream, ZEBRA_NEXTHOP_IPV4);
|
||||
stream_put_in_addr (stream, &nexthop->ip);
|
||||
} else {
|
||||
stream_putc (stream, ZEBRA_NEXTHOP_IFINDEX);
|
||||
stream_putl (stream, nexthop->ifindex);
|
||||
}
|
||||
}
|
||||
SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);
|
||||
SET_FLAG (message, ZAPI_MESSAGE_METRIC);
|
||||
#if 0
|
||||
if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
|
||||
stream_putc (stream, route_info->depth);
|
||||
SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);
|
||||
#endif
|
||||
if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
|
||||
stream_putl (stream, route_info->cost);
|
||||
|
||||
stream_putw_at (stream, 0, stream_get_endp (stream));
|
||||
writen (zclient->sock, stream->data, stream_get_endp (stream));
|
||||
}
|
||||
|
||||
stream = zclient->obuf;
|
||||
stream_reset (stream);
|
||||
/* Length place holder. */
|
||||
stream_putw (stream, 0);
|
||||
/* command */
|
||||
stream_putc (stream, ZEBRA_IPV4_ROUTE_ADD);
|
||||
/* type */
|
||||
stream_putc (stream, ZEBRA_ROUTE_ISIS);
|
||||
/* flags */
|
||||
stream_putc (stream, flags);
|
||||
/* message */
|
||||
stream_putc (stream, message);
|
||||
/* prefix information */
|
||||
psize = PSIZE (prefix->prefixlen);
|
||||
stream_putc (stream, prefix->prefixlen);
|
||||
stream_write (stream, (u_char *) & prefix->u.prefix4, psize);
|
||||
|
||||
stream_putc (stream, listcount (route_info->nexthops));
|
||||
|
||||
/* Nexthop, ifindex, distance and metric information */
|
||||
for (node = listhead (route_info->nexthops); node; nextnode (node))
|
||||
{
|
||||
nexthop = getdata (node);
|
||||
/* FIXME: can it be ? */
|
||||
if (nexthop->ip.s_addr != INADDR_ANY)
|
||||
{
|
||||
stream_putc (stream, ZEBRA_NEXTHOP_IPV4);
|
||||
stream_put_in_addr (stream, &nexthop->ip);
|
||||
}
|
||||
else
|
||||
{
|
||||
stream_putc (stream, ZEBRA_NEXTHOP_IFINDEX);
|
||||
stream_putl (stream, nexthop->ifindex);
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))
|
||||
stream_putc (stream, route_info->depth);
|
||||
#endif
|
||||
if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
|
||||
stream_putl (stream, route_info->cost);
|
||||
|
||||
stream_putw_at (stream, 0, stream_get_endp (stream));
|
||||
writen (zclient->sock, stream->data, stream_get_endp (stream));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
isis_zebra_route_del_ipv4 (struct prefix *prefix,
|
||||
struct isis_route_info *route_info)
|
||||
isis_zebra_route_del_ipv4 (struct prefix *prefix,
|
||||
struct isis_route_info *route_info)
|
||||
{
|
||||
struct zapi_ipv4 api;
|
||||
struct prefix_ipv4 prefix4;
|
||||
|
||||
if (zclient->redist[ZEBRA_ROUTE_ISIS]) {
|
||||
api.type = ZEBRA_ROUTE_ISIS;
|
||||
api.flags = 0;
|
||||
api.message = 0;
|
||||
prefix4.family = AF_INET;
|
||||
prefix4.prefixlen = prefix->prefixlen;
|
||||
prefix4.prefix = prefix->u.prefix4;
|
||||
zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, &prefix4, &api);
|
||||
}
|
||||
|
||||
|
||||
if (zclient->redist[ZEBRA_ROUTE_ISIS])
|
||||
{
|
||||
api.type = ZEBRA_ROUTE_ISIS;
|
||||
api.flags = 0;
|
||||
api.message = 0;
|
||||
prefix4.family = AF_INET;
|
||||
prefix4.prefixlen = prefix->prefixlen;
|
||||
prefix4.prefix = prefix->u.prefix4;
|
||||
zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, &prefix4, &api);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
void
|
||||
isis_zebra_route_add_ipv6 (struct prefix *prefix,
|
||||
struct isis_route_info *route_info)
|
||||
struct isis_route_info *route_info)
|
||||
{
|
||||
struct zapi_ipv6 api;
|
||||
struct in6_addr **nexthop_list;
|
||||
@ -315,7 +322,7 @@ isis_zebra_route_add_ipv6 (struct prefix *prefix,
|
||||
|
||||
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC))
|
||||
return;
|
||||
|
||||
|
||||
api.type = ZEBRA_ROUTE_ISIS;
|
||||
api.flags = 0;
|
||||
api.message = 0;
|
||||
@ -329,61 +336,66 @@ isis_zebra_route_add_ipv6 (struct prefix *prefix,
|
||||
#endif
|
||||
api.nexthop_num = listcount (route_info->nexthops6);
|
||||
api.ifindex_num = listcount (route_info->nexthops6);
|
||||
|
||||
|
||||
/* allocate memory for nexthop_list */
|
||||
size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
|
||||
nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
|
||||
if (!nexthop_list) {
|
||||
zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!nexthop_list)
|
||||
{
|
||||
zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
|
||||
return;
|
||||
}
|
||||
|
||||
/* allocate memory for ifindex_list */
|
||||
size = sizeof (unsigned int) * listcount (route_info->nexthops6);
|
||||
ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
|
||||
if (!ifindex_list) {
|
||||
zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
|
||||
XFREE (MTYPE_ISIS_TMP, nexthop_list);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ifindex_list)
|
||||
{
|
||||
zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
|
||||
XFREE (MTYPE_ISIS_TMP, nexthop_list);
|
||||
return;
|
||||
}
|
||||
|
||||
/* for each nexthop */
|
||||
i = 0;
|
||||
for (node = listhead (route_info->nexthops6); node; nextnode (node)) {
|
||||
nexthop6 = getdata (node);
|
||||
|
||||
if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
|
||||
!IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6)) {
|
||||
api.nexthop_num--;
|
||||
api.ifindex_num--;
|
||||
continue;
|
||||
for (node = listhead (route_info->nexthops6); node; nextnode (node))
|
||||
{
|
||||
nexthop6 = getdata (node);
|
||||
|
||||
if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
|
||||
!IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
|
||||
{
|
||||
api.nexthop_num--;
|
||||
api.ifindex_num--;
|
||||
continue;
|
||||
}
|
||||
|
||||
nexthop_list[i] = &nexthop6->ip6;
|
||||
ifindex_list[i] = nexthop6->ifindex;
|
||||
i++;
|
||||
}
|
||||
|
||||
nexthop_list[i] = &nexthop6->ip6;
|
||||
ifindex_list[i] = nexthop6->ifindex;
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
api.nexthop = nexthop_list;
|
||||
api.ifindex = ifindex_list;
|
||||
|
||||
if (api.nexthop_num && api.ifindex_num) {
|
||||
prefix6.family = AF_INET6;
|
||||
prefix6.prefixlen = prefix->prefixlen;
|
||||
memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
|
||||
zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, &prefix6, &api);
|
||||
SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
|
||||
}
|
||||
|
||||
|
||||
if (api.nexthop_num && api.ifindex_num)
|
||||
{
|
||||
prefix6.family = AF_INET6;
|
||||
prefix6.prefixlen = prefix->prefixlen;
|
||||
memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
|
||||
zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, &prefix6, &api);
|
||||
SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
|
||||
}
|
||||
|
||||
XFREE (MTYPE_ISIS_TMP, nexthop_list);
|
||||
XFREE (MTYPE_ISIS_TMP, ifindex_list);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
isis_zebra_route_del_ipv6 (struct prefix *prefix,
|
||||
struct isis_route_info *route_info)
|
||||
isis_zebra_route_del_ipv6 (struct prefix *prefix,
|
||||
struct isis_route_info *route_info)
|
||||
{
|
||||
struct zapi_ipv6 api;
|
||||
struct in6_addr **nexthop_list;
|
||||
@ -395,7 +407,7 @@ isis_zebra_route_del_ipv6 (struct prefix *prefix,
|
||||
|
||||
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC))
|
||||
return;
|
||||
|
||||
|
||||
api.type = ZEBRA_ROUTE_ISIS;
|
||||
api.flags = 0;
|
||||
api.message = 0;
|
||||
@ -403,64 +415,66 @@ isis_zebra_route_del_ipv6 (struct prefix *prefix,
|
||||
SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
|
||||
api.nexthop_num = listcount (route_info->nexthops6);
|
||||
api.ifindex_num = listcount (route_info->nexthops6);
|
||||
|
||||
|
||||
/* allocate memory for nexthop_list */
|
||||
size = sizeof (struct isis_nexthop6 *) * listcount (route_info->nexthops6);
|
||||
nexthop_list = (struct in6_addr **) XMALLOC (MTYPE_ISIS_TMP, size);
|
||||
if (!nexthop_list) {
|
||||
zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!nexthop_list)
|
||||
{
|
||||
zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
|
||||
return;
|
||||
}
|
||||
|
||||
/* allocate memory for ifindex_list */
|
||||
size = sizeof (unsigned int) * listcount (route_info->nexthops6);
|
||||
ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
|
||||
if (!ifindex_list) {
|
||||
zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
|
||||
XFREE (MTYPE_ISIS_TMP, nexthop_list);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ifindex_list)
|
||||
{
|
||||
zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
|
||||
XFREE (MTYPE_ISIS_TMP, nexthop_list);
|
||||
return;
|
||||
}
|
||||
|
||||
/* for each nexthop */
|
||||
i = 0;
|
||||
for (node = listhead (route_info->nexthops6); node; nextnode (node)) {
|
||||
nexthop6 = getdata (node);
|
||||
|
||||
if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
|
||||
!IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6)) {
|
||||
api.nexthop_num--;
|
||||
api.ifindex_num--;
|
||||
continue;
|
||||
for (node = listhead (route_info->nexthops6); node; nextnode (node))
|
||||
{
|
||||
nexthop6 = getdata (node);
|
||||
|
||||
if (!IN6_IS_ADDR_LINKLOCAL (&nexthop6->ip6) &&
|
||||
!IN6_IS_ADDR_UNSPECIFIED (&nexthop6->ip6))
|
||||
{
|
||||
api.nexthop_num--;
|
||||
api.ifindex_num--;
|
||||
continue;
|
||||
}
|
||||
|
||||
nexthop_list[i] = &nexthop6->ip6;
|
||||
ifindex_list[i] = nexthop6->ifindex;
|
||||
i++;
|
||||
}
|
||||
|
||||
nexthop_list[i] = &nexthop6->ip6;
|
||||
ifindex_list[i] = nexthop6->ifindex;
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
api.nexthop = nexthop_list;
|
||||
api.ifindex = ifindex_list;
|
||||
|
||||
if (api.nexthop_num && api.ifindex_num) {
|
||||
prefix6.family = AF_INET6;
|
||||
prefix6.prefixlen = prefix->prefixlen;
|
||||
memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
|
||||
zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, &prefix6, &api);
|
||||
UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
|
||||
}
|
||||
|
||||
XFREE (MTYPE_ISIS_TMP, nexthop_list);
|
||||
XFREE (MTYPE_ISIS_TMP, ifindex_list);
|
||||
}
|
||||
|
||||
if (api.nexthop_num && api.ifindex_num)
|
||||
{
|
||||
prefix6.family = AF_INET6;
|
||||
prefix6.prefixlen = prefix->prefixlen;
|
||||
memcpy (&prefix6.prefix, &prefix->u.prefix6, sizeof (struct in6_addr));
|
||||
zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, &prefix6, &api);
|
||||
UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNC);
|
||||
}
|
||||
|
||||
XFREE (MTYPE_ISIS_TMP, nexthop_list);
|
||||
XFREE (MTYPE_ISIS_TMP, ifindex_list);
|
||||
}
|
||||
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
|
||||
|
||||
void
|
||||
isis_zebra_route_update (struct prefix *prefix,
|
||||
struct isis_route_info *route_info)
|
||||
struct isis_route_info *route_info)
|
||||
{
|
||||
if (zclient->sock < 0)
|
||||
return;
|
||||
@ -468,27 +482,29 @@ isis_zebra_route_update (struct prefix *prefix,
|
||||
if (!zclient->redist[ZEBRA_ROUTE_ISIS])
|
||||
return;
|
||||
|
||||
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE)) {
|
||||
if (prefix->family == AF_INET)
|
||||
isis_zebra_route_add_ipv4 (prefix, route_info);
|
||||
if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ACTIVE))
|
||||
{
|
||||
if (prefix->family == AF_INET)
|
||||
isis_zebra_route_add_ipv4 (prefix, route_info);
|
||||
#ifdef HAVE_IPV6
|
||||
else if (prefix->family == AF_INET6)
|
||||
isis_zebra_route_add_ipv6 (prefix, route_info);
|
||||
else if (prefix->family == AF_INET6)
|
||||
isis_zebra_route_add_ipv6 (prefix, route_info);
|
||||
#endif /* HAVE_IPV6 */
|
||||
} else {
|
||||
if (prefix->family == AF_INET)
|
||||
isis_zebra_route_del_ipv4 (prefix, route_info);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (prefix->family == AF_INET)
|
||||
isis_zebra_route_del_ipv4 (prefix, route_info);
|
||||
#ifdef HAVE_IPV6
|
||||
else if (prefix->family == AF_INET6)
|
||||
isis_zebra_route_del_ipv6 (prefix, route_info);
|
||||
else if (prefix->family == AF_INET6)
|
||||
isis_zebra_route_del_ipv6 (prefix, route_info);
|
||||
#endif /* HAVE_IPV6 */
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
isis_zebra_read_ipv4 (int command, struct zclient *zclient,
|
||||
isis_zebra_read_ipv4 (int command, struct zclient *zclient,
|
||||
zebra_size_t length)
|
||||
{
|
||||
struct stream *stream;
|
||||
@ -501,42 +517,43 @@ isis_zebra_read_ipv4 (int command, struct zclient *zclient,
|
||||
memset (&p, 0, sizeof (struct prefix_ipv4));
|
||||
ifindex = 0;
|
||||
|
||||
api.type = stream_getc (stream);
|
||||
api.flags = stream_getc (stream);
|
||||
api.type = stream_getc (stream);
|
||||
api.flags = stream_getc (stream);
|
||||
api.message = stream_getc (stream);
|
||||
|
||||
p.family = AF_INET;
|
||||
p.prefixlen = stream_getc (stream);
|
||||
stream_get (&p.prefix, stream, PSIZE (p.prefixlen));
|
||||
|
||||
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) {
|
||||
|
||||
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
|
||||
{
|
||||
api.nexthop_num = stream_getc (stream);
|
||||
nexthop.s_addr = stream_get_ipv4 (stream);
|
||||
}
|
||||
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) {
|
||||
api.ifindex_num = stream_getc (stream);
|
||||
ifindex = stream_getl (stream);
|
||||
}
|
||||
}
|
||||
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
|
||||
{
|
||||
api.ifindex_num = stream_getc (stream);
|
||||
ifindex = stream_getl (stream);
|
||||
}
|
||||
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
|
||||
api.distance = stream_getc (stream);
|
||||
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
|
||||
api.metric = stream_getl (stream);
|
||||
else
|
||||
api.metric = 0;
|
||||
|
||||
if (command == ZEBRA_IPV4_ROUTE_ADD) {
|
||||
zlog_info ("IPv4 Route add from Z");
|
||||
}
|
||||
|
||||
if (command == ZEBRA_IPV4_ROUTE_ADD)
|
||||
{
|
||||
zlog_info ("IPv4 Route add from Z");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
isis_zebra_read_ipv6 (int command, struct zclient *zclient,
|
||||
int
|
||||
isis_zebra_read_ipv6 (int command, struct zclient *zclient,
|
||||
zebra_size_t length)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -550,16 +567,15 @@ isis_distribute_list_update (int routetype)
|
||||
}
|
||||
|
||||
int
|
||||
isis_redistribute_default_set(int routetype, int metric_type, int metric_value)
|
||||
isis_redistribute_default_set (int routetype, int metric_type,
|
||||
int metric_value)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
isis_zebra_init ()
|
||||
{
|
||||
|
||||
zclient = zclient_new ();
|
||||
zclient_init (zclient, ZEBRA_ROUTE_ISIS);
|
||||
zclient->interface_add = isis_zebra_if_add;
|
||||
@ -581,17 +597,9 @@ isis_zebra_init ()
|
||||
void
|
||||
isis_zebra_finish ()
|
||||
{
|
||||
|
||||
zclient_stop (zclient);
|
||||
zclient_free (zclient);
|
||||
zclient = (struct zclient *) NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -26,8 +26,8 @@ extern struct zclient *zclient;
|
||||
|
||||
void isis_zebra_init (void);
|
||||
void isis_zebra_finish (void);
|
||||
void isis_zebra_route_update (struct prefix *prefix,
|
||||
struct isis_route_info *route_info);
|
||||
void isis_zebra_route_update (struct prefix *prefix,
|
||||
struct isis_route_info *route_info);
|
||||
int isis_distribute_list_update (int routetype);
|
||||
|
||||
#endif /* _ZEBRA_ISIS_ZEBRA_H */
|
||||
|
||||
1325
isisd/isisd.c
1325
isisd/isisd.c
File diff suppressed because it is too large
Load Diff
@ -32,7 +32,8 @@
|
||||
/* If you want topology stuff compiled in */
|
||||
/* #define TOPOLOGY_GENERATE */
|
||||
|
||||
struct rmap{
|
||||
struct rmap
|
||||
{
|
||||
char *name;
|
||||
struct route_map *map;
|
||||
};
|
||||
@ -41,58 +42,62 @@ struct isis
|
||||
{
|
||||
u_long process_id;
|
||||
int sysid_set;
|
||||
u_char sysid[ISIS_SYS_ID_LEN]; /* SystemID for this IS */
|
||||
struct list *area_list; /* list of IS-IS areas */
|
||||
u_char sysid[ISIS_SYS_ID_LEN]; /* SystemID for this IS */
|
||||
struct list *area_list; /* list of IS-IS areas */
|
||||
struct list *init_circ_list;
|
||||
struct list *nexthops; /* IPv4 next hops from this IS */
|
||||
struct list *nexthops; /* IPv4 next hops from this IS */
|
||||
#ifdef HAVE_IPV6
|
||||
struct list *nexthops6; /* IPv6 next hops from this IS */
|
||||
#endif /* HAVE_IPV6 */
|
||||
u_char max_area_addrs; /* maximumAreaAdresses */
|
||||
struct area_addr *man_area_addrs; /* manualAreaAddresses */
|
||||
u_int32_t debugs; /* bitmap for debug */
|
||||
time_t uptime; /* when did we start */
|
||||
|
||||
struct list *nexthops6; /* IPv6 next hops from this IS */
|
||||
#endif /* HAVE_IPV6 */
|
||||
u_char max_area_addrs; /* maximumAreaAdresses */
|
||||
struct area_addr *man_area_addrs; /* manualAreaAddresses */
|
||||
u_int32_t debugs; /* bitmap for debug */
|
||||
time_t uptime; /* when did we start */
|
||||
|
||||
/* Redistributed external information. */
|
||||
struct route_table *external_info[ZEBRA_ROUTE_MAX + 1];
|
||||
/* Redistribute metric info. */
|
||||
struct {
|
||||
int type; /* Internal or External */
|
||||
int value; /* metric value */
|
||||
} dmetric [ZEBRA_ROUTE_MAX + 1];
|
||||
struct
|
||||
{
|
||||
int type; /* Internal or External */
|
||||
int value; /* metric value */
|
||||
} dmetric[ZEBRA_ROUTE_MAX + 1];
|
||||
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
char *name;
|
||||
struct route_map *map;
|
||||
} rmap [ZEBRA_ROUTE_MAX + 1];
|
||||
} rmap[ZEBRA_ROUTE_MAX + 1];
|
||||
#ifdef HAVE_IPV6
|
||||
struct {
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
char *name;
|
||||
struct route_map *map;
|
||||
} rmap [ZEBRA_ROUTE_MAX + 1];
|
||||
} rmap[ZEBRA_ROUTE_MAX + 1];
|
||||
} inet6_afmode;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct isis_area
|
||||
struct isis_area
|
||||
{
|
||||
struct isis *isis; /* back pointer */
|
||||
dict_t *lspdb[ISIS_LEVELS]; /* link-state dbs */
|
||||
struct isis_spftree *spftree[ISIS_LEVELS]; /* The v4 SPTs */
|
||||
struct route_table *route_table; /* IPv4 routes */
|
||||
struct isis *isis; /* back pointer */
|
||||
dict_t *lspdb[ISIS_LEVELS]; /* link-state dbs */
|
||||
struct isis_spftree *spftree[ISIS_LEVELS]; /* The v4 SPTs */
|
||||
struct route_table *route_table; /* IPv4 routes */
|
||||
#ifdef HAVE_IPV6
|
||||
struct isis_spftree *spftree6[ISIS_LEVELS]; /* The v4 SPTs */
|
||||
struct route_table *route_table6; /* IPv6 routes */
|
||||
struct isis_spftree *spftree6[ISIS_LEVELS]; /* The v4 SPTs */
|
||||
struct route_table *route_table6; /* IPv6 routes */
|
||||
#endif
|
||||
int min_bcast_mtu;
|
||||
struct list *circuit_list; /* IS-IS circuits */
|
||||
struct flags flags;
|
||||
struct thread *t_tick; /* LSP walker */
|
||||
struct thread *t_remove_aged;
|
||||
struct list *circuit_list; /* IS-IS circuits */
|
||||
struct flags flags;
|
||||
struct thread *t_tick; /* LSP walker */
|
||||
struct thread *t_remove_aged;
|
||||
int lsp_regenerate_pending[ISIS_LEVELS];
|
||||
struct thread *t_lsp_refresh[ISIS_LEVELS];
|
||||
|
||||
|
||||
/*
|
||||
* Configurables
|
||||
*/
|
||||
@ -101,34 +106,34 @@ struct isis_area
|
||||
/* do we support dynamic hostnames? */
|
||||
char dynhostname;
|
||||
/* do we support new style metrics? */
|
||||
char newmetric;
|
||||
char newmetric;
|
||||
/* identifies the routing instance */
|
||||
char *area_tag;
|
||||
char *area_tag;
|
||||
/* area addresses for this area */
|
||||
struct list *area_addrs;
|
||||
u_int16_t max_lsp_lifetime[ISIS_LEVELS];
|
||||
char is_type; /* level-1 level-1-2 or level-2-only */
|
||||
struct list *area_addrs;
|
||||
u_int16_t max_lsp_lifetime[ISIS_LEVELS];
|
||||
char is_type; /* level-1 level-1-2 or level-2-only */
|
||||
u_int16_t lsp_refresh[ISIS_LEVELS];
|
||||
/* minimum time allowed before lsp retransmission */
|
||||
u_int16_t lsp_gen_interval[ISIS_LEVELS];
|
||||
/* min interval between between consequtive SPFs */
|
||||
u_int16_t min_spf_interval[ISIS_LEVELS];
|
||||
u_int16_t min_spf_interval[ISIS_LEVELS];
|
||||
/* the percentage of LSP mtu size used, before generating a new frag */
|
||||
int lsp_frag_threshold;
|
||||
int lsp_frag_threshold;
|
||||
int ip_circuits;
|
||||
#ifdef HAVE_IPV6
|
||||
int ipv6_circuits;
|
||||
#endif /* HAVE_IPV6 */
|
||||
#endif /* HAVE_IPV6 */
|
||||
/* Counters */
|
||||
u_int32_t circuit_state_changes;
|
||||
#ifdef TOPOLOGY_GENERATE
|
||||
struct list *topology;
|
||||
char topology_baseis[ISIS_SYS_ID_LEN]; /* is for the first is emulated */
|
||||
char top_params[200]; /* FIXME: what is reasonable? */
|
||||
#endif /* TOPOLOGY_GENERATE */
|
||||
struct list *topology;
|
||||
char topology_baseis[ISIS_SYS_ID_LEN]; /* is for the first is emulated */
|
||||
char top_params[200]; /* FIXME: what is reasonable? */
|
||||
#endif /* TOPOLOGY_GENERATE */
|
||||
};
|
||||
|
||||
void isis_init(void);
|
||||
void isis_init (void);
|
||||
struct isis_area *isis_area_lookup (char *);
|
||||
|
||||
#define DEBUG_ADJ_PACKETS (1<<0)
|
||||
|
||||
@ -46,8 +46,8 @@
|
||||
*/
|
||||
|
||||
int
|
||||
iso_csum_verify (u_char *buffer, int len, uint16_t *csum)
|
||||
{
|
||||
iso_csum_verify (u_char * buffer, int len, uint16_t * csum)
|
||||
{
|
||||
u_int8_t *p;
|
||||
u_int32_t c0;
|
||||
u_int32_t c1;
|
||||
@ -70,28 +70,28 @@ iso_csum_verify (u_char *buffer, int len, uint16_t *csum)
|
||||
*/
|
||||
if (c0 == 0 || c1 == 0)
|
||||
return 1;
|
||||
|
||||
|
||||
/*
|
||||
* Otherwise initialize to zero and calculate...
|
||||
*/
|
||||
c0 = 0;
|
||||
c1 = 0;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
c0 = c0 + *(p++);
|
||||
c1 += c0;
|
||||
}
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
c0 = c0 + *(p++);
|
||||
c1 += c0;
|
||||
}
|
||||
|
||||
c0 = c0 % 255;
|
||||
c1 = c1 % 255;
|
||||
|
||||
if ( c0 == 0 && c1 == 0)
|
||||
|
||||
if (c0 == 0 && c1 == 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Creates the checksum. *csum points to the position of the checksum in the
|
||||
* PDU.
|
||||
@ -102,7 +102,7 @@ iso_csum_verify (u_char *buffer, int len, uint16_t *csum)
|
||||
*/
|
||||
#define FIXED_CODE
|
||||
u_int16_t
|
||||
iso_csum_create (u_char *buffer, int len, u_int16_t n)
|
||||
iso_csum_create (u_char * buffer, int len, u_int16_t n)
|
||||
{
|
||||
|
||||
u_int8_t *p;
|
||||
@ -112,7 +112,7 @@ iso_csum_create (u_char *buffer, int len, u_int16_t n)
|
||||
u_int32_t c0;
|
||||
u_int32_t c1;
|
||||
u_int16_t checksum;
|
||||
u_int16_t *csum;
|
||||
u_int16_t *csum;
|
||||
int i;
|
||||
|
||||
checksum = 0;
|
||||
@ -120,40 +120,46 @@ iso_csum_create (u_char *buffer, int len, u_int16_t n)
|
||||
/*
|
||||
* Zero the csum in the packet.
|
||||
*/
|
||||
csum = (u_int16_t*)(buffer + n);
|
||||
csum = (u_int16_t *) (buffer + n);
|
||||
*(csum) = checksum;
|
||||
|
||||
/* for the limitation of our implementation */
|
||||
if (len > 5000) {
|
||||
return 0;
|
||||
}
|
||||
if (len > 5000)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = buffer;
|
||||
c0 = 0;
|
||||
c1 = 0;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
c0 = c0 + *(p++);
|
||||
c1 += c0;
|
||||
}
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
c0 = c0 + *(p++);
|
||||
c1 += c0;
|
||||
}
|
||||
|
||||
c0 = c0 % 255;
|
||||
c1 = c1 % 255;
|
||||
|
||||
mul = (len - n)*(c0);
|
||||
|
||||
mul = (len - n) * (c0);
|
||||
|
||||
#ifdef FIXED_CODE
|
||||
x = mul - c0 - c1;
|
||||
y = c1 - mul - 1;
|
||||
|
||||
if ( y >= 0 ) y++;
|
||||
if ( x < 0 ) x--;
|
||||
if (y >= 0)
|
||||
y++;
|
||||
if (x < 0)
|
||||
x--;
|
||||
|
||||
x %= 255;
|
||||
y %= 255;
|
||||
|
||||
if (x == 0) x = 255;
|
||||
if (y == 0) y = 255;
|
||||
if (x == 0)
|
||||
x = 255;
|
||||
if (y == 0)
|
||||
y = 255;
|
||||
|
||||
x &= 0x00FF;
|
||||
|
||||
@ -166,12 +172,14 @@ iso_csum_create (u_char *buffer, int len, u_int16_t n)
|
||||
y = c1 - mul - 1;
|
||||
y %= 255;
|
||||
|
||||
if (x == 0) x = 255;
|
||||
if (y == 0) y = 255;
|
||||
if (x == 0)
|
||||
x = 255;
|
||||
if (y == 0)
|
||||
y = 255;
|
||||
|
||||
checksum = ((y << 8) | x);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Now we write this to the packet
|
||||
*/
|
||||
@ -181,12 +189,8 @@ iso_csum_create (u_char *buffer, int len, u_int16_t n)
|
||||
return checksum;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
iso_csum_modify (u_char *buffer, int len, uint16_t *csum)
|
||||
iso_csum_modify (u_char * buffer, int len, uint16_t * csum)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
#ifndef _ZEBRA_ISO_CSUM_H
|
||||
#define _ZEBRA_ISO_CSUM_H
|
||||
|
||||
int iso_csum_verify (u_char *buffer, int len, uint16_t *csum);
|
||||
u_int16_t iso_csum_create (u_char *buffer, int len, u_int16_t n);
|
||||
int iso_csum_verify (u_char * buffer, int len, uint16_t * csum);
|
||||
u_int16_t iso_csum_create (u_char * buffer, int len, u_int16_t n);
|
||||
|
||||
#endif /* _ZEBRA_ISO_CSUM_H */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user