Indentation only. No any functional changes.

This commit is contained in:
hasso 2004-09-10 20:48:21 +00:00
parent f3f27f60fd
commit f390d2c783
40 changed files with 9902 additions and 8915 deletions

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -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;
}

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -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;
};

View File

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

View File

@ -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;
}

View File

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

View File

@ -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;
}

View File

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

View File

@ -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;
}

View File

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

View File

@ -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;
}

View File

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

View File

@ -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);
}

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -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);
}

View File

@ -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;
}

View File

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

View File

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

View File

@ -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);

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -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;

View File

@ -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);

View File

@ -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);
}

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -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;
}

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -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)

View File

@ -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;
}

View File

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