1/*
2 * Copyright (C) 2001 Yasuhiro Ohara
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING.  If not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "log.h"
25#include "memory.h"
26
27#include "ospf6_hook.h"
28
29struct ospf6_hook_master neighbor_hook;
30struct ospf6_hook_master interface_hook;
31struct ospf6_hook_master area_hook;
32struct ospf6_hook_master top_hook;
33struct ospf6_hook_master database_hook;
34struct ospf6_hook_master intra_topology_hook;
35struct ospf6_hook_master inter_topology_hook;
36struct ospf6_hook_master route_hook;
37struct ospf6_hook_master redistribute_hook;
38
39static struct ospf6_hook *
40ospf6_hook_create ()
41{
42  struct ospf6_hook *new;
43  new = XMALLOC (MTYPE_OSPF6_OTHER, sizeof (struct ospf6_hook));
44  if (new == NULL)
45    return NULL;
46  memset (new, 0, sizeof (struct ospf6_hook));
47  return new;
48}
49
50static void
51ospf6_hook_delete (struct ospf6_hook *hook)
52{
53  XFREE (MTYPE_OSPF6_OTHER, hook);
54}
55
56static int
57ospf6_hook_issame (struct ospf6_hook *hook1, struct ospf6_hook *hook2)
58{
59  if (hook1->name && hook2->name &&
60      strcmp (hook1->name, hook2->name) != 0)
61    return 0;
62  if (hook1->hook_add != hook2->hook_add)
63    return 0;
64  if (hook1->hook_change != hook2->hook_change)
65    return 0;
66  if (hook1->hook_remove != hook2->hook_remove)
67    return 0;
68  return 1;
69}
70
71void
72ospf6_hook_register (struct ospf6_hook *hook,
73                     struct ospf6_hook_master *master)
74{
75  struct ospf6_hook *new;
76
77  new = ospf6_hook_create ();
78
79  if (hook->name)
80    new->name = strdup (hook->name);
81  new->hook_add = hook->hook_add;
82  new->hook_change = hook->hook_change;
83  new->hook_remove = hook->hook_remove;
84
85  new->prev = master->tail;
86  if (master->tail)
87    master->tail->next = new;
88
89  master->tail = new;
90  if (! master->head)
91    master->head = new;
92
93  master->count++;
94
95  if (IS_OSPF6_DUMP_HOOK)
96    {
97      zlog_info ("HOOK: Register hook%s%s%s%s",
98                 (hook->name ? " " : ""),
99                 (hook->name ? hook->name : ""),
100                 (master->name ? " to " : ""),
101                 (master->name ? master->name : ""));
102    }
103}
104
105void
106ospf6_hook_unregister (struct ospf6_hook *req,
107                       struct ospf6_hook_master *master)
108{
109  struct ospf6_hook *hook;
110
111  for (hook = master->head; hook; hook = hook->next)
112    {
113      if (ospf6_hook_issame (hook, req))
114        break;
115    }
116  if (! hook)
117    return;
118
119  if (hook->prev)
120    hook->prev->next = hook->next;
121  if (hook->next)
122    hook->next->prev = hook->prev;
123  if (master->head == hook)
124    master->head = hook->next;
125  if (master->tail == hook)
126    master->tail = hook->prev;
127
128  master->count--;
129
130  if (IS_OSPF6_DUMP_HOOK)
131    {
132      zlog_info ("HOOK: Unregister hook%s%s%s%s",
133                 (hook->name ? " " : ""),
134                 (hook->name ? hook->name : ""),
135                 (master->name ? " to " : ""),
136                 (master->name ? master->name : ""));
137    }
138
139  if (hook->name)
140    free (hook->name);
141  ospf6_hook_delete (hook);
142}
143
144void
145ospf6_hook_unregister_all (struct ospf6_hook_master *master)
146{
147  struct ospf6_hook *hook, *next;
148
149  for (hook = master->head; hook; hook = next)
150    {
151      next = hook->next;
152      ospf6_hook_delete (hook);
153    }
154
155  master->head = NULL;
156  master->tail = NULL;
157  master->count = 0;
158}
159
160
161void
162ospf6_hook_init ()
163{
164  neighbor_hook.name       =      "Neighbor Hooklist";
165  interface_hook.name      =     "Interface Hooklist";
166  area_hook.name           =          "Area Hooklist";
167  top_hook.name            =           "Top Hooklist";
168  database_hook.name       =      "Database Hooklist";
169  intra_topology_hook.name = "IntraTopology Hooklist";
170  inter_topology_hook.name = "InterTopology Hooklist";
171  route_hook.name          =         "Route Hooklist";
172}
173
174
175