1 /* 2 * Copyright (C) 2003 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 along 17 * with this program; see the file COPYING; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #ifndef OSPF6_ROUTE_H 22 #define OSPF6_ROUTE_H 23 24 #include "command.h" 25 #include "zclient.h" 26 27 #define OSPF6_MULTI_PATH_LIMIT 4 28 29 /* Debug option */ 30 extern unsigned char conf_debug_ospf6_route; 31 #define OSPF6_DEBUG_ROUTE_TABLE 0x01 32 #define OSPF6_DEBUG_ROUTE_INTRA 0x02 33 #define OSPF6_DEBUG_ROUTE_INTER 0x04 34 #define OSPF6_DEBUG_ROUTE_MEMORY 0x80 35 #define OSPF6_DEBUG_ROUTE_ON(level) (conf_debug_ospf6_route |= (level)) 36 #define OSPF6_DEBUG_ROUTE_OFF(level) (conf_debug_ospf6_route &= ~(level)) 37 #define IS_OSPF6_DEBUG_ROUTE(e) (conf_debug_ospf6_route & OSPF6_DEBUG_ROUTE_##e) 38 39 /* Nexthop */ 40 struct ospf6_nexthop { 41 /* Interface index */ 42 ifindex_t ifindex; 43 44 /* IP address, if any */ 45 struct in6_addr address; 46 }; 47 48 #define ospf6_nexthop_is_set(x) \ 49 ((x)->ifindex || !IN6_IS_ADDR_UNSPECIFIED(&(x)->address)) 50 #define ospf6_nexthop_is_same(a, b) \ 51 ((a)->ifindex == (b)->ifindex \ 52 && IN6_ARE_ADDR_EQUAL(&(a)->address, &(b)->address)) 53 #define ospf6_nexthop_clear(x) \ 54 do { \ 55 (x)->ifindex = 0; \ 56 memset(&(x)->address, 0, sizeof(struct in6_addr)); \ 57 } while (0) 58 #define ospf6_nexthop_copy(a, b) \ 59 do { \ 60 (a)->ifindex = (b)->ifindex; \ 61 memcpy(&(a)->address, &(b)->address, sizeof(struct in6_addr)); \ 62 } while (0) 63 64 /* Path */ 65 struct ospf6_ls_origin { 66 uint16_t type; 67 in_addr_t id; 68 in_addr_t adv_router; 69 }; 70 71 struct ospf6_path { 72 /* Link State Origin */ 73 struct ospf6_ls_origin origin; 74 75 /* Router bits */ 76 uint8_t router_bits; 77 78 /* Optional Capabilities */ 79 uint8_t options[3]; 80 81 /* Prefix Options */ 82 uint8_t prefix_options; 83 84 /* Associated Area */ 85 in_addr_t area_id; 86 87 /* Path-type */ 88 uint8_t type; 89 uint8_t subtype; /* only used for redistribute i.e ZEBRA_ROUTE_XXX */ 90 91 /* Cost */ 92 uint8_t metric_type; 93 uint32_t cost; 94 95 struct prefix ls_prefix; 96 97 union { 98 uint32_t cost_e2; 99 uint32_t cost_config; 100 } u; 101 uint32_t tag; 102 103 /* nh list for this path */ 104 struct list *nh_list; 105 }; 106 107 #define OSPF6_PATH_TYPE_NONE 0 108 #define OSPF6_PATH_TYPE_INTRA 1 109 #define OSPF6_PATH_TYPE_INTER 2 110 #define OSPF6_PATH_TYPE_EXTERNAL1 3 111 #define OSPF6_PATH_TYPE_EXTERNAL2 4 112 #define OSPF6_PATH_TYPE_REDISTRIBUTE 5 113 #define OSPF6_PATH_TYPE_MAX 6 114 115 #define OSPF6_PATH_SUBTYPE_DEFAULT_RT 1 116 117 #define OSPF6_PATH_COST_IS_CONFIGURED(path) (path.u.cost_config != OSPF_AREA_RANGE_COST_UNSPEC) 118 119 #include "prefix.h" 120 #include "table.h" 121 #include "bitfield.h" 122 123 struct ospf6_route { 124 struct route_node *rnode; 125 struct ospf6_route_table *table; 126 struct ospf6_route *prev; 127 struct ospf6_route *next; 128 129 unsigned int lock; 130 131 /* Destination Type */ 132 uint8_t type; 133 134 /* XXX: It would likely be better to use separate struct in_addr's 135 * for the advertising router-ID and prefix IDs, instead of stuffing 136 * them 137 * into one. See also XXX below. 138 */ 139 /* Destination ID */ 140 struct prefix prefix; 141 142 /* Time */ 143 struct timeval installed; 144 struct timeval changed; 145 146 /* flag */ 147 uint8_t flag; 148 149 /* route option */ 150 void *route_option; 151 152 /* link state id for advertising */ 153 uint32_t linkstate_id; 154 155 /* path */ 156 struct ospf6_path path; 157 158 /* List of Paths. */ 159 struct list *paths; 160 161 /* nexthop */ 162 struct list *nh_list; 163 }; 164 165 #define OSPF6_DEST_TYPE_NONE 0 166 #define OSPF6_DEST_TYPE_ROUTER 1 167 #define OSPF6_DEST_TYPE_NETWORK 2 168 #define OSPF6_DEST_TYPE_DISCARD 3 169 #define OSPF6_DEST_TYPE_LINKSTATE 4 170 #define OSPF6_DEST_TYPE_RANGE 5 171 #define OSPF6_DEST_TYPE_MAX 6 172 173 #define OSPF6_ROUTE_CHANGE 0x01 174 #define OSPF6_ROUTE_ADD 0x02 175 #define OSPF6_ROUTE_REMOVE 0x04 176 #define OSPF6_ROUTE_BEST 0x08 177 #define OSPF6_ROUTE_ACTIVE_SUMMARY 0x10 178 #define OSPF6_ROUTE_DO_NOT_ADVERTISE 0x20 179 #define OSPF6_ROUTE_WAS_REMOVED 0x40 180 #define OSPF6_ROUTE_BLACKHOLE_ADDED 0x80 181 182 struct ospf6_route_table { 183 int scope_type; 184 int table_type; 185 void *scope; 186 187 /* patricia tree */ 188 struct route_table *table; 189 190 uint32_t count; 191 192 bitfield_t idspace; 193 194 /* hooks */ 195 void (*hook_add)(struct ospf6_route *); 196 void (*hook_change)(struct ospf6_route *); 197 void (*hook_remove)(struct ospf6_route *); 198 }; 199 200 #define OSPF6_SCOPE_TYPE_NONE 0 201 #define OSPF6_SCOPE_TYPE_GLOBAL 1 202 #define OSPF6_SCOPE_TYPE_AREA 2 203 #define OSPF6_SCOPE_TYPE_INTERFACE 3 204 205 #define OSPF6_TABLE_TYPE_NONE 0 206 #define OSPF6_TABLE_TYPE_ROUTES 1 207 #define OSPF6_TABLE_TYPE_BORDER_ROUTERS 2 208 #define OSPF6_TABLE_TYPE_CONNECTED_ROUTES 3 209 #define OSPF6_TABLE_TYPE_EXTERNAL_ROUTES 4 210 #define OSPF6_TABLE_TYPE_SPF_RESULTS 5 211 #define OSPF6_TABLE_TYPE_PREFIX_RANGES 6 212 #define OSPF6_TABLE_TYPE_SUMMARY_PREFIXES 7 213 #define OSPF6_TABLE_TYPE_SUMMARY_ROUTERS 8 214 215 #define OSPF6_ROUTE_TABLE_CREATE(s, t) \ 216 ospf6_route_table_create(OSPF6_SCOPE_TYPE_##s, OSPF6_TABLE_TYPE_##t) 217 218 extern const char *const ospf6_dest_type_str[OSPF6_DEST_TYPE_MAX]; 219 extern const char *const ospf6_dest_type_substr[OSPF6_DEST_TYPE_MAX]; 220 #define OSPF6_DEST_TYPE_NAME(x) \ 221 (0 < (x) && (x) < OSPF6_DEST_TYPE_MAX ? ospf6_dest_type_str[(x)] \ 222 : ospf6_dest_type_str[0]) 223 #define OSPF6_DEST_TYPE_SUBSTR(x) \ 224 (0 < (x) && (x) < OSPF6_DEST_TYPE_MAX ? ospf6_dest_type_substr[(x)] \ 225 : ospf6_dest_type_substr[0]) 226 227 extern const char *const ospf6_path_type_str[OSPF6_PATH_TYPE_MAX]; 228 extern const char *const ospf6_path_type_substr[OSPF6_PATH_TYPE_MAX]; 229 #define OSPF6_PATH_TYPE_NAME(x) \ 230 (0 < (x) && (x) < OSPF6_PATH_TYPE_MAX ? ospf6_path_type_str[(x)] \ 231 : ospf6_path_type_str[0]) 232 #define OSPF6_PATH_TYPE_SUBSTR(x) \ 233 (0 < (x) && (x) < OSPF6_PATH_TYPE_MAX ? ospf6_path_type_substr[(x)] \ 234 : ospf6_path_type_substr[0]) 235 236 #define OSPF6_ROUTE_ADDRESS_STR "Display the route bestmatches the address\n" 237 #define OSPF6_ROUTE_PREFIX_STR "Display the route\n" 238 #define OSPF6_ROUTE_MATCH_STR "Display the route matches the prefix\n" 239 240 #define ospf6_route_is_prefix(p, r) \ 241 (memcmp(p, &(r)->prefix, sizeof(struct prefix)) == 0) 242 #define ospf6_route_is_same(ra, rb) (prefix_same(&(ra)->prefix, &(rb)->prefix)) 243 #define ospf6_route_is_same_origin(ra, rb) \ 244 ((ra)->path.area_id == (rb)->path.area_id \ 245 && memcmp(&(ra)->path.origin, &(rb)->path.origin, \ 246 sizeof(struct ospf6_ls_origin)) \ 247 == 0) 248 #define ospf6_route_is_identical(ra, rb) \ 249 ((ra)->type == (rb)->type \ 250 && memcmp(&(ra)->prefix, &(rb)->prefix, sizeof(struct prefix)) == 0 \ 251 && memcmp(&(ra)->path, &(rb)->path, sizeof(struct ospf6_path)) == 0 \ 252 && listcount(ra->paths) == listcount(rb->paths) \ 253 && ospf6_route_cmp_nexthops(ra, rb) == 0) 254 255 #define ospf6_route_is_best(r) (CHECK_FLAG ((r)->flag, OSPF6_ROUTE_BEST)) 256 257 #define ospf6_linkstate_prefix_adv_router(x) ((x)->u.lp.id.s_addr) 258 #define ospf6_linkstate_prefix_id(x) ((x)->u.lp.adv_router.s_addr) 259 260 #define ADV_ROUTER_IN_PREFIX(x) ((x)->u.lp.id.s_addr) 261 262 /* Function prototype */ 263 extern void ospf6_linkstate_prefix(uint32_t adv_router, uint32_t id, 264 struct prefix *prefix); 265 extern void ospf6_linkstate_prefix2str(struct prefix *prefix, char *buf, 266 int size); 267 268 extern struct ospf6_nexthop *ospf6_nexthop_create(void); 269 extern int ospf6_nexthop_cmp(struct ospf6_nexthop *a, struct ospf6_nexthop *b); 270 extern void ospf6_nexthop_delete(struct ospf6_nexthop *nh); 271 extern void ospf6_clear_nexthops(struct list *nh_list); 272 extern int ospf6_num_nexthops(struct list *nh_list); 273 extern void ospf6_copy_nexthops(struct list *dst, struct list *src); 274 extern void ospf6_merge_nexthops(struct list *dst, struct list *src); 275 extern void ospf6_add_nexthop(struct list *nh_list, int ifindex, 276 struct in6_addr *addr); 277 extern int ospf6_num_nexthops(struct list *nh_list); 278 extern int ospf6_route_cmp_nexthops(struct ospf6_route *a, 279 struct ospf6_route *b); 280 extern void ospf6_route_zebra_copy_nexthops(struct ospf6_route *route, 281 struct zapi_nexthop nexthops[], 282 int entries); 283 extern int ospf6_route_get_first_nh_index(struct ospf6_route *route); 284 285 /* Hide abstraction of nexthop implementation in route from outsiders */ 286 #define ospf6_route_copy_nexthops(dst, src) ospf6_copy_nexthops(dst->nh_list, src->nh_list) 287 #define ospf6_route_merge_nexthops(dst, src) ospf6_merge_nexthops(dst->nh_list, src->nh_list) 288 #define ospf6_route_num_nexthops(route) ospf6_num_nexthops(route->nh_list) 289 #define ospf6_route_add_nexthop(route, ifindex, addr) \ 290 ospf6_add_nexthop(route->nh_list, ifindex, addr) 291 292 extern struct ospf6_route *ospf6_route_create(void); 293 extern void ospf6_route_delete(struct ospf6_route *); 294 extern struct ospf6_route *ospf6_route_copy(struct ospf6_route *route); 295 extern int ospf6_route_cmp(struct ospf6_route *ra, struct ospf6_route *rb); 296 297 extern void ospf6_route_lock(struct ospf6_route *route); 298 extern void ospf6_route_unlock(struct ospf6_route *route); 299 300 extern struct ospf6_route *ospf6_route_lookup(struct prefix *prefix, 301 struct ospf6_route_table *table); 302 extern struct ospf6_route * 303 ospf6_route_lookup_identical(struct ospf6_route *route, 304 struct ospf6_route_table *table); 305 extern struct ospf6_route * 306 ospf6_route_lookup_bestmatch(struct prefix *prefix, 307 struct ospf6_route_table *table); 308 309 extern struct ospf6_route *ospf6_route_add(struct ospf6_route *route, 310 struct ospf6_route_table *table); 311 extern void ospf6_route_remove(struct ospf6_route *route, 312 struct ospf6_route_table *table); 313 314 extern struct ospf6_route *ospf6_route_head(struct ospf6_route_table *table); 315 extern struct ospf6_route *ospf6_route_next(struct ospf6_route *route); 316 extern struct ospf6_route *ospf6_route_best_next(struct ospf6_route *route); 317 318 extern struct ospf6_route * 319 ospf6_route_match_head(struct prefix *prefix, struct ospf6_route_table *table); 320 extern struct ospf6_route *ospf6_route_match_next(struct prefix *prefix, 321 struct ospf6_route *route); 322 323 extern void ospf6_route_remove_all(struct ospf6_route_table *); 324 extern struct ospf6_route_table *ospf6_route_table_create(int s, int t); 325 extern void ospf6_route_table_delete(struct ospf6_route_table *); 326 extern void ospf6_route_dump(struct ospf6_route_table *table); 327 328 329 extern void ospf6_route_show(struct vty *vty, struct ospf6_route *route); 330 extern void ospf6_route_show_detail(struct vty *vty, struct ospf6_route *route); 331 332 extern int ospf6_route_table_show(struct vty *, int, int, struct cmd_token **, 333 struct ospf6_route_table *); 334 extern int ospf6_linkstate_table_show(struct vty *vty, int idx_ipv4, int argc, 335 struct cmd_token **argv, 336 struct ospf6_route_table *table); 337 338 extern void ospf6_brouter_show_header(struct vty *vty); 339 extern void ospf6_brouter_show(struct vty *vty, struct ospf6_route *route); 340 341 extern int config_write_ospf6_debug_route(struct vty *vty); 342 extern void install_element_ospf6_debug_route(void); 343 extern void ospf6_route_init(void); 344 extern void ospf6_clean(void); 345 extern void ospf6_path_free(struct ospf6_path *op); 346 extern struct ospf6_path *ospf6_path_dup(struct ospf6_path *path); 347 extern void ospf6_copy_paths(struct list *dst, struct list *src); 348 349 #endif /* OSPF6_ROUTE_H */ 350