paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 1 | /* |
| 2 | * OSPF Link State Advertisement |
| 3 | * Copyright (C) 1999, 2000 Toshiaki Takada |
| 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 Free |
| 19 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA |
| 20 | * 02111-1307, USA. |
| 21 | */ |
| 22 | |
| 23 | #ifndef _ZEBRA_OSPF_LSA_H |
| 24 | #define _ZEBRA_OSPF_LSA_H |
| 25 | |
| 26 | /* OSPF LSA Range definition. */ |
| 27 | #define OSPF_MIN_LSA 1 /* begin range here */ |
| 28 | #if defined (HAVE_OPAQUE_LSA) |
| 29 | #define OSPF_MAX_LSA 12 |
| 30 | #elif defined (HAVE_NSSA) |
| 31 | #define OSPF_MAX_LSA 8 |
| 32 | #else |
| 33 | #define OSPF_MAX_LSA 6 |
| 34 | #endif |
| 35 | |
| 36 | /* OSPF LSA Type definition. */ |
| 37 | #define OSPF_UNKNOWN_LSA 0 |
| 38 | #define OSPF_ROUTER_LSA 1 |
| 39 | #define OSPF_NETWORK_LSA 2 |
| 40 | #define OSPF_SUMMARY_LSA 3 |
| 41 | #define OSPF_ASBR_SUMMARY_LSA 4 |
| 42 | #define OSPF_AS_EXTERNAL_LSA 5 |
| 43 | #define OSPF_GROUP_MEMBER_LSA 6 /* Not supported. */ |
| 44 | #define OSPF_AS_NSSA_LSA 7 |
| 45 | #define OSPF_EXTERNAL_ATTRIBUTES_LSA 8 /* Not supported. */ |
| 46 | #define OSPF_OPAQUE_LINK_LSA 9 |
| 47 | #define OSPF_OPAQUE_AREA_LSA 10 |
| 48 | #define OSPF_OPAQUE_AS_LSA 11 |
| 49 | |
| 50 | #define OSPF_LSA_HEADER_SIZE 20 |
| 51 | #define OSPF_MAX_LSA_SIZE 1500 |
| 52 | |
| 53 | /* AS-external-LSA refresh method. */ |
| 54 | #define LSA_REFRESH_IF_CHANGED 0 |
| 55 | #define LSA_REFRESH_FORCE 1 |
| 56 | |
| 57 | /* OSPF LSA header. */ |
| 58 | struct lsa_header |
| 59 | { |
| 60 | u_int16_t ls_age; |
| 61 | u_char options; |
| 62 | u_char type; |
| 63 | struct in_addr id; |
| 64 | struct in_addr adv_router; |
| 65 | int ls_seqnum; |
| 66 | u_int16_t checksum; |
| 67 | u_int16_t length; |
| 68 | }; |
| 69 | |
| 70 | /* OSPF LSA. */ |
| 71 | struct ospf_lsa |
| 72 | { |
| 73 | /* LSA origination flag. */ |
| 74 | u_char flags; |
| 75 | #define OSPF_LSA_SELF 0x01 |
| 76 | #define OSPF_LSA_SELF_CHECKED 0x02 |
| 77 | #define OSPF_LSA_RECEIVED 0x04 |
| 78 | #define OSPF_LSA_APPROVED 0x08 |
| 79 | #define OSPF_LSA_DISCARD 0x10 |
| 80 | #ifdef HAVE_NSSA |
| 81 | #define OSPF_LSA_LOCAL_XLT 0x20 |
| 82 | #endif /* HAVE_NSSA */ |
paul | 7ddf1d6 | 2003-10-13 09:06:46 +0000 | [diff] [blame] | 83 | #define OSPF_LSA_PREMATURE_AGE 0x40 |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 84 | |
| 85 | /* LSA data. */ |
| 86 | struct lsa_header *data; |
| 87 | |
| 88 | /* Received time stamp. */ |
| 89 | struct timeval tv_recv; |
| 90 | |
| 91 | /* Last time it was originated */ |
| 92 | struct timeval tv_orig; |
| 93 | |
| 94 | /* All of reference count, also lock to remove. */ |
| 95 | int lock; |
| 96 | |
| 97 | /* References to this LSA in neighbor retransmission lists*/ |
| 98 | int retransmit_counter; |
| 99 | |
| 100 | /* Area the LSA belongs to, may be NULL if AS-external-LSA. */ |
| 101 | struct ospf_area *area; |
| 102 | |
| 103 | /* Parent LSDB. */ |
| 104 | struct ospf_lsdb *lsdb; |
| 105 | |
| 106 | /* Related Route. */ |
| 107 | void *route; |
| 108 | |
| 109 | /* Refreshement List or Queue */ |
| 110 | int refresh_list; |
| 111 | |
| 112 | #ifdef HAVE_OPAQUE_LSA |
| 113 | /* For Type-9 Opaque-LSAs, reference to ospf-interface is required. */ |
| 114 | struct ospf_interface *oi; |
| 115 | #endif /* HAVE_OPAQUE_LSA */ |
| 116 | }; |
| 117 | |
| 118 | /* OSPF LSA Link Type. */ |
| 119 | #define LSA_LINK_TYPE_POINTOPOINT 1 |
| 120 | #define LSA_LINK_TYPE_TRANSIT 2 |
| 121 | #define LSA_LINK_TYPE_STUB 3 |
| 122 | #define LSA_LINK_TYPE_VIRTUALLINK 4 |
| 123 | |
| 124 | /* OSPF Router LSA Flag. */ |
| 125 | #define ROUTER_LSA_BORDER 0x01 /* The router is an ABR */ |
| 126 | #define ROUTER_LSA_EXTERNAL 0x02 /* The router is an ASBR */ |
| 127 | #define ROUTER_LSA_VIRTUAL 0x04 /* The router has a VL in this area */ |
paul | 0c9491b | 2003-06-22 08:23:01 +0000 | [diff] [blame] | 128 | #define ROUTER_LSA_NT 0x10 /* The routers always translates Type-7 */ |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 129 | #define ROUTER_LSA_SHORTCUT 0x20 /* Shortcut-ABR specific flag */ |
| 130 | |
| 131 | #define IS_ROUTER_LSA_VIRTUAL(x) ((x)->flags & ROUTER_LSA_VIRTUAL) |
| 132 | #define IS_ROUTER_LSA_EXTERNAL(x) ((x)->flags & ROUTER_LSA_EXTERNAL) |
| 133 | #define IS_ROUTER_LSA_BORDER(x) ((x)->flags & ROUTER_LSA_BORDER) |
| 134 | #define IS_ROUTER_LSA_SHORTCUT(x) ((x)->flags & ROUTER_LSA_SHORTCUT) |
paul | 0c9491b | 2003-06-22 08:23:01 +0000 | [diff] [blame] | 135 | #define IS_ROUTER_LSA_NT(x) ((x)->flags & ROUTER_LSA_NT) |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 136 | |
| 137 | /* OSPF Router-LSA Link information. */ |
| 138 | struct router_lsa_link |
| 139 | { |
| 140 | struct in_addr link_id; |
| 141 | struct in_addr link_data; |
| 142 | struct |
| 143 | { |
| 144 | u_char type; |
| 145 | u_char tos_count; |
| 146 | u_int16_t metric; |
| 147 | } m[1]; |
| 148 | }; |
| 149 | |
| 150 | /* OSPF Router-LSAs structure. */ |
| 151 | struct router_lsa |
| 152 | { |
| 153 | struct lsa_header header; |
| 154 | u_char flags; |
| 155 | u_char zero; |
| 156 | u_int16_t links; |
| 157 | struct |
| 158 | { |
| 159 | struct in_addr link_id; |
| 160 | struct in_addr link_data; |
| 161 | u_char type; |
| 162 | u_char tos; |
| 163 | u_int16_t metric; |
| 164 | } link[1]; |
| 165 | }; |
| 166 | |
| 167 | /* OSPF Network-LSAs structure. */ |
| 168 | struct network_lsa |
| 169 | { |
| 170 | struct lsa_header header; |
| 171 | struct in_addr mask; |
| 172 | struct in_addr routers[1]; |
| 173 | }; |
| 174 | |
| 175 | /* OSPF Summary-LSAs structure. */ |
| 176 | struct summary_lsa |
| 177 | { |
| 178 | struct lsa_header header; |
| 179 | struct in_addr mask; |
| 180 | u_char tos; |
| 181 | u_char metric[3]; |
| 182 | }; |
| 183 | |
| 184 | /* OSPF AS-external-LSAs structure. */ |
| 185 | struct as_external_lsa |
| 186 | { |
| 187 | struct lsa_header header; |
| 188 | struct in_addr mask; |
| 189 | struct |
| 190 | { |
| 191 | u_char tos; |
| 192 | u_char metric[3]; |
| 193 | struct in_addr fwd_addr; |
| 194 | u_int32_t route_tag; |
| 195 | } e[1]; |
| 196 | }; |
| 197 | |
| 198 | #ifdef HAVE_OPAQUE_LSA |
| 199 | #include "ospfd/ospf_opaque.h" |
| 200 | #endif /* HAVE_OPAQUE_LSA */ |
| 201 | |
| 202 | /* Macros. */ |
| 203 | #define GET_METRIC(x) get_metric(x) |
| 204 | #define IS_EXTERNAL_METRIC(x) ((x) & 0x80) |
| 205 | |
| 206 | #define GET_AGE(x) (ntohs ((x)->data->ls_age) + time (NULL) - (x)->tv_recv) |
| 207 | #define LS_AGE(x) (OSPF_LSA_MAXAGE < get_age(x) ? \ |
| 208 | OSPF_LSA_MAXAGE : get_age(x)) |
| 209 | #define IS_LSA_SELF(L) (CHECK_FLAG ((L)->flags, OSPF_LSA_SELF)) |
| 210 | #define IS_LSA_MAXAGE(L) (LS_AGE ((L)) == OSPF_LSA_MAXAGE) |
| 211 | |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 212 | #define OSPF_LSA_UPDATE_DELAY 2 |
| 213 | |
| 214 | #define OSPF_LSA_UPDATE_TIMER_ON(T,F) \ |
| 215 | if (!(T)) \ |
| 216 | (T) = thread_add_timer (master, (F), 0, 2) |
| 217 | |
| 218 | struct ospf_route; |
| 219 | struct ospf_lsdb; |
| 220 | |
| 221 | /* Prototypes. */ |
| 222 | struct timeval tv_adjust (struct timeval); |
| 223 | int tv_ceil (struct timeval); |
| 224 | int tv_floor (struct timeval); |
| 225 | struct timeval int2tv (int); |
| 226 | struct timeval tv_add (struct timeval, struct timeval); |
| 227 | struct timeval tv_sub (struct timeval, struct timeval); |
| 228 | int tv_cmp (struct timeval, struct timeval); |
| 229 | |
| 230 | int get_age (struct ospf_lsa *); |
| 231 | u_int16_t ospf_lsa_checksum (struct lsa_header *); |
| 232 | |
| 233 | struct stream; |
paul | 6898008 | 2003-03-25 05:07:42 +0000 | [diff] [blame] | 234 | const char *dump_lsa_key (struct ospf_lsa *); |
| 235 | u_int32_t lsa_seqnum_increment (struct ospf_lsa *); |
| 236 | void lsa_header_set (struct stream *, u_char, u_char, struct in_addr, |
| 237 | struct in_addr); |
| 238 | struct ospf_neighbor *ospf_nbr_lookup_ptop (struct ospf_interface *); |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 239 | |
| 240 | /* Prototype for LSA primitive. */ |
| 241 | struct ospf_lsa *ospf_lsa_new (); |
| 242 | struct ospf_lsa *ospf_lsa_dup (); |
paul | 6898008 | 2003-03-25 05:07:42 +0000 | [diff] [blame] | 243 | void ospf_lsa_free (struct ospf_lsa *); |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 244 | struct ospf_lsa *ospf_lsa_lock (struct ospf_lsa *); |
| 245 | void ospf_lsa_unlock (struct ospf_lsa *); |
| 246 | void ospf_lsa_discard (struct ospf_lsa *); |
| 247 | |
| 248 | struct lsa_header *ospf_lsa_data_new (size_t); |
| 249 | struct lsa_header *ospf_lsa_data_dup (struct lsa_header *); |
| 250 | void ospf_lsa_data_free (struct lsa_header *); |
| 251 | |
| 252 | /* Prototype for various LSAs */ |
| 253 | struct ospf_lsa *ospf_router_lsa_originate (struct ospf_area *); |
| 254 | int ospf_router_lsa_update_timer (struct thread *); |
| 255 | void ospf_router_lsa_timer_add (struct ospf_area *); |
| 256 | |
| 257 | int ospf_network_lsa_refresh (struct ospf_lsa *, struct ospf_interface *); |
| 258 | void ospf_network_lsa_timer_add (struct ospf_interface *); |
| 259 | |
| 260 | struct ospf_lsa *ospf_summary_lsa_originate (struct prefix_ipv4 *, u_int32_t, |
| 261 | struct ospf_area *); |
| 262 | struct ospf_lsa *ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *, |
| 263 | u_int32_t, |
| 264 | struct ospf_area *); |
paul | 6898008 | 2003-03-25 05:07:42 +0000 | [diff] [blame] | 265 | struct ospf_lsa *ospf_summary_lsa_refresh (struct ospf *, struct ospf_lsa *); |
| 266 | struct ospf_lsa *ospf_summary_asbr_lsa_refresh (struct ospf *, struct ospf_lsa *); |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 267 | |
paul | 6898008 | 2003-03-25 05:07:42 +0000 | [diff] [blame] | 268 | struct ospf_lsa *ospf_lsa_install (struct ospf *, |
| 269 | struct ospf_interface *, struct ospf_lsa *); |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 270 | |
paul | 645878f | 2003-04-13 21:42:11 +0000 | [diff] [blame] | 271 | void ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p); |
paul | 6898008 | 2003-03-25 05:07:42 +0000 | [diff] [blame] | 272 | void ospf_external_lsa_flush (struct ospf *, u_char, struct prefix_ipv4 *, |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 273 | unsigned int, struct in_addr); |
| 274 | |
paul | 6898008 | 2003-03-25 05:07:42 +0000 | [diff] [blame] | 275 | struct in_addr ospf_get_ip_from_ifp (struct ospf_interface *); |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 276 | |
paul | 6898008 | 2003-03-25 05:07:42 +0000 | [diff] [blame] | 277 | struct ospf_lsa *ospf_external_lsa_originate (struct ospf *, struct external_info *); |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 278 | int ospf_external_lsa_originate_timer (struct thread *); |
| 279 | struct ospf_lsa *ospf_lsa_lookup (struct ospf_area *, u_int32_t, |
| 280 | struct in_addr, struct in_addr); |
paul | d4a53d5 | 2003-07-12 21:30:57 +0000 | [diff] [blame] | 281 | struct ospf_lsa *ospf_lsa_lookup_by_id (struct ospf_area *, |
| 282 | u_int32_t, |
| 283 | struct in_addr); |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 284 | struct ospf_lsa *ospf_lsa_lookup_by_header (struct ospf_area *, |
| 285 | struct lsa_header *); |
| 286 | int ospf_lsa_more_recent (struct ospf_lsa *, struct ospf_lsa *); |
| 287 | int ospf_lsa_different (struct ospf_lsa *, struct ospf_lsa *); |
paul | 6898008 | 2003-03-25 05:07:42 +0000 | [diff] [blame] | 288 | void ospf_flush_self_originated_lsas_now (struct ospf *); |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 289 | |
paul | 6898008 | 2003-03-25 05:07:42 +0000 | [diff] [blame] | 290 | int ospf_lsa_is_self_originated (struct ospf *, struct ospf_lsa *); |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 291 | |
paul | 6898008 | 2003-03-25 05:07:42 +0000 | [diff] [blame] | 292 | struct ospf_lsa *ospf_lsa_lookup_by_prefix (struct ospf_lsdb *, u_char, |
| 293 | struct prefix_ipv4 *, |
| 294 | struct in_addr); |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 295 | |
paul | 6898008 | 2003-03-25 05:07:42 +0000 | [diff] [blame] | 296 | void ospf_lsa_maxage (struct ospf *, struct ospf_lsa *); |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 297 | u_int32_t get_metric (u_char *); |
| 298 | |
| 299 | int ospf_lsa_maxage_walker (struct thread *); |
| 300 | |
paul | 6898008 | 2003-03-25 05:07:42 +0000 | [diff] [blame] | 301 | void ospf_external_lsa_refresh_default (struct ospf *); |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 302 | |
paul | 6898008 | 2003-03-25 05:07:42 +0000 | [diff] [blame] | 303 | void ospf_external_lsa_refresh_type (struct ospf *, u_char, int); |
| 304 | void ospf_external_lsa_refresh (struct ospf *, struct ospf_lsa *, |
| 305 | struct external_info *, int); |
| 306 | struct in_addr ospf_lsa_unique_id (struct ospf *, struct ospf_lsdb *, u_char, |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 307 | struct prefix_ipv4 *); |
| 308 | void ospf_schedule_lsa_flood_area (struct ospf_area *, struct ospf_lsa *); |
| 309 | void ospf_schedule_lsa_flush_area (struct ospf_area *, struct ospf_lsa *); |
| 310 | |
| 311 | void ospf_refresher_register_lsa (struct ospf *, struct ospf_lsa *); |
| 312 | void ospf_refresher_unregister_lsa (struct ospf *, struct ospf_lsa *); |
| 313 | int ospf_lsa_refresh_walker (struct thread *); |
| 314 | |
paul | 6898008 | 2003-03-25 05:07:42 +0000 | [diff] [blame] | 315 | void ospf_lsa_maxage_delete (struct ospf *, struct ospf_lsa *); |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 316 | |
paul | 6898008 | 2003-03-25 05:07:42 +0000 | [diff] [blame] | 317 | void ospf_discard_from_db (struct ospf *, struct ospf_lsdb *, struct ospf_lsa*); |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 318 | int is_prefix_default (struct prefix_ipv4 *); |
| 319 | |
paul | 6898008 | 2003-03-25 05:07:42 +0000 | [diff] [blame] | 320 | int metric_type (struct ospf *, u_char); |
| 321 | int metric_value (struct ospf *, u_char); |
| 322 | |
| 323 | #ifdef HAVE_NSSA |
| 324 | struct in_addr ospf_get_nssa_ip (struct ospf_area *); |
paul | d4a53d5 | 2003-07-12 21:30:57 +0000 | [diff] [blame] | 325 | int ospf_translated_nssa_compare (struct ospf_lsa *, struct ospf_lsa *); |
| 326 | struct ospf_lsa *ospf_translated_nssa_refresh (struct ospf *, struct ospf_lsa *, |
| 327 | struct ospf_lsa *); |
| 328 | struct ospf_lsa *ospf_translated_nssa_originate (struct ospf *, struct ospf_lsa *); |
paul | f2c8065 | 2002-12-13 21:44:27 +0000 | [diff] [blame] | 329 | #endif |
| 330 | |
paul | 718e374 | 2002-12-13 20:15:29 +0000 | [diff] [blame] | 331 | #endif /* _ZEBRA_OSPF_LSA_H */ |