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