diff options
Diffstat (limited to 'ospf6d/ospf6_area.c')
-rw-r--r-- | ospf6d/ospf6_area.c | 186 |
1 files changed, 160 insertions, 26 deletions
diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index 04cbb0a3..fc2103ca 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -48,29 +48,18 @@ ospf6_area_cmp (void *va, void *vb) { struct ospf6_area *oa = (struct ospf6_area *) va; struct ospf6_area *ob = (struct ospf6_area *) vb; - return (ntohl (oa->area_id) - ntohl (ob->area_id)); -} - -int -ospf6_area_is_stub (struct ospf6_area *o6a) -{ - if (OSPF6_OPT_ISSET (o6a->options, OSPF6_OPT_E)) - return 0; - return 1; + return (ntohl (oa->area_id) < ntohl (ob->area_id) ? -1 : 1); } /* schedule routing table recalculation */ void ospf6_area_lsdb_hook_add (struct ospf6_lsa *lsa) { - struct ospf6_area *oa; - - oa = (struct ospf6_area *) lsa->scope; switch (ntohs (lsa->header->type)) { case OSPF6_LSTYPE_ROUTER: case OSPF6_LSTYPE_NETWORK: - ospf6_spf_schedule (oa); + ospf6_spf_schedule (OSPF6_AREA (lsa->lsdb->data)); break; case OSPF6_LSTYPE_INTRA_PREFIX: @@ -83,7 +72,8 @@ ospf6_area_lsdb_hook_add (struct ospf6_lsa *lsa) default: if (IS_OSPF6_DEBUG_LSA (RECV)) - zlog_info ("Unknown LSA in Area %s's lsdb", oa->name); + zlog_info ("Unknown LSA in Area %s's lsdb", + OSPF6_AREA (lsa->lsdb->data)->name); break; } } @@ -91,14 +81,11 @@ ospf6_area_lsdb_hook_add (struct ospf6_lsa *lsa) void ospf6_area_lsdb_hook_remove (struct ospf6_lsa *lsa) { - struct ospf6_area *oa; - - oa = (struct ospf6_area *) lsa->scope; switch (ntohs (lsa->header->type)) { case OSPF6_LSTYPE_ROUTER: case OSPF6_LSTYPE_NETWORK: - ospf6_spf_schedule (oa); + ospf6_spf_schedule (OSPF6_AREA (lsa->lsdb->data)); break; case OSPF6_LSTYPE_INTRA_PREFIX: @@ -111,7 +98,8 @@ ospf6_area_lsdb_hook_remove (struct ospf6_lsa *lsa) default: if (IS_OSPF6_DEBUG_LSA (RECV)) - zlog_info ("Unknown LSA in Area %s's lsdb", oa->name); + zlog_info ("Unknown LSA in Area %s's lsdb", + OSPF6_AREA (lsa->lsdb->data)->name); break; } } @@ -146,17 +134,20 @@ ospf6_area_create (u_int32_t area_id, struct ospf6 *o) oa->area_id = area_id; oa->if_list = list_new (); - oa->summary_table = ospf6_route_table_create (); - - oa->lsdb = ospf6_lsdb_create (); + oa->lsdb = ospf6_lsdb_create (oa); oa->lsdb->hook_add = ospf6_area_lsdb_hook_add; oa->lsdb->hook_remove = ospf6_area_lsdb_hook_remove; + oa->lsdb_self = ospf6_lsdb_create (oa); oa->spf_table = ospf6_route_table_create (); oa->route_table = ospf6_route_table_create (); oa->route_table->hook_add = ospf6_area_route_hook_add; oa->route_table->hook_remove = ospf6_area_route_hook_remove; + oa->range_table = ospf6_route_table_create (); + oa->summary_prefix = ospf6_route_table_create (); + oa->summary_router = ospf6_route_table_create (); + /* set default options */ OSPF6_OPT_SET (oa->options, OSPF6_OPT_V6); OSPF6_OPT_SET (oa->options, OSPF6_OPT_E); @@ -168,7 +159,7 @@ ospf6_area_create (u_int32_t area_id, struct ospf6 *o) /* import athoer area's routes as inter-area routes */ for (route = ospf6_route_head (o->route_table); route; route = ospf6_route_next (route)) - ospf6_abr_originate_prefix_to_area (route, oa); + ospf6_abr_originate_summary_to_area (route, oa); return oa; } @@ -179,7 +170,9 @@ ospf6_area_delete (struct ospf6_area *oa) listnode n; struct ospf6_interface *oi; - ospf6_route_table_delete (oa->summary_table); + ospf6_route_table_delete (oa->range_table); + ospf6_route_table_delete (oa->summary_prefix); + ospf6_route_table_delete (oa->summary_router); /* ospf6 interface list */ for (n = listhead (oa->if_list); n; nextnode (n)) @@ -190,6 +183,8 @@ ospf6_area_delete (struct ospf6_area *oa) list_delete (oa->if_list); ospf6_lsdb_delete (oa->lsdb); + ospf6_lsdb_delete (oa->lsdb_self); + ospf6_route_table_delete (oa->spf_table); ospf6_route_table_delete (oa->route_table); @@ -224,13 +219,23 @@ ospf6_area_lookup (u_int32_t area_id, struct ospf6 *ospf6) return (struct ospf6_area *) NULL; } +struct ospf6_area * +ospf6_area_get (u_int32_t area_id, struct ospf6 *o) +{ + struct ospf6_area *oa; + oa = ospf6_area_lookup (area_id, o); + if (oa == NULL) + oa = ospf6_area_create (area_id, o); + return oa; +} + void ospf6_area_enable (struct ospf6_area *oa) { listnode i; struct ospf6_interface *oi; - UNSET_FLAG (oa->flag, OSPF6_AREA_DISABLE); + SET_FLAG (oa->flag, OSPF6_AREA_ENABLE); for (i = listhead (oa->if_list); i; nextnode (i)) { @@ -245,7 +250,7 @@ ospf6_area_disable (struct ospf6_area *oa) listnode i; struct ospf6_interface *oi; - SET_FLAG (oa->flag, OSPF6_AREA_DISABLE); + UNSET_FLAG (oa->flag, OSPF6_AREA_ENABLE); for (i = listhead (oa->if_list); i; nextnode (i)) { @@ -291,6 +296,130 @@ ospf6_area_show (struct vty *vty, struct ospf6_area *oa) } \ } +#define OSPF6_CMD_AREA_GET(str, oa) \ +{ \ + u_int32_t area_id = 0; \ + if (inet_pton (AF_INET, str, &area_id) != 1) \ + { \ + vty_out (vty, "Malformed Area-ID: %s%s", str, VNL); \ + return CMD_SUCCESS; \ + } \ + oa = ospf6_area_get (area_id, ospf6); \ +} + +DEFUN (area_range, + area_range_cmd, + "area A.B.C.D range X:X::X:X/M", + "OSPF area parameters\n" + OSPF6_AREA_ID_STR + "Configured address range\n" + "Specify IPv6 prefix\n" + ) +{ + int ret; + struct ospf6_area *oa; + struct prefix prefix; + struct ospf6_route *range; + + OSPF6_CMD_AREA_GET (argv[0], oa); + argc--; + argv++; + + ret = str2prefix (argv[0], &prefix); + if (ret != 1 || prefix.family != AF_INET6) + { + vty_out (vty, "Malformed argument: %s%s", argv[0], VNL); + return CMD_SUCCESS; + } + argc--; + argv++; + + range = ospf6_route_lookup (&prefix, oa->range_table); + if (range == NULL) + { + range = ospf6_route_create (); + range->type = OSPF6_DEST_TYPE_RANGE; + range->prefix = prefix; + } + + if (argc) + { + if (! strcmp (argv[0], "not-advertise")) + SET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE); + else if (! strcmp (argv[0], "advertise")) + UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE); + } + + ospf6_route_add (range, oa->range_table); + return CMD_SUCCESS; +} + +ALIAS (area_range, + area_range_advertise_cmd, + "area A.B.C.D range X:X::X:X/M (advertise|not-advertise)", + "OSPF area parameters\n" + OSPF6_AREA_ID_STR + "Configured address range\n" + "Specify IPv6 prefix\n" + ); + +DEFUN (no_area_range, + no_area_range_cmd, + "no area A.B.C.D range X:X::X:X/M", + "OSPF area parameters\n" + OSPF6_AREA_ID_STR + "Configured address range\n" + "Specify IPv6 prefix\n" + ) +{ + int ret; + struct ospf6_area *oa; + struct prefix prefix; + struct ospf6_route *range; + + OSPF6_CMD_AREA_GET (argv[0], oa); + argc--; + argv++; + + ret = str2prefix (argv[0], &prefix); + if (ret != 1 || prefix.family != AF_INET6) + { + vty_out (vty, "Malformed argument: %s%s", argv[0], VNL); + return CMD_SUCCESS; + } + + range = ospf6_route_lookup (&prefix, oa->range_table); + if (range == NULL) + { + vty_out (vty, "Range %s does not exists.%s", argv[0], VNL); + return CMD_SUCCESS; + } + + ospf6_route_remove (range, oa->range_table); + return CMD_SUCCESS; +} + +void +ospf6_area_config_write (struct vty *vty) +{ + listnode node; + struct ospf6_area *oa; + struct ospf6_route *range; + char buf[128]; + + for (node = listhead (ospf6->area_list); node; nextnode (node)) + { + oa = OSPF6_AREA (getdata (node)); + + for (range = ospf6_route_head (oa->range_table); range; + range = ospf6_route_next (range)) + { + prefix2str (&range->prefix, buf, sizeof (buf)); + vty_out (vty, " area %s range %s%s", oa->name, buf, VNL); + } + } +} + DEFUN (show_ipv6_ospf6_area_route_intra, show_ipv6_ospf6_area_route_intra_cmd, "show ipv6 ospf6 area A.B.C.D route intra-area", @@ -876,5 +1005,10 @@ ospf6_area_init () install_element (ENABLE_NODE, &show_ipv6_ospf6_area_route_intra_match_detail_cmd); install_element (ENABLE_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd); + + install_element (OSPF6_NODE, &area_range_cmd); + install_element (OSPF6_NODE, &area_range_advertise_cmd); + install_element (OSPF6_NODE, &no_area_range_cmd); } + |