1/*
2 * LSA function
3 * Copyright (C) 1999 Yasuhiro Ohara
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING.  If not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 */
22
23#ifndef OSPF6_LSA_H
24#define OSPF6_LSA_H
25
26#include "ospf6_hook.h"
27
28/* LSA definition */
29
30#define MAXLSASIZE   1024
31
32#define OSPF6_LSA_MAXAGE           3600    /* 1 hour */
33#define OSPF6_LSA_CHECKAGE         300     /* 5 min */
34#define OSPF6_LSA_MAXAGEDIFF       900     /* 15 min */
35
36/* Type */
37#define OSPF6_LSA_TYPE_NONE             0x0000
38#define OSPF6_LSA_TYPE_ROUTER           0x2001
39#define OSPF6_LSA_TYPE_NETWORK          0x2002
40#define OSPF6_LSA_TYPE_INTER_PREFIX     0x2003
41#define OSPF6_LSA_TYPE_INTER_ROUTER     0x2004
42#define OSPF6_LSA_TYPE_AS_EXTERNAL      0x4005
43#define OSPF6_LSA_TYPE_GROUP_MEMBERSHIP 0x2006
44#define OSPF6_LSA_TYPE_TYPE_7           0x2007
45#define OSPF6_LSA_TYPE_LINK             0x0008
46#define OSPF6_LSA_TYPE_INTRA_PREFIX     0x2009
47#define OSPF6_LSA_TYPE_MAX              0x000a
48#define OSPF6_LSA_TYPE_SIZE             0x000b
49
50/* Masks for LS Type : RFC 2740 A.4.2.1 "LS type" */
51#define OSPF6_LSTYPE_UBIT_MASK        0x8000
52#define OSPF6_LSTYPE_SCOPE_MASK       0x6000
53#define OSPF6_LSTYPE_CODE_MASK        0x1fff
54
55#define OSPF6_LSA_TYPESW_MASK         OSPF6_LSTYPE_CODE_MASK
56#define OSPF6_LSA_TYPESW(x) (ntohs((x)) & OSPF6_LSA_TYPESW_MASK)
57#define OSPF6_LSA_TYPESW_ISKNOWN(x) (OSPF6_LSA_TYPESW(x) < OSPF6_LSA_TYPE_MAX)
58
59/* lsa scope */
60#define OSPF6_LSA_SCOPE_LINKLOCAL  0x0000
61#define OSPF6_LSA_SCOPE_AREA       0x2000
62#define OSPF6_LSA_SCOPE_AS         0x4000
63#define OSPF6_LSA_SCOPE_RESERVED   0x6000
64#define OSPF6_LSA_IS_SCOPE_LINKLOCAL(x) \
65  (((x) & OSPF6_LSTYPE_SCOPE_MASK) == OSPF6_LSA_SCOPE_LINKLOCAL)
66#define OSPF6_LSA_IS_SCOPE_AREA(x) \
67  (((x) & OSPF6_LSTYPE_SCOPE_MASK) == OSPF6_LSA_SCOPE_AREA)
68#define OSPF6_LSA_IS_SCOPE_AS(x) \
69  (((x) & OSPF6_LSTYPE_SCOPE_MASK) == OSPF6_LSA_SCOPE_AS)
70
71/* NOTE that all LSAs are kept NETWORK BYTE ORDER */
72
73/* Router-LSA */
74struct ospf6_router_lsa
75{
76  u_char bits;
77  u_char options[3];
78  /* followed by ospf6_router_lsd(s) */
79};
80
81#define OSPF6_ROUTER_LSA_BIT_B     (1 << 0)
82#define OSPF6_ROUTER_LSA_BIT_E     (1 << 1)
83#define OSPF6_ROUTER_LSA_BIT_V     (1 << 2)
84#define OSPF6_ROUTER_LSA_BIT_W     (1 << 3)
85
86#define OSPF6_ROUTER_LSA_SET(x,y)    ((x)->bits |=  (y))
87#define OSPF6_ROUTER_LSA_ISSET(x,y)  ((x)->bits &   (y))
88#define OSPF6_ROUTER_LSA_CLEAR(x,y)  ((x)->bits &= ~(y))
89#define OSPF6_ROUTER_LSA_CLEAR_ALL_BITS(x)  ((x)->bits = 0)
90
91/* Link State Description in Router-LSA */
92struct ospf6_router_lsd
93{
94  u_char    type;
95  u_char    reserved;
96  u_int16_t metric;                /* output cost */
97  u_int32_t interface_id;
98  u_int32_t neighbor_interface_id;
99  u_int32_t neighbor_router_id;
100};
101
102#define OSPF6_ROUTER_LSD_TYPE_POINTTOPOINT       1
103#define OSPF6_ROUTER_LSD_TYPE_TRANSIT_NETWORK    2
104#define OSPF6_ROUTER_LSD_TYPE_STUB_NETWORK       3
105#define OSPF6_ROUTER_LSD_TYPE_VIRTUAL_LINK       4
106
107/* Network-LSA */
108struct ospf6_network_lsa
109{
110  u_char reserved;
111  u_char options[3];
112  /* followed by ospf6_netowrk_lsd(s) */
113};
114
115/* Link State Description in Router-LSA */
116struct ospf6_network_lsd
117{
118  u_int32_t adv_router;
119};
120
121/* Link-LSA */
122struct ospf6_link_lsa
123{
124  u_char          llsa_rtr_pri;
125  u_char          llsa_options[3];
126  struct in6_addr llsa_linklocal;
127  u_int32_t       llsa_prefix_num;
128  /* followed by prefix(es) */
129};
130
131/* Intra-Area-Prefix-LSA */
132struct ospf6_intra_area_prefix_lsa
133{
134  u_int16_t prefix_number;
135  u_int16_t refer_lstype;
136  u_int32_t refer_lsid;
137  u_int32_t refer_advrtr;
138};
139
140/* AS-External-LSA */
141struct ospf6_as_external_lsa
142{
143  u_char    ase_bits;
144  u_char    ase_pre_metric; /* 1st byte of metric */
145  u_int16_t ase_metric;     /* 2nd, 3rd byte of metric */
146#if 1
147  struct ospf6_prefix ospf6_prefix;
148#else
149  u_char    ase_prefix_len;
150  u_char    ase_prefix_opt;
151  u_int16_t ase_refer_lstype;
152  /* followed by one address prefix */
153#endif
154  /* followed by none or one forwarding address */
155  /* followed by none or one external route tag */
156  /* followed by none or one referenced LS-ID */
157};
158#define ASE_LSA_BIT_T     (1 << 0)
159#define ASE_LSA_BIT_F     (1 << 1)
160#define ASE_LSA_BIT_E     (1 << 2)
161
162#define ASE_LSA_SET(x,y)    ((x)->ase_bits |=  (y))
163#define ASE_LSA_ISSET(x,y)  ((x)->ase_bits &   (y))
164#define ASE_LSA_CLEAR(x,y)  ((x)->ase_bits &= ~(y))
165
166/* LSA Header */
167struct ospf6_lsa_hdr
168{
169  u_int16_t lsh_age;      /* LS age */
170  u_int16_t lsh_type;     /* LS type */
171  u_int32_t lsh_id;       /* Link State ID */
172  u_int32_t lsh_advrtr;   /* Advertising Router */
173  u_int32_t lsh_seqnum;   /* LS sequence number */
174  u_int16_t lsh_cksum;    /* LS checksum */
175  u_int16_t lsh_len;      /* length */
176};
177struct ospf6_lsa_header
178{
179  u_int16_t age;       /* LS age */
180  u_int16_t type;      /* LS type */
181  u_int32_t ls_id;     /* Link State ID */
182  u_int32_t advrtr;    /* Advertising Router */
183  u_int32_t seqnum;    /* LS sequence number */
184  u_int16_t checksum;  /* LS checksum */
185  u_int16_t length;    /* LSA length */
186};
187struct ospf6_lsa_header__
188{
189  u_int16_t age;        /* LS age */
190  u_int16_t type;       /* LS type */
191  u_int32_t id;         /* Link State ID */
192  u_int32_t adv_router; /* Advertising Router */
193  u_int32_t seqnum;     /* LS sequence number */
194  u_int16_t checksum;   /* LS checksum */
195  u_int16_t length;     /* LSA length */
196};
197
198#define OSPF6_LSA_NEXT(x) ((struct ospf6_lsa_header *) \
199                             ((char *)(x) + ntohs ((x)->length)))
200
201#define OSPF6_LSA_HEADER_END(header) \
202  ((void *)((char *)(header) + sizeof (struct ospf6_lsa_header)))
203
204struct ospf6_lsa
205{
206  char                   str[256];  /* dump string */
207
208  u_long                 lock;      /* reference counter */
209  int                    summary;   /* indicate this is LS header only */
210  void                  *scope;     /* pointer of scoped data structure */
211  unsigned char          flag;      /* to decide ack type and refresh */
212  struct timeval         birth;     /* tv_sec when LS age 0 */
213  struct timeval         installed; /* installed time */
214  struct thread         *expire;
215  struct thread         *refresh;   /* For self-originated LSA */
216  u_int32_t              from;      /* from which neighbor */
217
218  /* lsa instance */
219  struct ospf6_lsa_hdr  *lsa_hdr;
220  struct ospf6_lsa_header__ *header;
221
222  /* statistics */
223  u_long turnover_num;
224  u_long turnover_total;
225  u_long turnover_min;
226  u_long turnover_max;
227};
228
229struct ospf6_lsa_slot
230{
231  struct ospf6_lsa_slot *prev;
232  struct ospf6_lsa_slot *next;
233
234  u_int16_t  type;
235  char      *name;
236
237  int (*func_print)        (struct ospf6_lsa *lsa);
238  int (*func_show)         (struct vty *vty, struct ospf6_lsa *lsa);
239  int (*func_refresh)      (void *lsa);
240
241  int (*database_add)      (void *lsa);
242  int (*database_remove)   (void *lsa);
243
244  struct ospf6_hook_master database_hook;
245
246  struct ospf6_hook hook_neighbor;
247  struct ospf6_hook hook_interface;
248  struct ospf6_hook hook_area;
249  struct ospf6_hook hook_top;
250  struct ospf6_hook hook_database;
251  struct ospf6_hook hook_route;
252};
253
254#define OSPF6_LSA_FLAG_FLOODBACK  0x01
255#define OSPF6_LSA_FLAG_DUPLICATE  0x02
256#define OSPF6_LSA_FLAG_IMPLIEDACK 0x04
257#define OSPF6_LSA_FLAG_REFRESH    0x08
258
259/* Back pointer check, Is X's reference field bound to Y ? */
260#define x_ipl(x) ((struct intra_area_prefix_lsa *)LSH_NEXT((x)->lsa_hdr))
261#define is_reference_network_ok(x,y) \
262          ((x_ipl(x))->intra_prefix_refer_lstype == (y)->lsa_hdr->lsh_type &&\
263           (x_ipl(x))->intra_prefix_refer_lsid == (y)->lsa_hdr->lsh_id &&\
264           (x_ipl(x))->intra_prefix_refer_advrtr == (y)->lsa_hdr->lsh_advrtr)
265  /* referencing router's ifid must be 0,
266     see draft-ietf-ospf-ospfv6-06.txt */
267#define is_reference_router_ok(x,y) \
268          ((x_ipl(x))->intra_prefix_refer_lstype == (y)->lsa_hdr->lsh_type &&\
269           (x_ipl(x))->intra_prefix_refer_lsid == htonl (0) &&\
270           (x_ipl(x))->intra_prefix_refer_advrtr == (y)->lsa_hdr->lsh_advrtr)
271
272/* MaxAge check.  */
273/* ospf6_lsa_is_maxage (struct ospf6_lsa *lsa) */
274#define IS_LSA_MAXAGE(L)      (ospf6_lsa_age_current (L) == OSPF6_LSA_MAXAGE)
275
276struct ospf6_lsa_slot *ospf6_lsa_slot_get (u_int16_t type);
277int ospf6_lsa_slot_register (struct ospf6_lsa_slot *src);
278int ospf6_lsa_slot_unregister (u_int16_t type);
279
280extern struct ospf6_lsa_slot *slot_head;
281#define CALL_FOREACH_LSA_HOOK(hook,func,data) \
282  if (ospf6)\
283    {\
284      struct ospf6_lsa_slot *slot;\
285      for (slot = slot_head; slot; slot = slot->next)\
286        {\
287          if (slot->hook.func)\
288            (*slot->hook.func) (data);\
289        }\
290    }
291#define CALL_LSA_FUNC(type,func,data) \
292  if (ospf6)\
293    {\
294      struct ospf6_lsa_slot *slot;\
295      slot = ospf6_lsa_slot_get (type);\
296      if (slot && slot->func)\
297        {\
298          (*slot->func) (data);\
299        }\
300      else\
301        {\
302          zlog_warn ("LSA: No slot for type %#x: %s line:%d",\
303                     ntohs (type), __FILE__, __LINE__);\
304        }\
305    }
306
307#define CALL_LSA_DATABASE_ADD(type,data) \
308  if (ospf6)\
309    {\
310      struct ospf6_lsa_slot *slot;\
311      slot = ospf6_lsa_slot_get (type);\
312      if (slot)\
313        {\
314          CALL_ADD_HOOK (&slot->database_hook, data);\
315        }\
316      else\
317        {\
318          zlog_warn ("LSA: No slot for type %#x: %s line:%d",\
319                     ntohs (type), __FILE__, __LINE__);\
320        }\
321    }
322#define CALL_LSA_DATABASE_CHANGE(type,data) \
323  if (ospf6)\
324    {\
325      struct ospf6_lsa_slot *slot;\
326      slot = ospf6_lsa_slot_get (type);\
327      if (slot)\
328        {\
329          CALL_CHANGE_HOOK (&slot->database_hook, data);\
330        }\
331      else\
332        {\
333          zlog_warn ("LSA: No slot for type %#x: %s line:%d",\
334                     ntohs (type), __FILE__, __LINE__);\
335        }\
336    }
337#define CALL_LSA_DATABASE_REMOVE(type,data) \
338  if (ospf6)\
339    {\
340      struct ospf6_lsa_slot *slot;\
341      slot = ospf6_lsa_slot_get (type);\
342      if (slot)\
343        {\
344          CALL_REMOVE_HOOK (&slot->database_hook, data);\
345        }\
346      else\
347        {\
348          zlog_warn ("LSA: No slot for type %#x: %s line:%d",\
349                     ntohs (type), __FILE__, __LINE__);\
350        }\
351    }
352
353void ospf6_lsa_init ();
354
355/* Function Prototypes */
356
357struct router_lsd *
358get_router_lsd (u_int32_t, struct ospf6_lsa *);
359unsigned long get_ifindex_to_router (u_int32_t, struct ospf6_lsa *);
360
361int ospf6_lsa_differ (struct ospf6_lsa *lsa1, struct ospf6_lsa *lsa2);
362int ospf6_lsa_match (u_int16_t, u_int32_t, u_int32_t,
363                     struct ospf6_lsa_header *);
364
365void ospf6_lsa_show (struct vty *, struct ospf6_lsa *);
366void ospf6_lsa_show_dump (struct vty *, struct ospf6_lsa *);
367void ospf6_lsa_show_summary (struct vty *, struct ospf6_lsa *);
368void ospf6_lsa_show_summary_header (struct vty *);
369
370struct ospf6_lsa *
371ospf6_lsa_create (struct ospf6_lsa_header *);
372struct ospf6_lsa *
373ospf6_lsa_summary_create (struct ospf6_lsa_header__ *);
374void
375ospf6_lsa_delete (struct ospf6_lsa *);
376
377void ospf6_lsa_lock (struct ospf6_lsa *);
378void ospf6_lsa_unlock (struct ospf6_lsa *);
379
380unsigned short ospf6_lsa_age_current (struct ospf6_lsa *);
381int ospf6_lsa_is_maxage (struct ospf6_lsa *);
382void ospf6_lsa_age_update_to_send (struct ospf6_lsa *, u_int32_t);
383void ospf6_lsa_premature_aging (struct ospf6_lsa *);
384
385int ospf6_lsa_check_recent (struct ospf6_lsa *, struct ospf6_lsa *);
386
387int
388ospf6_lsa_lsd_num (struct ospf6_lsa_header *lsa_header);
389void *
390ospf6_lsa_lsd_get (int index, struct ospf6_lsa_header *lsa_header);
391int
392ospf6_lsa_lsd_is_refer_ok (int index1, struct ospf6_lsa_header *lsa_header1,
393                           int index2, struct ospf6_lsa_header *lsa_header2);
394
395int ospf6_lsa_expire (struct thread *);
396int ospf6_lsa_refresh (struct thread *);
397
398u_short ospf6_lsa_checksum (struct ospf6_lsa_header *);
399
400void ospf6_lsa_update_router (u_int32_t area_id);
401void ospf6_lsa_update_network (char *ifname);
402void ospf6_lsa_update_link (char *ifname);
403void ospf6_lsa_update_as_external (u_int32_t ls_id);
404void ospf6_lsa_update_intra_prefix_transit (char *ifname);
405void ospf6_lsa_update_intra_prefix_stub (u_int32_t area_id);
406
407void ospf6_lsa_reoriginate (struct ospf6_lsa *);
408void
409ospf6_lsa_originate (u_int16_t, u_int32_t, u_int32_t, char *, int, void *);
410
411u_int16_t ospf6_lsa_get_scope_type (u_int16_t);
412int ospf6_lsa_is_known_type (struct ospf6_lsa_header *lsa_header);
413
414char *ospf6_lsa_type_string (u_int16_t type, char *buf, int bufsize);
415char *ospf6_lsa_router_bits_string (u_char router_bits, char *buf, int size);
416
417#endif /* OSPF6_LSA_H */
418
419