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