diff options
Diffstat (limited to 'ospf6d/ospf6_route.c')
| -rw-r--r-- | ospf6d/ospf6_route.c | 184 |
1 files changed, 110 insertions, 74 deletions
diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index 0a026785f4..a4ed99ea2d 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -37,6 +37,9 @@ #include "ospf6_interface.h" #include "ospf6d.h" #include "ospf6_zebra.h" +#ifndef VTYSH_EXTRACT_PL +#include "ospf6d/ospf6_route_clippy.c" +#endif DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_ROUTE, "OSPF6 route"); DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_ROUTE_TABLE, "OSPF6 route table"); @@ -284,12 +287,21 @@ void ospf6_add_nexthop(struct list *nh_list, int ifindex, struct in6_addr *addr) struct ospf6_nexthop nh_match; if (nh_list) { - nh_match.ifindex = ifindex; - if (addr != NULL) + if (addr) { + if (ifindex) + nh_match.type = NEXTHOP_TYPE_IPV6_IFINDEX; + else + nh_match.type = NEXTHOP_TYPE_IPV6; + memcpy(&nh_match.address, addr, sizeof(struct in6_addr)); - else + } else { + nh_match.type = NEXTHOP_TYPE_IFINDEX; + memset(&nh_match.address, 0, sizeof(struct in6_addr)); + } + + nh_match.ifindex = ifindex; if (!ospf6_route_find_nexthop(nh_list, &nh_match)) { nh = ospf6_nexthop_create(); @@ -299,36 +311,76 @@ void ospf6_add_nexthop(struct list *nh_list, int ifindex, struct in6_addr *addr) } } +void ospf6_add_route_nexthop_blackhole(struct ospf6_route *route) +{ + struct ospf6_nexthop *nh; + struct ospf6_nexthop nh_match = {}; + + /* List not allocated. */ + if (route->nh_list == NULL) + return; + + /* Entry already exists. */ + nh_match.type = NEXTHOP_TYPE_BLACKHOLE; + if (ospf6_route_find_nexthop(route->nh_list, &nh_match)) + return; + + nh = ospf6_nexthop_create(); + ospf6_nexthop_copy(nh, &nh_match); + listnode_add(route->nh_list, nh); +} + void ospf6_route_zebra_copy_nexthops(struct ospf6_route *route, struct zapi_nexthop nexthops[], int entries, vrf_id_t vrf_id) { struct ospf6_nexthop *nh; struct listnode *node; - char buf[64]; int i; if (route) { i = 0; for (ALL_LIST_ELEMENTS_RO(route->nh_list, node, nh)) { if (IS_OSPF6_DEBUG_ZEBRA(SEND)) { - const char *ifname; - inet_ntop(AF_INET6, &nh->address, buf, - sizeof(buf)); - ifname = ifindex2ifname(nh->ifindex, vrf_id); - zlog_debug(" nexthop: %s%%%.*s(%d)", buf, - IFNAMSIZ, ifname, nh->ifindex); + zlog_debug(" nexthop: %s %pI6%%%.*s(%d)", + nexthop_type_to_str(nh->type), + &nh->address, IFNAMSIZ, + ifindex2ifname(nh->ifindex, vrf_id), + nh->ifindex); } + if (i >= entries) return; nexthops[i].vrf_id = vrf_id; - nexthops[i].ifindex = nh->ifindex; - if (!IN6_IS_ADDR_UNSPECIFIED(&nh->address)) { + nexthops[i].type = nh->type; + + switch (nh->type) { + case NEXTHOP_TYPE_BLACKHOLE: + /* NOTHING */ + break; + + case NEXTHOP_TYPE_IFINDEX: + nexthops[i].ifindex = nh->ifindex; + break; + + case NEXTHOP_TYPE_IPV4_IFINDEX: + case NEXTHOP_TYPE_IPV4: + /* + * OSPFv3 with IPv4 routes is not supported + * yet. Skip this next hop. + */ + if (IS_OSPF6_DEBUG_ZEBRA(SEND)) + zlog_debug(" Skipping IPv4 next hop"); + continue; + + case NEXTHOP_TYPE_IPV6_IFINDEX: + nexthops[i].ifindex = nh->ifindex; + /* FALLTHROUGH */ + case NEXTHOP_TYPE_IPV6: nexthops[i].gate.ipv6 = nh->address; - nexthops[i].type = NEXTHOP_TYPE_IPV6_IFINDEX; - } else - nexthops[i].type = NEXTHOP_TYPE_IFINDEX; + break; + } i++; } } @@ -356,8 +408,6 @@ int ospf6_nexthop_cmp(struct ospf6_nexthop *a, struct ospf6_nexthop *b) else return memcmp(&a->address, &b->address, sizeof(struct in6_addr)); - - return 0; } static int ospf6_path_cmp(struct ospf6_path *a, struct ospf6_path *b) @@ -404,7 +454,7 @@ void ospf6_copy_paths(struct list *dst, struct list *src) } } -struct ospf6_route *ospf6_route_create(void) +struct ospf6_route *ospf6_route_create(struct ospf6 *ospf6) { struct ospf6_route *route; @@ -415,6 +465,8 @@ struct ospf6_route *ospf6_route_create(void) route->paths = list_new(); route->paths->cmp = (int (*)(void *, void *))ospf6_path_cmp; route->paths->del = (void (*)(void *))ospf6_path_free; + route->ospf6 = ospf6; + return route; } @@ -433,9 +485,10 @@ struct ospf6_route *ospf6_route_copy(struct ospf6_route *route) { struct ospf6_route *new; - new = ospf6_route_create(); + new = ospf6_route_create(route->ospf6); new->type = route->type; memcpy(&new->prefix, &route->prefix, sizeof(struct prefix)); + new->prefix_options = route->prefix_options; new->installed = route->installed; new->changed = route->changed; new->flag = route->flag; @@ -615,6 +668,9 @@ struct ospf6_route *ospf6_route_add(struct ospf6_route *route, if (route->type == OSPF6_DEST_TYPE_LINKSTATE) ospf6_linkstate_prefix2str(&route->prefix, buf, sizeof(buf)); + else if (route->type == OSPF6_DEST_TYPE_ROUTER) + inet_ntop(AF_INET, &ADV_ROUTER_IN_PREFIX(&route->prefix), buf, + sizeof(buf)); else prefix2str(&route->prefix, buf, sizeof(buf)); @@ -847,6 +903,9 @@ void ospf6_route_remove(struct ospf6_route *route, if (route->type == OSPF6_DEST_TYPE_LINKSTATE) ospf6_linkstate_prefix2str(&route->prefix, buf, sizeof(buf)); + else if (route->type == OSPF6_DEST_TYPE_ROUTER) + inet_ntop(AF_INET, &ADV_ROUTER_IN_PREFIX(&route->prefix), buf, + sizeof(buf)); else prefix2str(&route->prefix, buf, sizeof(buf)); @@ -1039,7 +1098,6 @@ struct ospf6_route_table *ospf6_route_table_create(int s, int t) void ospf6_route_table_delete(struct ospf6_route_table *table) { ospf6_route_remove_all(table); - bf_free(table->idspace); route_table_finish(table->table); XFREE(MTYPE_OSPF6_ROUTE_TABLE, table); } @@ -1059,11 +1117,6 @@ void ospf6_route_show(struct vty *vty, struct ospf6_route *route, json_object *json_array_next_hops = NULL; json_object *json_next_hop; - if (om6->ospf6 == NULL) { - vty_out(vty, "OSPFv3 is not running\n"); - return; - } - monotime(&now); timersub(&now, &route->changed, &res); timerstring(&res, duration, sizeof(duration)); @@ -1137,6 +1190,7 @@ void ospf6_route_show_detail(struct vty *vty, struct ospf6_route *route, { char destination[PREFIX2STR_BUFFER], nexthop[64]; char area_id[16], id[16], adv_router[16], capa[16], options[16]; + char pfx_options[16]; struct timeval now, res; char duration[64]; struct listnode *node; @@ -1146,11 +1200,6 @@ void ospf6_route_show_detail(struct vty *vty, struct ospf6_route *route, json_object *json_array_next_hops = NULL; json_object *json_next_hop; - if (om6->ospf6 == NULL) { - vty_out(vty, "OSPFv3 is not running\n"); - return; - } - monotime(&now); /* destination */ @@ -1264,10 +1313,13 @@ void ospf6_route_show_detail(struct vty *vty, struct ospf6_route *route, vty_out(vty, "Router Bits: %s\n", capa); /* Prefix Options */ + ospf6_prefix_options_printbuf(route->prefix_options, pfx_options, + sizeof(pfx_options)); if (use_json) - json_object_string_add(json_route, "prefixOptions", "xxx"); + json_object_string_add(json_route, "prefixOptions", + pfx_options); else - vty_out(vty, "Prefix Options: xxx\n"); + vty_out(vty, "Prefix Options: %s\n", pfx_options); /* Metrics */ if (use_json) { @@ -1775,49 +1827,27 @@ void ospf6_brouter_show(struct vty *vty, struct ospf6_route *route) OSPF6_PATH_TYPE_NAME(route->path.type), area); } -DEFUN (debug_ospf6_route, - debug_ospf6_route_cmd, - "debug ospf6 route <table|intra-area|inter-area|memory>", - DEBUG_STR - OSPF6_STR - "Debug routes\n" - "Debug route table calculation\n" - "Debug intra-area route calculation\n" - "Debug inter-area route calculation\n" - "Debug route memory use\n" - ) +DEFPY(debug_ospf6_route, + debug_ospf6_route_cmd, + "[no$no] debug ospf6 route <all|table|intra-area|inter-area|memory>", + NO_STR + DEBUG_STR + OSPF6_STR + "Debug routes\n" + "Debug for all types of route calculation\n" + "Debug route table calculation\n" + "Debug intra-area route calculation\n" + "Debug inter-area route calculation\n" + "Debug route memory use\n") { - int idx_type = 3; + int idx_type; unsigned char level = 0; - if (!strcmp(argv[idx_type]->text, "table")) - level = OSPF6_DEBUG_ROUTE_TABLE; - else if (!strcmp(argv[idx_type]->text, "intra-area")) - level = OSPF6_DEBUG_ROUTE_INTRA; - else if (!strcmp(argv[idx_type]->text, "inter-area")) - level = OSPF6_DEBUG_ROUTE_INTER; - else if (!strcmp(argv[idx_type]->text, "memory")) - level = OSPF6_DEBUG_ROUTE_MEMORY; - OSPF6_DEBUG_ROUTE_ON(level); - return CMD_SUCCESS; -} - -DEFUN (no_debug_ospf6_route, - no_debug_ospf6_route_cmd, - "no debug ospf6 route <table|intra-area|inter-area|memory>", - NO_STR - DEBUG_STR - OSPF6_STR - "Debug routes\n" - "Debug route table calculation\n" - "Debug intra-area route calculation\n" - "Debug inter-area route calculation\n" - "Debug route memory use\n") -{ - int idx_type = 4; - unsigned char level = 0; + idx_type = ((no) ? 4 : 3); - if (!strcmp(argv[idx_type]->text, "table")) + if (!strcmp(argv[idx_type]->text, "all")) + level = OSPF6_DEBUG_ROUTE_ALL; + else if (!strcmp(argv[idx_type]->text, "table")) level = OSPF6_DEBUG_ROUTE_TABLE; else if (!strcmp(argv[idx_type]->text, "intra-area")) level = OSPF6_DEBUG_ROUTE_INTRA; @@ -1825,12 +1855,20 @@ DEFUN (no_debug_ospf6_route, level = OSPF6_DEBUG_ROUTE_INTER; else if (!strcmp(argv[idx_type]->text, "memory")) level = OSPF6_DEBUG_ROUTE_MEMORY; - OSPF6_DEBUG_ROUTE_OFF(level); + + if (no) + OSPF6_DEBUG_ROUTE_OFF(level); + else + OSPF6_DEBUG_ROUTE_ON(level); return CMD_SUCCESS; } int config_write_ospf6_debug_route(struct vty *vty) { + if (IS_OSPF6_DEBUG_ROUTE(ALL) == OSPF6_DEBUG_ROUTE_ALL) { + vty_out(vty, "debug ospf6 route all\n"); + return 0; + } if (IS_OSPF6_DEBUG_ROUTE(TABLE)) vty_out(vty, "debug ospf6 route table\n"); if (IS_OSPF6_DEBUG_ROUTE(INTRA)) @@ -1846,7 +1884,5 @@ int config_write_ospf6_debug_route(struct vty *vty) void install_element_ospf6_debug_route(void) { install_element(ENABLE_NODE, &debug_ospf6_route_cmd); - install_element(ENABLE_NODE, &no_debug_ospf6_route_cmd); install_element(CONFIG_NODE, &debug_ospf6_route_cmd); - install_element(CONFIG_NODE, &no_debug_ospf6_route_cmd); } |
