frr/ospfd/ospf_opaque.c

2181 lines
62 KiB
C
Raw Normal View History

2002-12-13 21:15:29 +01:00
/*
* This is an implementation of rfc2370.
* Copyright (C) 2001 KDD R&D Laboratories, Inc.
* http://www.kddlabs.co.jp/
*
* This file is part of GNU Zebra.
*
* GNU Zebra is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* GNU Zebra 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 GNU Zebra; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <zebra.h>
#include "linklist.h"
#include "prefix.h"
#include "if.h"
#include "table.h"
#include "memory.h"
#include "command.h"
#include "vty.h"
#include "stream.h"
#include "log.h"
#include "thread.h"
#include "hash.h"
#include "sockunion.h" /* for inet_aton() */
#include "ospfd/ospfd.h"
#include "ospfd/ospf_interface.h"
#include "ospfd/ospf_ism.h"
#include "ospfd/ospf_asbr.h"
#include "ospfd/ospf_lsa.h"
#include "ospfd/ospf_lsdb.h"
#include "ospfd/ospf_neighbor.h"
#include "ospfd/ospf_nsm.h"
#include "ospfd/ospf_flood.h"
#include "ospfd/ospf_packet.h"
#include "ospfd/ospf_spf.h"
#include "ospfd/ospf_dump.h"
#include "ospfd/ospf_route.h"
#include "ospfd/ospf_ase.h"
#include "ospfd/ospf_zebra.h"
DEFINE_MTYPE_STATIC(OSPFD, OSPF_OPAQUE_FUNCTAB, "OSPF opaque function table")
DEFINE_MTYPE_STATIC(OSPFD, OPAQUE_INFO_PER_TYPE, "OSPF opaque per-type info")
DEFINE_MTYPE_STATIC(OSPFD, OPAQUE_INFO_PER_ID, "OSPF opaque per-ID info")
2002-12-13 21:15:29 +01:00
/*------------------------------------------------------------------------*
* Followings are initialize/terminate functions for Opaque-LSAs handling.
*------------------------------------------------------------------------*/
#include "ospfd/ospf_te.h"
#include "ospfd/ospf_ri.h"
2002-12-13 21:15:29 +01:00
#ifdef SUPPORT_OSPF_API
int ospf_apiserver_init (void);
void ospf_apiserver_term (void);
2004-10-12 08:13:54 +02:00
/* Init apiserver? It's disabled by default. */
int ospf_apiserver_enable;
#endif /* SUPPORT_OSPF_API */
2002-12-13 21:15:29 +01:00
static void ospf_opaque_register_vty (void);
static void ospf_opaque_funclist_init (void);
static void ospf_opaque_funclist_term (void);
static void free_opaque_info_per_type (void *val);
static void free_opaque_info_per_id (void *val);
static int ospf_opaque_lsa_install_hook (struct ospf_lsa *lsa);
static int ospf_opaque_lsa_delete_hook (struct ospf_lsa *lsa);
void
ospf_opaque_init (void)
{
ospf_opaque_register_vty ();
ospf_opaque_funclist_init ();
if (ospf_mpls_te_init () != 0)
exit (1);
if (ospf_router_info_init () != 0)
exit (1);
#ifdef SUPPORT_OSPF_API
2004-10-11 18:27:03 +02:00
if ((ospf_apiserver_enable) && (ospf_apiserver_init () != 0))
exit (1);
#endif /* SUPPORT_OSPF_API */
2002-12-13 21:15:29 +01:00
return;
}
void
ospf_opaque_term (void)
{
ospf_mpls_te_term ();
ospf_router_info_term ();
#ifdef SUPPORT_OSPF_API
ospf_apiserver_term ();
#endif /* SUPPORT_OSPF_API */
2002-12-13 21:15:29 +01:00
ospf_opaque_funclist_term ();
return;
}
int
ospf_opaque_type9_lsa_init (struct ospf_interface *oi)
{
if (oi->opaque_lsa_self != NULL)
list_delete (oi->opaque_lsa_self);
oi->opaque_lsa_self = list_new ();
oi->opaque_lsa_self->del = free_opaque_info_per_type;
oi->t_opaque_lsa_self = NULL;
return 0;
}
void
ospf_opaque_type9_lsa_term (struct ospf_interface *oi)
{
OSPF_TIMER_OFF (oi->t_opaque_lsa_self);
if (oi->opaque_lsa_self != NULL)
list_delete (oi->opaque_lsa_self);
oi->opaque_lsa_self = NULL;
return;
}
int
ospf_opaque_type10_lsa_init (struct ospf_area *area)
{
if (area->opaque_lsa_self != NULL)
list_delete (area->opaque_lsa_self);
area->opaque_lsa_self = list_new ();
area->opaque_lsa_self->del = free_opaque_info_per_type;
area->t_opaque_lsa_self = NULL;
#ifdef MONITOR_LSDB_CHANGE
area->lsdb->new_lsa_hook = ospf_opaque_lsa_install_hook;
area->lsdb->del_lsa_hook = ospf_opaque_lsa_delete_hook;
#endif /* MONITOR_LSDB_CHANGE */
return 0;
}
void
ospf_opaque_type10_lsa_term (struct ospf_area *area)
{
#ifdef MONITOR_LSDB_CHANGE
area->lsdb->new_lsa_hook =
area->lsdb->del_lsa_hook = NULL;
#endif /* MONITOR_LSDB_CHANGE */
OSPF_TIMER_OFF (area->t_opaque_lsa_self);
if (area->opaque_lsa_self != NULL)
list_delete (area->opaque_lsa_self);
area->opaque_lsa_self = NULL;
return;
}
int
ospf_opaque_type11_lsa_init (struct ospf *top)
{
if (top->opaque_lsa_self != NULL)
list_delete (top->opaque_lsa_self);
top->opaque_lsa_self = list_new ();
top->opaque_lsa_self->del = free_opaque_info_per_type;
top->t_opaque_lsa_self = NULL;
#ifdef MONITOR_LSDB_CHANGE
top->lsdb->new_lsa_hook = ospf_opaque_lsa_install_hook;
top->lsdb->del_lsa_hook = ospf_opaque_lsa_delete_hook;
#endif /* MONITOR_LSDB_CHANGE */
return 0;
}
void
ospf_opaque_type11_lsa_term (struct ospf *top)
{
#ifdef MONITOR_LSDB_CHANGE
top->lsdb->new_lsa_hook =
top->lsdb->del_lsa_hook = NULL;
#endif /* MONITOR_LSDB_CHANGE */
OSPF_TIMER_OFF (top->t_opaque_lsa_self);
if (top->opaque_lsa_self != NULL)
list_delete (top->opaque_lsa_self);
top->opaque_lsa_self = NULL;
return;
}
static const char *
ospf_opaque_type_name (u_char opaque_type)
{
const char *name = "Unknown";
switch (opaque_type)
{
case OPAQUE_TYPE_WILDCARD: /* This is a special assignment! */
name = "Wildcard";
break;
case OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA:
name = "Traffic Engineering LSA";
break;
case OPAQUE_TYPE_SYCAMORE_OPTICAL_TOPOLOGY_DESC:
name = "Sycamore optical topology description";
break;
case OPAQUE_TYPE_GRACE_LSA:
name = "Grace-LSA";
break;
Update Traffic Engineering Support for OSPFD NOTE: I am squashing several commits together because they do not independently compile and we need this ability to do any type of sane testing on the patches. Since this series builds together I am doing this. -DBS This new structure is the basis to get new link parameters for Traffic Engineering from Zebra/interface layer to OSPFD and ISISD for the support of Traffic Engineering * lib/if.[c,h]: link parameters struture and get/set functions * lib/command.[c,h]: creation of a new link-node * lib/zclient.[c,h]: modification to the ZBUS message to convey the link parameters structure * lib/zebra.h: New ZBUS message Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Add support for IEEE 754 format * lib/stream.[c,h]: Add stream_get{f,d} and stream_put{f,d}) demux and muxers to safely convert between big-endian IEEE-754 single and double binary format, as used in IETF RFCs, and C99. Implementation depends on host using __STDC_IEC_559__, which should be everything we care about. Should correctly error out otherwise. * lib/network.[c,h]: Add ntohf and htonf converter * lib/memtypes.c: Add new memeory type for Traffic Engineering support Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Add link parameters support to Zebra * zebra/interface.c: - Add new link-params CLI commands - Add new functions to set/get link parameters for interface * zebra/redistribute.[c,h]: Add new function to propagate link parameters to routing daemon (essentially OSPFD and ISISD) for Traffic Engineering. * zebra/redistribute_null.c: Add new function zebra_interface_parameters_update() * zebra/zserv.[c,h]: Add new functions to send link parameters Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Add support of new link-params CLI to vtysh In vtysh_config.c/vtysh_config_parse_line(), it is not possible to continue to use the ordered version for adding line i.e. config_add_line_uniq() to print Interface CLI commands as it completely break the new LINK_PARAMS_NODE. Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Update Traffic Engineering support for OSPFD These patches update original code to RFC3630 (OSPF-TE) and add support of RFC5392 (Inter-AS v2) & RFC7471 (TE metric extensions) and partial support of RFC6827 (ASON - GMPLS). * ospfd/ospf_dump.[c,h]: Add new dump functions for Traffic Engineering * ospfd/ospf_opaque.[c,h]: Add new TLV code points for RFC5392 * ospfd/ospf_packet.c: Update checking of OSPF_OPTION * ospfd/ospf_vty.[c,h]: Update ospf_str2area_id * ospfd/ospf_zebra.c: Add new function ospf_interface_link_params() to get Link Parameters information from the interface to populate Traffic Engineering metrics * ospfd/ospfd.[c,h]: Update OSPF_OPTION flags (T -> MT and new DN) * ospfd/ospf_te.[c,h]: Major modifications to update the code to new link parameters structure and new RFCs Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> tmp
2016-04-19 16:21:46 +02:00
case OPAQUE_TYPE_INTER_AS_LSA:
name = "Inter-AS TE-v2 LSA";
break;
case OPAQUE_TYPE_ROUTER_INFORMATION_LSA:
name = "Router Information LSA";
break;
2002-12-13 21:15:29 +01:00
default:
if (OPAQUE_TYPE_RANGE_UNASSIGNED (opaque_type))
name = "Unassigned";
else
{
u_int32_t bigger_range = opaque_type;
/*
* Get around type-limits warning: comparison is always true due to limited range of data type
*/
if (OPAQUE_TYPE_RANGE_RESERVED (bigger_range))
name = "Private/Experimental";
}
2002-12-13 21:15:29 +01:00
break;
}
return name;
}
/*------------------------------------------------------------------------*
* Followings are management functions to store user specified callbacks.
*------------------------------------------------------------------------*/
struct opaque_info_per_type; /* Forward declaration. */
struct ospf_opaque_functab
{
u_char opaque_type;
struct opaque_info_per_type *oipt;
int (* new_if_hook)(struct interface *ifp);
int (* del_if_hook)(struct interface *ifp);
void (* ism_change_hook)(struct ospf_interface *oi, int old_status);
void (* nsm_change_hook)(struct ospf_neighbor *nbr, int old_status);
void (* config_write_router)(struct vty *vty);
void (* config_write_if )(struct vty *vty, struct interface *ifp);
void (* config_write_debug )(struct vty *vty);
void (* show_opaque_info )(struct vty *vty, struct ospf_lsa *lsa);
int (* lsa_originator)(void *arg);
struct ospf_lsa *(* lsa_refresher )(struct ospf_lsa *lsa);
2002-12-13 21:15:29 +01:00
int (* new_lsa_hook)(struct ospf_lsa *lsa);
int (* del_lsa_hook)(struct ospf_lsa *lsa);
};
/* Handle LSA-9/10/11 altogether. */
static struct list *ospf_opaque_wildcard_funclist;
static struct list *ospf_opaque_type9_funclist;
static struct list *ospf_opaque_type10_funclist;
static struct list *ospf_opaque_type11_funclist;
2002-12-13 21:15:29 +01:00
static void
ospf_opaque_del_functab (void *val)
{
XFREE (MTYPE_OSPF_OPAQUE_FUNCTAB, val);
return;
}
static void
ospf_opaque_funclist_init (void)
{
struct list *funclist;
2002-12-13 21:15:29 +01:00
funclist = ospf_opaque_wildcard_funclist = list_new ();
funclist->del = ospf_opaque_del_functab;
2002-12-13 21:15:29 +01:00
funclist = ospf_opaque_type9_funclist = list_new ();
funclist->del = ospf_opaque_del_functab;
funclist = ospf_opaque_type10_funclist = list_new ();
funclist->del = ospf_opaque_del_functab;
funclist = ospf_opaque_type11_funclist = list_new ();
funclist->del = ospf_opaque_del_functab;
return;
}
static void
ospf_opaque_funclist_term (void)
{
struct list *funclist;
2002-12-13 21:15:29 +01:00
funclist = ospf_opaque_wildcard_funclist;
list_delete (funclist);
2002-12-13 21:15:29 +01:00
funclist = ospf_opaque_type9_funclist;
list_delete (funclist);
funclist = ospf_opaque_type10_funclist;
list_delete (funclist);
funclist = ospf_opaque_type11_funclist;
list_delete (funclist);
return;
}
static struct list *
2002-12-13 21:15:29 +01:00
ospf_get_opaque_funclist (u_char lsa_type)
{
struct list *funclist = NULL;
2002-12-13 21:15:29 +01:00
switch (lsa_type)
{
case OPAQUE_TYPE_WILDCARD:
/* XXX
* This is an ugly trick to handle type-9/10/11 LSA altogether.
* Yes, "OPAQUE_TYPE_WILDCARD (value 0)" is not an LSA-type, nor
* an officially assigned opaque-type.
* Though it is possible that the value might be officially used
* in the future, we use it internally as a special label, for now.
*/
funclist = ospf_opaque_wildcard_funclist;
break;
2002-12-13 21:15:29 +01:00
case OSPF_OPAQUE_LINK_LSA:
funclist = ospf_opaque_type9_funclist;
break;
case OSPF_OPAQUE_AREA_LSA:
funclist = ospf_opaque_type10_funclist;
break;
case OSPF_OPAQUE_AS_LSA:
funclist = ospf_opaque_type11_funclist;
break;
default:
zlog_warn ("ospf_get_opaque_funclist: Unexpected LSA-type(%u)", lsa_type);
break;
}
return funclist;
}
/* XXX: such a huge argument list can /not/ be healthy... */
2002-12-13 21:15:29 +01:00
int
ospf_register_opaque_functab (
u_char lsa_type,
u_char opaque_type,
int (* new_if_hook)(struct interface *ifp),
int (* del_if_hook)(struct interface *ifp),
void (* ism_change_hook)(struct ospf_interface *oi, int old_status),
void (* nsm_change_hook)(struct ospf_neighbor *nbr, int old_status),
void (* config_write_router)(struct vty *vty),
void (* config_write_if )(struct vty *vty, struct interface *ifp),
void (* config_write_debug )(struct vty *vty),
void (* show_opaque_info )(struct vty *vty, struct ospf_lsa *lsa),
int (* lsa_originator)(void *arg),
struct ospf_lsa *(* lsa_refresher )(struct ospf_lsa *lsa),
2002-12-13 21:15:29 +01:00
int (* new_lsa_hook)(struct ospf_lsa *lsa),
int (* del_lsa_hook)(struct ospf_lsa *lsa))
{
struct list *funclist;
2002-12-13 21:15:29 +01:00
struct ospf_opaque_functab *new;
int rc = -1;
if ((funclist = ospf_get_opaque_funclist (lsa_type)) == NULL)
{
zlog_warn ("ospf_register_opaque_functab: Cannot get funclist"
" for Type-%u LSAs?",
lsa_type);
2002-12-13 21:15:29 +01:00
goto out;
}
else
{
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
struct ospf_opaque_functab *functab;
for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
if (functab->opaque_type == opaque_type)
{
zlog_warn ("ospf_register_opaque_functab: Duplicated entry?:"
" lsa_type(%u), opaque_type(%u)",
lsa_type, opaque_type);
goto out;
}
2002-12-13 21:15:29 +01:00
}
if ((new = XCALLOC (MTYPE_OSPF_OPAQUE_FUNCTAB,
sizeof (struct ospf_opaque_functab))) == NULL)
{
zlog_warn ("ospf_register_opaque_functab: XMALLOC: %s",
safe_strerror (errno));
2002-12-13 21:15:29 +01:00
goto out;
}
new->opaque_type = opaque_type;
new->oipt = NULL;
new->new_if_hook = new_if_hook;
new->del_if_hook = del_if_hook;
new->ism_change_hook = ism_change_hook;
new->nsm_change_hook = nsm_change_hook;
new->config_write_router = config_write_router;
new->config_write_if = config_write_if;
new->config_write_debug = config_write_debug;
new->show_opaque_info = show_opaque_info;
new->lsa_originator = lsa_originator;
new->lsa_refresher = lsa_refresher;
new->new_lsa_hook = new_lsa_hook;
new->del_lsa_hook = del_lsa_hook;
listnode_add (funclist, new);
rc = 0;
out:
return rc;
}
void
ospf_delete_opaque_functab (u_char lsa_type, u_char opaque_type)
{
struct list *funclist;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
struct ospf_opaque_functab *functab;
if ((funclist = ospf_get_opaque_funclist (lsa_type)) != NULL)
for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
2002-12-13 21:15:29 +01:00
{
if (functab->opaque_type == opaque_type)
2002-12-13 21:15:29 +01:00
{
/* Cleanup internal control information, if it still remains. */
if (functab->oipt != NULL)
free_opaque_info_per_type (functab->oipt);
/* Dequeue listnode entry from the list. */
listnode_delete (funclist, functab);
/* Avoid misjudgement in the next lookup. */
if (listcount (funclist) == 0)
funclist->head = funclist->tail = NULL;
XFREE (MTYPE_OSPF_OPAQUE_FUNCTAB, functab);
break;
2002-12-13 21:15:29 +01:00
}
}
2002-12-13 21:15:29 +01:00
return;
}
static struct ospf_opaque_functab *
ospf_opaque_functab_lookup (struct ospf_lsa *lsa)
{
struct list *funclist;
struct listnode *node;
2002-12-13 21:15:29 +01:00
struct ospf_opaque_functab *functab;
u_char key = GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr));
if ((funclist = ospf_get_opaque_funclist (lsa->data->type)) != NULL)
for (ALL_LIST_ELEMENTS_RO (funclist, node, functab))
if (functab->opaque_type == key)
return functab;
2002-12-13 21:15:29 +01:00
return NULL;
}
/*------------------------------------------------------------------------*
* Followings are management functions for self-originated LSA entries.
*------------------------------------------------------------------------*/
/*
* Opaque-LSA control information per opaque-type.
* Single Opaque-Type may have multiple instances; each of them will be
* identified by their opaque-id.
*/
struct opaque_info_per_type
{
u_char lsa_type;
2002-12-13 21:15:29 +01:00
u_char opaque_type;
enum { PROC_NORMAL, PROC_SUSPEND } status;
/*
* Thread for (re-)origination scheduling for this opaque-type.
*
* Initial origination of Opaque-LSAs is controlled by generic
* Opaque-LSA handling module so that same opaque-type entries are
* called all at once when certain conditions are met.
* However, there might be cases that some Opaque-LSA clients need
* to (re-)originate their own Opaque-LSAs out-of-sync with others.
* This thread is prepared for that specific purpose.
*/
struct thread *t_opaque_lsa_self;
/*
* Backpointer to an "owner" which is LSA-type dependent.
2002-12-13 21:15:29 +01:00
* type-9: struct ospf_interface
* type-10: struct ospf_area
* type-11: struct ospf
*/
void *owner;
/* Collection of callback functions for this opaque-type. */
struct ospf_opaque_functab *functab;
/* List of Opaque-LSA control informations per opaque-id. */
struct list *id_list;
2002-12-13 21:15:29 +01:00
};
/* Opaque-LSA control information per opaque-id. */
struct opaque_info_per_id
{
u_int32_t opaque_id;
/* Thread for refresh/flush scheduling for this opaque-type/id. */
struct thread *t_opaque_lsa_self;
/* Backpointer to Opaque-LSA control information per opaque-type. */
struct opaque_info_per_type *opqctl_type;
/* Here comes an actual Opaque-LSA entry for this opaque-type/id. */
struct ospf_lsa *lsa;
};
static struct opaque_info_per_type *register_opaque_info_per_type (struct ospf_opaque_functab *functab, struct ospf_lsa *new);
static struct opaque_info_per_type *lookup_opaque_info_by_type (struct ospf_lsa *lsa);
static struct opaque_info_per_id *register_opaque_info_per_id (struct opaque_info_per_type *oipt, struct ospf_lsa *new);
static struct opaque_info_per_id *lookup_opaque_info_by_id (struct opaque_info_per_type *oipt, struct ospf_lsa *lsa);
static struct opaque_info_per_id *register_opaque_lsa (struct ospf_lsa *new);
static struct opaque_info_per_type *
register_opaque_info_per_type (struct ospf_opaque_functab *functab,
struct ospf_lsa *new)
{
struct ospf *top;
struct opaque_info_per_type *oipt;
if ((oipt = XCALLOC (MTYPE_OPAQUE_INFO_PER_TYPE,
sizeof (struct opaque_info_per_type))) == NULL)
{
zlog_warn ("register_opaque_info_per_type: XMALLOC: %s", safe_strerror (errno));
2002-12-13 21:15:29 +01:00
goto out;
}
switch (new->data->type)
{
case OSPF_OPAQUE_LINK_LSA:
oipt->owner = new->oi;
listnode_add (new->oi->opaque_lsa_self, oipt);
break;
case OSPF_OPAQUE_AREA_LSA:
oipt->owner = new->area;
listnode_add (new->area->opaque_lsa_self, oipt);
break;
case OSPF_OPAQUE_AS_LSA:
top = ospf_lookup ();
if (new->area != NULL && (top = new->area->ospf) == NULL)
2002-12-13 21:15:29 +01:00
{
free_opaque_info_per_type ((void *) oipt);
oipt = NULL;
goto out; /* This case may not exist. */
}
oipt->owner = top;
listnode_add (top->opaque_lsa_self, oipt);
break;
default:
zlog_warn ("register_opaque_info_per_type: Unexpected LSA-type(%u)", new->data->type);
2002-12-13 21:15:29 +01:00
free_opaque_info_per_type ((void *) oipt);
oipt = NULL;
goto out; /* This case may not exist. */
}
oipt->lsa_type = new->data->type;
2002-12-13 21:15:29 +01:00
oipt->opaque_type = GET_OPAQUE_TYPE (ntohl (new->data->id.s_addr));
oipt->status = PROC_NORMAL;
oipt->t_opaque_lsa_self = NULL;
oipt->functab = functab;
functab->oipt = oipt;
oipt->id_list = list_new ();
oipt->id_list->del = free_opaque_info_per_id;
out:
return oipt;
}
static void
free_opaque_info_per_type (void *val)
{
struct opaque_info_per_type *oipt = (struct opaque_info_per_type *) val;
struct opaque_info_per_id *oipi;
struct ospf_lsa *lsa;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
/* Control information per opaque-id may still exist. */
for (ALL_LIST_ELEMENTS (oipt->id_list, node, nnode, oipi))
2002-12-13 21:15:29 +01:00
{
if ((lsa = oipi->lsa) == NULL)
continue;
if (IS_LSA_MAXAGE (lsa))
continue;
ospf_opaque_lsa_flush_schedule (lsa);
}
/* Remove "oipt" from its owner's self-originated LSA list. */
switch (oipt->lsa_type)
{
case OSPF_OPAQUE_LINK_LSA:
{
struct ospf_interface *oi = (struct ospf_interface *)(oipt->owner);
listnode_delete (oi->opaque_lsa_self, oipt);
break;
}
case OSPF_OPAQUE_AREA_LSA:
{
struct ospf_area *area = (struct ospf_area *)(oipt->owner);
listnode_delete (area->opaque_lsa_self, oipt);
break;
}
case OSPF_OPAQUE_AS_LSA:
{
struct ospf *top = (struct ospf *)(oipt->owner);
listnode_delete (top->opaque_lsa_self, oipt);
break;
}
default:
zlog_warn ("free_opaque_info_per_type: Unexpected LSA-type(%u)", oipt->lsa_type);
break; /* This case may not exist. */
}
2002-12-13 21:15:29 +01:00
OSPF_TIMER_OFF (oipt->t_opaque_lsa_self);
list_delete (oipt->id_list);
XFREE (MTYPE_OPAQUE_INFO_PER_TYPE, oipt);
return;
}
static struct opaque_info_per_type *
lookup_opaque_info_by_type (struct ospf_lsa *lsa)
{
struct ospf *top;
struct ospf_area *area;
struct ospf_interface *oi;
struct list *listtop = NULL;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
struct opaque_info_per_type *oipt = NULL;
u_char key = GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr));
switch (lsa->data->type)
{
case OSPF_OPAQUE_LINK_LSA:
if ((oi = lsa->oi) != NULL)
listtop = oi->opaque_lsa_self;
else
zlog_warn ("Type-9 Opaque-LSA: Reference to OI is missing?");
break;
case OSPF_OPAQUE_AREA_LSA:
if ((area = lsa->area) != NULL)
listtop = area->opaque_lsa_self;
else
zlog_warn ("Type-10 Opaque-LSA: Reference to AREA is missing?");
break;
case OSPF_OPAQUE_AS_LSA:
top = ospf_lookup ();
if ((area = lsa->area) != NULL && (top = area->ospf) == NULL)
2002-12-13 21:15:29 +01:00
{
zlog_warn ("Type-11 Opaque-LSA: Reference to OSPF is missing?");
break; /* Unlikely to happen. */
}
listtop = top->opaque_lsa_self;
break;
default:
zlog_warn ("lookup_opaque_info_by_type: Unexpected LSA-type(%u)", lsa->data->type);
break;
}
if (listtop != NULL)
for (ALL_LIST_ELEMENTS (listtop, node, nnode, oipt))
if (oipt->opaque_type == key)
return oipt;
2002-12-13 21:15:29 +01:00
return NULL;
}
static struct opaque_info_per_id *
register_opaque_info_per_id (struct opaque_info_per_type *oipt,
struct ospf_lsa *new)
{
struct opaque_info_per_id *oipi;
if ((oipi = XCALLOC (MTYPE_OPAQUE_INFO_PER_ID,
sizeof (struct opaque_info_per_id))) == NULL)
{
zlog_warn ("register_opaque_info_per_id: XMALLOC: %s", safe_strerror (errno));
2002-12-13 21:15:29 +01:00
goto out;
}
oipi->opaque_id = GET_OPAQUE_ID (ntohl (new->data->id.s_addr));
oipi->t_opaque_lsa_self = NULL;
oipi->opqctl_type = oipt;
oipi->lsa = ospf_lsa_lock (new);
listnode_add (oipt->id_list, oipi);
out:
return oipi;
}
static void
free_opaque_info_per_id (void *val)
{
struct opaque_info_per_id *oipi = (struct opaque_info_per_id *) val;
OSPF_TIMER_OFF (oipi->t_opaque_lsa_self);
if (oipi->lsa != NULL)
ospf_lsa_unlock (&oipi->lsa);
2002-12-13 21:15:29 +01:00
XFREE (MTYPE_OPAQUE_INFO_PER_ID, oipi);
return;
}
static struct opaque_info_per_id *
lookup_opaque_info_by_id (struct opaque_info_per_type *oipt,
struct ospf_lsa *lsa)
{
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
struct opaque_info_per_id *oipi;
u_int32_t key = GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr));
for (ALL_LIST_ELEMENTS (oipt->id_list, node, nnode, oipi))
if (oipi->opaque_id == key)
return oipi;
2002-12-13 21:15:29 +01:00
return NULL;
}
static struct opaque_info_per_id *
register_opaque_lsa (struct ospf_lsa *new)
{
struct ospf_opaque_functab *functab;
struct opaque_info_per_type *oipt;
struct opaque_info_per_id *oipi = NULL;
if ((functab = ospf_opaque_functab_lookup (new)) == NULL)
goto out;
if ((oipt = lookup_opaque_info_by_type (new)) == NULL
&& (oipt = register_opaque_info_per_type (functab, new)) == NULL)
goto out;
if ((oipi = register_opaque_info_per_id (oipt, new)) == NULL)
goto out;
out:
return oipi;
}
/*------------------------------------------------------------------------*
* Followings are (vty) configuration functions for Opaque-LSAs handling.
*------------------------------------------------------------------------*/
/*
* CHECK ME - The following ALIASes need to be implemented in this DEFUN
* "ospf opaque-lsa",
* "OSPF specific commands\n"
* "Enable the Opaque-LSA capability (rfc2370)\n"
*
*/
2002-12-13 21:15:29 +01:00
DEFUN (capability_opaque,
capability_opaque_cmd,
"capability opaque",
"Enable specific OSPF feature\n"
"Opaque LSA\n")
{
struct ospf *ospf = (struct ospf *) vty->index;
Multi-Instance OSPF Summary ——————————————------------- - etc/init.d/quagga is modified to support creating separate ospf daemon process for each instance. Each individual instance is monitored by watchquagga just like any protocol daemons.(requires initd-mi.patch). - Vtysh is modified to able to connect to multiple daemons of the same protocol (supported for OSPF only for now). - ospfd is modified to remember the Instance-ID that its invoked with. For the entire life of the process it caters to any command request that matches that instance-ID (unless its a non instance specific command). Routes/messages to zebra are tagged with instance-ID. - zebra route/redistribute mechanisms are modified to work with [protocol type + instance-id] - bgpd now has ability to have multiple instance specific redistribution for a protocol (OSPF only supported/tested for now). - zlog ability to display instance-id besides the protocol/daemon name. - Changes in other daemons are to because of the needed integration with some of the modified APIs/routines. (Didn’t prefer replicating too many separate instance specific APIs.) - config/show/debug commands are modified to take instance-id argument as appropriate. Guidelines to start using multi-instance ospf --------------------------------------------- The patch is backward compatible, i.e for any previous way of single ospf deamon(router ospf <cr>) will continue to work as is, including all the show commands etc. To enable multiple instances, do the following: 1. service quagga stop 2. Modify /etc/quagga/daemons to add instance-ids of each desired instance in the following format: ospfd=“yes" ospfd_instances="1,2,3" assuming you want to enable 3 instances with those instance ids. 3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf and ospfd-3.conf. 4. service quagga start/restart 5. Verify that the deamons are started as expected. You should see ospfd started with -n <instance-id> option. ps –ef | grep quagga With that /var/run/quagga/ should have ospfd-<instance-id>.pid and ospfd-<instance-id>/vty to each instance. 6. vtysh to work with instances as you would with any other deamons. 7. Overall most quagga semantics are the same working with the instance deamon, like it is for any other daemon. NOTE: To safeguard against errors leading to too many processes getting invoked, a hard limit on number of instance-ids is in place, currently its 5. Allowed instance-id range is <1-65535> Once daemons are up, show running from vtysh should show the instance-id of each daemon as 'router ospf <instance-id>’ (without needing explicit configuration) Instance-id can not be changed via vtysh, other router ospf configuration is allowed as before. Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com> Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com> Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
if (!ospf)
return CMD_SUCCESS;
2002-12-13 21:15:29 +01:00
/* Turn on the "master switch" of opaque-lsa capability. */
if (!CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE))
{
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Opaque capability: OFF -> ON");
2002-12-13 21:15:29 +01:00
SET_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE);
ospf_renegotiate_optional_capabilities (ospf);
}
return CMD_SUCCESS;
}
/*
* CHECK ME - The following ALIASes need to be implemented in this DEFUN
* "no ospf opaque-lsa",
* NO_STR
* "OSPF specific commands\n"
* "Disable the Opaque-LSA capability (rfc2370)\n"
*
*/
2002-12-13 21:15:29 +01:00
DEFUN (no_capability_opaque,
no_capability_opaque_cmd,
"no capability opaque",
NO_STR
"Enable specific OSPF feature\n"
"Opaque LSA\n")
{
struct ospf *ospf = (struct ospf *) vty->index;
Multi-Instance OSPF Summary ——————————————------------- - etc/init.d/quagga is modified to support creating separate ospf daemon process for each instance. Each individual instance is monitored by watchquagga just like any protocol daemons.(requires initd-mi.patch). - Vtysh is modified to able to connect to multiple daemons of the same protocol (supported for OSPF only for now). - ospfd is modified to remember the Instance-ID that its invoked with. For the entire life of the process it caters to any command request that matches that instance-ID (unless its a non instance specific command). Routes/messages to zebra are tagged with instance-ID. - zebra route/redistribute mechanisms are modified to work with [protocol type + instance-id] - bgpd now has ability to have multiple instance specific redistribution for a protocol (OSPF only supported/tested for now). - zlog ability to display instance-id besides the protocol/daemon name. - Changes in other daemons are to because of the needed integration with some of the modified APIs/routines. (Didn’t prefer replicating too many separate instance specific APIs.) - config/show/debug commands are modified to take instance-id argument as appropriate. Guidelines to start using multi-instance ospf --------------------------------------------- The patch is backward compatible, i.e for any previous way of single ospf deamon(router ospf <cr>) will continue to work as is, including all the show commands etc. To enable multiple instances, do the following: 1. service quagga stop 2. Modify /etc/quagga/daemons to add instance-ids of each desired instance in the following format: ospfd=“yes" ospfd_instances="1,2,3" assuming you want to enable 3 instances with those instance ids. 3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf and ospfd-3.conf. 4. service quagga start/restart 5. Verify that the deamons are started as expected. You should see ospfd started with -n <instance-id> option. ps –ef | grep quagga With that /var/run/quagga/ should have ospfd-<instance-id>.pid and ospfd-<instance-id>/vty to each instance. 6. vtysh to work with instances as you would with any other deamons. 7. Overall most quagga semantics are the same working with the instance deamon, like it is for any other daemon. NOTE: To safeguard against errors leading to too many processes getting invoked, a hard limit on number of instance-ids is in place, currently its 5. Allowed instance-id range is <1-65535> Once daemons are up, show running from vtysh should show the instance-id of each daemon as 'router ospf <instance-id>’ (without needing explicit configuration) Instance-id can not be changed via vtysh, other router ospf configuration is allowed as before. Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com> Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com> Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
if (!ospf)
return CMD_SUCCESS;
2002-12-13 21:15:29 +01:00
/* Turn off the "master switch" of opaque-lsa capability. */
if (CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE))
{
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Opaque capability: ON -> OFF");
2002-12-13 21:15:29 +01:00
UNSET_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE);
ospf_renegotiate_optional_capabilities (ospf);
}
return CMD_SUCCESS;
}
static void
ospf_opaque_register_vty (void)
{
install_element (OSPF_NODE, &capability_opaque_cmd);
install_element (OSPF_NODE, &no_capability_opaque_cmd);
return;
}
/*------------------------------------------------------------------------*
* Followings are collection of user-registered function callers.
*------------------------------------------------------------------------*/
static int
opaque_lsa_new_if_callback (struct list *funclist, struct interface *ifp)
2002-12-13 21:15:29 +01:00
{
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
struct ospf_opaque_functab *functab;
int rc = -1;
for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
if (functab->new_if_hook != NULL)
if ((* functab->new_if_hook)(ifp) != 0)
goto out;
2002-12-13 21:15:29 +01:00
rc = 0;
out:
return rc;
}
static int
opaque_lsa_del_if_callback (struct list *funclist, struct interface *ifp)
2002-12-13 21:15:29 +01:00
{
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
struct ospf_opaque_functab *functab;
int rc = -1;
for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
if (functab->del_if_hook != NULL)
if ((* functab->del_if_hook)(ifp) != 0)
goto out;
2002-12-13 21:15:29 +01:00
rc = 0;
out:
return rc;
}
static void
opaque_lsa_ism_change_callback (struct list *funclist,
2002-12-13 21:15:29 +01:00
struct ospf_interface *oi, int old_status)
{
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
struct ospf_opaque_functab *functab;
for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
if (functab->ism_change_hook != NULL)
(* functab->ism_change_hook)(oi, old_status);
2002-12-13 21:15:29 +01:00
return;
}
static void
opaque_lsa_nsm_change_callback (struct list *funclist,
2002-12-13 21:15:29 +01:00
struct ospf_neighbor *nbr, int old_status)
{
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
struct ospf_opaque_functab *functab;
for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
if (functab->nsm_change_hook != NULL)
(* functab->nsm_change_hook)(nbr, old_status);
2002-12-13 21:15:29 +01:00
return;
}
static void
opaque_lsa_config_write_router_callback (struct list *funclist,
struct vty *vty)
2002-12-13 21:15:29 +01:00
{
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
struct ospf_opaque_functab *functab;
for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
if (functab->config_write_router != NULL)
(* functab->config_write_router)(vty);
2002-12-13 21:15:29 +01:00
return;
}
static void
opaque_lsa_config_write_if_callback (struct list *funclist,
2002-12-13 21:15:29 +01:00
struct vty *vty, struct interface *ifp)
{
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
struct ospf_opaque_functab *functab;
for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
if (functab->config_write_if != NULL)
(* functab->config_write_if)(vty, ifp);
2002-12-13 21:15:29 +01:00
return;
}
static void
opaque_lsa_config_write_debug_callback (struct list *funclist, struct vty *vty)
2002-12-13 21:15:29 +01:00
{
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
struct ospf_opaque_functab *functab;
for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
if (functab->config_write_debug != NULL)
(* functab->config_write_debug)(vty);
2002-12-13 21:15:29 +01:00
return;
}
static int
opaque_lsa_originate_callback (struct list *funclist, void *lsa_type_dependent)
2002-12-13 21:15:29 +01:00
{
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
struct ospf_opaque_functab *functab;
int rc = -1;
for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
if (functab->lsa_originator != NULL)
if ((* functab->lsa_originator)(lsa_type_dependent) != 0)
goto out;
2002-12-13 21:15:29 +01:00
rc = 0;
out:
return rc;
}
static int
new_lsa_callback (struct list *funclist, struct ospf_lsa *lsa)
2002-12-13 21:15:29 +01:00
{
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
struct ospf_opaque_functab *functab;
int rc = -1;
/* This function handles ALL types of LSAs, not only opaque ones. */
for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
if (functab->new_lsa_hook != NULL)
if ((* functab->new_lsa_hook)(lsa) != 0)
goto out;
2002-12-13 21:15:29 +01:00
rc = 0;
out:
return rc;
}
static int
del_lsa_callback (struct list *funclist, struct ospf_lsa *lsa)
2002-12-13 21:15:29 +01:00
{
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
struct ospf_opaque_functab *functab;
int rc = -1;
/* This function handles ALL types of LSAs, not only opaque ones. */
for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
if (functab->del_lsa_hook != NULL)
if ((* functab->del_lsa_hook)(lsa) != 0)
goto out;
2002-12-13 21:15:29 +01:00
rc = 0;
out:
return rc;
}
/*------------------------------------------------------------------------*
* Followings are glue functions to call Opaque-LSA specific processing.
*------------------------------------------------------------------------*/
int
ospf_opaque_new_if (struct interface *ifp)
{
struct list *funclist;
2002-12-13 21:15:29 +01:00
int rc = -1;
funclist = ospf_opaque_wildcard_funclist;
if (opaque_lsa_new_if_callback (funclist, ifp) != 0)
goto out;
2002-12-13 21:15:29 +01:00
funclist = ospf_opaque_type9_funclist;
if (opaque_lsa_new_if_callback (funclist, ifp) != 0)
goto out;
funclist = ospf_opaque_type10_funclist;
if (opaque_lsa_new_if_callback (funclist, ifp) != 0)
goto out;
funclist = ospf_opaque_type11_funclist;
if (opaque_lsa_new_if_callback (funclist, ifp) != 0)
goto out;
rc = 0;
out:
return rc;
}
int
ospf_opaque_del_if (struct interface *ifp)
{
struct list *funclist;
2002-12-13 21:15:29 +01:00
int rc = -1;
funclist = ospf_opaque_wildcard_funclist;
if (opaque_lsa_del_if_callback (funclist, ifp) != 0)
goto out;
2002-12-13 21:15:29 +01:00
funclist = ospf_opaque_type9_funclist;
if (opaque_lsa_del_if_callback (funclist, ifp) != 0)
goto out;
funclist = ospf_opaque_type10_funclist;
if (opaque_lsa_del_if_callback (funclist, ifp) != 0)
goto out;
funclist = ospf_opaque_type11_funclist;
if (opaque_lsa_del_if_callback (funclist, ifp) != 0)
goto out;
rc = 0;
out:
return rc;
}
void
ospf_opaque_ism_change (struct ospf_interface *oi, int old_status)
{
struct list *funclist;
2002-12-13 21:15:29 +01:00
funclist = ospf_opaque_wildcard_funclist;
opaque_lsa_ism_change_callback (funclist, oi, old_status);
2002-12-13 21:15:29 +01:00
funclist = ospf_opaque_type9_funclist;
opaque_lsa_ism_change_callback (funclist, oi, old_status);
funclist = ospf_opaque_type10_funclist;
opaque_lsa_ism_change_callback (funclist, oi, old_status);
funclist = ospf_opaque_type11_funclist;
opaque_lsa_ism_change_callback (funclist, oi, old_status);
return;
}
void
ospf_opaque_nsm_change (struct ospf_neighbor *nbr, int old_state)
{
struct ospf *top;
struct list *funclist;
2002-12-13 21:15:29 +01:00
if ((top = oi_to_top (nbr->oi)) == NULL)
goto out;
if (old_state != NSM_Full && nbr->state == NSM_Full)
{
if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
{
if (! CHECK_FLAG (top->opaque, OPAQUE_OPERATION_READY_BIT))
{
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Opaque-LSA: Now get operational!");
2002-12-13 21:15:29 +01:00
SET_FLAG (top->opaque, OPAQUE_OPERATION_READY_BIT);
}
ospf_opaque_lsa_originate_schedule (nbr->oi, NULL);
}
}
else
if (old_state == NSM_Full && nbr->state != NSM_Full)
{
#ifdef NOTYET
/*
* If no more opaque-capable full-state neighbor remains in the
* flooding scope which corresponds to Opaque-LSA type, periodic
* LS flooding should be stopped.
*/
#endif /* NOTYET */
;
}
funclist = ospf_opaque_wildcard_funclist;
opaque_lsa_nsm_change_callback (funclist, nbr, old_state);
2002-12-13 21:15:29 +01:00
funclist = ospf_opaque_type9_funclist;
opaque_lsa_nsm_change_callback (funclist, nbr, old_state);
funclist = ospf_opaque_type10_funclist;
opaque_lsa_nsm_change_callback (funclist, nbr, old_state);
funclist = ospf_opaque_type11_funclist;
opaque_lsa_nsm_change_callback (funclist, nbr, old_state);
out:
return;
}
void
ospf_opaque_config_write_router (struct vty *vty, struct ospf *ospf)
{
struct list *funclist;
2002-12-13 21:15:29 +01:00
if (CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE))
vty_out (vty, " capability opaque%s", VTY_NEWLINE);
funclist = ospf_opaque_wildcard_funclist;
opaque_lsa_config_write_router_callback (funclist, vty);
2002-12-13 21:15:29 +01:00
funclist = ospf_opaque_type9_funclist;
opaque_lsa_config_write_router_callback (funclist, vty);
funclist = ospf_opaque_type10_funclist;
opaque_lsa_config_write_router_callback (funclist, vty);
funclist = ospf_opaque_type11_funclist;
opaque_lsa_config_write_router_callback (funclist, vty);
return;
}
void
ospf_opaque_config_write_if (struct vty *vty, struct interface *ifp)
{
struct list *funclist;
2002-12-13 21:15:29 +01:00
funclist = ospf_opaque_wildcard_funclist;
opaque_lsa_config_write_if_callback (funclist, vty, ifp);
2002-12-13 21:15:29 +01:00
funclist = ospf_opaque_type9_funclist;
opaque_lsa_config_write_if_callback (funclist, vty, ifp);
funclist = ospf_opaque_type10_funclist;
opaque_lsa_config_write_if_callback (funclist, vty, ifp);
funclist = ospf_opaque_type11_funclist;
opaque_lsa_config_write_if_callback (funclist, vty, ifp);
return;
}
void
ospf_opaque_config_write_debug (struct vty *vty)
{
struct list *funclist;
2002-12-13 21:15:29 +01:00
funclist = ospf_opaque_wildcard_funclist;
opaque_lsa_config_write_debug_callback (funclist, vty);
2002-12-13 21:15:29 +01:00
funclist = ospf_opaque_type9_funclist;
opaque_lsa_config_write_debug_callback (funclist, vty);
funclist = ospf_opaque_type10_funclist;
opaque_lsa_config_write_debug_callback (funclist, vty);
funclist = ospf_opaque_type11_funclist;
opaque_lsa_config_write_debug_callback (funclist, vty);
return;
}
void
show_opaque_info_detail (struct vty *vty, struct ospf_lsa *lsa)
{
struct lsa_header *lsah = (struct lsa_header *) lsa->data;
u_int32_t lsid = ntohl (lsah->id.s_addr);
u_char opaque_type = GET_OPAQUE_TYPE (lsid);
u_int32_t opaque_id = GET_OPAQUE_ID (lsid);
struct ospf_opaque_functab *functab;
/* Switch output functionality by vty address. */
if (vty != NULL)
{
vty_out (vty, " Opaque-Type %u (%s)%s", opaque_type,
ospf_opaque_type_name (opaque_type), VTY_NEWLINE);
2002-12-13 21:15:29 +01:00
vty_out (vty, " Opaque-ID 0x%x%s", opaque_id, VTY_NEWLINE);
vty_out (vty, " Opaque-Info: %u octets of data%s%s",
ntohs (lsah->length) - OSPF_LSA_HEADER_SIZE,
VALID_OPAQUE_INFO_LEN(lsah) ? "" : "(Invalid length?)",
VTY_NEWLINE);
}
else
{
zlog_debug (" Opaque-Type %u (%s)", opaque_type,
ospf_opaque_type_name (opaque_type));
zlog_debug (" Opaque-ID 0x%x", opaque_id);
2002-12-13 21:15:29 +01:00
zlog_debug (" Opaque-Info: %u octets of data%s",
2002-12-13 21:15:29 +01:00
ntohs (lsah->length) - OSPF_LSA_HEADER_SIZE,
VALID_OPAQUE_INFO_LEN(lsah) ? "" : "(Invalid length?)");
}
/* Call individual output functions. */
if ((functab = ospf_opaque_functab_lookup (lsa)) != NULL)
if (functab->show_opaque_info != NULL)
(* functab->show_opaque_info)(vty, lsa);
return;
}
void
ospf_opaque_lsa_dump (struct stream *s, u_int16_t length)
{
struct ospf_lsa lsa;
lsa.data = (struct lsa_header *) STREAM_PNT (s);
show_opaque_info_detail (NULL, &lsa);
return;
}
static int
ospf_opaque_lsa_install_hook (struct ospf_lsa *lsa)
{
struct list *funclist;
2002-12-13 21:15:29 +01:00
int rc = -1;
/*
* Some Opaque-LSA user may want to monitor every LSA installation
* into the LSDB, regardless with target LSA type.
*/
funclist = ospf_opaque_wildcard_funclist;
if (new_lsa_callback (funclist, lsa) != 0)
goto out;
2002-12-13 21:15:29 +01:00
funclist = ospf_opaque_type9_funclist;
if (new_lsa_callback (funclist, lsa) != 0)
goto out;
funclist = ospf_opaque_type10_funclist;
if (new_lsa_callback (funclist, lsa) != 0)
goto out;
funclist = ospf_opaque_type11_funclist;
if (new_lsa_callback (funclist, lsa) != 0)
goto out;
rc = 0;
out:
return rc;
}
static int
ospf_opaque_lsa_delete_hook (struct ospf_lsa *lsa)
{
struct list *funclist;
2002-12-13 21:15:29 +01:00
int rc = -1;
/*
* Some Opaque-LSA user may want to monitor every LSA deletion
* from the LSDB, regardless with target LSA type.
*/
funclist = ospf_opaque_wildcard_funclist;
if (del_lsa_callback (funclist, lsa) != 0)
goto out;
2002-12-13 21:15:29 +01:00
funclist = ospf_opaque_type9_funclist;
if (del_lsa_callback (funclist, lsa) != 0)
goto out;
funclist = ospf_opaque_type10_funclist;
if (del_lsa_callback (funclist, lsa) != 0)
goto out;
funclist = ospf_opaque_type11_funclist;
if (del_lsa_callback (funclist, lsa) != 0)
goto out;
rc = 0;
out:
return rc;
}
/*------------------------------------------------------------------------*
* Followings are Opaque-LSA origination/refresh management functions.
*------------------------------------------------------------------------*/
static int ospf_opaque_type9_lsa_originate (struct thread *t);
static int ospf_opaque_type10_lsa_originate (struct thread *t);
static int ospf_opaque_type11_lsa_originate (struct thread *t);
static void ospf_opaque_lsa_reoriginate_resume (struct list *listtop, void *arg);
2002-12-13 21:15:29 +01:00
void
ospf_opaque_lsa_originate_schedule (struct ospf_interface *oi, int *delay0)
{
struct ospf *top;
struct ospf_area *area;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
struct opaque_info_per_type *oipt;
int delay = 0;
if ((top = oi_to_top (oi)) == NULL || (area = oi->area) == NULL)
{
zlog_warn ("ospf_opaque_lsa_originate_schedule: Invalid argument?");
goto out;
}
/* It may not a right time to schedule origination now. */
if (! CHECK_FLAG (top->opaque, OPAQUE_OPERATION_READY_BIT))
{
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("ospf_opaque_lsa_originate_schedule: Not operational.");
2002-12-13 21:15:29 +01:00
goto out; /* This is not an error. */
}
2002-12-13 21:15:29 +01:00
if (delay0 != NULL)
delay = *delay0;
/*
* There might be some entries that have been waiting for triggering
* of per opaque-type re-origination get resumed.
*/
ospf_opaque_lsa_reoriginate_resume ( oi->opaque_lsa_self, (void *) oi);
ospf_opaque_lsa_reoriginate_resume (area->opaque_lsa_self, (void *) area);
ospf_opaque_lsa_reoriginate_resume ( top->opaque_lsa_self, (void *) top);
/*
* Now, schedule origination of all Opaque-LSAs per opaque-type.
*/
if (! list_isempty (ospf_opaque_type9_funclist)
&& list_isempty (oi->opaque_lsa_self)
&& oi->t_opaque_lsa_self == NULL)
{
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Schedule Type-9 Opaque-LSA origination in %d ms later.", delay);
2002-12-13 21:15:29 +01:00
oi->t_opaque_lsa_self =
thread_add_timer_msec (master, ospf_opaque_type9_lsa_originate, oi, delay);
delay += top->min_ls_interval;
2002-12-13 21:15:29 +01:00
}
if (! list_isempty (ospf_opaque_type10_funclist)
&& list_isempty (area->opaque_lsa_self)
&& area->t_opaque_lsa_self == NULL)
{
/*
* One AREA may contain multiple OIs, but above 2nd and 3rd
* conditions prevent from scheduling the originate function
* again and again.
*/
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Schedule Type-10 Opaque-LSA origination in %d ms later.", delay);
2002-12-13 21:15:29 +01:00
area->t_opaque_lsa_self =
thread_add_timer_msec (master, ospf_opaque_type10_lsa_originate,
area, delay);
delay += top->min_ls_interval;
2002-12-13 21:15:29 +01:00
}
if (! list_isempty (ospf_opaque_type11_funclist)
&& list_isempty (top->opaque_lsa_self)
&& top->t_opaque_lsa_self == NULL)
{
/*
* One OSPF may contain multiple AREAs, but above 2nd and 3rd
* conditions prevent from scheduling the originate function
* again and again.
*/
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Schedule Type-11 Opaque-LSA origination in %d ms later.", delay);
2002-12-13 21:15:29 +01:00
top->t_opaque_lsa_self =
thread_add_timer_msec (master, ospf_opaque_type11_lsa_originate,
top, delay);
delay += top->min_ls_interval;
2002-12-13 21:15:29 +01:00
}
/*
* Following section treats a special situation that this node's
* opaque capability has changed as "ON -> OFF -> ON".
*/
if (! list_isempty (ospf_opaque_type9_funclist)
&& ! list_isempty (oi->opaque_lsa_self))
{
for (ALL_LIST_ELEMENTS (oi->opaque_lsa_self, node, nnode, oipt))
2002-12-13 21:15:29 +01:00
{
/*
* removed the test for
* (! list_isempty (oipt->id_list)) * Handler is already active. *
* because opaque cababilities ON -> OFF -> ON result in list_isempty (oipt->id_list)
* not being empty.
*/
if (oipt->t_opaque_lsa_self != NULL /* Waiting for a thread call. */
|| oipt->status == PROC_SUSPEND) /* Cannot originate now. */
2002-12-13 21:15:29 +01:00
continue;
ospf_opaque_lsa_reoriginate_schedule ((void *) oi,
OSPF_OPAQUE_LINK_LSA, oipt->opaque_type);
}
}
if (! list_isempty (ospf_opaque_type10_funclist)
&& ! list_isempty (area->opaque_lsa_self))
{
for (ALL_LIST_ELEMENTS (area->opaque_lsa_self, node, nnode, oipt))
2002-12-13 21:15:29 +01:00
{
/*
* removed the test for
* (! list_isempty (oipt->id_list)) * Handler is already active. *
* because opaque cababilities ON -> OFF -> ON result in list_isempty (oipt->id_list)
* not being empty.
*/
if (oipt->t_opaque_lsa_self != NULL /* Waiting for a thread call. */
|| oipt->status == PROC_SUSPEND) /* Cannot originate now. */
2002-12-13 21:15:29 +01:00
continue;
ospf_opaque_lsa_reoriginate_schedule ((void *) area,
OSPF_OPAQUE_AREA_LSA, oipt->opaque_type);
}
}
if (! list_isempty (ospf_opaque_type11_funclist)
&& ! list_isempty (top->opaque_lsa_self))
{
for (ALL_LIST_ELEMENTS (top->opaque_lsa_self, node, nnode, oipt))
2002-12-13 21:15:29 +01:00
{
/*
* removed the test for
* (! list_isempty (oipt->id_list)) * Handler is already active. *
* because opaque cababilities ON -> OFF -> ON result in list_isempty (oipt->id_list)
* not being empty.
*/
if (oipt->t_opaque_lsa_self != NULL /* Waiting for a thread call. */
|| oipt->status == PROC_SUSPEND) /* Cannot originate now. */
2002-12-13 21:15:29 +01:00
continue;
ospf_opaque_lsa_reoriginate_schedule ((void *) top,
OSPF_OPAQUE_AS_LSA, oipt->opaque_type);
}
}
if (delay0 != NULL)
*delay0 = delay;
out:
return;
}
static int
ospf_opaque_type9_lsa_originate (struct thread *t)
{
struct ospf_interface *oi;
int rc;
oi = THREAD_ARG (t);
oi->t_opaque_lsa_self = NULL;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Timer[Type9-LSA]: Originate Opaque-LSAs for OI %s",
2002-12-13 21:15:29 +01:00
IF_NAME (oi));
rc = opaque_lsa_originate_callback (ospf_opaque_type9_funclist, oi);
return rc;
}
static int
ospf_opaque_type10_lsa_originate (struct thread *t)
{
struct ospf_area *area;
int rc;
area = THREAD_ARG (t);
area->t_opaque_lsa_self = NULL;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Timer[Type10-LSA]: Originate Opaque-LSAs for Area %s",
2002-12-13 21:15:29 +01:00
inet_ntoa (area->area_id));
rc = opaque_lsa_originate_callback (ospf_opaque_type10_funclist, area);
return rc;
}
static int
ospf_opaque_type11_lsa_originate (struct thread *t)
{
struct ospf *top;
int rc;
top = THREAD_ARG (t);
top->t_opaque_lsa_self = NULL;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Timer[Type11-LSA]: Originate AS-External Opaque-LSAs");
2002-12-13 21:15:29 +01:00
rc = opaque_lsa_originate_callback (ospf_opaque_type11_funclist, top);
return rc;
}
static void
ospf_opaque_lsa_reoriginate_resume (struct list *listtop, void *arg)
2002-12-13 21:15:29 +01:00
{
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
struct opaque_info_per_type *oipt;
struct ospf_opaque_functab *functab;
if (listtop == NULL)
goto out;
/*
* Pickup oipt entries those which in SUSPEND status, and give
* them a chance to start re-origination now.
*/
for (ALL_LIST_ELEMENTS (listtop, node, nnode, oipt))
2002-12-13 21:15:29 +01:00
{
if (oipt->status != PROC_SUSPEND)
2002-12-13 21:15:29 +01:00
continue;
oipt->status = PROC_NORMAL;
if ((functab = oipt->functab) == NULL
|| functab->lsa_originator == NULL)
2002-12-13 21:15:29 +01:00
continue;
if ((* functab->lsa_originator)(arg) != 0)
{
zlog_warn ("ospf_opaque_lsa_reoriginate_resume: Failed (opaque-type=%u)", oipt->opaque_type);
continue;
}
}
out:
return;
}
struct ospf_lsa *
ospf_opaque_lsa_install (struct ospf_lsa *lsa, int rt_recalc)
{
struct ospf_lsa *new = NULL;
struct opaque_info_per_type *oipt;
struct opaque_info_per_id *oipi;
struct ospf *top;
/* Don't take "rt_recalc" into consideration for now. *//* XXX */
if (! IS_LSA_SELF (lsa))
{
new = lsa; /* Don't touch this LSA. */
goto out;
}
if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
zlog_debug ("Install Type-%u Opaque-LSA: [opaque-type=%u, opaque-id=%x]", lsa->data->type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)));
2002-12-13 21:15:29 +01:00
/* Replace the existing lsa with the new one. */
if ((oipt = lookup_opaque_info_by_type (lsa)) != NULL
&& (oipi = lookup_opaque_info_by_id (oipt, lsa)) != NULL)
2002-12-13 21:15:29 +01:00
{
ospf_lsa_unlock (&oipi->lsa);
2002-12-13 21:15:29 +01:00
oipi->lsa = ospf_lsa_lock (lsa);
}
/* Register the new lsa entry and get its control info. */
else
if ((oipi = register_opaque_lsa (lsa)) == NULL)
{
zlog_warn ("ospf_opaque_lsa_install: register_opaque_lsa() ?");
goto out;
}
/*
* Make use of a common mechanism (ospf_lsa_refresh_walker)
* for periodic refresh of self-originated Opaque-LSAs.
*/
switch (lsa->data->type)
{
case OSPF_OPAQUE_LINK_LSA:
if ((top = oi_to_top (lsa->oi)) == NULL)
{
/* Above conditions must have passed. */
zlog_warn ("ospf_opaque_lsa_install: Sonmething wrong?");
goto out;
}
break;
2002-12-13 21:15:29 +01:00
case OSPF_OPAQUE_AREA_LSA:
if (lsa->area == NULL || (top = lsa->area->ospf) == NULL)
2002-12-13 21:15:29 +01:00
{
/* Above conditions must have passed. */
zlog_warn ("ospf_opaque_lsa_install: Sonmething wrong?");
goto out;
}
break;
case OSPF_OPAQUE_AS_LSA:
top = ospf_lookup ();
if (lsa->area != NULL && (top = lsa->area->ospf) == NULL)
2002-12-13 21:15:29 +01:00
{
/* Above conditions must have passed. */
zlog_warn ("ospf_opaque_lsa_install: Sonmething wrong?");
goto out;
}
break;
default:
zlog_warn ("ospf_opaque_lsa_install: Unexpected LSA-type(%u)", lsa->data->type);
goto out;
}
ospf_refresher_register_lsa (top, lsa);
new = lsa;
out:
return new;
}
struct ospf_lsa *
2002-12-13 21:15:29 +01:00
ospf_opaque_lsa_refresh (struct ospf_lsa *lsa)
{
struct ospf *ospf;
2002-12-13 21:15:29 +01:00
struct ospf_opaque_functab *functab;
struct ospf_lsa *new = NULL;
ospf = ospf_lookup ();
2002-12-13 21:15:29 +01:00
if ((functab = ospf_opaque_functab_lookup (lsa)) == NULL
|| functab->lsa_refresher == NULL)
2002-12-13 21:15:29 +01:00
{
/*
* Though this LSA seems to have originated on this node, the
* handling module for this "lsa-type and opaque-type" was
* already deleted sometime ago.
* Anyway, this node still has a responsibility to flush this
* LSA from the routing domain.
*/
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("LSA[Type%d:%s]: Flush stray Opaque-LSA", lsa->data->type, inet_ntoa (lsa->data->id));
2002-12-13 21:15:29 +01:00
lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
ospf_lsa_flush (ospf, lsa);
2002-12-13 21:15:29 +01:00
}
else
new = (* functab->lsa_refresher)(lsa);
2002-12-13 21:15:29 +01:00
return new;
2002-12-13 21:15:29 +01:00
}
/*------------------------------------------------------------------------*
* Followings are re-origination/refresh/flush operations of Opaque-LSAs,
* triggered by external interventions (vty session, signaling, etc).
*------------------------------------------------------------------------*/
#define OSPF_OPAQUE_TIMER_ON(T,F,L,V) \
if (!(T)) \
(T) = thread_add_timer_msec (master, (F), (L), (V))
2002-12-13 21:15:29 +01:00
static struct ospf_lsa *pseudo_lsa (struct ospf_interface *oi, struct ospf_area *area, u_char lsa_type, u_char opaque_type);
static int ospf_opaque_type9_lsa_reoriginate_timer (struct thread *t);
static int ospf_opaque_type10_lsa_reoriginate_timer (struct thread *t);
static int ospf_opaque_type11_lsa_reoriginate_timer (struct thread *t);
static int ospf_opaque_lsa_refresh_timer (struct thread *t);
void
ospf_opaque_lsa_reoriginate_schedule (void *lsa_type_dependent,
u_char lsa_type, u_char opaque_type)
{
struct ospf *top;
struct ospf_area dummy, *area = NULL;
struct ospf_interface *oi = NULL;
struct ospf_lsa *lsa;
struct opaque_info_per_type *oipt;
int (*func) (struct thread * t) = NULL;
2002-12-13 21:15:29 +01:00
int delay;
switch (lsa_type)
{
case OSPF_OPAQUE_LINK_LSA:
if ((oi = (struct ospf_interface *) lsa_type_dependent) == NULL)
{
zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:"
" Type-9 Opaque-LSA: Invalid parameter?");
goto out;
2002-12-13 21:15:29 +01:00
}
if ((top = oi_to_top (oi)) == NULL)
{
zlog_warn ("ospf_opaque_lsa_reoriginate_schedule: OI(%s) -> TOP?",
IF_NAME (oi));
2002-12-13 21:15:29 +01:00
goto out;
}
if (!list_isempty (ospf_opaque_type9_funclist)
&& list_isempty (oi->opaque_lsa_self)
&& oi->t_opaque_lsa_self != NULL)
2002-12-13 21:15:29 +01:00
{
zlog_warn ("Type-9 Opaque-LSA (opaque_type=%u):"
" Common origination for OI(%s) has already started",
opaque_type, IF_NAME (oi));
2002-12-13 21:15:29 +01:00
goto out;
}
func = ospf_opaque_type9_lsa_reoriginate_timer;
break;
case OSPF_OPAQUE_AREA_LSA:
if ((area = (struct ospf_area *) lsa_type_dependent) == NULL)
{
zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:"
" Type-10 Opaque-LSA: Invalid parameter?");
2002-12-13 21:15:29 +01:00
goto out;
}
if ((top = area->ospf) == NULL)
2002-12-13 21:15:29 +01:00
{
zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:"
" AREA(%s) -> TOP?", inet_ntoa (area->area_id));
2002-12-13 21:15:29 +01:00
goto out;
}
if (!list_isempty (ospf_opaque_type10_funclist)
&& list_isempty (area->opaque_lsa_self)
&& area->t_opaque_lsa_self != NULL)
2002-12-13 21:15:29 +01:00
{
zlog_warn ("Type-10 Opaque-LSA (opaque_type=%u):"
" Common origination for AREA(%s) has already started",
opaque_type, inet_ntoa (area->area_id));
2002-12-13 21:15:29 +01:00
goto out;
}
func = ospf_opaque_type10_lsa_reoriginate_timer;
break;
case OSPF_OPAQUE_AS_LSA:
if ((top = (struct ospf *) lsa_type_dependent) == NULL)
{
zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:"
" Type-11 Opaque-LSA: Invalid parameter?");
goto out;
2002-12-13 21:15:29 +01:00
}
if (!list_isempty (ospf_opaque_type11_funclist)
&& list_isempty (top->opaque_lsa_self)
&& top->t_opaque_lsa_self != NULL)
2002-12-13 21:15:29 +01:00
{
zlog_warn ("Type-11 Opaque-LSA (opaque_type=%u):"
" Common origination has already started", opaque_type);
2002-12-13 21:15:29 +01:00
goto out;
}
/* Fake "area" to pass "ospf" to a lookup function later. */
dummy.ospf = top;
2002-12-13 21:15:29 +01:00
area = &dummy;
func = ospf_opaque_type11_lsa_reoriginate_timer;
break;
default:
zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:"
" Unexpected LSA-type(%u)",
lsa_type);
2002-12-13 21:15:29 +01:00
goto out;
}
/* It may not a right time to schedule reorigination now. */
if (!CHECK_FLAG (top->opaque, OPAQUE_OPERATION_READY_BIT))
2002-12-13 21:15:29 +01:00
{
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("ospf_opaque_lsa_reoriginate_schedule: Not operational.");
goto out; /* This is not an error. */
2002-12-13 21:15:29 +01:00
}
2002-12-13 21:15:29 +01:00
/* Generate a dummy lsa to be passed for a lookup function. */
lsa = pseudo_lsa (oi, area, lsa_type, opaque_type);
if ((oipt = lookup_opaque_info_by_type (lsa)) == NULL)
{
struct ospf_opaque_functab *functab;
if ((functab = ospf_opaque_functab_lookup (lsa)) == NULL)
{
zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:"
" No associated function?: lsa_type(%u),"
" opaque_type(%u)",
lsa_type, opaque_type);
2002-12-13 21:15:29 +01:00
goto out;
}
if ((oipt = register_opaque_info_per_type (functab, lsa)) == NULL)
{
zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:"
" Cannot get a control info?: lsa_type(%u),"
" opaque_type(%u)",
lsa_type, opaque_type);
2002-12-13 21:15:29 +01:00
goto out;
}
}
if (oipt->t_opaque_lsa_self != NULL)
{
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Type-%u Opaque-LSA has already scheduled to"
" RE-ORIGINATE: [opaque-type=%u]",
lsa_type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)));
2002-12-13 21:15:29 +01:00
goto out;
}
/*
* Different from initial origination time, in which various conditions
* (opaque capability, neighbor status etc) are assured by caller of
* the originating function "ospf_opaque_lsa_originate_schedule ()",
* it is highly possible that these conditions might not be satisfied
* at the time of re-origination function is to be called.
*/
delay = top->min_ls_interval; /* XXX */
2002-12-13 21:15:29 +01:00
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Schedule Type-%u Opaque-LSA to RE-ORIGINATE in %d"
" ms later: [opaque-type=%u]",
lsa_type, delay,
GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)));
2002-12-13 21:15:29 +01:00
OSPF_OPAQUE_TIMER_ON (oipt->t_opaque_lsa_self, func, oipt, delay * 1000);
2002-12-13 21:15:29 +01:00
out:
return;
}
static struct ospf_lsa *
pseudo_lsa (struct ospf_interface *oi, struct ospf_area *area,
u_char lsa_type, u_char opaque_type)
{
static struct ospf_lsa lsa = { 0 };
static struct lsa_header lsah = { 0 };
u_int32_t tmp;
lsa.oi = oi;
lsa.area = area;
lsa.data = &lsah;
lsah.type = lsa_type;
tmp = SET_OPAQUE_LSID (opaque_type, 0); /* Opaque-ID is unused here. */
lsah.id.s_addr = htonl (tmp);
return &lsa;
}
static int
ospf_opaque_type9_lsa_reoriginate_timer (struct thread *t)
{
struct opaque_info_per_type *oipt;
struct ospf_opaque_functab *functab;
struct ospf *top;
struct ospf_interface *oi;
int rc = -1;
oipt = THREAD_ARG (t);
oipt->t_opaque_lsa_self = NULL;
if ((functab = oipt->functab) == NULL
|| functab->lsa_originator == NULL)
{
zlog_warn ("ospf_opaque_type9_lsa_reoriginate_timer: No associated function?");
goto out;
}
oi = (struct ospf_interface *) oipt->owner;
if ((top = oi_to_top (oi)) == NULL)
{
zlog_warn ("ospf_opaque_type9_lsa_reoriginate_timer: Something wrong?");
goto out;
}
if (! CHECK_FLAG (top->config, OSPF_OPAQUE_CAPABLE)
|| ! ospf_if_is_enable (oi)
|| ospf_nbr_count_opaque_capable (oi) == 0)
2002-12-13 21:15:29 +01:00
{
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Suspend re-origination of Type-9 Opaque-LSAs (opaque-type=%u) for a while...", oipt->opaque_type);
2002-12-13 21:15:29 +01:00
oipt->status = PROC_SUSPEND;
rc = 0;
goto out;
}
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Timer[Type9-LSA]: Re-originate Opaque-LSAs (opaque-type=%u) for OI (%s)", oipt->opaque_type, IF_NAME (oi));
2002-12-13 21:15:29 +01:00
rc = (* functab->lsa_originator)(oi);
out:
return rc;
}
static int
ospf_opaque_type10_lsa_reoriginate_timer (struct thread *t)
{
struct opaque_info_per_type *oipt;
struct ospf_opaque_functab *functab;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
struct ospf *top;
struct ospf_area *area;
struct ospf_interface *oi;
int n, rc = -1;
oipt = THREAD_ARG (t);
oipt->t_opaque_lsa_self = NULL;
if ((functab = oipt->functab) == NULL
|| functab->lsa_originator == NULL)
{
zlog_warn ("ospf_opaque_type10_lsa_reoriginate_timer: No associated function?");
goto out;
}
area = (struct ospf_area *) oipt->owner;
if (area == NULL || (top = area->ospf) == NULL)
2002-12-13 21:15:29 +01:00
{
zlog_warn ("ospf_opaque_type10_lsa_reoriginate_timer: Something wrong?");
goto out;
}
/* There must be at least one "opaque-capable, full-state" neighbor. */
n = 0;
for (ALL_LIST_ELEMENTS (area->oiflist, node, nnode, oi))
2002-12-13 21:15:29 +01:00
{
if ((n = ospf_nbr_count_opaque_capable (oi)) > 0)
2002-12-13 21:15:29 +01:00
break;
}
if (n == 0 || ! CHECK_FLAG (top->config, OSPF_OPAQUE_CAPABLE))
{
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Suspend re-origination of Type-10 Opaque-LSAs"
" (opaque-type=%u) for a while...",
oipt->opaque_type);
2002-12-13 21:15:29 +01:00
oipt->status = PROC_SUSPEND;
rc = 0;
goto out;
}
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Timer[Type10-LSA]: Re-originate Opaque-LSAs"
" (opaque-type=%u) for Area %s",
oipt->opaque_type, inet_ntoa (area->area_id));
2002-12-13 21:15:29 +01:00
rc = (* functab->lsa_originator)(area);
out:
return rc;
}
static int
ospf_opaque_type11_lsa_reoriginate_timer (struct thread *t)
{
struct opaque_info_per_type *oipt;
struct ospf_opaque_functab *functab;
struct ospf *top;
int rc = -1;
oipt = THREAD_ARG (t);
oipt->t_opaque_lsa_self = NULL;
if ((functab = oipt->functab) == NULL
|| functab->lsa_originator == NULL)
2002-12-13 21:15:29 +01:00
{
zlog_warn ("ospf_opaque_type11_lsa_reoriginate_timer:"
" No associated function?");
2002-12-13 21:15:29 +01:00
goto out;
}
if ((top = (struct ospf *) oipt->owner) == NULL)
{
zlog_warn ("ospf_opaque_type11_lsa_reoriginate_timer: Something wrong?");
goto out;
}
if (! CHECK_FLAG (top->config, OSPF_OPAQUE_CAPABLE))
{
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Suspend re-origination of Type-11 Opaque-LSAs (opaque-type=%u) for a while...", oipt->opaque_type);
2002-12-13 21:15:29 +01:00
oipt->status = PROC_SUSPEND;
rc = 0;
goto out;
}
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Timer[Type11-LSA]: Re-originate Opaque-LSAs (opaque-type=%u).", oipt->opaque_type);
2002-12-13 21:15:29 +01:00
rc = (* functab->lsa_originator)(top);
out:
return rc;
}
void
ospf_opaque_lsa_refresh_schedule (struct ospf_lsa *lsa0)
{
struct opaque_info_per_type *oipt;
struct opaque_info_per_id *oipi;
struct ospf_lsa *lsa;
Update Traffic Engineering Support for OSPFD NOTE: I am squashing several commits together because they do not independently compile and we need this ability to do any type of sane testing on the patches. Since this series builds together I am doing this. -DBS This new structure is the basis to get new link parameters for Traffic Engineering from Zebra/interface layer to OSPFD and ISISD for the support of Traffic Engineering * lib/if.[c,h]: link parameters struture and get/set functions * lib/command.[c,h]: creation of a new link-node * lib/zclient.[c,h]: modification to the ZBUS message to convey the link parameters structure * lib/zebra.h: New ZBUS message Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Add support for IEEE 754 format * lib/stream.[c,h]: Add stream_get{f,d} and stream_put{f,d}) demux and muxers to safely convert between big-endian IEEE-754 single and double binary format, as used in IETF RFCs, and C99. Implementation depends on host using __STDC_IEC_559__, which should be everything we care about. Should correctly error out otherwise. * lib/network.[c,h]: Add ntohf and htonf converter * lib/memtypes.c: Add new memeory type for Traffic Engineering support Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Add link parameters support to Zebra * zebra/interface.c: - Add new link-params CLI commands - Add new functions to set/get link parameters for interface * zebra/redistribute.[c,h]: Add new function to propagate link parameters to routing daemon (essentially OSPFD and ISISD) for Traffic Engineering. * zebra/redistribute_null.c: Add new function zebra_interface_parameters_update() * zebra/zserv.[c,h]: Add new functions to send link parameters Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Add support of new link-params CLI to vtysh In vtysh_config.c/vtysh_config_parse_line(), it is not possible to continue to use the ordered version for adding line i.e. config_add_line_uniq() to print Interface CLI commands as it completely break the new LINK_PARAMS_NODE. Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Update Traffic Engineering support for OSPFD These patches update original code to RFC3630 (OSPF-TE) and add support of RFC5392 (Inter-AS v2) & RFC7471 (TE metric extensions) and partial support of RFC6827 (ASON - GMPLS). * ospfd/ospf_dump.[c,h]: Add new dump functions for Traffic Engineering * ospfd/ospf_opaque.[c,h]: Add new TLV code points for RFC5392 * ospfd/ospf_packet.c: Update checking of OSPF_OPTION * ospfd/ospf_vty.[c,h]: Update ospf_str2area_id * ospfd/ospf_zebra.c: Add new function ospf_interface_link_params() to get Link Parameters information from the interface to populate Traffic Engineering metrics * ospfd/ospfd.[c,h]: Update OSPF_OPTION flags (T -> MT and new DN) * ospfd/ospf_te.[c,h]: Major modifications to update the code to new link parameters structure and new RFCs Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> tmp
2016-04-19 16:21:46 +02:00
struct ospf *top;
2002-12-13 21:15:29 +01:00
int delay;
if ((oipt = lookup_opaque_info_by_type (lsa0)) == NULL
|| (oipi = lookup_opaque_info_by_id (oipt, lsa0)) == NULL)
{
zlog_warn ("ospf_opaque_lsa_refresh_schedule: Invalid parameter?");
goto out;
}
/* Given "lsa0" and current "oipi->lsa" may different, but harmless. */
if ((lsa = oipi->lsa) == NULL)
{
zlog_warn ("ospf_opaque_lsa_refresh_schedule: Something wrong?");
goto out;
}
if (oipi->t_opaque_lsa_self != NULL)
{
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Type-%u Opaque-LSA has already scheduled to REFRESH: [opaque-type=%u, opaque-id=%x]", lsa->data->type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)));
2002-12-13 21:15:29 +01:00
goto out;
}
/* Delete this lsa from neighbor retransmit-list. */
switch (lsa->data->type)
{
case OSPF_OPAQUE_LINK_LSA:
case OSPF_OPAQUE_AREA_LSA:
ospf_ls_retransmit_delete_nbr_area (lsa->area, lsa);
2002-12-13 21:15:29 +01:00
break;
case OSPF_OPAQUE_AS_LSA:
Update Traffic Engineering Support for OSPFD NOTE: I am squashing several commits together because they do not independently compile and we need this ability to do any type of sane testing on the patches. Since this series builds together I am doing this. -DBS This new structure is the basis to get new link parameters for Traffic Engineering from Zebra/interface layer to OSPFD and ISISD for the support of Traffic Engineering * lib/if.[c,h]: link parameters struture and get/set functions * lib/command.[c,h]: creation of a new link-node * lib/zclient.[c,h]: modification to the ZBUS message to convey the link parameters structure * lib/zebra.h: New ZBUS message Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Add support for IEEE 754 format * lib/stream.[c,h]: Add stream_get{f,d} and stream_put{f,d}) demux and muxers to safely convert between big-endian IEEE-754 single and double binary format, as used in IETF RFCs, and C99. Implementation depends on host using __STDC_IEC_559__, which should be everything we care about. Should correctly error out otherwise. * lib/network.[c,h]: Add ntohf and htonf converter * lib/memtypes.c: Add new memeory type for Traffic Engineering support Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Add link parameters support to Zebra * zebra/interface.c: - Add new link-params CLI commands - Add new functions to set/get link parameters for interface * zebra/redistribute.[c,h]: Add new function to propagate link parameters to routing daemon (essentially OSPFD and ISISD) for Traffic Engineering. * zebra/redistribute_null.c: Add new function zebra_interface_parameters_update() * zebra/zserv.[c,h]: Add new functions to send link parameters Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Add support of new link-params CLI to vtysh In vtysh_config.c/vtysh_config_parse_line(), it is not possible to continue to use the ordered version for adding line i.e. config_add_line_uniq() to print Interface CLI commands as it completely break the new LINK_PARAMS_NODE. Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Update Traffic Engineering support for OSPFD These patches update original code to RFC3630 (OSPF-TE) and add support of RFC5392 (Inter-AS v2) & RFC7471 (TE metric extensions) and partial support of RFC6827 (ASON - GMPLS). * ospfd/ospf_dump.[c,h]: Add new dump functions for Traffic Engineering * ospfd/ospf_opaque.[c,h]: Add new TLV code points for RFC5392 * ospfd/ospf_packet.c: Update checking of OSPF_OPTION * ospfd/ospf_vty.[c,h]: Update ospf_str2area_id * ospfd/ospf_zebra.c: Add new function ospf_interface_link_params() to get Link Parameters information from the interface to populate Traffic Engineering metrics * ospfd/ospfd.[c,h]: Update OSPF_OPTION flags (T -> MT and new DN) * ospfd/ospf_te.[c,h]: Major modifications to update the code to new link parameters structure and new RFCs Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> tmp
2016-04-19 16:21:46 +02:00
top = ospf_lookup ();
if ((lsa0->area != NULL) && (lsa0->area->ospf != NULL))
top = lsa0->area->ospf;
ospf_ls_retransmit_delete_nbr_as (top, lsa);
2002-12-13 21:15:29 +01:00
break;
default:
zlog_warn ("ospf_opaque_lsa_refresh_schedule: Unexpected LSA-type(%u)", lsa->data->type);
goto out;
}
delay = ospf_lsa_refresh_delay (lsa);
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Schedule Type-%u Opaque-LSA to REFRESH in %d sec later: [opaque-type=%u, opaque-id=%x]", lsa->data->type, delay, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)));
2002-12-13 21:15:29 +01:00
OSPF_OPAQUE_TIMER_ON (oipi->t_opaque_lsa_self,
ospf_opaque_lsa_refresh_timer, oipi, delay * 1000);
2002-12-13 21:15:29 +01:00
out:
return;
}
static int
ospf_opaque_lsa_refresh_timer (struct thread *t)
{
struct opaque_info_per_id *oipi;
struct ospf_opaque_functab *functab;
struct ospf_lsa *lsa;
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Timer[Opaque-LSA]: (Opaque-LSA Refresh expire)");
2002-12-13 21:15:29 +01:00
oipi = THREAD_ARG (t);
oipi->t_opaque_lsa_self = NULL;
if ((lsa = oipi->lsa) != NULL)
if ((functab = oipi->opqctl_type->functab) != NULL)
if (functab->lsa_refresher != NULL)
(* functab->lsa_refresher)(lsa);
return 0;
}
void
ospf_opaque_lsa_flush_schedule (struct ospf_lsa *lsa0)
{
struct opaque_info_per_type *oipt;
struct opaque_info_per_id *oipi;
struct ospf_lsa *lsa;
Update Traffic Engineering Support for OSPFD NOTE: I am squashing several commits together because they do not independently compile and we need this ability to do any type of sane testing on the patches. Since this series builds together I am doing this. -DBS This new structure is the basis to get new link parameters for Traffic Engineering from Zebra/interface layer to OSPFD and ISISD for the support of Traffic Engineering * lib/if.[c,h]: link parameters struture and get/set functions * lib/command.[c,h]: creation of a new link-node * lib/zclient.[c,h]: modification to the ZBUS message to convey the link parameters structure * lib/zebra.h: New ZBUS message Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Add support for IEEE 754 format * lib/stream.[c,h]: Add stream_get{f,d} and stream_put{f,d}) demux and muxers to safely convert between big-endian IEEE-754 single and double binary format, as used in IETF RFCs, and C99. Implementation depends on host using __STDC_IEC_559__, which should be everything we care about. Should correctly error out otherwise. * lib/network.[c,h]: Add ntohf and htonf converter * lib/memtypes.c: Add new memeory type for Traffic Engineering support Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Add link parameters support to Zebra * zebra/interface.c: - Add new link-params CLI commands - Add new functions to set/get link parameters for interface * zebra/redistribute.[c,h]: Add new function to propagate link parameters to routing daemon (essentially OSPFD and ISISD) for Traffic Engineering. * zebra/redistribute_null.c: Add new function zebra_interface_parameters_update() * zebra/zserv.[c,h]: Add new functions to send link parameters Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Add support of new link-params CLI to vtysh In vtysh_config.c/vtysh_config_parse_line(), it is not possible to continue to use the ordered version for adding line i.e. config_add_line_uniq() to print Interface CLI commands as it completely break the new LINK_PARAMS_NODE. Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Update Traffic Engineering support for OSPFD These patches update original code to RFC3630 (OSPF-TE) and add support of RFC5392 (Inter-AS v2) & RFC7471 (TE metric extensions) and partial support of RFC6827 (ASON - GMPLS). * ospfd/ospf_dump.[c,h]: Add new dump functions for Traffic Engineering * ospfd/ospf_opaque.[c,h]: Add new TLV code points for RFC5392 * ospfd/ospf_packet.c: Update checking of OSPF_OPTION * ospfd/ospf_vty.[c,h]: Update ospf_str2area_id * ospfd/ospf_zebra.c: Add new function ospf_interface_link_params() to get Link Parameters information from the interface to populate Traffic Engineering metrics * ospfd/ospfd.[c,h]: Update OSPF_OPTION flags (T -> MT and new DN) * ospfd/ospf_te.[c,h]: Major modifications to update the code to new link parameters structure and new RFCs Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> tmp
2016-04-19 16:21:46 +02:00
struct ospf *top;
top = ospf_lookup ();
2002-12-13 21:15:29 +01:00
if ((oipt = lookup_opaque_info_by_type (lsa0)) == NULL
|| (oipi = lookup_opaque_info_by_id (oipt, lsa0)) == NULL)
{
zlog_warn ("ospf_opaque_lsa_flush_schedule: Invalid parameter?");
goto out;
}
/* Given "lsa0" and current "oipi->lsa" may different, but harmless. */
if ((lsa = oipi->lsa) == NULL)
{
zlog_warn ("ospf_opaque_lsa_flush_schedule: Something wrong?");
goto out;
}
/* Delete this lsa from neighbor retransmit-list. */
switch (lsa->data->type)
{
case OSPF_OPAQUE_LINK_LSA:
case OSPF_OPAQUE_AREA_LSA:
ospf_ls_retransmit_delete_nbr_area (lsa->area, lsa);
2002-12-13 21:15:29 +01:00
break;
case OSPF_OPAQUE_AS_LSA:
Update Traffic Engineering Support for OSPFD NOTE: I am squashing several commits together because they do not independently compile and we need this ability to do any type of sane testing on the patches. Since this series builds together I am doing this. -DBS This new structure is the basis to get new link parameters for Traffic Engineering from Zebra/interface layer to OSPFD and ISISD for the support of Traffic Engineering * lib/if.[c,h]: link parameters struture and get/set functions * lib/command.[c,h]: creation of a new link-node * lib/zclient.[c,h]: modification to the ZBUS message to convey the link parameters structure * lib/zebra.h: New ZBUS message Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Add support for IEEE 754 format * lib/stream.[c,h]: Add stream_get{f,d} and stream_put{f,d}) demux and muxers to safely convert between big-endian IEEE-754 single and double binary format, as used in IETF RFCs, and C99. Implementation depends on host using __STDC_IEC_559__, which should be everything we care about. Should correctly error out otherwise. * lib/network.[c,h]: Add ntohf and htonf converter * lib/memtypes.c: Add new memeory type for Traffic Engineering support Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Add link parameters support to Zebra * zebra/interface.c: - Add new link-params CLI commands - Add new functions to set/get link parameters for interface * zebra/redistribute.[c,h]: Add new function to propagate link parameters to routing daemon (essentially OSPFD and ISISD) for Traffic Engineering. * zebra/redistribute_null.c: Add new function zebra_interface_parameters_update() * zebra/zserv.[c,h]: Add new functions to send link parameters Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Add support of new link-params CLI to vtysh In vtysh_config.c/vtysh_config_parse_line(), it is not possible to continue to use the ordered version for adding line i.e. config_add_line_uniq() to print Interface CLI commands as it completely break the new LINK_PARAMS_NODE. Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Update Traffic Engineering support for OSPFD These patches update original code to RFC3630 (OSPF-TE) and add support of RFC5392 (Inter-AS v2) & RFC7471 (TE metric extensions) and partial support of RFC6827 (ASON - GMPLS). * ospfd/ospf_dump.[c,h]: Add new dump functions for Traffic Engineering * ospfd/ospf_opaque.[c,h]: Add new TLV code points for RFC5392 * ospfd/ospf_packet.c: Update checking of OSPF_OPTION * ospfd/ospf_vty.[c,h]: Update ospf_str2area_id * ospfd/ospf_zebra.c: Add new function ospf_interface_link_params() to get Link Parameters information from the interface to populate Traffic Engineering metrics * ospfd/ospfd.[c,h]: Update OSPF_OPTION flags (T -> MT and new DN) * ospfd/ospf_te.[c,h]: Major modifications to update the code to new link parameters structure and new RFCs Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> tmp
2016-04-19 16:21:46 +02:00
if ((lsa0->area != NULL) && (lsa0->area->ospf != NULL))
top = lsa0->area->ospf;
ospf_ls_retransmit_delete_nbr_as (top, lsa);
2002-12-13 21:15:29 +01:00
break;
default:
zlog_warn ("ospf_opaque_lsa_flush_schedule: Unexpected LSA-type(%u)", lsa->data->type);
goto out;
}
/* Dequeue listnode entry from the list. */
listnode_delete (oipt->id_list, oipi);
/* Avoid misjudgement in the next lookup. */
if (listcount (oipt->id_list) == 0)
oipt->id_list->head = oipt->id_list->tail = NULL;
/* Disassociate internal control information with the given lsa. */
free_opaque_info_per_id ((void *) oipi);
/* Force given lsa's age to MaxAge. */
lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
if (IS_DEBUG_OSPF_EVENT)
zlog_debug ("Schedule Type-%u Opaque-LSA to FLUSH: [opaque-type=%u, opaque-id=%x]", lsa->data->type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)));
2002-12-13 21:15:29 +01:00
/* This lsa will be flushed and removed eventually. */
Update Traffic Engineering Support for OSPFD NOTE: I am squashing several commits together because they do not independently compile and we need this ability to do any type of sane testing on the patches. Since this series builds together I am doing this. -DBS This new structure is the basis to get new link parameters for Traffic Engineering from Zebra/interface layer to OSPFD and ISISD for the support of Traffic Engineering * lib/if.[c,h]: link parameters struture and get/set functions * lib/command.[c,h]: creation of a new link-node * lib/zclient.[c,h]: modification to the ZBUS message to convey the link parameters structure * lib/zebra.h: New ZBUS message Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Add support for IEEE 754 format * lib/stream.[c,h]: Add stream_get{f,d} and stream_put{f,d}) demux and muxers to safely convert between big-endian IEEE-754 single and double binary format, as used in IETF RFCs, and C99. Implementation depends on host using __STDC_IEC_559__, which should be everything we care about. Should correctly error out otherwise. * lib/network.[c,h]: Add ntohf and htonf converter * lib/memtypes.c: Add new memeory type for Traffic Engineering support Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Add link parameters support to Zebra * zebra/interface.c: - Add new link-params CLI commands - Add new functions to set/get link parameters for interface * zebra/redistribute.[c,h]: Add new function to propagate link parameters to routing daemon (essentially OSPFD and ISISD) for Traffic Engineering. * zebra/redistribute_null.c: Add new function zebra_interface_parameters_update() * zebra/zserv.[c,h]: Add new functions to send link parameters Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Add support of new link-params CLI to vtysh In vtysh_config.c/vtysh_config_parse_line(), it is not possible to continue to use the ordered version for adding line i.e. config_add_line_uniq() to print Interface CLI commands as it completely break the new LINK_PARAMS_NODE. Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> Update Traffic Engineering support for OSPFD These patches update original code to RFC3630 (OSPF-TE) and add support of RFC5392 (Inter-AS v2) & RFC7471 (TE metric extensions) and partial support of RFC6827 (ASON - GMPLS). * ospfd/ospf_dump.[c,h]: Add new dump functions for Traffic Engineering * ospfd/ospf_opaque.[c,h]: Add new TLV code points for RFC5392 * ospfd/ospf_packet.c: Update checking of OSPF_OPTION * ospfd/ospf_vty.[c,h]: Update ospf_str2area_id * ospfd/ospf_zebra.c: Add new function ospf_interface_link_params() to get Link Parameters information from the interface to populate Traffic Engineering metrics * ospfd/ospfd.[c,h]: Update OSPF_OPTION flags (T -> MT and new DN) * ospfd/ospf_te.[c,h]: Major modifications to update the code to new link parameters structure and new RFCs Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com> tmp
2016-04-19 16:21:46 +02:00
ospf_lsa_flush (top, lsa);
2002-12-13 21:15:29 +01:00
out:
return;
}
void
ospf_opaque_self_originated_lsa_received (struct ospf_neighbor *nbr,
struct ospf_lsa *lsa)
2002-12-13 21:15:29 +01:00
{
struct ospf *top;
2002-12-13 21:15:29 +01:00
if ((top = oi_to_top (nbr->oi)) == NULL)
return;
2002-12-13 21:15:29 +01:00
/*
* Since these LSA entries are not yet installed into corresponding
* LSDB, just flush them without calling ospf_ls_maxage() afterward.
*/
lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
switch (lsa->data->type)
2002-12-13 21:15:29 +01:00
{
case OSPF_OPAQUE_LINK_LSA:
ospf_flood_through_area (nbr->oi->area, NULL/*inbr*/, lsa);
break;
case OSPF_OPAQUE_AREA_LSA:
ospf_flood_through_area (nbr->oi->area, NULL/*inbr*/, lsa);
break;
case OSPF_OPAQUE_AS_LSA:
ospf_flood_through_as (top, NULL/*inbr*/, lsa);
break;
default:
zlog_warn ("ospf_opaque_self_originated_lsa_received: Unexpected LSA-type(%u)", lsa->data->type);
return;
2002-12-13 21:15:29 +01:00
}
ospf_lsa_discard (lsa); /* List "lsas" will be deleted by caller. */
2002-12-13 21:15:29 +01:00
}
/*------------------------------------------------------------------------*
* Followings are util functions; probably be used by Opaque-LSAs only...
*------------------------------------------------------------------------*/
struct ospf *
oi_to_top (struct ospf_interface *oi)
{
struct ospf *top = NULL;
struct ospf_area *area;
if (oi == NULL || (area = oi->area) == NULL || (top = area->ospf) == NULL)
2002-12-13 21:15:29 +01:00
zlog_warn ("Broken relationship for \"OI -> AREA -> OSPF\"?");
return top;
}