📄 ospf_opaque.c
字号:
/* * 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. *//***** MTYPE definitions are not reflected to "memory.h" yet. *****/#define MTYPE_OSPF_OPAQUE_FUNCTAB 0#define MTYPE_OPAQUE_INFO_PER_TYPE 0#define MTYPE_OPAQUE_INFO_PER_ID 0#include <zebra.h>#ifdef HAVE_OPAQUE_LSA#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"/*------------------------------------------------------------------------* * Followings are initialize/terminate functions for Opaque-LSAs handling. *------------------------------------------------------------------------*/#ifdef HAVE_OSPF_TE#include "ospfd/ospf_te.h"#endif /* HAVE_OSPF_TE */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);voidospf_opaque_init (void){ ospf_opaque_register_vty (); ospf_opaque_funclist_init ();#ifdef HAVE_OSPF_TE if (ospf_mpls_te_init () != 0) exit (1);#endif /* HAVE_OSPF_TE */ return;}voidospf_opaque_term (void){#ifdef HAVE_OSPF_TE ospf_mpls_te_term ();#endif /* HAVE_OSPF_TE */ ospf_opaque_funclist_term (); return;}intospf_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;}voidospf_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;}intospf_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;}voidospf_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;}intospf_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;}voidospf_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; default: if (OPAQUE_TYPE_RANGE_UNASSIGNED (opaque_type)) name = "Unassigned"; else if (OPAQUE_TYPE_RANGE_RESERVED (opaque_type)) name = "Private/Experimental"; 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); void (* lsa_refresher )(struct ospf_lsa *lsa); int (* new_lsa_hook)(struct ospf_lsa *lsa); int (* del_lsa_hook)(struct ospf_lsa *lsa);};static list ospf_opaque_wildcard_funclist; /* Handle LSA-9/10/11 altogether. */static list ospf_opaque_type9_funclist;static list ospf_opaque_type10_funclist;static list ospf_opaque_type11_funclist;static voidospf_opaque_del_functab (void *val){ XFREE (MTYPE_OSPF_OPAQUE_FUNCTAB, val); return;}static voidospf_opaque_funclist_init (void){ list funclist; funclist = ospf_opaque_wildcard_funclist = list_new (); funclist->del = ospf_opaque_del_functab; 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 voidospf_opaque_funclist_term (void){ list funclist; funclist = ospf_opaque_wildcard_funclist; list_delete (funclist); 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 listospf_get_opaque_funclist (u_char lsa_type){ list funclist = NULL; 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; 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;}intospf_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), void (* lsa_refresher )(struct ospf_lsa *lsa), int (* new_lsa_hook)(struct ospf_lsa *lsa), int (* del_lsa_hook)(struct ospf_lsa *lsa)){ list funclist; 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); goto out; } else { listnode node; struct ospf_opaque_functab *functab; for (node = listhead (funclist); node; nextnode (node)) if ((functab = getdata (node)) != NULL) 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; } } if ((new = XCALLOC (MTYPE_OSPF_OPAQUE_FUNCTAB, sizeof (struct ospf_opaque_functab))) == NULL) { zlog_warn ("ospf_register_opaque_functab: XMALLOC: %s", strerror (errno)); 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;}voidospf_delete_opaque_functab (u_char lsa_type, u_char opaque_type){ list funclist; listnode node; struct ospf_opaque_functab *functab; if ((funclist = ospf_get_opaque_funclist (lsa_type)) != NULL) for (node = listhead (funclist); node; nextnode (node)) { if ((functab = getdata (node)) != NULL && functab->opaque_type == opaque_type) { /* 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); goto out; } }out: return;}static struct ospf_opaque_functab *ospf_opaque_functab_lookup (struct ospf_lsa *lsa){ list funclist; listnode node; 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 (node = listhead (funclist); node; nextnode (node)) if ((functab = getdata (node)) != NULL) if (functab->opaque_type == key) return functab; return NULL;}/*------------------------------------------------------------------------* * Followings are management functions for self-originated LSA entries. *------------------------------------------------------------------------*//*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -