2003-12-23 09:09:43 +01:00
|
|
|
/*
|
|
|
|
* IS-IS Rout(e)ing protocol - isis_lsp.c
|
|
|
|
* LSP processing
|
|
|
|
*
|
|
|
|
* Copyright (C) 2001,2002 Sampo Saaristo
|
|
|
|
* Tampere University of Technology
|
|
|
|
* Institute of Communications Engineering
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public Licenseas published by the Free
|
|
|
|
* Software Foundation; either version 2 of the License, or (at your option)
|
|
|
|
* any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
|
|
* more details.
|
|
|
|
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
2005-05-03 11:27:23 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <zebra.h>
|
|
|
|
|
|
|
|
#include "linklist.h"
|
|
|
|
#include "thread.h"
|
|
|
|
#include "vty.h"
|
|
|
|
#include "stream.h"
|
|
|
|
#include "memory.h"
|
|
|
|
#include "log.h"
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "command.h"
|
|
|
|
#include "hash.h"
|
|
|
|
#include "if.h"
|
|
|
|
|
|
|
|
#include "isisd/dict.h"
|
|
|
|
#include "isisd/isis_constants.h"
|
|
|
|
#include "isisd/isis_common.h"
|
|
|
|
#include "isisd/isis_circuit.h"
|
|
|
|
#include "isisd/isisd.h"
|
|
|
|
#include "isisd/isis_tlv.h"
|
|
|
|
#include "isisd/isis_lsp.h"
|
|
|
|
#include "isisd/isis_pdu.h"
|
|
|
|
#include "isisd/isis_dynhn.h"
|
|
|
|
#include "isisd/isis_misc.h"
|
|
|
|
#include "isisd/isis_flags.h"
|
|
|
|
#include "isisd/iso_checksum.h"
|
|
|
|
#include "isisd/isis_csm.h"
|
|
|
|
#include "isisd/isis_adjacency.h"
|
|
|
|
#include "isisd/isis_spf.h"
|
|
|
|
|
|
|
|
#ifdef TOPOLOGY_GENERATE
|
|
|
|
#include "spgrid.h"
|
|
|
|
#endif
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
#define LSP_MEMORY_PREASSIGN
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
extern struct isis *isis;
|
|
|
|
extern struct thread_master *master;
|
2004-10-03 20:18:34 +02:00
|
|
|
extern struct in_addr router_id_zebra;
|
2003-12-23 09:09:43 +01:00
|
|
|
|
2004-09-24 12:45:28 +02:00
|
|
|
/* staticly assigned vars for printing purposes */
|
|
|
|
char lsp_bits_string[200]; /* FIXME: enough ? */
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
int
|
|
|
|
lsp_id_cmp (u_char * id1, u_char * id2)
|
|
|
|
{
|
2003-12-23 09:09:43 +01:00
|
|
|
return memcmp (id1, id2, ISIS_SYS_ID_LEN + 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
dict_t *
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp_db_init (void)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
dict_t *dict;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
|
|
|
dict = dict_create (DICTCOUNT_T_MAX, (dict_comp_t) lsp_id_cmp);
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return dict;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct isis_lsp *
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp_search (u_char * id, dict_t * lspdb)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
dnode_t *node;
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
#ifdef EXTREME_DEBUG
|
2003-12-23 09:09:43 +01:00
|
|
|
dnode_t *dn;
|
|
|
|
|
2004-12-24 01:14:50 +01:00
|
|
|
zlog_debug ("searching db");
|
2004-09-10 22:48:21 +02:00
|
|
|
for (dn = dict_first (lspdb); dn; dn = dict_next (lspdb, dn))
|
|
|
|
{
|
2004-12-24 01:14:50 +01:00
|
|
|
zlog_debug ("%s\t%pX", rawlspid_print ((char *) dnode_getkey (dn)),
|
|
|
|
dnode_get (dn));
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
#endif /* EXTREME DEBUG */
|
|
|
|
|
|
|
|
node = dict_lookup (lspdb, id);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
if (node)
|
2004-09-10 22:48:21 +02:00
|
|
|
return (struct isis_lsp *) dnode_get (node);
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2005-01-18 14:53:33 +01:00
|
|
|
static void
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_clear_data (struct isis_lsp *lsp)
|
|
|
|
{
|
|
|
|
if (!lsp)
|
|
|
|
return;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
|
|
|
if (lsp->own_lsp)
|
|
|
|
{
|
|
|
|
if (lsp->tlv_data.nlpids)
|
|
|
|
XFREE (MTYPE_ISIS_TLV, lsp->tlv_data.nlpids);
|
|
|
|
if (lsp->tlv_data.hostname)
|
|
|
|
XFREE (MTYPE_ISIS_TLV, lsp->tlv_data.hostname);
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
if (lsp->tlv_data.is_neighs)
|
|
|
|
list_delete (lsp->tlv_data.is_neighs);
|
|
|
|
if (lsp->tlv_data.area_addrs)
|
|
|
|
list_delete (lsp->tlv_data.area_addrs);
|
|
|
|
if (lsp->tlv_data.es_neighs)
|
|
|
|
list_delete (lsp->tlv_data.es_neighs);
|
|
|
|
if (lsp->tlv_data.ipv4_addrs)
|
|
|
|
list_delete (lsp->tlv_data.ipv4_addrs);
|
|
|
|
if (lsp->tlv_data.ipv4_int_reachs)
|
|
|
|
list_delete (lsp->tlv_data.ipv4_int_reachs);
|
|
|
|
if (lsp->tlv_data.ipv4_ext_reachs)
|
|
|
|
list_delete (lsp->tlv_data.ipv4_ext_reachs);
|
|
|
|
#ifdef HAVE_IPV6
|
|
|
|
if (lsp->tlv_data.ipv6_addrs)
|
|
|
|
list_delete (lsp->tlv_data.ipv6_addrs);
|
|
|
|
if (lsp->tlv_data.ipv6_reachs)
|
|
|
|
list_delete (lsp->tlv_data.ipv6_reachs);
|
|
|
|
#endif /* HAVE_IPV6 */
|
|
|
|
|
|
|
|
memset (&lsp->tlv_data, 0, sizeof (struct tlvs));
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-01-18 14:53:33 +01:00
|
|
|
static void
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_destroy (struct isis_lsp *lsp)
|
|
|
|
{
|
|
|
|
if (!lsp)
|
|
|
|
return;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_clear_data (lsp);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
|
|
|
if (LSP_FRAGMENT (lsp->lsp_header->lsp_id) == 0 && lsp->lspu.frags)
|
|
|
|
{
|
2003-12-23 09:09:43 +01:00
|
|
|
list_delete (lsp->lspu.frags);
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
if (lsp->pdu)
|
|
|
|
stream_free (lsp->pdu);
|
|
|
|
XFREE (MTYPE_ISIS_LSP, lsp);
|
|
|
|
}
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
void
|
|
|
|
lsp_db_destroy (dict_t * lspdb)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
dnode_t *dnode, *next;
|
|
|
|
struct isis_lsp *lsp;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
dnode = dict_first (lspdb);
|
2004-09-10 22:48:21 +02:00
|
|
|
while (dnode)
|
|
|
|
{
|
|
|
|
next = dict_next (lspdb, dnode);
|
|
|
|
lsp = dnode_get (dnode);
|
|
|
|
lsp_destroy (lsp);
|
|
|
|
dict_delete_free (lspdb, dnode);
|
|
|
|
dnode = next;
|
|
|
|
}
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
dict_free (lspdb);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Remove all the frags belonging to the given lsp
|
|
|
|
*/
|
2005-01-18 14:53:33 +01:00
|
|
|
static void
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp_remove_frags (struct list *frags, dict_t * lspdb)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
dnode_t *dnode;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *lnode, *lnnode;
|
2003-12-23 09:09:43 +01:00
|
|
|
struct isis_lsp *lsp;
|
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (frags, lnode, lnnode, lsp))
|
2004-09-10 22:48:21 +02:00
|
|
|
{
|
|
|
|
dnode = dict_lookup (lspdb, lsp->lsp_header->lsp_id);
|
|
|
|
lsp_destroy (lsp);
|
|
|
|
dnode_destroy (dict_delete (lspdb, dnode));
|
|
|
|
}
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
list_delete_all_node (frags);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp_search_and_destroy (u_char * id, dict_t * lspdb)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
dnode_t *node;
|
|
|
|
struct isis_lsp *lsp;
|
|
|
|
|
|
|
|
node = dict_lookup (lspdb, id);
|
2004-09-10 22:48:21 +02:00
|
|
|
if (node)
|
|
|
|
{
|
|
|
|
node = dict_delete (lspdb, node);
|
|
|
|
lsp = dnode_get (node);
|
|
|
|
/*
|
|
|
|
* If this is a zero lsp, remove all the frags now
|
|
|
|
*/
|
|
|
|
if (LSP_FRAGMENT (lsp->lsp_header->lsp_id) == 0)
|
|
|
|
{
|
|
|
|
if (lsp->lspu.frags)
|
|
|
|
lsp_remove_frags (lsp->lspu.frags, lspdb);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* else just remove this frag, from the zero lsps' frag list
|
|
|
|
*/
|
|
|
|
if (lsp->lspu.zero_lsp && lsp->lspu.zero_lsp->lspu.frags)
|
|
|
|
listnode_delete (lsp->lspu.zero_lsp->lspu.frags, lsp);
|
|
|
|
}
|
|
|
|
lsp_destroy (lsp);
|
|
|
|
dnode_destroy (node);
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Compares a LSP to given values
|
|
|
|
* Params are given in net order
|
|
|
|
*/
|
2004-09-10 22:48:21 +02:00
|
|
|
int
|
|
|
|
lsp_compare (char *areatag, struct isis_lsp *lsp, u_int32_t seq_num,
|
2003-12-23 09:09:43 +01:00
|
|
|
u_int16_t checksum, u_int16_t rem_lifetime)
|
|
|
|
{
|
2004-09-10 22:48:21 +02:00
|
|
|
/* no point in double ntohl on seqnum */
|
|
|
|
if (lsp->lsp_header->seq_num == seq_num &&
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp->lsp_header->checksum == checksum &&
|
|
|
|
/*comparing with 0, no need to do ntohl */
|
|
|
|
((lsp->lsp_header->rem_lifetime == 0 && rem_lifetime == 0) ||
|
2004-09-10 22:48:21 +02:00
|
|
|
(lsp->lsp_header->rem_lifetime != 0 && rem_lifetime != 0)))
|
|
|
|
{
|
|
|
|
if (isis->debugs & DEBUG_SNP_PACKETS)
|
|
|
|
{
|
2004-12-24 01:14:50 +01:00
|
|
|
zlog_debug ("ISIS-Snp (%s): LSP %s seq 0x%08x, cksum 0x%04x,"
|
|
|
|
" lifetime %us",
|
|
|
|
areatag,
|
|
|
|
rawlspid_print (lsp->lsp_header->lsp_id),
|
|
|
|
ntohl (lsp->lsp_header->seq_num),
|
|
|
|
ntohs (lsp->lsp_header->checksum),
|
|
|
|
ntohs (lsp->lsp_header->rem_lifetime));
|
|
|
|
zlog_debug ("ISIS-Snp (%s): is equal to ours seq 0x%08x,"
|
|
|
|
" cksum 0x%04x, lifetime %us",
|
|
|
|
areatag,
|
|
|
|
ntohl (seq_num), ntohs (checksum), ntohs (rem_lifetime));
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
|
|
|
return LSP_EQUAL;
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
if (ntohl (seq_num) >= ntohl (lsp->lsp_header->seq_num))
|
|
|
|
{
|
|
|
|
if (isis->debugs & DEBUG_SNP_PACKETS)
|
|
|
|
{
|
2004-12-24 01:14:50 +01:00
|
|
|
zlog_debug ("ISIS-Snp (%s): LSP %s seq 0x%08x, cksum 0x%04x,"
|
|
|
|
" lifetime %us",
|
|
|
|
areatag,
|
|
|
|
rawlspid_print (lsp->lsp_header->lsp_id),
|
|
|
|
ntohl (seq_num), ntohs (checksum), ntohs (rem_lifetime));
|
|
|
|
zlog_debug ("ISIS-Snp (%s): is newer than ours seq 0x%08x, "
|
|
|
|
"cksum 0x%04x, lifetime %us",
|
|
|
|
areatag,
|
|
|
|
ntohl (lsp->lsp_header->seq_num),
|
|
|
|
ntohs (lsp->lsp_header->checksum),
|
|
|
|
ntohs (lsp->lsp_header->rem_lifetime));
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
|
|
|
return LSP_NEWER;
|
|
|
|
}
|
|
|
|
if (isis->debugs & DEBUG_SNP_PACKETS)
|
|
|
|
{
|
2004-12-24 01:14:50 +01:00
|
|
|
zlog_debug
|
2004-09-10 22:48:21 +02:00
|
|
|
("ISIS-Snp (%s): LSP %s seq 0x%08x, cksum 0x%04x, lifetime %us",
|
|
|
|
areatag, rawlspid_print (lsp->lsp_header->lsp_id), ntohl (seq_num),
|
|
|
|
ntohs (checksum), ntohs (rem_lifetime));
|
2004-12-24 01:14:50 +01:00
|
|
|
zlog_debug ("ISIS-Snp (%s): is older than ours seq 0x%08x,"
|
|
|
|
" cksum 0x%04x, lifetime %us", areatag,
|
|
|
|
ntohl (lsp->lsp_header->seq_num),
|
|
|
|
ntohs (lsp->lsp_header->checksum),
|
|
|
|
ntohs (lsp->lsp_header->rem_lifetime));
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
return LSP_OLDER;
|
|
|
|
}
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
void
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_inc_seqnum (struct isis_lsp *lsp, u_int32_t seq_num)
|
|
|
|
{
|
|
|
|
u_int32_t newseq;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
if (seq_num == 0 || ntohl (lsp->lsp_header->seq_num) > seq_num)
|
|
|
|
newseq = ntohl (lsp->lsp_header->seq_num) + 1;
|
|
|
|
else
|
2004-09-10 22:48:21 +02:00
|
|
|
newseq = seq_num++;
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp->lsp_header->seq_num = htonl (newseq);
|
2004-09-10 22:48:21 +02:00
|
|
|
iso_csum_create (STREAM_DATA (lsp->pdu) + 12,
|
|
|
|
ntohs (lsp->lsp_header->pdu_len) - 12, 12);
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Genetates checksum for LSP and its frags
|
|
|
|
*/
|
2005-01-18 14:53:33 +01:00
|
|
|
static void
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_seqnum_update (struct isis_lsp *lsp0)
|
|
|
|
{
|
|
|
|
struct isis_lsp *lsp;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *node, *nnode;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_inc_seqnum (lsp0, 0);
|
|
|
|
|
|
|
|
if (!lsp0->lspu.frags)
|
|
|
|
return;
|
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (lsp0->lspu.frags, node, nnode, lsp))
|
|
|
|
lsp_inc_seqnum (lsp, 0);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
int
|
2003-12-23 09:09:43 +01:00
|
|
|
isis_lsp_authinfo_check (struct stream *stream, struct isis_area *area,
|
2004-09-10 22:48:21 +02:00
|
|
|
int pdulen, struct isis_passwd *passwd)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
uint32_t expected = 0, found;
|
|
|
|
struct tlvs tlvs;
|
|
|
|
int retval = 0;
|
|
|
|
|
|
|
|
expected |= TLVFLAG_AUTH_INFO;
|
|
|
|
retval = parse_tlvs (area->area_tag, stream->data +
|
2004-09-10 22:48:21 +02:00
|
|
|
ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN,
|
|
|
|
pdulen - ISIS_FIXED_HDR_LEN
|
|
|
|
- ISIS_LSP_HDR_LEN, &expected, &found, &tlvs);
|
2003-12-23 09:09:43 +01:00
|
|
|
if (retval || !(found & TLVFLAG_AUTH_INFO))
|
2004-09-10 22:48:21 +02:00
|
|
|
return 1; /* Auth fail (parsing failed or no auth-tlv) */
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
return authentication_check (passwd, &tlvs.auth_info);
|
|
|
|
}
|
|
|
|
|
2005-01-18 14:53:33 +01:00
|
|
|
static void
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp_update_data (struct isis_lsp *lsp, struct stream *stream,
|
|
|
|
struct isis_area *area)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
2004-09-10 22:48:21 +02:00
|
|
|
uint32_t expected = 0, found;
|
2003-12-23 09:09:43 +01:00
|
|
|
int retval;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
/* copying only the relevant part of our stream */
|
2005-05-03 11:27:23 +02:00
|
|
|
lsp->pdu = stream_dup (stream);
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
/* setting pointers to the correct place */
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp->isis_header = (struct isis_fixed_hdr *) (STREAM_DATA (lsp->pdu));
|
|
|
|
lsp->lsp_header = (struct isis_link_state_hdr *) (STREAM_DATA (lsp->pdu) +
|
|
|
|
ISIS_FIXED_HDR_LEN);
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp->age_out = ZERO_AGE_LIFETIME;
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp->installed = time (NULL);
|
2003-12-23 09:09:43 +01:00
|
|
|
/*
|
|
|
|
* Get LSP data i.e. TLVs
|
|
|
|
*/
|
|
|
|
expected |= TLVFLAG_AUTH_INFO;
|
|
|
|
expected |= TLVFLAG_AREA_ADDRS;
|
|
|
|
expected |= TLVFLAG_IS_NEIGHS;
|
2004-09-10 22:48:21 +02:00
|
|
|
if ((lsp->lsp_header->lsp_bits & 3) == 3) /* a level 2 LSP */
|
2003-12-23 09:09:43 +01:00
|
|
|
expected |= TLVFLAG_PARTITION_DESIG_LEVEL2_IS;
|
|
|
|
expected |= TLVFLAG_NLPID;
|
|
|
|
if (area->dynhostname)
|
|
|
|
expected |= TLVFLAG_DYN_HOSTNAME;
|
2004-09-10 22:48:21 +02:00
|
|
|
if (area->newmetric)
|
|
|
|
{
|
|
|
|
expected |= TLVFLAG_TE_IS_NEIGHS;
|
|
|
|
expected |= TLVFLAG_TE_IPV4_REACHABILITY;
|
|
|
|
expected |= TLVFLAG_TE_ROUTER_ID;
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
expected |= TLVFLAG_IPV4_ADDR;
|
|
|
|
expected |= TLVFLAG_IPV4_INT_REACHABILITY;
|
|
|
|
expected |= TLVFLAG_IPV4_EXT_REACHABILITY;
|
|
|
|
#ifdef HAVE_IPV6
|
|
|
|
expected |= TLVFLAG_IPV6_ADDR;
|
|
|
|
expected |= TLVFLAG_IPV6_REACHABILITY;
|
|
|
|
#endif /* HAVE_IPV6 */
|
|
|
|
|
|
|
|
retval = parse_tlvs (area->area_tag, lsp->pdu->data +
|
2004-09-10 22:48:21 +02:00
|
|
|
ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN,
|
|
|
|
ntohs (lsp->lsp_header->pdu_len) - ISIS_FIXED_HDR_LEN
|
|
|
|
- ISIS_LSP_HDR_LEN, &expected, &found, &lsp->tlv_data);
|
|
|
|
|
|
|
|
if (found & TLVFLAG_DYN_HOSTNAME)
|
|
|
|
{
|
|
|
|
if (area->dynhostname)
|
|
|
|
isis_dynhn_insert (lsp->lsp_header->lsp_id, lsp->tlv_data.hostname,
|
|
|
|
(lsp->lsp_header->lsp_bits & LSPBIT_IST) ==
|
|
|
|
IS_LEVEL_1_AND_2 ? IS_LEVEL_2 :
|
|
|
|
(lsp->lsp_header->lsp_bits & LSPBIT_IST));
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
lsp_update (struct isis_lsp *lsp, struct isis_link_state_hdr *lsp_hdr,
|
2004-09-10 22:48:21 +02:00
|
|
|
struct stream *stream, struct isis_area *area)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
2004-09-10 22:48:21 +02:00
|
|
|
/* free the old lsp data */
|
2003-12-23 09:09:43 +01:00
|
|
|
XFREE (MTYPE_STREAM_DATA, lsp->pdu);
|
|
|
|
lsp_clear_data (lsp);
|
|
|
|
|
|
|
|
/* rebuild the lsp data */
|
|
|
|
lsp_update_data (lsp, stream, area);
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
/* set the new values for lsp header */
|
2003-12-23 09:09:43 +01:00
|
|
|
memcpy (lsp->lsp_header, lsp_hdr, ISIS_LSP_HDR_LEN);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* creation of LSP directly from what we received */
|
|
|
|
struct isis_lsp *
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp_new_from_stream_ptr (struct stream *stream,
|
|
|
|
u_int16_t pdu_len, struct isis_lsp *lsp0,
|
|
|
|
struct isis_area *area)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
struct isis_lsp *lsp;
|
|
|
|
|
2005-09-01 19:52:33 +02:00
|
|
|
lsp = XCALLOC (MTYPE_ISIS_LSP, sizeof (struct isis_lsp));
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_update_data (lsp, stream, area);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
|
|
|
if (lsp0 == NULL)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* zero lsp -> create the list for fragments
|
|
|
|
*/
|
|
|
|
lsp->lspu.frags = list_new ();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* a fragment -> set the backpointer and add this to zero lsps frag list
|
|
|
|
*/
|
|
|
|
lsp->lspu.zero_lsp = lsp0;
|
|
|
|
listnode_add (lsp0->lspu.frags, lsp);
|
|
|
|
}
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return lsp;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct isis_lsp *
|
2004-09-10 22:48:21 +02:00
|
|
|
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)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
struct isis_lsp *lsp;
|
|
|
|
|
2005-09-01 19:52:33 +02:00
|
|
|
lsp = XCALLOC (MTYPE_ISIS_LSP, sizeof (struct isis_lsp));
|
2004-09-10 22:48:21 +02:00
|
|
|
if (!lsp)
|
|
|
|
{
|
|
|
|
/* FIXME: set lspdbol bit */
|
|
|
|
zlog_warn ("lsp_new(): out of memory");
|
|
|
|
return NULL;
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
#ifdef LSP_MEMORY_PREASSIGN
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp->pdu = stream_new (1514); /*Should be minimal mtu? yup... */
|
2003-12-23 09:09:43 +01:00
|
|
|
#else
|
2004-09-10 22:48:21 +02:00
|
|
|
/* We need to do realloc on TLVs additions */
|
|
|
|
lsp->pdu = malloc (ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN);
|
2003-12-23 09:09:43 +01:00
|
|
|
#endif /* LSP_MEMORY_PREASSIGN */
|
|
|
|
if (LSP_FRAGMENT (lsp_id) == 0)
|
|
|
|
lsp->lspu.frags = list_new ();
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp->isis_header = (struct isis_fixed_hdr *) (STREAM_DATA (lsp->pdu));
|
|
|
|
lsp->lsp_header = (struct isis_link_state_hdr *)
|
|
|
|
(STREAM_DATA (lsp->pdu) + ISIS_FIXED_HDR_LEN);
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
/* at first we fill the FIXED HEADER */
|
2004-09-10 22:48:21 +02:00
|
|
|
(level == 1) ? fill_fixed_hdr (lsp->isis_header, L1_LINK_STATE) :
|
|
|
|
fill_fixed_hdr (lsp->isis_header, L2_LINK_STATE);
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
/* now for the LSP HEADER */
|
|
|
|
/* Minimal LSP PDU size */
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp->lsp_header->pdu_len = htons (ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN);
|
2003-12-23 09:09:43 +01:00
|
|
|
memcpy (lsp->lsp_header->lsp_id, lsp_id, ISIS_SYS_ID_LEN + 2);
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp->lsp_header->checksum = checksum; /* Provided in network order */
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp->lsp_header->seq_num = htonl (seq_num);
|
|
|
|
lsp->lsp_header->rem_lifetime = htons (rem_lifetime);
|
|
|
|
lsp->lsp_header->lsp_bits = lsp_bits;
|
|
|
|
lsp->level = level;
|
|
|
|
lsp->age_out = ZERO_AGE_LIFETIME;
|
|
|
|
|
2005-02-09 16:51:56 +01:00
|
|
|
stream_forward_endp (lsp->pdu, ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN);
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
/* #ifdef EXTREME_DEBUG */
|
|
|
|
/* logging */
|
2004-12-24 01:14:50 +01:00
|
|
|
zlog_debug ("New LSP with ID %s-%02x-%02x seqnum %08x", sysid_print (lsp_id),
|
|
|
|
LSP_PSEUDO_ID (lsp->lsp_header->lsp_id),
|
|
|
|
LSP_FRAGMENT (lsp->lsp_header->lsp_id),
|
|
|
|
ntohl (lsp->lsp_header->seq_num));
|
2003-12-23 09:09:43 +01:00
|
|
|
/* #endif EXTREME DEBUG */
|
|
|
|
|
|
|
|
return lsp;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp_insert (struct isis_lsp *lsp, dict_t * lspdb)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
dict_alloc_insert (lspdb, lsp->lsp_header->lsp_id, lsp);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Build a list of LSPs with non-zero ht bounded by start and stop ids
|
|
|
|
*/
|
2004-09-10 22:48:21 +02:00
|
|
|
void
|
|
|
|
lsp_build_list_nonzero_ht (u_char * start_id, u_char * stop_id,
|
|
|
|
struct list *list, dict_t * lspdb)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
dnode_t *first, *last, *curr;
|
|
|
|
|
|
|
|
first = dict_lower_bound (lspdb, start_id);
|
|
|
|
if (!first)
|
|
|
|
return;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
last = dict_upper_bound (lspdb, stop_id);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
curr = first;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
|
|
|
if (((struct isis_lsp *) (curr->dict_data))->lsp_header->rem_lifetime)
|
2003-12-23 09:09:43 +01:00
|
|
|
listnode_add (list, first->dict_data);
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
while (curr)
|
|
|
|
{
|
|
|
|
curr = dict_next (lspdb, curr);
|
|
|
|
if (curr &&
|
|
|
|
((struct isis_lsp *) (curr->dict_data))->lsp_header->rem_lifetime)
|
|
|
|
listnode_add (list, curr->dict_data);
|
|
|
|
if (curr == last)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Build a list of all LSPs bounded by start and stop ids
|
|
|
|
*/
|
2004-09-10 22:48:21 +02:00
|
|
|
void
|
|
|
|
lsp_build_list (u_char * start_id, u_char * stop_id,
|
|
|
|
struct list *list, dict_t * lspdb)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
dnode_t *first, *last, *curr;
|
|
|
|
|
|
|
|
first = dict_lower_bound (lspdb, start_id);
|
|
|
|
if (!first)
|
|
|
|
return;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
last = dict_upper_bound (lspdb, stop_id);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
curr = first;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
listnode_add (list, first->dict_data);
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
while (curr)
|
|
|
|
{
|
|
|
|
curr = dict_next (lspdb, curr);
|
|
|
|
if (curr)
|
|
|
|
listnode_add (list, curr->dict_data);
|
|
|
|
if (curr == last)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Build a list of LSPs with SSN flag set for the given circuit
|
|
|
|
*/
|
|
|
|
void
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp_build_list_ssn (struct isis_circuit *circuit, struct list *list,
|
|
|
|
dict_t * lspdb)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
dnode_t *dnode, *next;
|
|
|
|
struct isis_lsp *lsp;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
dnode = dict_first (lspdb);
|
2004-09-10 22:48:21 +02:00
|
|
|
while (dnode != NULL)
|
|
|
|
{
|
|
|
|
next = dict_next (lspdb, dnode);
|
|
|
|
lsp = dnode_get (dnode);
|
|
|
|
if (ISIS_CHECK_FLAG (lsp->SSNflags, circuit))
|
|
|
|
listnode_add (list, lsp);
|
|
|
|
dnode = next;
|
|
|
|
}
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-01-18 14:53:33 +01:00
|
|
|
static void
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_set_time (struct isis_lsp *lsp)
|
|
|
|
{
|
|
|
|
assert (lsp);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
|
|
|
if (lsp->lsp_header->rem_lifetime == 0)
|
|
|
|
{
|
|
|
|
if (lsp->age_out != 0)
|
|
|
|
lsp->age_out--;
|
|
|
|
return;
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
/* If we are turning 0 */
|
|
|
|
/* ISO 10589 - 7.3.16.4 first paragraph */
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
if (ntohs (lsp->lsp_header->rem_lifetime) == 1)
|
|
|
|
{
|
|
|
|
/* 7.3.16.4 a) set SRM flags on all */
|
|
|
|
ISIS_FLAGS_SET_ALL (lsp->SRMflags);
|
|
|
|
/* 7.3.16.4 b) retain only the header FIXME */
|
|
|
|
/* 7.3.16.4 c) record the time to purge FIXME (other way to do it) */
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp->lsp_header->rem_lifetime =
|
2003-12-23 09:09:43 +01:00
|
|
|
htons (ntohs (lsp->lsp_header->rem_lifetime) - 1);
|
|
|
|
}
|
|
|
|
|
2005-01-18 14:53:33 +01:00
|
|
|
static void
|
2004-09-10 22:48:21 +02:00
|
|
|
lspid_print (u_char * lsp_id, u_char * trg, char dynhost, char frag)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
struct isis_dynhn *dyn = NULL;
|
2004-09-10 22:48:21 +02:00
|
|
|
u_char id[SYSID_STRLEN];
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
if (dynhost)
|
|
|
|
dyn = dynhn_find_by_id (lsp_id);
|
|
|
|
else
|
|
|
|
dyn = NULL;
|
|
|
|
|
|
|
|
if (dyn)
|
2004-09-26 18:24:14 +02:00
|
|
|
sprintf ((char *)id, "%.14s", dyn->name.name);
|
2003-12-23 09:09:43 +01:00
|
|
|
else if (!memcmp (isis->sysid, lsp_id, ISIS_SYS_ID_LEN) & dynhost)
|
2004-09-26 18:24:14 +02:00
|
|
|
sprintf ((char *)id, "%.14s", unix_hostname ());
|
2004-09-10 22:48:21 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
memcpy (id, sysid_print (lsp_id), 15);
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
if (frag)
|
2004-09-26 18:24:14 +02:00
|
|
|
sprintf ((char *)trg, "%s.%02x-%02x", id, LSP_PSEUDO_ID (lsp_id),
|
2004-09-10 22:48:21 +02:00
|
|
|
LSP_FRAGMENT (lsp_id));
|
2003-12-23 09:09:43 +01:00
|
|
|
else
|
2004-09-26 18:24:14 +02:00
|
|
|
sprintf ((char *)trg, "%s.%02x", id, LSP_PSEUDO_ID (lsp_id));
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
/* Convert the lsp attribute bits to attribute string */
|
2004-10-07 22:07:40 +02:00
|
|
|
const char *
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp_bits2string (u_char * lsp_bits)
|
|
|
|
{
|
|
|
|
char *pos = lsp_bits_string;
|
2003-12-23 09:09:43 +01:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
if (!*lsp_bits)
|
2003-12-23 09:09:43 +01:00
|
|
|
return " none";
|
|
|
|
|
|
|
|
/* we only focus on the default metric */
|
|
|
|
pos += sprintf (pos, "%d/",
|
2004-09-10 22:48:21 +02:00
|
|
|
ISIS_MASK_LSP_ATT_DEFAULT_BIT (*lsp_bits) ? 1 : 0);
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
pos += sprintf (pos, "%d/",
|
2004-09-10 22:48:21 +02:00
|
|
|
ISIS_MASK_LSP_PARTITION_BIT (*lsp_bits) ? 1 : 0);
|
|
|
|
|
|
|
|
pos += sprintf (pos, "%d", ISIS_MASK_LSP_OL_BIT (*lsp_bits) ? 1 : 0);
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
*(pos) = '\0';
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
return lsp_bits_string;
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* this function prints the lsp on show isis database */
|
2005-01-18 14:53:33 +01:00
|
|
|
static void
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp_print (dnode_t * node, struct vty *vty, char dynhost)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
2004-09-10 22:48:21 +02:00
|
|
|
struct isis_lsp *lsp = dnode_get (node);
|
2003-12-23 09:09:43 +01:00
|
|
|
u_char LSPid[255];
|
|
|
|
|
|
|
|
lspid_print (lsp->lsp_header->lsp_id, LSPid, dynhost, 1);
|
2004-09-10 22:48:21 +02:00
|
|
|
vty_out (vty, "%-21s%c ", LSPid, lsp->own_lsp ? '*' : ' ');
|
|
|
|
vty_out (vty, "0x%08x ", ntohl (lsp->lsp_header->seq_num));
|
|
|
|
vty_out (vty, "0x%04x ", ntohs (lsp->lsp_header->checksum));
|
2003-12-23 09:09:43 +01:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
if (ntohs (lsp->lsp_header->rem_lifetime) == 0)
|
|
|
|
vty_out (vty, " (%2u)", lsp->age_out);
|
2003-12-23 09:09:43 +01:00
|
|
|
else
|
2004-09-10 22:48:21 +02:00
|
|
|
vty_out (vty, "%5u", ntohs (lsp->lsp_header->rem_lifetime));
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
vty_out (vty, " %s%s",
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp_bits2string (&lsp->lsp_header->lsp_bits), VTY_NEWLINE);
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
2005-01-18 14:53:33 +01:00
|
|
|
static void
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp_print_detail (dnode_t * node, struct vty *vty, char dynhost)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
struct isis_lsp *lsp = dnode_get (node);
|
|
|
|
struct area_addr *area_addr;
|
2004-09-10 22:48:21 +02:00
|
|
|
int i;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *lnode, *lnnode;
|
2003-12-23 09:09:43 +01:00
|
|
|
struct is_neigh *is_neigh;
|
|
|
|
struct te_is_neigh *te_is_neigh;
|
|
|
|
struct ipv4_reachability *ipv4_reach;
|
|
|
|
struct in_addr *ipv4_addr;
|
|
|
|
struct te_ipv4_reachability *te_ipv4_reach;
|
|
|
|
#ifdef HAVE_IPV6
|
|
|
|
struct ipv6_reachability *ipv6_reach;
|
|
|
|
struct in6_addr in6;
|
|
|
|
#endif
|
|
|
|
u_char LSPid[255];
|
|
|
|
u_char hostname[255];
|
|
|
|
u_char buff[BUFSIZ];
|
|
|
|
u_char ipv4_reach_prefix[20];
|
|
|
|
u_char ipv4_reach_mask[20];
|
|
|
|
u_char ipv4_address[20];
|
|
|
|
|
|
|
|
lspid_print (lsp->lsp_header->lsp_id, LSPid, dynhost, 1);
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp_print (node, vty, dynhost);
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
/* for all area address */
|
2004-09-10 22:48:21 +02:00
|
|
|
if (lsp->tlv_data.area_addrs)
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (lsp->tlv_data.area_addrs, lnode,
|
|
|
|
lnnode, area_addr))
|
2004-09-10 22:48:21 +02:00
|
|
|
{
|
2004-10-07 22:07:40 +02:00
|
|
|
vty_out (vty, " Area Address: %s%s",
|
2004-09-10 22:48:21 +02:00
|
|
|
isonet_print (area_addr->area_addr, area_addr->addr_len),
|
|
|
|
VTY_NEWLINE);
|
|
|
|
}
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
/* for the nlpid tlv */
|
2004-09-10 22:48:21 +02:00
|
|
|
if (lsp->tlv_data.nlpids)
|
|
|
|
{
|
|
|
|
for (i = 0; i < lsp->tlv_data.nlpids->count; i++)
|
|
|
|
{
|
|
|
|
switch (lsp->tlv_data.nlpids->nlpids[i])
|
|
|
|
{
|
|
|
|
case NLPID_IP:
|
|
|
|
case NLPID_IPV6:
|
2004-10-07 22:07:40 +02:00
|
|
|
vty_out (vty, " NLPID: 0x%X%s",
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp->tlv_data.nlpids->nlpids[i], VTY_NEWLINE);
|
|
|
|
break;
|
|
|
|
default:
|
2004-10-07 22:07:40 +02:00
|
|
|
vty_out (vty, " NLPID: %s%s", "unknown", VTY_NEWLINE);
|
2004-09-10 22:48:21 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
/* for the hostname tlv */
|
2004-09-10 22:48:21 +02:00
|
|
|
if (lsp->tlv_data.hostname)
|
|
|
|
{
|
|
|
|
bzero (hostname, sizeof (hostname));
|
|
|
|
memcpy (hostname, lsp->tlv_data.hostname->name,
|
|
|
|
lsp->tlv_data.hostname->namelen);
|
|
|
|
vty_out (vty, " Hostname: %s%s", hostname, VTY_NEWLINE);
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
if (lsp->tlv_data.ipv4_addrs)
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (lsp->tlv_data.ipv4_addrs, lnode,
|
|
|
|
lnnode, ipv4_addr))
|
2004-09-10 22:48:21 +02:00
|
|
|
{
|
|
|
|
memcpy (ipv4_address, inet_ntoa (*ipv4_addr), sizeof (ipv4_address));
|
|
|
|
vty_out (vty, " IP: %s%s", ipv4_address, VTY_NEWLINE);
|
|
|
|
}
|
|
|
|
|
2004-10-07 22:07:40 +02:00
|
|
|
/* TE router id */
|
|
|
|
if (lsp->tlv_data.router_id)
|
|
|
|
{
|
|
|
|
memcpy (ipv4_address, inet_ntoa (lsp->tlv_data.router_id->id),
|
|
|
|
sizeof (ipv4_address));
|
|
|
|
vty_out (vty, " Router ID: %s%s", ipv4_address, VTY_NEWLINE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* for the IS neighbor tlv */
|
|
|
|
if (lsp->tlv_data.is_neighs)
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (lsp->tlv_data.is_neighs, lnode, lnnode, is_neigh))
|
2004-10-07 22:07:40 +02:00
|
|
|
{
|
|
|
|
lspid_print (is_neigh->neigh_id, LSPid, dynhost, 0);
|
|
|
|
vty_out (vty, " Metric: %d IS %s%s",
|
|
|
|
is_neigh->metrics.metric_default, LSPid, VTY_NEWLINE);
|
|
|
|
}
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
/* for the internal reachable tlv */
|
|
|
|
if (lsp->tlv_data.ipv4_int_reachs)
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (lsp->tlv_data.ipv4_int_reachs, lnode,
|
|
|
|
lnnode, ipv4_reach))
|
2004-09-10 22:48:21 +02:00
|
|
|
{
|
|
|
|
memcpy (ipv4_reach_prefix, inet_ntoa (ipv4_reach->prefix),
|
|
|
|
sizeof (ipv4_reach_prefix));
|
|
|
|
memcpy (ipv4_reach_mask, inet_ntoa (ipv4_reach->mask),
|
|
|
|
sizeof (ipv4_reach_mask));
|
2003-12-23 12:51:08 +01:00
|
|
|
vty_out (vty, " Metric: %d IP %s %s%s",
|
2004-09-10 22:48:21 +02:00
|
|
|
ipv4_reach->metrics.metric_default, ipv4_reach_prefix,
|
|
|
|
ipv4_reach_mask, VTY_NEWLINE);
|
|
|
|
}
|
2003-12-23 12:51:08 +01:00
|
|
|
|
|
|
|
/* for the external reachable tlv */
|
|
|
|
if (lsp->tlv_data.ipv4_ext_reachs)
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (lsp->tlv_data.ipv4_ext_reachs, lnode,
|
|
|
|
lnnode, ipv4_reach))
|
2004-09-10 22:48:21 +02:00
|
|
|
{
|
|
|
|
memcpy (ipv4_reach_prefix, inet_ntoa (ipv4_reach->prefix),
|
|
|
|
sizeof (ipv4_reach_prefix));
|
|
|
|
memcpy (ipv4_reach_mask, inet_ntoa (ipv4_reach->mask),
|
|
|
|
sizeof (ipv4_reach_mask));
|
2003-12-23 12:51:08 +01:00
|
|
|
vty_out (vty, " Metric: %d IP-External %s %s%s",
|
2004-09-10 22:48:21 +02:00
|
|
|
ipv4_reach->metrics.metric_default, ipv4_reach_prefix,
|
|
|
|
ipv4_reach_mask, VTY_NEWLINE);
|
|
|
|
}
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
|
2003-12-23 12:51:08 +01:00
|
|
|
/* IPv6 tlv */
|
|
|
|
#ifdef HAVE_IPV6
|
|
|
|
if (lsp->tlv_data.ipv6_reachs)
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (lsp->tlv_data.ipv6_reachs, lnode,
|
|
|
|
lnnode, ipv6_reach))
|
2004-09-10 22:48:21 +02:00
|
|
|
{
|
|
|
|
memset (&in6, 0, sizeof (in6));
|
|
|
|
memcpy (in6.s6_addr, ipv6_reach->prefix,
|
|
|
|
PSIZE (ipv6_reach->prefix_len));
|
2004-09-26 18:24:14 +02:00
|
|
|
inet_ntop (AF_INET6, &in6, (char *)buff, BUFSIZ);
|
2003-12-23 12:51:08 +01:00
|
|
|
if ((ipv6_reach->control_info &&
|
2004-09-10 22:48:21 +02:00
|
|
|
CTRL_INFO_DISTRIBUTION) == DISTRIBUTION_INTERNAL)
|
|
|
|
vty_out (vty, " Metric: %d IPv6-Intern %s/%d%s",
|
|
|
|
ntohl (ipv6_reach->metric),
|
|
|
|
buff, ipv6_reach->prefix_len, VTY_NEWLINE);
|
2003-12-23 12:51:08 +01:00
|
|
|
else
|
2004-09-10 22:48:21 +02:00
|
|
|
vty_out (vty, " Metric: %d IPv6-Extern %s/%d%s",
|
|
|
|
ntohl (ipv6_reach->metric),
|
|
|
|
buff, ipv6_reach->prefix_len, VTY_NEWLINE);
|
2003-12-23 12:51:08 +01:00
|
|
|
}
|
|
|
|
#endif
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
|
2004-10-07 22:07:40 +02:00
|
|
|
/* TE IS neighbor tlv */
|
2003-12-23 09:09:43 +01:00
|
|
|
if (lsp->tlv_data.te_is_neighs)
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (lsp->tlv_data.te_is_neighs, lnode,
|
|
|
|
lnnode, te_is_neigh))
|
2004-09-10 22:48:21 +02:00
|
|
|
{
|
2004-10-07 22:07:40 +02:00
|
|
|
/* FIXME: metric display is wrong. */
|
2004-09-10 22:48:21 +02:00
|
|
|
lspid_print (te_is_neigh->neigh_id, LSPid, dynhost, 0);
|
2004-10-07 22:07:40 +02:00
|
|
|
vty_out (vty, " Metric: %d extd-IS %s%s",
|
|
|
|
te_is_neigh->te_metric[0], LSPid, VTY_NEWLINE);
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
|
2004-10-07 22:07:40 +02:00
|
|
|
/* TE IPv4 tlv */
|
2003-12-23 09:09:43 +01:00
|
|
|
if (lsp->tlv_data.te_ipv4_reachs)
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (lsp->tlv_data.te_ipv4_reachs, lnode,
|
|
|
|
lnnode, te_ipv4_reach))
|
2004-09-10 22:48:21 +02:00
|
|
|
{
|
2004-10-07 22:07:40 +02:00
|
|
|
/* FIXME: There should be better way to output this stuff. */
|
2004-10-08 08:40:24 +02:00
|
|
|
vty_out (vty, " Metric: %d extd-IP %s/%d%s",
|
2004-10-07 22:07:40 +02:00
|
|
|
ntohl (te_ipv4_reach->te_metric),
|
2004-09-10 22:48:21 +02:00
|
|
|
inet_ntoa (newprefix2inaddr (&te_ipv4_reach->prefix_start,
|
|
|
|
te_ipv4_reach->control)),
|
2004-10-07 22:07:40 +02:00
|
|
|
te_ipv4_reach->control & 0x3F, VTY_NEWLINE);
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
return;
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* print all the lsps info in the local lspdb */
|
2004-09-10 22:48:21 +02:00
|
|
|
int
|
|
|
|
lsp_print_all (struct vty *vty, dict_t * lspdb, char detail, char dynhost)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
dnode_t *node = dict_first (lspdb), *next;
|
2003-12-23 09:09:43 +01:00
|
|
|
int lsp_count = 0;
|
|
|
|
|
|
|
|
/* print the title, for both modes */
|
|
|
|
vty_out (vty, "LSP ID LSP Seq Num LSP Checksum "
|
2004-09-10 22:48:21 +02:00
|
|
|
"LSP Holdtime ATT/P/OL%s", VTY_NEWLINE);
|
|
|
|
|
|
|
|
if (detail == ISIS_UI_LEVEL_BRIEF)
|
|
|
|
{
|
|
|
|
while (node != NULL)
|
|
|
|
{
|
|
|
|
/* I think it is unnecessary, so I comment it out */
|
|
|
|
/* dict_contains (lspdb, node); */
|
|
|
|
next = dict_next (lspdb, node);
|
|
|
|
lsp_print (node, vty, dynhost);
|
|
|
|
node = next;
|
|
|
|
lsp_count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (detail == ISIS_UI_LEVEL_DETAIL)
|
|
|
|
{
|
|
|
|
while (node != NULL)
|
|
|
|
{
|
|
|
|
next = dict_next (lspdb, node);
|
|
|
|
lsp_print_detail (node, vty, dynhost);
|
|
|
|
node = next;
|
|
|
|
lsp_count++;
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return lsp_count;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* this function reallocate memory to an lsp pdu, with an additional
|
|
|
|
* size of memory, it scans the lsp and moves all pointers the
|
|
|
|
* way they should */
|
2005-01-18 14:53:33 +01:00
|
|
|
static u_char *
|
2004-09-10 22:48:21 +02:00
|
|
|
lsppdu_realloc (struct isis_lsp * lsp, int memorytype, int size)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
u_char *retval;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
|
|
|
retval = STREAM_DATA (lsp->pdu) + ntohs (lsp->lsp_header->pdu_len);
|
2003-12-23 09:09:43 +01:00
|
|
|
#ifdef LSP_MEMORY_PREASSIGN
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp->lsp_header->pdu_len = htons (ntohs (lsp->lsp_header->pdu_len) + size);
|
2003-12-23 09:09:43 +01:00
|
|
|
return retval;
|
2004-09-10 22:48:21 +02:00
|
|
|
#else /* otherwise we have to move all pointers */
|
2003-12-23 09:09:43 +01:00
|
|
|
u_char *newpdu;
|
|
|
|
newpdu = stream_new (ntohs (lsp->lsp_header->pdu_len) + size);
|
2005-09-01 19:52:33 +02:00
|
|
|
stream_put (newpdu, STREAM_DATA(lsp->pdu), ntohs (lsp->lsp_header->pdu_len));
|
2003-12-23 09:09:43 +01:00
|
|
|
XFREE (memorytype, lsp->pdu);
|
|
|
|
lsp->pdu = newpdu;
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp->isis_header = (struct isis_fixed_hdr *) STREAM_DATA (lsp->pdu);
|
|
|
|
lsp->lsp_header = (struct isis_link_state_hdr *)
|
|
|
|
(STREAM_DATA (lsp->pdu) + ISIS_FIXED_HDR_LEN);
|
2003-12-23 09:09:43 +01:00
|
|
|
htons (ntohs (lsp->lsp_header->pdu_len) += size);
|
2004-09-10 22:48:21 +02:00
|
|
|
return STREAM_DATA (lsp->pdu) + (lsp->lsp_header->pdu_len - size);
|
2003-12-23 09:09:43 +01:00
|
|
|
#endif /* LSP_MEMORY_PREASSIGN */
|
|
|
|
}
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
#if 0 /* Saving the old one just in case :) */
|
2003-12-23 09:09:43 +01:00
|
|
|
/*
|
|
|
|
* Builds the lsp->tlv_data
|
|
|
|
* and writes the tlvs into lsp->pdu
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
lsp_build_nonpseudo (struct isis_lsp *lsp, struct isis_area *area)
|
|
|
|
{
|
|
|
|
struct is_neigh *is_neigh;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *node, *nnode, *ipnode, *ipnnode;
|
2003-12-23 09:09:43 +01:00
|
|
|
int level = lsp->level;
|
|
|
|
struct isis_circuit *circuit;
|
|
|
|
struct prefix_ipv4 *ipv4;
|
|
|
|
struct ipv4_reachability *ipreach;
|
|
|
|
struct isis_adjacency *nei;
|
|
|
|
#ifdef HAVE_IPV6
|
|
|
|
struct prefix_ipv6 *ipv6;
|
|
|
|
struct ipv6_reachability *ip6reach;
|
|
|
|
#endif /* HAVE_IPV6 */
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
/*
|
|
|
|
* First add the tlvs related to area
|
|
|
|
*/
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
/* Area addresses */
|
|
|
|
if (lsp->tlv_data.area_addrs == NULL)
|
|
|
|
lsp->tlv_data.area_addrs = list_new ();
|
|
|
|
list_add_list (lsp->tlv_data.area_addrs, area->area_addrs);
|
|
|
|
/* Protocols Supported */
|
2004-09-10 22:48:21 +02:00
|
|
|
if (area->ip_circuits > 0
|
2003-12-23 09:09:43 +01:00
|
|
|
#ifdef HAVE_IPV6
|
|
|
|
|| area->ipv6_circuits > 0
|
|
|
|
#endif /* HAVE_IPV6 */
|
2004-09-10 22:48:21 +02:00
|
|
|
)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
lsp->tlv_data.nlpids = XMALLOC (MTYPE_ISIS_TLV, sizeof (struct nlpids));
|
|
|
|
lsp->tlv_data.nlpids->count = 0;
|
2004-09-10 22:48:21 +02:00
|
|
|
if (area->ip_circuits > 0)
|
|
|
|
{
|
|
|
|
lsp->tlv_data.nlpids->count++;
|
|
|
|
lsp->tlv_data.nlpids->nlpids[0] = NLPID_IP;
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
#ifdef HAVE_IPV6
|
2004-09-10 22:48:21 +02:00
|
|
|
if (area->ipv6_circuits > 0)
|
|
|
|
{
|
|
|
|
lsp->tlv_data.nlpids->count++;
|
|
|
|
lsp->tlv_data.nlpids->nlpids[lsp->tlv_data.nlpids->count - 1] =
|
|
|
|
NLPID_IPV6;
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
#endif /* HAVE_IPV6 */
|
|
|
|
}
|
|
|
|
/* Dynamic Hostname */
|
2004-09-10 22:48:21 +02:00
|
|
|
if (area->dynhostname)
|
|
|
|
{
|
|
|
|
lsp->tlv_data.hostname = XMALLOC (MTYPE_ISIS_TLV,
|
|
|
|
sizeof (struct hostname));
|
|
|
|
memcpy (&lsp->tlv_data.hostname->name, unix_hostname (),
|
|
|
|
strlen (unix_hostname ()));
|
|
|
|
lsp->tlv_data.hostname->namelen = strlen (unix_hostname ());
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
#ifdef TOPOLOGY_GENERATE
|
|
|
|
/*
|
|
|
|
* If we have a topology in this area, we need to connect this lsp to
|
|
|
|
* the first topology lsp
|
|
|
|
*/
|
2004-09-10 22:48:21 +02:00
|
|
|
if ((area->topology) && (level == 1))
|
|
|
|
{
|
|
|
|
if (lsp->tlv_data.is_neighs == NULL)
|
|
|
|
lsp->tlv_data.is_neighs = list_new ();
|
2005-09-01 19:52:33 +02:00
|
|
|
is_neigh = XCALLOC (MTYPE_ISIS_TLV, sizeof (struct is_neigh));
|
2004-09-10 22:48:21 +02:00
|
|
|
memcpy (&is_neigh->neigh_id, area->topology_baseis, ISIS_SYS_ID_LEN);
|
|
|
|
/* connected to the first */
|
|
|
|
is_neigh->neigh_id[ISIS_SYS_ID_LEN - 1] = (0x01);
|
|
|
|
/* this is actually the same system, why mess the SPT */
|
|
|
|
is_neigh->metrics.metric_default = 0;
|
|
|
|
is_neigh->metrics.metric_delay = METRICS_UNSUPPORTED;
|
|
|
|
is_neigh->metrics.metric_expense = METRICS_UNSUPPORTED;
|
|
|
|
is_neigh->metrics.metric_error = METRICS_UNSUPPORTED;
|
|
|
|
listnode_add (lsp->tlv_data.is_neighs, is_neigh);
|
2003-12-23 09:09:43 +01:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Then add tlvs related to circuits
|
|
|
|
*/
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (area->circuit_list, node, nnode, circuit))
|
2004-09-10 22:48:21 +02:00
|
|
|
{
|
|
|
|
if (circuit->state != C_STATE_UP)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Add IPv4 internal reachability of this circuit
|
|
|
|
*/
|
|
|
|
if (circuit->ip_router && circuit->ip_addrs &&
|
|
|
|
circuit->ip_addrs->count > 0)
|
|
|
|
{
|
|
|
|
if (lsp->tlv_data.ipv4_int_reachs == NULL)
|
|
|
|
{
|
|
|
|
lsp->tlv_data.ipv4_int_reachs = list_new ();
|
|
|
|
lsp->tlv_data.ipv4_int_reachs->del = free_tlv;
|
|
|
|
}
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (circuit->ip_addrs, ipnode, ipnnode, ipv4))
|
2004-09-10 22:48:21 +02:00
|
|
|
{
|
|
|
|
ipreach =
|
2005-09-01 19:52:33 +02:00
|
|
|
XCALLOC (MTYPE_ISIS_TLV, sizeof (struct ipv4_reachability));
|
2004-09-10 22:48:21 +02:00
|
|
|
ipreach->metrics = circuit->metrics[level - 1];
|
|
|
|
ipreach->prefix = ipv4->prefix;
|
|
|
|
masklen2ip (ipv4->prefixlen, &ipreach->mask);
|
|
|
|
listnode_add (lsp->tlv_data.ipv4_int_reachs, ipreach);
|
|
|
|
}
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
#ifdef HAVE_IPV6
|
2004-09-10 22:48:21 +02:00
|
|
|
/*
|
|
|
|
* Add IPv6 reachability of this circuit
|
|
|
|
*/
|
|
|
|
if (circuit->ipv6_router && circuit->ipv6_non_link &&
|
|
|
|
circuit->ipv6_non_link->count > 0)
|
|
|
|
{
|
|
|
|
if (lsp->tlv_data.ipv6_reachs == NULL)
|
|
|
|
{
|
|
|
|
lsp->tlv_data.ipv6_reachs = list_new ();
|
|
|
|
lsp->tlv_data.ipv6_reachs->del = free_tlv;
|
|
|
|
}
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (circuit->ipv6_non_link, ipnode,
|
|
|
|
ipnnode, ipv6))
|
2004-09-10 22:48:21 +02:00
|
|
|
{
|
|
|
|
ip6reach =
|
2005-09-01 19:52:33 +02:00
|
|
|
XCALLOC (MTYPE_ISIS_TLV, sizeof (struct ipv6_reachability));
|
2004-09-10 22:48:21 +02:00
|
|
|
ip6reach->metric =
|
|
|
|
htonl (circuit->metrics[level - 1].metric_default);
|
|
|
|
ip6reach->control_info = 0;
|
|
|
|
ip6reach->prefix_len = ipv6->prefixlen;
|
|
|
|
memcpy (&ip6reach->prefix, ipv6->prefix.s6_addr,
|
|
|
|
(ipv6->prefixlen + 7) / 8);
|
|
|
|
listnode_add (lsp->tlv_data.ipv6_reachs, ip6reach);
|
|
|
|
}
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
#endif /* HAVE_IPV6 */
|
2004-09-10 22:48:21 +02:00
|
|
|
|
|
|
|
switch (circuit->circ_type)
|
|
|
|
{
|
|
|
|
case CIRCUIT_T_BROADCAST:
|
|
|
|
if (level & circuit->circuit_is_type)
|
|
|
|
{
|
|
|
|
if (lsp->tlv_data.is_neighs == NULL)
|
|
|
|
{
|
|
|
|
lsp->tlv_data.is_neighs = list_new ();
|
|
|
|
lsp->tlv_data.is_neighs->del = free_tlv;
|
|
|
|
}
|
2005-09-01 19:52:33 +02:00
|
|
|
is_neigh = XCALLOC (MTYPE_ISIS_TLV, sizeof (struct is_neigh));
|
2004-09-10 22:48:21 +02:00
|
|
|
if (level == 1)
|
|
|
|
memcpy (&is_neigh->neigh_id,
|
|
|
|
circuit->u.bc.l1_desig_is, ISIS_SYS_ID_LEN + 1);
|
|
|
|
else
|
|
|
|
memcpy (&is_neigh->neigh_id,
|
|
|
|
circuit->u.bc.l2_desig_is, ISIS_SYS_ID_LEN + 1);
|
|
|
|
is_neigh->metrics = circuit->metrics[level - 1];
|
|
|
|
listnode_add (lsp->tlv_data.is_neighs, is_neigh);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CIRCUIT_T_P2P:
|
|
|
|
nei = circuit->u.p2p.neighbor;
|
|
|
|
if (nei && (level & nei->circuit_t))
|
|
|
|
{
|
|
|
|
if (lsp->tlv_data.is_neighs == NULL)
|
|
|
|
{
|
|
|
|
lsp->tlv_data.is_neighs = list_new ();
|
|
|
|
lsp->tlv_data.is_neighs->del = free_tlv;
|
|
|
|
}
|
2005-09-01 19:52:33 +02:00
|
|
|
is_neigh = XCALLOC (MTYPE_ISIS_TLV, sizeof (struct is_neigh));
|
2004-09-10 22:48:21 +02:00
|
|
|
memcpy (&is_neigh->neigh_id, nei->sysid, ISIS_SYS_ID_LEN);
|
|
|
|
is_neigh->metrics = circuit->metrics[level - 1];
|
|
|
|
listnode_add (lsp->tlv_data.is_neighs, is_neigh);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CIRCUIT_T_STATIC_IN:
|
|
|
|
zlog_warn ("lsp_area_create: unsupported circuit type");
|
|
|
|
break;
|
|
|
|
case CIRCUIT_T_STATIC_OUT:
|
|
|
|
zlog_warn ("lsp_area_create: unsupported circuit type");
|
|
|
|
break;
|
|
|
|
case CIRCUIT_T_DA:
|
|
|
|
zlog_warn ("lsp_area_create: unsupported circuit type");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
zlog_warn ("lsp_area_create: unknown circuit type");
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
if (lsp->tlv_data.nlpids)
|
|
|
|
tlv_add_nlpid (lsp->tlv_data.nlpids, lsp->pdu);
|
|
|
|
if (lsp->tlv_data.hostname)
|
|
|
|
tlv_add_dynamic_hostname (lsp->tlv_data.hostname, lsp->pdu);
|
2004-09-10 22:48:21 +02:00
|
|
|
if (lsp->tlv_data.area_addrs && listcount (lsp->tlv_data.area_addrs) > 0)
|
2003-12-23 09:09:43 +01:00
|
|
|
tlv_add_area_addrs (lsp->tlv_data.area_addrs, lsp->pdu);
|
|
|
|
if (lsp->tlv_data.is_neighs && listcount (lsp->tlv_data.is_neighs) > 0)
|
|
|
|
tlv_add_is_neighs (lsp->tlv_data.is_neighs, lsp->pdu);
|
2004-09-10 22:48:21 +02:00
|
|
|
if (lsp->tlv_data.ipv4_int_reachs &&
|
2003-12-23 09:09:43 +01:00
|
|
|
listcount (lsp->tlv_data.ipv4_int_reachs) > 0)
|
|
|
|
tlv_add_ipv4_reachs (lsp->tlv_data.ipv4_int_reachs, lsp->pdu);
|
2004-09-10 22:48:21 +02:00
|
|
|
#ifdef HAVE_IPV6
|
|
|
|
if (lsp->tlv_data.ipv6_reachs && listcount (lsp->tlv_data.ipv6_reachs) > 0)
|
2003-12-23 09:09:43 +01:00
|
|
|
tlv_add_ipv6_reachs (lsp->tlv_data.ipv6_reachs, lsp->pdu);
|
|
|
|
#endif /* HAVE_IPV6 */
|
|
|
|
|
2005-02-09 16:51:56 +01:00
|
|
|
lsp->lsp_header->pdu_len = htons (stream_get_endp (lsp->pdu));
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define FRAG_THOLD(S,T) \
|
|
|
|
((STREAM_SIZE(S)*T)/100)
|
|
|
|
|
|
|
|
/* stream*, area->lsp_frag_threshold, increment */
|
|
|
|
#define FRAG_NEEDED(S,T,I) \
|
|
|
|
(STREAM_SIZE(S)-STREAM_REMAIN(S)+(I) > FRAG_THOLD(S,T))
|
|
|
|
|
2005-01-18 14:53:33 +01:00
|
|
|
static void
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_tlv_fit (struct isis_lsp *lsp, struct list **from, struct list **to,
|
2004-09-10 22:48:21 +02:00
|
|
|
int tlvsize, int frag_thold,
|
|
|
|
int tlv_build_func (struct list *, struct stream *))
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
int count, i;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
/* can we fit all ? */
|
2004-09-10 22:48:21 +02:00
|
|
|
if (!FRAG_NEEDED (lsp->pdu, frag_thold, listcount (*from) * tlvsize + 2))
|
|
|
|
{
|
|
|
|
tlv_build_func (*from, lsp->pdu);
|
|
|
|
*to = *from;
|
|
|
|
*from = NULL;
|
|
|
|
}
|
|
|
|
else if (!FRAG_NEEDED (lsp->pdu, frag_thold, tlvsize + 2))
|
|
|
|
{
|
|
|
|
/* fit all we can */
|
|
|
|
count = FRAG_THOLD (lsp->pdu, frag_thold) - 2 -
|
|
|
|
(STREAM_SIZE (lsp->pdu) - STREAM_REMAIN (lsp->pdu));
|
|
|
|
if (count)
|
|
|
|
count = count / tlvsize;
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
listnode_add (*to, listgetdata (listhead (*from)));
|
|
|
|
listnode_delete (*from, listgetdata (listhead (*from)));
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
|
|
|
tlv_build_func (*to, lsp->pdu);
|
|
|
|
}
|
2005-02-09 16:51:56 +01:00
|
|
|
lsp->lsp_header->pdu_len = htons (stream_get_endp (lsp->pdu));
|
2003-12-23 09:09:43 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-01-18 14:53:33 +01:00
|
|
|
static struct isis_lsp *
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp_next_frag (u_char frag_num, struct isis_lsp *lsp0, struct isis_area *area,
|
|
|
|
int level)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
struct isis_lsp *lsp;
|
2004-09-10 22:48:21 +02:00
|
|
|
u_char frag_id[ISIS_SYS_ID_LEN + 2];
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
memcpy (frag_id, lsp0->lsp_header->lsp_id, ISIS_SYS_ID_LEN + 1);
|
|
|
|
LSP_FRAGMENT (frag_id) = frag_num;
|
|
|
|
lsp = lsp_search (frag_id, area->lspdb[level - 1]);
|
2004-09-10 22:48:21 +02:00
|
|
|
if (lsp)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Clear the TLVs, but inherit the authinfo
|
|
|
|
*/
|
|
|
|
lsp_clear_data (lsp);
|
|
|
|
if (lsp0->tlv_data.auth_info.type)
|
|
|
|
{
|
|
|
|
memcpy (&lsp->tlv_data.auth_info, &lsp->tlv_data.auth_info,
|
|
|
|
sizeof (struct isis_passwd));
|
|
|
|
tlv_add_authinfo (lsp->tlv_data.auth_info.type,
|
|
|
|
lsp->tlv_data.auth_info.len,
|
|
|
|
lsp->tlv_data.auth_info.passwd, lsp->pdu);
|
|
|
|
}
|
|
|
|
return lsp;
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
lsp = lsp_new (frag_id, area->max_lsp_lifetime[level - 1], 0, area->is_type,
|
2004-09-10 22:48:21 +02:00
|
|
|
0, level);
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp->own_lsp = 1;
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp_insert (lsp, area->lspdb[level - 1]);
|
2003-12-23 09:09:43 +01:00
|
|
|
listnode_add (lsp0->lspu.frags, lsp);
|
|
|
|
lsp->lspu.zero_lsp = lsp0;
|
|
|
|
/*
|
|
|
|
* Copy the authinfo from zero LSP
|
|
|
|
*/
|
2004-09-10 22:48:21 +02:00
|
|
|
if (lsp0->tlv_data.auth_info.type)
|
|
|
|
{
|
|
|
|
memcpy (&lsp->tlv_data.auth_info, &lsp->tlv_data.auth_info,
|
|
|
|
sizeof (struct isis_passwd));
|
|
|
|
tlv_add_authinfo (lsp->tlv_data.auth_info.type,
|
|
|
|
lsp->tlv_data.auth_info.len,
|
|
|
|
lsp->tlv_data.auth_info.passwd, lsp->pdu);
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
return lsp;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Builds the LSP data part. This func creates a new frag whenever
|
|
|
|
* area->lsp_frag_threshold is exceeded.
|
|
|
|
*/
|
|
|
|
#if 1
|
2005-01-18 14:53:33 +01:00
|
|
|
static void
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_build_nonpseudo (struct isis_lsp *lsp, struct isis_area *area)
|
|
|
|
{
|
|
|
|
struct is_neigh *is_neigh;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *node, *nnode, *ipnode, *ipnnode;
|
2003-12-23 09:09:43 +01:00
|
|
|
int level = lsp->level;
|
|
|
|
struct isis_circuit *circuit;
|
|
|
|
struct prefix_ipv4 *ipv4;
|
|
|
|
struct ipv4_reachability *ipreach;
|
|
|
|
struct isis_adjacency *nei;
|
|
|
|
#ifdef HAVE_IPV6
|
2004-09-21 16:17:04 +02:00
|
|
|
struct prefix_ipv6 *ipv6, *ip6prefix;
|
2003-12-23 09:09:43 +01:00
|
|
|
struct ipv6_reachability *ip6reach;
|
|
|
|
#endif /* HAVE_IPV6 */
|
|
|
|
struct tlvs tlv_data;
|
|
|
|
struct isis_lsp *lsp0 = lsp;
|
|
|
|
struct isis_passwd *passwd;
|
2004-10-03 20:18:34 +02:00
|
|
|
struct in_addr *routerid;
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* First add the tlvs related to area
|
|
|
|
*/
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
/* Area addresses */
|
|
|
|
if (lsp->tlv_data.area_addrs == NULL)
|
|
|
|
lsp->tlv_data.area_addrs = list_new ();
|
|
|
|
list_add_list (lsp->tlv_data.area_addrs, area->area_addrs);
|
|
|
|
/* Protocols Supported */
|
2004-09-10 22:48:21 +02:00
|
|
|
if (area->ip_circuits > 0
|
2003-12-23 09:09:43 +01:00
|
|
|
#ifdef HAVE_IPV6
|
|
|
|
|| area->ipv6_circuits > 0
|
|
|
|
#endif /* HAVE_IPV6 */
|
2004-09-10 22:48:21 +02:00
|
|
|
)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
2005-09-01 19:52:33 +02:00
|
|
|
lsp->tlv_data.nlpids = XCALLOC (MTYPE_ISIS_TLV, sizeof (struct nlpids));
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp->tlv_data.nlpids->count = 0;
|
2004-09-10 22:48:21 +02:00
|
|
|
if (area->ip_circuits > 0)
|
|
|
|
{
|
|
|
|
lsp->tlv_data.nlpids->count++;
|
|
|
|
lsp->tlv_data.nlpids->nlpids[0] = NLPID_IP;
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
#ifdef HAVE_IPV6
|
2004-09-10 22:48:21 +02:00
|
|
|
if (area->ipv6_circuits > 0)
|
|
|
|
{
|
|
|
|
lsp->tlv_data.nlpids->count++;
|
|
|
|
lsp->tlv_data.nlpids->nlpids[lsp->tlv_data.nlpids->count - 1] =
|
|
|
|
NLPID_IPV6;
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
#endif /* HAVE_IPV6 */
|
|
|
|
}
|
|
|
|
/* Dynamic Hostname */
|
2004-09-10 22:48:21 +02:00
|
|
|
if (area->dynhostname)
|
|
|
|
{
|
|
|
|
lsp->tlv_data.hostname = XMALLOC (MTYPE_ISIS_TLV,
|
|
|
|
sizeof (struct hostname));
|
2003-12-23 09:56:18 +01:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
memcpy (lsp->tlv_data.hostname->name, unix_hostname (),
|
|
|
|
strlen (unix_hostname ()));
|
|
|
|
lsp->tlv_data.hostname->namelen = strlen (unix_hostname ());
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Building the zero lsp
|
|
|
|
*/
|
2005-09-01 19:52:33 +02:00
|
|
|
|
|
|
|
/* Reset stream endp. Stream is always there and on every LSP refresh only
|
|
|
|
* TLV part of it is overwritten. So we must seek past header we will not
|
|
|
|
* touch. */
|
|
|
|
lsp->pdu->endp = 0;
|
|
|
|
stream_forward_endp (lsp->pdu, ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN);
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
/*
|
|
|
|
* Add the authentication info if its present
|
|
|
|
*/
|
2004-09-10 22:48:21 +02:00
|
|
|
(level == 1) ? (passwd = &area->area_passwd) :
|
|
|
|
(passwd = &area->domain_passwd);
|
|
|
|
if (passwd->type)
|
|
|
|
{
|
|
|
|
memcpy (&lsp->tlv_data.auth_info, passwd, sizeof (struct isis_passwd));
|
|
|
|
tlv_add_authinfo (passwd->type, passwd->len, passwd->passwd, lsp->pdu);
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
if (lsp->tlv_data.nlpids)
|
|
|
|
tlv_add_nlpid (lsp->tlv_data.nlpids, lsp->pdu);
|
|
|
|
if (lsp->tlv_data.hostname)
|
|
|
|
tlv_add_dynamic_hostname (lsp->tlv_data.hostname, lsp->pdu);
|
2004-09-10 22:48:21 +02:00
|
|
|
if (lsp->tlv_data.area_addrs && listcount (lsp->tlv_data.area_addrs) > 0)
|
2003-12-23 09:09:43 +01:00
|
|
|
tlv_add_area_addrs (lsp->tlv_data.area_addrs, lsp->pdu);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
memset (&tlv_data, 0, sizeof (struct tlvs));
|
2004-10-03 20:18:34 +02:00
|
|
|
/*
|
|
|
|
* IPv4 address TLV. We don't follow "C" vendor, but "J" vendor behavior -
|
|
|
|
* one IPv4 address is put into LSP and this address is same as router id.
|
|
|
|
*/
|
|
|
|
if (router_id_zebra.s_addr != 0)
|
|
|
|
{
|
|
|
|
if (lsp->tlv_data.ipv4_addrs == NULL)
|
2005-09-02 03:38:16 +02:00
|
|
|
{
|
|
|
|
lsp->tlv_data.ipv4_addrs = list_new ();
|
|
|
|
lsp->tlv_data.ipv4_addrs->del = free_tlv;
|
|
|
|
}
|
2004-10-03 20:18:34 +02:00
|
|
|
|
|
|
|
routerid = XMALLOC (MTYPE_ISIS_TLV, sizeof (struct in_addr));
|
|
|
|
routerid->s_addr = router_id_zebra.s_addr;
|
|
|
|
|
|
|
|
listnode_add (lsp->tlv_data.ipv4_addrs, routerid);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* FIXME: Using add_tlv() directly is hack, but tlv_add_ip_addrs()
|
|
|
|
* expects list of prefix_ipv4 structures, but we have list of
|
|
|
|
* in_addr structures.
|
|
|
|
*/
|
|
|
|
add_tlv (IPV4_ADDR, IPV4_MAX_BYTELEN, (u_char *) &routerid->s_addr,
|
|
|
|
lsp->pdu);
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
/*
|
|
|
|
* Then build lists of tlvs related to circuits
|
|
|
|
*/
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (area->circuit_list, node, nnode, circuit))
|
2004-09-10 22:48:21 +02:00
|
|
|
{
|
|
|
|
if (circuit->state != C_STATE_UP)
|
|
|
|
continue;
|
2003-12-23 09:09:43 +01:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
/*
|
|
|
|
* Add IPv4 internal reachability of this circuit
|
|
|
|
*/
|
|
|
|
if (circuit->ip_router && circuit->ip_addrs &&
|
|
|
|
circuit->ip_addrs->count > 0)
|
|
|
|
{
|
|
|
|
if (tlv_data.ipv4_int_reachs == NULL)
|
|
|
|
{
|
|
|
|
tlv_data.ipv4_int_reachs = list_new ();
|
2005-09-02 03:38:16 +02:00
|
|
|
tlv_data.ipv4_int_reachs->del = free_tlv;
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (circuit->ip_addrs, ipnode, ipnnode, ipv4))
|
2004-09-10 22:48:21 +02:00
|
|
|
{
|
|
|
|
ipreach =
|
2005-09-01 19:52:33 +02:00
|
|
|
XCALLOC (MTYPE_ISIS_TLV, sizeof (struct ipv4_reachability));
|
2004-09-10 22:48:21 +02:00
|
|
|
ipreach->metrics = circuit->metrics[level - 1];
|
|
|
|
masklen2ip (ipv4->prefixlen, &ipreach->mask);
|
2004-09-21 16:17:04 +02:00
|
|
|
ipreach->prefix.s_addr = ((ipreach->mask.s_addr) &
|
|
|
|
(ipv4->prefix.s_addr));
|
2004-09-10 22:48:21 +02:00
|
|
|
listnode_add (tlv_data.ipv4_int_reachs, ipreach);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
#ifdef HAVE_IPV6
|
2004-09-10 22:48:21 +02:00
|
|
|
/*
|
|
|
|
* Add IPv6 reachability of this circuit
|
|
|
|
*/
|
|
|
|
if (circuit->ipv6_router && circuit->ipv6_non_link &&
|
|
|
|
circuit->ipv6_non_link->count > 0)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (tlv_data.ipv6_reachs == NULL)
|
|
|
|
{
|
|
|
|
tlv_data.ipv6_reachs = list_new ();
|
2005-09-02 03:38:16 +02:00
|
|
|
tlv_data.ipv6_reachs->del = free_tlv;
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (circuit->ipv6_non_link, ipnode, ipnnode,
|
|
|
|
ipv6))
|
2004-09-10 22:48:21 +02:00
|
|
|
{
|
|
|
|
ip6reach =
|
2005-09-01 19:52:33 +02:00
|
|
|
XCALLOC (MTYPE_ISIS_TLV, sizeof (struct ipv6_reachability));
|
2004-09-10 22:48:21 +02:00
|
|
|
ip6reach->metric =
|
|
|
|
htonl (circuit->metrics[level - 1].metric_default);
|
|
|
|
ip6reach->control_info = 0;
|
|
|
|
ip6reach->prefix_len = ipv6->prefixlen;
|
2004-09-21 16:17:04 +02:00
|
|
|
memcpy (&ip6prefix, &ipv6, sizeof(ip6prefix));
|
|
|
|
apply_mask_ipv6 (ip6prefix);
|
|
|
|
memcpy (ip6reach->prefix, ip6prefix->prefix.s6_addr,
|
|
|
|
sizeof (ip6reach->prefix));
|
2004-09-10 22:48:21 +02:00
|
|
|
listnode_add (tlv_data.ipv6_reachs, ip6reach);
|
|
|
|
}
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
#endif /* HAVE_IPV6 */
|
2004-09-10 22:48:21 +02:00
|
|
|
|
|
|
|
switch (circuit->circ_type)
|
|
|
|
{
|
|
|
|
case CIRCUIT_T_BROADCAST:
|
|
|
|
if (level & circuit->circuit_is_type)
|
|
|
|
{
|
|
|
|
if (tlv_data.is_neighs == NULL)
|
|
|
|
{
|
|
|
|
tlv_data.is_neighs = list_new ();
|
2005-09-02 03:38:16 +02:00
|
|
|
tlv_data.is_neighs->del = free_tlv;
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
2005-09-01 19:52:33 +02:00
|
|
|
is_neigh = XCALLOC (MTYPE_ISIS_TLV, sizeof (struct is_neigh));
|
2004-09-10 22:48:21 +02:00
|
|
|
if (level == 1)
|
|
|
|
memcpy (is_neigh->neigh_id,
|
|
|
|
circuit->u.bc.l1_desig_is, ISIS_SYS_ID_LEN + 1);
|
|
|
|
else
|
|
|
|
memcpy (is_neigh->neigh_id,
|
|
|
|
circuit->u.bc.l2_desig_is, ISIS_SYS_ID_LEN + 1);
|
|
|
|
is_neigh->metrics = circuit->metrics[level - 1];
|
|
|
|
listnode_add (tlv_data.is_neighs, is_neigh);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CIRCUIT_T_P2P:
|
|
|
|
nei = circuit->u.p2p.neighbor;
|
|
|
|
if (nei && (level & nei->circuit_t))
|
|
|
|
{
|
|
|
|
if (tlv_data.is_neighs == NULL)
|
|
|
|
{
|
|
|
|
tlv_data.is_neighs = list_new ();
|
|
|
|
tlv_data.is_neighs->del = free_tlv;
|
|
|
|
}
|
2005-09-01 19:52:33 +02:00
|
|
|
is_neigh = XCALLOC (MTYPE_ISIS_TLV, sizeof (struct is_neigh));
|
2004-09-10 22:48:21 +02:00
|
|
|
memcpy (is_neigh->neigh_id, nei->sysid, ISIS_SYS_ID_LEN);
|
|
|
|
is_neigh->metrics = circuit->metrics[level - 1];
|
|
|
|
listnode_add (tlv_data.is_neighs, is_neigh);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CIRCUIT_T_STATIC_IN:
|
|
|
|
zlog_warn ("lsp_area_create: unsupported circuit type");
|
|
|
|
break;
|
|
|
|
case CIRCUIT_T_STATIC_OUT:
|
|
|
|
zlog_warn ("lsp_area_create: unsupported circuit type");
|
|
|
|
break;
|
|
|
|
case CIRCUIT_T_DA:
|
|
|
|
zlog_warn ("lsp_area_create: unsupported circuit type");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
zlog_warn ("lsp_area_create: unknown circuit type");
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
while (tlv_data.ipv4_int_reachs && listcount (tlv_data.ipv4_int_reachs))
|
|
|
|
{
|
|
|
|
if (lsp->tlv_data.ipv4_int_reachs == NULL)
|
|
|
|
lsp->tlv_data.ipv4_int_reachs = list_new ();
|
|
|
|
lsp_tlv_fit (lsp, &tlv_data.ipv4_int_reachs,
|
|
|
|
&lsp->tlv_data.ipv4_int_reachs,
|
|
|
|
IPV4_REACH_LEN, area->lsp_frag_threshold,
|
|
|
|
tlv_add_ipv4_reachs);
|
|
|
|
if (tlv_data.ipv4_int_reachs && listcount (tlv_data.ipv4_int_reachs))
|
|
|
|
lsp = lsp_next_frag (LSP_FRAGMENT (lsp->lsp_header->lsp_id) + 1,
|
|
|
|
lsp0, area, level);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef HAVE_IPV6
|
|
|
|
while (tlv_data.ipv6_reachs && listcount (tlv_data.ipv6_reachs))
|
|
|
|
{
|
|
|
|
if (lsp->tlv_data.ipv6_reachs == NULL)
|
|
|
|
lsp->tlv_data.ipv6_reachs = list_new ();
|
|
|
|
lsp_tlv_fit (lsp, &tlv_data.ipv6_reachs,
|
|
|
|
&lsp->tlv_data.ipv6_reachs,
|
|
|
|
IPV6_REACH_LEN, area->lsp_frag_threshold,
|
|
|
|
tlv_add_ipv6_reachs);
|
|
|
|
if (tlv_data.ipv6_reachs && listcount (tlv_data.ipv6_reachs))
|
|
|
|
lsp = lsp_next_frag (LSP_FRAGMENT (lsp->lsp_header->lsp_id) + 1,
|
|
|
|
lsp0, area, level);
|
|
|
|
}
|
|
|
|
#endif /* HAVE_IPV6 */
|
|
|
|
|
|
|
|
while (tlv_data.is_neighs && listcount (tlv_data.is_neighs))
|
|
|
|
{
|
|
|
|
if (lsp->tlv_data.is_neighs == NULL)
|
|
|
|
lsp->tlv_data.is_neighs = list_new ();
|
|
|
|
lsp_tlv_fit (lsp, &tlv_data.is_neighs,
|
|
|
|
&lsp->tlv_data.is_neighs,
|
|
|
|
IS_NEIGHBOURS_LEN, area->lsp_frag_threshold,
|
|
|
|
tlv_add_is_neighs);
|
|
|
|
if (tlv_data.is_neighs && listcount (tlv_data.is_neighs))
|
|
|
|
lsp = lsp_next_frag (LSP_FRAGMENT (lsp->lsp_header->lsp_id) + 1,
|
|
|
|
lsp0, area, level);
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2005-01-18 14:53:33 +01:00
|
|
|
#if 0 /* Old code? */
|
|
|
|
static void
|
2003-12-23 09:09:43 +01:00
|
|
|
build_lsp_data (struct isis_lsp *lsp, struct isis_area *area)
|
|
|
|
{
|
|
|
|
struct list *circuit_list = area->circuit_list;
|
|
|
|
struct isis_circuit *circuit;
|
|
|
|
u_char *tlv_ptr;
|
|
|
|
struct is_neigh *is_neigh;
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
/* add our nlpids */
|
2004-09-10 22:48:21 +02:00
|
|
|
/* the 2 is for the TL plus 1 for the nlpid */
|
|
|
|
tlv_ptr = lsppdu_realloc (lsp, MTYPE_ISIS_TLV, 3);
|
|
|
|
*tlv_ptr = PROTOCOLS_SUPPORTED; /* Type */
|
|
|
|
*(tlv_ptr + 1) = 1; /* one protocol */
|
|
|
|
#ifdef HAVE_IPV6 /*dunno if its right */
|
|
|
|
*(tlv_ptr + 2) = NLPID_IPV6;
|
2003-12-23 09:09:43 +01:00
|
|
|
#else
|
2004-09-10 22:48:21 +02:00
|
|
|
*(tlv_ptr + 2) = NLPID_IP;
|
2003-12-23 09:09:43 +01:00
|
|
|
#endif /* HAVE_IPV6 */
|
|
|
|
|
|
|
|
/* we should add our areas here
|
|
|
|
* FIXME: we need to figure out which should be added? Adj? All? First? */
|
|
|
|
|
|
|
|
/* first, lets add ourselves to the IS neighbours info */
|
2004-09-10 22:48:21 +02:00
|
|
|
/* the 2 is for the TL plus 1 for the virtual field */
|
|
|
|
tlv_ptr = lsppdu_realloc (lsp, MTYPE_ISIS_TLV, 3);
|
|
|
|
*tlv_ptr = IS_NEIGHBOURS; /* Type */
|
|
|
|
*(tlv_ptr + 2) = 0; /* virtual is zero */
|
|
|
|
lsp->tlv_data.is_neighs = list_new (); /* new list of is_neighbours */
|
2003-12-23 09:09:43 +01:00
|
|
|
/* assign space for the is_neigh at the pdu end */
|
2004-09-10 22:48:21 +02:00
|
|
|
is_neigh = (struct is_neigh *) lsppdu_realloc (lsp, MTYPE_ISIS_TLV,
|
|
|
|
sizeof (struct is_neigh));
|
2003-12-23 09:09:43 +01:00
|
|
|
/* add this node to our list */
|
2004-09-10 22:48:21 +02:00
|
|
|
listnode_add (lsp->tlv_data.is_neighs, is_neigh);
|
2003-12-23 09:09:43 +01:00
|
|
|
/* FIXME: Do we need our designated address here? */
|
2004-09-10 22:48:21 +02:00
|
|
|
memcpy (&is_neigh->neigh_id, isis->sysid, ISIS_SYS_ID_LEN + 1);
|
2003-12-23 09:09:43 +01:00
|
|
|
/* FIXME: Where should we really get our own LSPs metrics from? */
|
2004-09-10 22:48:21 +02:00
|
|
|
circuit = (struct isis_circuit *) listhead (circuit_list);
|
|
|
|
/* is_neigh->metrics = circuit->metrics[lsp->level -1]; */
|
2003-12-23 09:09:43 +01:00
|
|
|
/* Length */
|
2004-09-10 22:48:21 +02:00
|
|
|
*(tlv_ptr + 1) =
|
|
|
|
(lsp->tlv_data.is_neighs->count * sizeof (struct is_neigh) + 1);
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
/* FIXME: scan for adjencecies and add them */
|
|
|
|
|
|
|
|
/* FIXME: add reachability info */
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
/* adding dynamic hostname if needed */
|
|
|
|
if (area->dynhostname)
|
|
|
|
{
|
|
|
|
tlv_ptr = lsppdu_realloc (lsp, MTYPE_ISIS_TLV, 2); /* the 2 is for the TL */
|
|
|
|
*tlv_ptr = DYNAMIC_HOSTNAME; /* Type */
|
|
|
|
*(tlv_ptr + 1) = strlen (unix_hostname ()); /* Length */
|
|
|
|
lsp->tlv_data.hostname = (struct hostname *)
|
|
|
|
(lsppdu_realloc (lsp, MTYPE_ISIS_TLV,
|
|
|
|
/* the -1 is to fit the length in the struct */
|
|
|
|
strlen (unix_hostname ())) - 1);
|
|
|
|
memcpy (lsp->tlv_data.hostname->name, unix_hostname (),
|
|
|
|
strlen (unix_hostname ()));
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
}
|
2005-01-18 14:53:33 +01:00
|
|
|
#endif /* 0 */
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 7.3.7 Generation on non-pseudonode LSPs
|
|
|
|
*/
|
2005-01-18 14:53:33 +01:00
|
|
|
static int
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp_generate_non_pseudo (struct isis_area *area, int level)
|
|
|
|
{
|
2003-12-23 09:09:43 +01:00
|
|
|
struct isis_lsp *oldlsp, *newlsp;
|
|
|
|
u_int32_t seq_num = 0;
|
|
|
|
u_char lspid[ISIS_SYS_ID_LEN + 2];
|
|
|
|
|
|
|
|
memset (&lspid, 0, ISIS_SYS_ID_LEN + 2);
|
|
|
|
memcpy (&lspid, isis->sysid, ISIS_SYS_ID_LEN);
|
|
|
|
|
|
|
|
/* only builds the lsp if the area shares the level */
|
2004-09-10 22:48:21 +02:00
|
|
|
if ((area->is_type & level) == level)
|
|
|
|
{
|
|
|
|
oldlsp = lsp_search (lspid, area->lspdb[level - 1]);
|
|
|
|
if (oldlsp)
|
|
|
|
{
|
|
|
|
seq_num = ntohl (oldlsp->lsp_header->seq_num);
|
|
|
|
lsp_search_and_destroy (oldlsp->lsp_header->lsp_id,
|
|
|
|
area->lspdb[level - 1]);
|
|
|
|
/* FIXME: we should actually initiate a purge */
|
|
|
|
}
|
|
|
|
newlsp = lsp_new (lspid, area->max_lsp_lifetime[level - 1], seq_num,
|
|
|
|
area->is_type, 0, level);
|
|
|
|
newlsp->own_lsp = 1;
|
|
|
|
|
|
|
|
lsp_insert (newlsp, area->lspdb[level - 1]);
|
|
|
|
/* build_lsp_data (newlsp, area); */
|
|
|
|
lsp_build_nonpseudo (newlsp, area);
|
|
|
|
/* time to calculate our checksum */
|
|
|
|
lsp_seqnum_update (newlsp);
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
/* DEBUG_ADJ_PACKETS */
|
2004-09-10 22:48:21 +02:00
|
|
|
if (isis->debugs & DEBUG_ADJ_PACKETS)
|
|
|
|
{
|
|
|
|
/* FIXME: is this place right? fix missing info */
|
2004-12-24 01:14:50 +01:00
|
|
|
zlog_debug ("ISIS-Upd (%s): Building L%d LSP", area->area_tag, level);
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
return ISIS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 7.3.9 Generation of level 1 LSPs (non-pseudonode)
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
lsp_l1_generate (struct isis_area *area)
|
|
|
|
{
|
2004-09-10 22:48:21 +02:00
|
|
|
THREAD_TIMER_ON (master, area->t_lsp_refresh[0], lsp_refresh_l1, area,
|
|
|
|
MAX_LSP_GEN_INTERVAL);
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
return lsp_generate_non_pseudo (area, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 7.3.9 Generation of level 2 LSPs (non-pseudonode)
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
lsp_l2_generate (struct isis_area *area)
|
|
|
|
{
|
2004-09-10 22:48:21 +02:00
|
|
|
THREAD_TIMER_ON (master, area->t_lsp_refresh[1], lsp_refresh_l2, area,
|
|
|
|
MAX_LSP_GEN_INTERVAL);
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
return lsp_generate_non_pseudo (area, 2);
|
|
|
|
}
|
|
|
|
|
2005-01-18 14:53:33 +01:00
|
|
|
static int
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_non_pseudo_regenerate (struct isis_area *area, int level)
|
|
|
|
{
|
|
|
|
dict_t *lspdb = area->lspdb[level - 1];
|
|
|
|
struct isis_lsp *lsp, *frag;
|
|
|
|
struct listnode *node;
|
|
|
|
u_char lspid[ISIS_SYS_ID_LEN + 2];
|
|
|
|
|
|
|
|
memset (lspid, 0, ISIS_SYS_ID_LEN + 2);
|
|
|
|
memcpy (lspid, isis->sysid, ISIS_SYS_ID_LEN);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp = lsp_search (lspid, lspdb);
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
if (!lsp)
|
|
|
|
{
|
|
|
|
zlog_err
|
|
|
|
("ISIS-Upd (%s): lsp_non_pseudo_regenerate(): no L%d LSP found!",
|
|
|
|
area->area_tag, level);
|
2003-12-23 09:09:43 +01:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
return ISIS_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
lsp_clear_data (lsp);
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_build_nonpseudo (lsp, area);
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp->lsp_header->rem_lifetime = htons (isis_jitter
|
|
|
|
(area->max_lsp_lifetime[level - 1],
|
|
|
|
MAX_AGE_JITTER));
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_seqnum_update (lsp);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
|
|
|
if (isis->debugs & DEBUG_UPDATE_PACKETS)
|
|
|
|
{
|
2004-12-24 01:14:50 +01:00
|
|
|
zlog_debug ("ISIS-Upd (%s): refreshing our L%d LSP %s, "
|
|
|
|
"seq 0x%08x, cksum 0x%04x lifetime %us",
|
|
|
|
area->area_tag,
|
|
|
|
level,
|
|
|
|
rawlspid_print (lsp->lsp_header->lsp_id),
|
|
|
|
ntohl (lsp->lsp_header->seq_num),
|
|
|
|
ntohs (lsp->lsp_header->checksum),
|
|
|
|
ntohs (lsp->lsp_header->rem_lifetime));
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
lsp->last_generated = time (NULL);
|
|
|
|
area->lsp_regenerate_pending[level - 1] = 0;
|
|
|
|
ISIS_FLAGS_SET_ALL (lsp->SRMflags);
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO (lsp->lspu.frags, node, frag))
|
2004-09-10 22:48:21 +02:00
|
|
|
{
|
|
|
|
frag->lsp_header->rem_lifetime = htons (isis_jitter
|
|
|
|
(area->
|
|
|
|
max_lsp_lifetime[level - 1],
|
|
|
|
MAX_AGE_JITTER));
|
|
|
|
ISIS_FLAGS_SET_ALL (frag->SRMflags);
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
if (area->ip_circuits)
|
|
|
|
isis_spf_schedule (area, level);
|
|
|
|
#ifdef HAVE_IPV6
|
|
|
|
if (area->ipv6_circuits)
|
|
|
|
isis_spf_schedule6 (area, level);
|
|
|
|
#endif
|
|
|
|
return ISIS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Done at least every MAX_LSP_GEN_INTERVAL. Search own LSPs, update holding
|
|
|
|
* time and set SRM
|
|
|
|
*/
|
2004-09-10 22:48:21 +02:00
|
|
|
int
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_refresh_l1 (struct thread *thread)
|
|
|
|
{
|
|
|
|
struct isis_area *area;
|
|
|
|
unsigned long ref_time;
|
|
|
|
|
|
|
|
area = THREAD_ARG (thread);
|
|
|
|
assert (area);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
area->t_lsp_refresh[0] = NULL;
|
2004-09-10 22:48:21 +02:00
|
|
|
if (area->is_type & IS_LEVEL_1)
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_non_pseudo_regenerate (area, 1);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
|
|
|
ref_time = area->lsp_refresh[0] > MAX_LSP_GEN_INTERVAL ?
|
2003-12-23 09:09:43 +01:00
|
|
|
MAX_LSP_GEN_INTERVAL : area->lsp_refresh[0];
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
THREAD_TIMER_ON (master, area->t_lsp_refresh[0], lsp_refresh_l1, area,
|
|
|
|
isis_jitter (ref_time, MAX_AGE_JITTER));
|
2004-02-11 21:26:31 +01:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return ISIS_OK;
|
|
|
|
}
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
int
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_refresh_l2 (struct thread *thread)
|
|
|
|
{
|
|
|
|
struct isis_area *area;
|
|
|
|
unsigned long ref_time;
|
|
|
|
|
|
|
|
area = THREAD_ARG (thread);
|
|
|
|
assert (area);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
area->t_lsp_refresh[1] = NULL;
|
2004-09-10 22:48:21 +02:00
|
|
|
if (area->is_type & IS_LEVEL_2)
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_non_pseudo_regenerate (area, 2);
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
ref_time = area->lsp_refresh[1] > MAX_LSP_GEN_INTERVAL ?
|
2003-12-23 09:09:43 +01:00
|
|
|
MAX_LSP_GEN_INTERVAL : area->lsp_refresh[1];
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
THREAD_TIMER_ON (master, area->t_lsp_refresh[1], lsp_refresh_l2, area,
|
|
|
|
isis_jitter (ref_time, MAX_AGE_JITTER));
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
return ISIS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Something has changed -> regenerate LSP
|
|
|
|
*/
|
|
|
|
|
2005-01-18 14:53:33 +01:00
|
|
|
static int
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_l1_regenerate (struct thread *thread)
|
|
|
|
{
|
|
|
|
struct isis_area *area;
|
|
|
|
|
|
|
|
area = THREAD_ARG (thread);
|
|
|
|
area->lsp_regenerate_pending[0] = 0;
|
|
|
|
|
|
|
|
return lsp_non_pseudo_regenerate (area, 1);
|
|
|
|
}
|
|
|
|
|
2005-01-18 14:53:33 +01:00
|
|
|
static int
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_l2_regenerate (struct thread *thread)
|
|
|
|
{
|
|
|
|
struct isis_area *area;
|
|
|
|
|
|
|
|
area = THREAD_ARG (thread);
|
|
|
|
area->lsp_regenerate_pending[1] = 0;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return lsp_non_pseudo_regenerate (area, 2);
|
|
|
|
}
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
int
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_regenerate_schedule (struct isis_area *area)
|
|
|
|
{
|
|
|
|
struct isis_lsp *lsp;
|
|
|
|
u_char id[ISIS_SYS_ID_LEN + 2];
|
|
|
|
time_t now, diff;
|
2004-09-10 22:48:21 +02:00
|
|
|
memcpy (id, isis->sysid, ISIS_SYS_ID_LEN);
|
|
|
|
LSP_PSEUDO_ID (id) = LSP_FRAGMENT (id) = 0;
|
2003-12-23 09:09:43 +01:00
|
|
|
now = time (NULL);
|
|
|
|
/*
|
|
|
|
* First level 1
|
|
|
|
*/
|
2004-09-10 22:48:21 +02:00
|
|
|
if (area->is_type & IS_LEVEL_1)
|
|
|
|
{
|
|
|
|
lsp = lsp_search (id, area->lspdb[0]);
|
|
|
|
if (!lsp || area->lsp_regenerate_pending[0])
|
|
|
|
goto L2;
|
|
|
|
/*
|
|
|
|
* Throttle avoidance
|
|
|
|
*/
|
|
|
|
diff = now - lsp->last_generated;
|
|
|
|
if (diff < MIN_LSP_GEN_INTERVAL)
|
|
|
|
{
|
|
|
|
area->lsp_regenerate_pending[0] = 1;
|
|
|
|
thread_add_timer (master, lsp_l1_regenerate, area,
|
|
|
|
MIN_LSP_GEN_INTERVAL - diff);
|
2004-09-19 21:39:26 +02:00
|
|
|
goto L2;
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
lsp_non_pseudo_regenerate (area, 1);
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
/*
|
|
|
|
* then 2
|
|
|
|
*/
|
2004-09-10 22:48:21 +02:00
|
|
|
L2:
|
|
|
|
if (area->is_type & IS_LEVEL_2)
|
|
|
|
{
|
|
|
|
lsp = lsp_search (id, area->lspdb[1]);
|
|
|
|
if (!lsp || area->lsp_regenerate_pending[1])
|
|
|
|
return ISIS_OK;
|
|
|
|
/*
|
|
|
|
* Throttle avoidance
|
|
|
|
*/
|
|
|
|
diff = now - lsp->last_generated;
|
|
|
|
if (diff < MIN_LSP_GEN_INTERVAL)
|
|
|
|
{
|
|
|
|
area->lsp_regenerate_pending[1] = 1;
|
|
|
|
thread_add_timer (master, lsp_l2_regenerate, area,
|
|
|
|
MIN_LSP_GEN_INTERVAL - diff);
|
|
|
|
return ISIS_OK;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
lsp_non_pseudo_regenerate (area, 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ISIS_OK;
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Funcs for pseudonode LSPs
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 7.3.8 and 7.3.10 Generation of level 1 and 2 pseudonode LSPs
|
|
|
|
*/
|
2005-01-18 14:53:33 +01:00
|
|
|
static void
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp_build_pseudo (struct isis_lsp *lsp, struct isis_circuit *circuit,
|
|
|
|
int level)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
struct isis_adjacency *adj;
|
|
|
|
struct is_neigh *is_neigh;
|
|
|
|
struct es_neigh *es_neigh;
|
|
|
|
struct list *adj_list;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *node, *nnode;
|
2003-12-23 09:09:43 +01:00
|
|
|
struct isis_passwd *passwd;
|
|
|
|
|
|
|
|
assert (circuit);
|
|
|
|
assert (circuit->circ_type == CIRCUIT_T_BROADCAST);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
if (!circuit->u.bc.is_dr[level - 1])
|
2004-09-10 22:48:21 +02:00
|
|
|
return; /* we are not DIS on this circuit */
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp->level = level;
|
|
|
|
if (level == 1)
|
|
|
|
lsp->lsp_header->lsp_bits |= IS_LEVEL_1;
|
|
|
|
else
|
|
|
|
lsp->lsp_header->lsp_bits |= IS_LEVEL_2;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* add self to IS neighbours
|
|
|
|
*/
|
2004-09-10 22:48:21 +02:00
|
|
|
if (lsp->tlv_data.is_neighs == NULL)
|
|
|
|
{
|
|
|
|
lsp->tlv_data.is_neighs = list_new ();
|
|
|
|
lsp->tlv_data.is_neighs->del = free_tlv;
|
|
|
|
}
|
2005-05-03 11:27:23 +02:00
|
|
|
is_neigh = XCALLOC (MTYPE_ISIS_TLV, sizeof (struct is_neigh));
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
memcpy (&is_neigh->neigh_id, isis->sysid, ISIS_SYS_ID_LEN);
|
|
|
|
listnode_add (lsp->tlv_data.is_neighs, is_neigh);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
|
|
|
adj_list = list_new ();
|
|
|
|
isis_adj_build_up_list (circuit->u.bc.adjdb[level - 1], adj_list);
|
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (adj_list, node, nnode, adj))
|
2004-09-10 22:48:21 +02:00
|
|
|
{
|
|
|
|
if (adj->circuit_t & level)
|
|
|
|
{
|
|
|
|
if ((level == 1 && adj->sys_type == ISIS_SYSTYPE_L1_IS) ||
|
|
|
|
(level == 1 && adj->sys_type == ISIS_SYSTYPE_L2_IS &&
|
|
|
|
adj->adj_usage == ISIS_ADJ_LEVEL1AND2) ||
|
|
|
|
(level == 2 && adj->sys_type == ISIS_SYSTYPE_L2_IS))
|
|
|
|
{
|
|
|
|
/* an IS neighbour -> add it */
|
2005-05-03 11:27:23 +02:00
|
|
|
is_neigh = XCALLOC (MTYPE_ISIS_TLV, sizeof (struct is_neigh));
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
memcpy (&is_neigh->neigh_id, adj->sysid, ISIS_SYS_ID_LEN);
|
|
|
|
listnode_add (lsp->tlv_data.is_neighs, is_neigh);
|
|
|
|
}
|
|
|
|
else if (level == 1 && adj->sys_type == ISIS_SYSTYPE_ES)
|
|
|
|
{
|
|
|
|
/* an ES neigbour add it, if we are building level 1 LSP */
|
|
|
|
/* FIXME: the tlv-format is hard to use here */
|
|
|
|
if (lsp->tlv_data.es_neighs == NULL)
|
|
|
|
{
|
|
|
|
lsp->tlv_data.es_neighs = list_new ();
|
|
|
|
lsp->tlv_data.es_neighs->del = free_tlv;
|
|
|
|
}
|
2005-05-03 11:27:23 +02:00
|
|
|
es_neigh = XCALLOC (MTYPE_ISIS_TLV, sizeof (struct es_neigh));
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
memcpy (&es_neigh->first_es_neigh, adj->sysid, ISIS_SYS_ID_LEN);
|
2005-09-01 19:52:33 +02:00
|
|
|
listnode_add (lsp->tlv_data.es_neighs, es_neigh);
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
/*
|
|
|
|
* Add the authentication info if it's present
|
|
|
|
*/
|
2004-09-10 22:48:21 +02:00
|
|
|
(level == 1) ? (passwd = &circuit->area->area_passwd) :
|
|
|
|
(passwd = &circuit->area->domain_passwd);
|
|
|
|
if (passwd->type)
|
|
|
|
{
|
|
|
|
memcpy (&lsp->tlv_data.auth_info, passwd, sizeof (struct isis_passwd));
|
|
|
|
tlv_add_authinfo (passwd->type, passwd->len, passwd->passwd, lsp->pdu);
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
if (lsp->tlv_data.is_neighs && listcount (lsp->tlv_data.is_neighs) > 0)
|
|
|
|
tlv_add_is_neighs (lsp->tlv_data.is_neighs, lsp->pdu);
|
|
|
|
|
|
|
|
if (lsp->tlv_data.es_neighs && listcount (lsp->tlv_data.es_neighs) > 0)
|
|
|
|
tlv_add_is_neighs (lsp->tlv_data.es_neighs, lsp->pdu);
|
|
|
|
|
2005-02-09 16:51:56 +01:00
|
|
|
lsp->lsp_header->pdu_len = htons (stream_get_endp (lsp->pdu));
|
2004-09-10 22:48:21 +02:00
|
|
|
iso_csum_create (STREAM_DATA (lsp->pdu) + 12,
|
|
|
|
ntohs (lsp->lsp_header->pdu_len) - 12, 12);
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
list_delete (adj_list);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-01-18 14:53:33 +01:00
|
|
|
static int
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_pseudo_regenerate (struct isis_circuit *circuit, int level)
|
|
|
|
{
|
|
|
|
dict_t *lspdb = circuit->area->lspdb[level - 1];
|
|
|
|
struct isis_lsp *lsp;
|
|
|
|
u_char lsp_id[ISIS_SYS_ID_LEN + 2];
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
memcpy (lsp_id, isis->sysid, ISIS_SYS_ID_LEN);
|
2004-09-10 22:48:21 +02:00
|
|
|
LSP_PSEUDO_ID (lsp_id) = circuit->circuit_id;
|
|
|
|
LSP_FRAGMENT (lsp_id) = 0;
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp = lsp_search (lsp_id, lspdb);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
|
|
|
if (!lsp)
|
|
|
|
{
|
|
|
|
zlog_err ("lsp_pseudo_regenerate(): no l%d LSP %s found!", level,
|
|
|
|
rawlspid_print (lsp_id));
|
|
|
|
return ISIS_ERROR;
|
|
|
|
}
|
|
|
|
lsp_clear_data (lsp);
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
lsp_build_pseudo (lsp, circuit, level);
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp->lsp_header->rem_lifetime =
|
2003-12-23 09:09:43 +01:00
|
|
|
htons (isis_jitter (circuit->area->max_lsp_lifetime[level - 1],
|
2004-09-10 22:48:21 +02:00
|
|
|
MAX_AGE_JITTER));
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
lsp_inc_seqnum (lsp, 0);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
|
|
|
if (isis->debugs & DEBUG_UPDATE_PACKETS)
|
|
|
|
{
|
2004-12-24 01:14:50 +01:00
|
|
|
zlog_debug ("ISIS-Upd (%s): refreshing pseudo LSP L%d %s",
|
|
|
|
circuit->area->area_tag, level,
|
|
|
|
rawlspid_print (lsp->lsp_header->lsp_id));
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
lsp->last_generated = time (NULL);
|
|
|
|
ISIS_FLAGS_SET_ALL (lsp->SRMflags);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return ISIS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
lsp_l1_refresh_pseudo (struct thread *thread)
|
|
|
|
{
|
|
|
|
struct isis_circuit *circuit;
|
|
|
|
int retval;
|
|
|
|
unsigned long ref_time;
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
circuit = THREAD_ARG (thread);
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
if (!circuit->u.bc.is_dr[0])
|
2004-09-10 22:48:21 +02:00
|
|
|
return ISIS_ERROR; /* FIXME: purge and such */
|
|
|
|
|
2004-09-10 23:19:13 +02:00
|
|
|
circuit->u.bc.t_refresh_pseudo_lsp[0] = NULL;
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
retval = lsp_pseudo_regenerate (circuit, 1);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
|
|
|
ref_time = circuit->area->lsp_refresh[0] > MAX_LSP_GEN_INTERVAL ?
|
2003-12-23 09:09:43 +01:00
|
|
|
MAX_LSP_GEN_INTERVAL : circuit->area->lsp_refresh[0];
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
THREAD_TIMER_ON (master, circuit->u.bc.t_refresh_pseudo_lsp[0],
|
|
|
|
lsp_l1_refresh_pseudo, circuit,
|
|
|
|
isis_jitter (ref_time, MAX_AGE_JITTER));
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
int
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_l1_pseudo_generate (struct isis_circuit *circuit)
|
|
|
|
{
|
|
|
|
struct isis_lsp *lsp;
|
|
|
|
u_char id[ISIS_SYS_ID_LEN + 2];
|
|
|
|
unsigned long ref_time;
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
memcpy (id, isis->sysid, ISIS_SYS_ID_LEN);
|
|
|
|
LSP_FRAGMENT (id) = 0;
|
|
|
|
LSP_PSEUDO_ID (id) = circuit->circuit_id;
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If for some reason have a pseudo LSP in the db already -> regenerate
|
|
|
|
*/
|
|
|
|
if (lsp_search (id, circuit->area->lspdb[0]))
|
|
|
|
return lsp_pseudo_regenerate (circuit, 1);
|
|
|
|
lsp = lsp_new (id, circuit->area->max_lsp_lifetime[0],
|
2004-09-10 22:48:21 +02:00
|
|
|
1, circuit->area->is_type, 0, 1);
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_build_pseudo (lsp, circuit, 1);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp->own_lsp = 1;
|
|
|
|
lsp_insert (lsp, circuit->area->lspdb[0]);
|
|
|
|
ISIS_FLAGS_SET_ALL (lsp->SRMflags);
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
ref_time = circuit->area->lsp_refresh[0] > MAX_LSP_GEN_INTERVAL ?
|
2003-12-23 09:09:43 +01:00
|
|
|
MAX_LSP_GEN_INTERVAL : circuit->area->lsp_refresh[0];
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
THREAD_TIMER_ON (master, circuit->u.bc.t_refresh_pseudo_lsp[0],
|
|
|
|
lsp_l1_refresh_pseudo, circuit,
|
|
|
|
isis_jitter (ref_time, MAX_AGE_JITTER));
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
return lsp_regenerate_schedule (circuit->area);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
lsp_l2_refresh_pseudo (struct thread *thread)
|
|
|
|
{
|
|
|
|
struct isis_circuit *circuit;
|
|
|
|
int retval;
|
|
|
|
unsigned long ref_time;
|
2004-09-10 22:48:21 +02:00
|
|
|
circuit = THREAD_ARG (thread);
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
if (!circuit->u.bc.is_dr[1])
|
2004-09-10 22:48:21 +02:00
|
|
|
return ISIS_ERROR; /* FIXME: purge and such */
|
|
|
|
|
2004-09-10 23:19:13 +02:00
|
|
|
circuit->u.bc.t_refresh_pseudo_lsp[1] = NULL;
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
retval = lsp_pseudo_regenerate (circuit, 2);
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
ref_time = circuit->area->lsp_refresh[1] > MAX_LSP_GEN_INTERVAL ?
|
2003-12-23 09:09:43 +01:00
|
|
|
MAX_LSP_GEN_INTERVAL : circuit->area->lsp_refresh[1];
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
THREAD_TIMER_ON (master, circuit->u.bc.t_refresh_pseudo_lsp[1],
|
|
|
|
lsp_l2_refresh_pseudo, circuit,
|
|
|
|
isis_jitter (ref_time, MAX_AGE_JITTER));
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
int
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_l2_pseudo_generate (struct isis_circuit *circuit)
|
|
|
|
{
|
|
|
|
struct isis_lsp *lsp;
|
|
|
|
u_char id[ISIS_SYS_ID_LEN + 2];
|
|
|
|
unsigned long ref_time;
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
memcpy (id, isis->sysid, ISIS_SYS_ID_LEN);
|
|
|
|
LSP_FRAGMENT (id) = 0;
|
|
|
|
LSP_PSEUDO_ID (id) = circuit->circuit_id;
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
if (lsp_search (id, circuit->area->lspdb[1]))
|
|
|
|
return lsp_pseudo_regenerate (circuit, 2);
|
|
|
|
|
|
|
|
lsp = lsp_new (id, circuit->area->max_lsp_lifetime[1],
|
2004-09-10 22:48:21 +02:00
|
|
|
1, circuit->area->is_type, 0, 2);
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
lsp_build_pseudo (lsp, circuit, 2);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
|
|
|
ref_time = circuit->area->lsp_refresh[1] > MAX_LSP_GEN_INTERVAL ?
|
2003-12-23 09:09:43 +01:00
|
|
|
MAX_LSP_GEN_INTERVAL : circuit->area->lsp_refresh[1];
|
|
|
|
|
|
|
|
|
|
|
|
lsp->own_lsp = 1;
|
|
|
|
lsp_insert (lsp, circuit->area->lspdb[1]);
|
|
|
|
ISIS_FLAGS_SET_ALL (lsp->SRMflags);
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
THREAD_TIMER_ON (master, circuit->u.bc.t_refresh_pseudo_lsp[1],
|
|
|
|
lsp_l2_refresh_pseudo, circuit,
|
|
|
|
isis_jitter (ref_time, MAX_AGE_JITTER));
|
2003-12-23 09:09:43 +01:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
return lsp_regenerate_schedule (circuit->area);
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Walk through LSPs for an area
|
|
|
|
* - set remaining lifetime
|
|
|
|
* - set LSPs with SRMflag set for sending
|
|
|
|
*/
|
2004-09-10 22:48:21 +02:00
|
|
|
int
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp_tick (struct thread *thread)
|
|
|
|
{
|
|
|
|
struct isis_area *area;
|
|
|
|
struct isis_circuit *circuit;
|
|
|
|
struct isis_lsp *lsp;
|
|
|
|
struct list *lsp_list;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *lspnode, *lspnnode, *cnode;
|
2003-12-23 09:09:43 +01:00
|
|
|
dnode_t *dnode, *dnode_next;
|
|
|
|
int level;
|
|
|
|
|
|
|
|
lsp_list = list_new ();
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
area = THREAD_ARG (thread);
|
|
|
|
assert (area);
|
2004-09-10 23:19:13 +02:00
|
|
|
area->t_tick = NULL;
|
2004-09-10 22:48:21 +02:00
|
|
|
THREAD_TIMER_ON (master, area->t_tick, lsp_tick, area, 1);
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Build a list of LSPs with (any) SRMflag set
|
|
|
|
* and removed the ones that have aged out
|
|
|
|
*/
|
2004-09-10 22:48:21 +02:00
|
|
|
for (level = 0; level < ISIS_LEVELS; level++)
|
|
|
|
{
|
|
|
|
if (area->lspdb[level] && dict_count (area->lspdb[level]) > 0)
|
|
|
|
{
|
|
|
|
dnode = dict_first (area->lspdb[level]);
|
|
|
|
while (dnode != NULL)
|
|
|
|
{
|
|
|
|
dnode_next = dict_next (area->lspdb[level], dnode);
|
|
|
|
lsp = dnode_get (dnode);
|
|
|
|
lsp_set_time (lsp);
|
|
|
|
if (lsp->age_out == 0)
|
|
|
|
{
|
|
|
|
|
2004-12-24 01:14:50 +01:00
|
|
|
zlog_debug ("ISIS-Upd (%s): L%u LSP %s seq 0x%08x aged out",
|
|
|
|
area->area_tag,
|
|
|
|
lsp->level,
|
|
|
|
rawlspid_print (lsp->lsp_header->lsp_id),
|
|
|
|
ntohl (lsp->lsp_header->seq_num));
|
2004-09-10 22:48:21 +02:00
|
|
|
|
|
|
|
lsp_destroy (lsp);
|
|
|
|
dict_delete (area->lspdb[level], dnode);
|
|
|
|
}
|
|
|
|
else if (flags_any_set (lsp->SRMflags))
|
|
|
|
listnode_add (lsp_list, lsp);
|
|
|
|
dnode = dnode_next;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Send LSPs on circuits indicated by the SRMflags
|
|
|
|
*/
|
|
|
|
if (listcount (lsp_list) > 0)
|
|
|
|
{
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO (area->circuit_list, cnode, circuit))
|
2004-09-10 22:48:21 +02:00
|
|
|
{
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (lsp_list, lspnode, lspnnode, lsp))
|
2004-09-10 22:48:21 +02:00
|
|
|
{
|
|
|
|
if (ISIS_CHECK_FLAG (lsp->SRMflags, circuit))
|
|
|
|
{
|
|
|
|
/* FIXME: if same or elder lsp is already in lsp
|
|
|
|
* queue */
|
|
|
|
listnode_add (circuit->lsp_queue, lsp);
|
|
|
|
thread_add_event (master, send_lsp, circuit, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
list_delete_all_node (lsp_list);
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
list_delete (lsp_list);
|
|
|
|
|
|
|
|
return ISIS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp_purge_dr (u_char * id, struct isis_circuit *circuit, int level)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
struct isis_lsp *lsp;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp = lsp_search (id, circuit->area->lspdb[level - 1]);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
|
|
|
if (lsp && lsp->purged == 0)
|
|
|
|
{
|
|
|
|
lsp->lsp_header->rem_lifetime = htons (0);
|
|
|
|
lsp->lsp_header->pdu_len =
|
|
|
|
htons (ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN);
|
|
|
|
lsp->purged = 0;
|
|
|
|
iso_csum_create (STREAM_DATA (lsp->pdu) + 12,
|
|
|
|
ntohs (lsp->lsp_header->pdu_len) - 12, 12);
|
|
|
|
ISIS_FLAGS_SET_ALL (lsp->SRMflags);
|
|
|
|
}
|
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Purge own LSP that is received and we don't have.
|
|
|
|
* -> Do as in 7.3.16.4
|
|
|
|
*/
|
|
|
|
void
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp_purge_non_exist (struct isis_link_state_hdr *lsp_hdr,
|
|
|
|
struct isis_area *area)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
struct isis_lsp *lsp;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We need to create the LSP to be purged
|
|
|
|
*/
|
2004-12-24 01:14:50 +01:00
|
|
|
zlog_debug ("LSP PURGE NON EXIST");
|
2005-09-01 19:52:33 +02:00
|
|
|
lsp = XCALLOC (MTYPE_ISIS_LSP, sizeof (struct isis_lsp));
|
2004-09-10 22:48:21 +02:00
|
|
|
/*FIXME: BUG BUG BUG! the lsp doesn't exist here! */
|
|
|
|
/*did smt here, maybe good probably not */
|
2003-12-23 09:09:43 +01:00
|
|
|
lsp->level = ((lsp_hdr->lsp_bits & LSPBIT_IST) == IS_LEVEL_1) ? 1 : 2;
|
|
|
|
lsp->pdu = stream_new (ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN);
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp->isis_header = (struct isis_fixed_hdr *) STREAM_DATA (lsp->pdu);
|
2003-12-23 09:09:43 +01:00
|
|
|
fill_fixed_hdr (lsp->isis_header, (lsp->level == 1) ? L1_LINK_STATE
|
2004-09-10 22:48:21 +02:00
|
|
|
: L2_LINK_STATE);
|
|
|
|
lsp->lsp_header = (struct isis_link_state_hdr *) (STREAM_DATA (lsp->pdu) +
|
|
|
|
ISIS_FIXED_HDR_LEN);
|
2003-12-23 09:09:43 +01:00
|
|
|
memcpy (lsp->lsp_header, lsp_hdr, ISIS_LSP_HDR_LEN);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
/*
|
|
|
|
* Retain only LSP header
|
|
|
|
*/
|
|
|
|
lsp->lsp_header->pdu_len = htons (ISIS_FIXED_HDR_LEN + ISIS_LSP_HDR_LEN);
|
|
|
|
/*
|
|
|
|
* Set the remaining lifetime to 0
|
|
|
|
*/
|
|
|
|
lsp->lsp_header->rem_lifetime = 0;
|
|
|
|
/*
|
|
|
|
* Put the lsp into LSPdb
|
|
|
|
*/
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp_insert (lsp, area->lspdb[lsp->level - 1]);
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Send in to whole area
|
|
|
|
*/
|
|
|
|
ISIS_FLAGS_SET_ALL (lsp->SRMflags);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef TOPOLOGY_GENERATE
|
2005-01-18 14:53:33 +01:00
|
|
|
static int
|
2003-12-23 09:09:43 +01:00
|
|
|
top_lsp_refresh (struct thread *thread)
|
|
|
|
{
|
2004-09-10 22:48:21 +02:00
|
|
|
struct isis_lsp *lsp;
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
lsp = THREAD_ARG (thread);
|
|
|
|
assert (lsp);
|
|
|
|
|
|
|
|
lsp->t_lsp_top_ref = NULL;
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
lsp->lsp_header->rem_lifetime =
|
|
|
|
htons (isis_jitter (MAX_AGE, MAX_AGE_JITTER));
|
|
|
|
lsp->lsp_header->seq_num = htonl (ntohl (lsp->lsp_header->seq_num) + 1);
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
ISIS_FLAGS_SET_ALL (lsp->SRMflags);
|
2004-09-10 22:48:21 +02:00
|
|
|
if (isis->debugs & DEBUG_UPDATE_PACKETS)
|
|
|
|
{
|
2004-12-24 01:14:50 +01:00
|
|
|
zlog_debug ("ISIS-Upd (): refreshing Topology L1 %s",
|
|
|
|
rawlspid_print (lsp->lsp_header->lsp_id));
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
/* time to calculate our checksum */
|
|
|
|
iso_csum_create (STREAM_DATA (lsp->pdu) + 12,
|
2004-09-10 22:48:21 +02:00
|
|
|
ntohs (lsp->lsp_header->pdu_len) - 12, 12);
|
|
|
|
THREAD_TIMER_ON (master, lsp->t_lsp_top_ref, top_lsp_refresh, lsp,
|
|
|
|
isis_jitter (MAX_LSP_GEN_INTERVAL, MAX_LSP_GEN_JITTER));
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
return ISIS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
generate_topology_lsps (struct isis_area *area)
|
|
|
|
{
|
|
|
|
struct listnode *node;
|
|
|
|
int i, max = 0;
|
|
|
|
struct arc *arc;
|
|
|
|
u_char lspid[ISIS_SYS_ID_LEN + 2];
|
|
|
|
struct isis_lsp *lsp;
|
|
|
|
|
|
|
|
/* first we find the maximal node */
|
2005-04-10 17:58:10 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO (area->topology, node, arc))
|
2004-09-10 22:48:21 +02:00
|
|
|
{
|
|
|
|
if (arc->from_node > max)
|
|
|
|
max = arc->from_node;
|
|
|
|
if (arc->to_node > max)
|
|
|
|
max = arc->to_node;
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
for (i = 1; i < (max + 1); i++)
|
|
|
|
{
|
|
|
|
memcpy (lspid, area->topology_baseis, ISIS_SYS_ID_LEN);
|
|
|
|
LSP_PSEUDO_ID (lspid) = 0x00;
|
|
|
|
LSP_FRAGMENT (lspid) = 0x00;
|
|
|
|
lspid[ISIS_SYS_ID_LEN - 1] = (i & 0xFF);
|
|
|
|
lspid[ISIS_SYS_ID_LEN - 2] = ((i >> 8) & 0xFF);
|
|
|
|
|
|
|
|
lsp = lsp_new (lspid, isis_jitter (area->max_lsp_lifetime[0],
|
|
|
|
MAX_AGE_JITTER), 1, IS_LEVEL_1, 0,
|
|
|
|
1);
|
|
|
|
lsp->from_topology = 1;
|
|
|
|
/* creating data based on topology */
|
|
|
|
build_topology_lsp_data (lsp, area, i);
|
|
|
|
/* time to calculate our checksum */
|
|
|
|
iso_csum_create (STREAM_DATA (lsp->pdu) + 12,
|
|
|
|
ntohs (lsp->lsp_header->pdu_len) - 12, 12);
|
|
|
|
THREAD_TIMER_ON (master, lsp->t_lsp_top_ref, top_lsp_refresh, lsp,
|
|
|
|
isis_jitter (MAX_LSP_GEN_INTERVAL,
|
|
|
|
MAX_LSP_GEN_JITTER));
|
|
|
|
|
|
|
|
ISIS_FLAGS_SET_ALL (lsp->SRMflags);
|
|
|
|
lsp_insert (lsp, area->lspdb[0]);
|
2003-12-23 09:09:43 +01:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
remove_topology_lsps (struct isis_area *area)
|
|
|
|
{
|
|
|
|
struct isis_lsp *lsp;
|
|
|
|
dnode_t *dnode, *dnode_next;
|
|
|
|
|
|
|
|
dnode = dict_first (area->lspdb[0]);
|
2004-09-10 22:48:21 +02:00
|
|
|
while (dnode != NULL)
|
|
|
|
{
|
|
|
|
dnode_next = dict_next (area->lspdb[0], dnode);
|
|
|
|
lsp = dnode_get (dnode);
|
|
|
|
if (lsp->from_topology)
|
|
|
|
{
|
|
|
|
THREAD_TIMER_OFF (lsp->t_lsp_top_ref);
|
|
|
|
lsp_destroy (lsp);
|
|
|
|
dict_delete (area->lspdb[0], dnode);
|
|
|
|
}
|
|
|
|
dnode = dnode_next;
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-09-10 22:48:21 +02:00
|
|
|
build_topology_lsp_data (struct isis_lsp *lsp, struct isis_area *area,
|
2003-12-23 09:09:43 +01:00
|
|
|
int lsp_top_num)
|
|
|
|
{
|
2005-04-10 17:58:10 +02:00
|
|
|
struct listnode *node, *nnode;
|
2003-12-23 09:09:43 +01:00
|
|
|
struct arc *arc;
|
|
|
|
u_char *tlv_ptr;
|
|
|
|
struct is_neigh *is_neigh;
|
|
|
|
int to_lsp = 0;
|
|
|
|
char buff[200];
|
|
|
|
|
|
|
|
/* add our nlpids */
|
2004-09-10 22:48:21 +02:00
|
|
|
/* the 2 is for the TL plus 1 for the nlpid */
|
|
|
|
tlv_ptr = lsppdu_realloc (lsp, MTYPE_ISIS_TLV, 3);
|
|
|
|
*tlv_ptr = PROTOCOLS_SUPPORTED; /* Type */
|
|
|
|
*(tlv_ptr + 1) = 1; /* one protocol */
|
|
|
|
*(tlv_ptr + 2) = NLPID_IP;
|
|
|
|
lsp->tlv_data.nlpids = (struct nlpids *) (tlv_ptr + 1);
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
/* first, lets add the tops */
|
2004-09-10 22:48:21 +02:00
|
|
|
/* the 2 is for the TL plus 1 for the virtual field */
|
|
|
|
tlv_ptr = lsppdu_realloc (lsp, MTYPE_ISIS_TLV, 3);
|
|
|
|
*tlv_ptr = IS_NEIGHBOURS; /* Type */
|
|
|
|
*(tlv_ptr + 1) = 1; /* this is the virtual char len */
|
|
|
|
*(tlv_ptr + 2) = 0; /* virtual is zero */
|
|
|
|
lsp->tlv_data.is_neighs = list_new (); /* new list of is_neighbours */
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
/* add reachability for this IS for simulated 1 */
|
2004-09-10 22:48:21 +02:00
|
|
|
if (lsp_top_num == 1)
|
|
|
|
{
|
2003-12-23 09:09:43 +01:00
|
|
|
/* assign space for the is_neigh at the pdu end */
|
2004-09-10 22:48:21 +02:00
|
|
|
is_neigh = (struct is_neigh *) lsppdu_realloc (lsp, MTYPE_ISIS_TLV,
|
|
|
|
sizeof (struct
|
|
|
|
is_neigh));
|
2003-12-23 09:09:43 +01:00
|
|
|
/* add this node to our list */
|
2004-09-10 22:48:21 +02:00
|
|
|
listnode_add (lsp->tlv_data.is_neighs, is_neigh);
|
|
|
|
memcpy (&is_neigh->neigh_id, isis->sysid, ISIS_SYS_ID_LEN);
|
2003-12-23 09:09:43 +01:00
|
|
|
LSP_PSEUDO_ID (is_neigh->neigh_id) = 0x00;
|
2004-09-10 22:48:21 +02:00
|
|
|
is_neigh->metrics.metric_default = 0x00; /* no special reason */
|
2003-12-23 09:09:43 +01:00
|
|
|
is_neigh->metrics.metric_delay = METRICS_UNSUPPORTED;
|
|
|
|
is_neigh->metrics.metric_expense = METRICS_UNSUPPORTED;
|
|
|
|
is_neigh->metrics.metric_error = METRICS_UNSUPPORTED;
|
|
|
|
/* don't forget the length */
|
2004-09-10 22:48:21 +02:00
|
|
|
*(tlv_ptr + 1) += IS_NEIGHBOURS_LEN; /* the -1 is the virtual */
|
|
|
|
/* no need to check for fragging here, it is a lonely is_reach */
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
/* addding is reachabilities */
|
2005-04-10 17:58:10 +02:00
|
|
|
for (ALL_LIST_ELEMENTS (area->topology, node, nnode, arc))
|
2004-09-10 22:48:21 +02:00
|
|
|
{
|
|
|
|
if ((arc->from_node == lsp_top_num) || (arc->to_node == lsp_top_num))
|
|
|
|
{
|
|
|
|
if (arc->to_node == lsp_top_num)
|
|
|
|
to_lsp = arc->from_node;
|
|
|
|
if (arc->from_node == lsp_top_num)
|
|
|
|
to_lsp = arc->to_node;
|
|
|
|
|
|
|
|
/* if the length here is about to cross the FF limit, we reTLV */
|
|
|
|
if (*(tlv_ptr + 1) >= (0xFF - IS_NEIGHBOURS_LEN))
|
|
|
|
{
|
|
|
|
/* retlv */
|
|
|
|
/* the 2 is for the TL plus 1 for the virtual field */
|
|
|
|
tlv_ptr = lsppdu_realloc (lsp, MTYPE_ISIS_TLV, 3);
|
|
|
|
*tlv_ptr = IS_NEIGHBOURS; /* Type */
|
|
|
|
*(tlv_ptr + 1) = 1; /* this is the virtual char len */
|
|
|
|
*(tlv_ptr + 2) = 0; /* virtual is zero */
|
|
|
|
}
|
|
|
|
/* doing this here assures us that we won't add an "empty" tlv */
|
|
|
|
/* assign space for the is_neigh at the pdu end */
|
|
|
|
is_neigh = (struct is_neigh *) lsppdu_realloc (lsp, MTYPE_ISIS_TLV,
|
|
|
|
sizeof (struct
|
|
|
|
is_neigh));
|
|
|
|
/* add this node to our list */
|
|
|
|
listnode_add (lsp->tlv_data.is_neighs, is_neigh);
|
|
|
|
memcpy (&is_neigh->neigh_id, area->topology_baseis, ISIS_SYS_ID_LEN);
|
|
|
|
LSP_PSEUDO_ID (is_neigh->neigh_id) = 0x00;
|
|
|
|
is_neigh->neigh_id[ISIS_SYS_ID_LEN - 1] = (to_lsp & 0xFF);
|
|
|
|
is_neigh->neigh_id[ISIS_SYS_ID_LEN - 2] = ((to_lsp >> 8) & 0xFF);
|
|
|
|
is_neigh->metrics.metric_default = arc->distance;
|
|
|
|
is_neigh->metrics.metric_delay = METRICS_UNSUPPORTED;
|
|
|
|
is_neigh->metrics.metric_expense = METRICS_UNSUPPORTED;
|
|
|
|
is_neigh->metrics.metric_error = METRICS_UNSUPPORTED;
|
|
|
|
/* don't forget the length */
|
|
|
|
*(tlv_ptr + 1) += IS_NEIGHBOURS_LEN; /* the -1 is the virtual */
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
/* adding dynamic hostname if needed */
|
|
|
|
if (area->dynhostname)
|
|
|
|
{
|
|
|
|
memset (buff, 0x00, 200);
|
|
|
|
sprintf (buff, "feedme%d", lsp_top_num);
|
|
|
|
/* the 2 is for the TL */
|
|
|
|
tlv_ptr = lsppdu_realloc (lsp, MTYPE_ISIS_TLV, 2);
|
|
|
|
*tlv_ptr = DYNAMIC_HOSTNAME; /* Type */
|
|
|
|
*(tlv_ptr + 1) = strlen (buff); /* Length */
|
|
|
|
/* the -1 is to fit the length in the struct */
|
|
|
|
lsp->tlv_data.hostname = (struct hostname *)
|
|
|
|
(lsppdu_realloc (lsp, MTYPE_ISIS_TLV, strlen (buff)) - 1);
|
|
|
|
memcpy (lsp->tlv_data.hostname->name, buff, strlen (buff));
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
#endif /* TOPOLOGY_GENERATE */
|