diff options
Diffstat (limited to 'ospf6d/ospf6_route.c')
-rw-r--r-- | ospf6d/ospf6_route.c | 485 |
1 files changed, 271 insertions, 214 deletions
diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index 3ca21a31..b054c7b4 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -51,25 +51,29 @@ void ospf6_linkstate_prefix2str (struct prefix *prefix, char *buf, int size) { u_int32_t adv_router, id; - char adv_router_str[16]; + char adv_router_str[16], id_str[16]; memcpy (&adv_router, &prefix->u.prefix6.s6_addr[0], 4); memcpy (&id, &prefix->u.prefix6.s6_addr[4], 4); inet_ntop (AF_INET, &adv_router, adv_router_str, sizeof (adv_router_str)); - snprintf (buf, size, "%s(%lu)", adv_router_str, (u_long) ntohl (id)); + inet_ntop (AF_INET, &id, id_str, sizeof (id_str)); + if (ntohl (id)) + snprintf (buf, size, "%s Net-ID: %s", adv_router_str, id_str); + else + snprintf (buf, size, "%s", adv_router_str); } /* Global strings for logging */ char *ospf6_dest_type_str[OSPF6_DEST_TYPE_MAX] = -{ "Unknown", "Router", "Network", "Discard", "Linkstate", }; +{ "Unknown", "Router", "Network", "Discard", "Linkstate", "AddressRange", }; char *ospf6_dest_type_substr[OSPF6_DEST_TYPE_MAX] = -{ "?", "R", "N", "D", "L", }; +{ "?", "R", "N", "D", "L", "A", }; char *ospf6_path_type_str[OSPF6_PATH_TYPE_MAX] = { "Unknown", "Intra-Area", "Inter-Area", "External-1", "External-2", }; char *ospf6_path_type_substr[OSPF6_PATH_TYPE_MAX] = -{ "??", "Ia", "Ie", "E1", "E2", }; +{ "??", "IA", "IE", "E1", "E2", }; struct ospf6_route * @@ -763,8 +767,7 @@ ospf6_route_show_table_summary (struct vty *vty, int i, pathtype[OSPF6_PATH_TYPE_MAX]; int number = 0; int nhinval = 0, ecmp = 0; - int multipath = 0, destination = 0; - int desttype = 0, desttype_mismatch = 0; + int alternative = 0, destination = 0; for (i = 0; i < OSPF6_PATH_TYPE_MAX; i++) pathtype[i] = 0; @@ -772,48 +775,131 @@ ospf6_route_show_table_summary (struct vty *vty, for (route = ospf6_route_head (table); route; route = ospf6_route_next (route)) { - if (desttype == 0) - desttype = route->type; - else if (desttype != route->type) - desttype_mismatch++; - if (prev == NULL || ! ospf6_route_is_same (prev, route)) destination++; else - multipath++; - + alternative++; if (! ospf6_nexthop_is_set (&route->nexthop[0])) nhinval++; else if (ospf6_nexthop_is_set (&route->nexthop[1])) ecmp++; - - if (prev == NULL || ! ospf6_route_is_same (prev, route)) - pathtype[route->path.type]++; - + pathtype[route->path.type]++; number++; + prev = route; } assert (number == table->count); - vty_out (vty, "Number of Destination: %d (%d routes)%s", - destination, number, VNL); - if (multipath) - vty_out (vty, " Number of Multi-path: %d%s", multipath, VNL); - if (desttype_mismatch) - vty_out (vty, " Number of Different Dest-type: %d%s", - desttype_mismatch, VNL); - if (ecmp) - vty_out (vty, " Number of Equal Cost Multi Path: %d%s", - ecmp, VNL); - if (ecmp) - vty_out (vty, " Number of Invalid Nexthop: %d%s", - nhinval, VNL); - for (i = 0; i < OSPF6_PATH_TYPE_MAX; i++) + vty_out (vty, "Number of OSPFv3 routes: %d%s", number, VNL); + vty_out (vty, "Number of Destination: %d%s", destination, VNL); + vty_out (vty, "Number of Alternative routes: %d%s", alternative, VNL); + vty_out (vty, "Number of Equal Cost Multi Path: %d%s", ecmp, VNL); + for (i = OSPF6_PATH_TYPE_INTRA; i <= OSPF6_PATH_TYPE_EXTERNAL2; i++) + { + vty_out (vty, "Number of %s routes: %d%s", + OSPF6_PATH_TYPE_NAME (i), pathtype[i], VNL); + } +} + +void +ospf6_route_show_table_prefix (struct vty *vty, + struct prefix *prefix, + struct ospf6_route_table *table) +{ + struct ospf6_route *route; + + route = ospf6_route_lookup (prefix, table); + if (route == NULL) + return; + + ospf6_route_lock (route); + while (route && ospf6_route_is_prefix (prefix, route)) + { + /* Specifying a prefix will always display details */ + ospf6_route_show_detail (vty, route); + route = ospf6_route_next (route); + } + if (route) + ospf6_route_unlock (route); +} + +void +ospf6_route_show_table_address (struct vty *vty, + struct prefix *prefix, + struct ospf6_route_table *table) +{ + struct ospf6_route *route; + + route = ospf6_route_lookup_bestmatch (prefix, table); + if (route == NULL) + return; + + prefix = &route->prefix; + ospf6_route_lock (route); + while (route && ospf6_route_is_prefix (prefix, route)) + { + /* Specifying a prefix will always display details */ + ospf6_route_show_detail (vty, route); + route = ospf6_route_next (route); + } + if (route) + ospf6_route_unlock (route); +} + +void +ospf6_route_show_table_match (struct vty *vty, int detail, + struct prefix *prefix, + struct ospf6_route_table *table) +{ + struct ospf6_route *route; + assert (prefix->family); + + route = ospf6_route_match_head (prefix, table); + while (route) + { + if (detail) + ospf6_route_show_detail (vty, route); + else + ospf6_route_show (vty, route); + route = ospf6_route_match_next (prefix, route); + } +} + +void +ospf6_route_show_table_type (struct vty *vty, int detail, u_char type, + struct ospf6_route_table *table) +{ + struct ospf6_route *route; + + route = ospf6_route_head (table); + while (route) + { + if (route->path.type == type) + { + if (detail) + ospf6_route_show_detail (vty, route); + else + ospf6_route_show (vty, route); + } + route = ospf6_route_next (route); + } +} + +void +ospf6_route_show_table (struct vty *vty, int detail, + struct ospf6_route_table *table) +{ + struct ospf6_route *route; + + route = ospf6_route_head (table); + while (route) { - if (pathtype[i]) - vty_out (vty, " Number of %s routes: %d%s", - OSPF6_PATH_TYPE_NAME (i), pathtype[i], VNL); + if (detail) + ospf6_route_show_detail (vty, route); + else + ospf6_route_show (vty, route); + route = ospf6_route_next (route); } } @@ -821,269 +907,240 @@ int ospf6_route_table_show (struct vty *vty, int argc, char **argv, struct ospf6_route_table *table) { - unsigned char flag = 0; -#define MATCH 0x01 -#define DETAIL 0x02 -#define PREFIX 0x04 -#define SUMMARY 0x08 + int summary = 0; + int match = 0; + int detail = 0; + int slash = 0; + int isprefix = 0; int i, ret; - struct prefix prefix, *p; - struct ospf6_route *route; + struct prefix prefix; + u_char type = 0; memset (&prefix, 0, sizeof (struct prefix)); for (i = 0; i < argc; i++) { - /* set "detail" */ if (! strcmp (argv[i], "summary")) { - SET_FLAG (flag, SUMMARY); + summary++; continue; } - /* set "detail" */ - if (! strcmp (argv[i], "detail")) + if (! strcmp (argv[i], "intra-area")) { - SET_FLAG (flag, DETAIL); + type = OSPF6_PATH_TYPE_INTRA; continue; } - /* set "match" */ - if (! strcmp (argv[i], "match")) + if (! strcmp (argv[i], "inter-area")) { - SET_FLAG (flag, MATCH); + type = OSPF6_PATH_TYPE_INTER; continue; } - if (prefix.family) + if (! strcmp (argv[i], "external-1")) { - vty_out (vty, "Invalid argument: %s%s", argv[i], VNL); - return CMD_SUCCESS; + type = OSPF6_PATH_TYPE_EXTERNAL1; + continue; + } + + if (! strcmp (argv[i], "external-2")) + { + type = OSPF6_PATH_TYPE_EXTERNAL2; + continue; + } + + if (! strcmp (argv[i], "detail")) + { + detail++; + continue; + } + + if (! strcmp (argv[i], "match")) + { + match++; + continue; } ret = str2prefix (argv[i], &prefix); - if (ret != 1 || prefix.family != AF_INET6) + if (ret == 1 && prefix.family == AF_INET6) { - vty_out (vty, "Malformed argument: %s%s", argv[i], VNL); - return CMD_SUCCESS; + isprefix++; + if (strchr (argv[i], '/')) + slash++; + continue; } - if (strchr (argv[i], '/')) - SET_FLAG (flag, PREFIX); + vty_out (vty, "Malformed argument: %s%s", argv[i], VNL); + return CMD_SUCCESS; } /* Give summary of this route table */ - if (CHECK_FLAG (flag, SUMMARY)) + if (summary) { ospf6_route_show_table_summary (vty, table); return CMD_SUCCESS; } /* Give exact prefix-match route */ - if (prefix.family && ! CHECK_FLAG (flag, MATCH)) + if (isprefix && ! match) { /* If exact address, give best matching route */ - if (! CHECK_FLAG (flag, PREFIX)) - route = ospf6_route_lookup_bestmatch (&prefix, table); + if (! slash) + ospf6_route_show_table_address (vty, &prefix, table); else - route = ospf6_route_lookup (&prefix, table); + ospf6_route_show_table_prefix (vty, &prefix, table); - if (route) - { - ospf6_route_lock (route); - p = &route->prefix; - } + return CMD_SUCCESS; + } - while (route && ospf6_route_is_prefix (p, route)) - { - /* Seaching an entry will always display details */ - if (route) - ospf6_route_show_detail (vty, route); + if (match) + ospf6_route_show_table_match (vty, detail, &prefix, table); + else if (type) + ospf6_route_show_table_type (vty, detail, type, table); + else + ospf6_route_show_table (vty, detail, table); - route = ospf6_route_next (route); - } + return CMD_SUCCESS; +} - return CMD_SUCCESS; - } +void +ospf6_linkstate_show_header (struct vty *vty) +{ + vty_out (vty, "%-7s %-15s %-15s %-8s %-14s %s%s", + "Type", "Router-ID", "Net-ID", "Rtr-Bits", "Options", "Cost", VNL); +} + +void +ospf6_linkstate_show (struct vty *vty, struct ospf6_route *route) +{ + u_int32_t router, id; + char routername[16], idname[16], rbits[16], options[16]; + + router = ospf6_linkstate_prefix_adv_router (&route->prefix); + inet_ntop (AF_INET, &router, routername, sizeof (routername)); + id = ospf6_linkstate_prefix_id (&route->prefix); + inet_ntop (AF_INET, &id, idname, sizeof (idname)); + + ospf6_capability_printbuf (route->path.router_bits, rbits, sizeof (rbits)); + ospf6_options_printbuf (route->path.options, options, sizeof (options)); - if (prefix.family == 0) - route = ospf6_route_head (table); + if (ntohl (id)) + vty_out (vty, "%-7s %-15s %-15s %-8s %-14s %lu%s", + "Network", routername, idname, rbits, options, + (unsigned long) route->path.cost, VNL); else - route = ospf6_route_match_head (&prefix, table); + vty_out (vty, "%-7s %-15s %-15s %-8s %-14s %lu%s", + "Router", routername, idname, rbits, options, + (unsigned long) route->path.cost, VNL); +} + + +void +ospf6_linkstate_show_table_exact (struct vty *vty, + struct prefix *prefix, + struct ospf6_route_table *table) +{ + struct ospf6_route *route; + + route = ospf6_route_lookup (prefix, table); + if (route == NULL) + return; + + ospf6_route_lock (route); + while (route && ospf6_route_is_prefix (prefix, route)) + { + /* Specifying a prefix will always display details */ + ospf6_route_show_detail (vty, route); + route = ospf6_route_next (route); + } + if (route) + ospf6_route_unlock (route); +} + +void +ospf6_linkstate_show_table (struct vty *vty, int detail, + struct ospf6_route_table *table) +{ + struct ospf6_route *route; + + if (! detail) + ospf6_linkstate_show_header (vty); + route = ospf6_route_head (table); while (route) { - if (CHECK_FLAG (flag, DETAIL)) + if (detail) ospf6_route_show_detail (vty, route); else - ospf6_route_show (vty, route); - - if (prefix.family == 0) - route = ospf6_route_next (route); - else - route = ospf6_route_match_next (&prefix, route); + ospf6_linkstate_show (vty, route); + route = ospf6_route_next (route); } - - return CMD_SUCCESS; } - int -ospf6_lsentry_table_show (struct vty *vty, int argc, char **argv, - struct ospf6_route_table *table) +ospf6_linkstate_table_show (struct vty *vty, int argc, char **argv, + struct ospf6_route_table *table) { - unsigned char flag = 0; -#define MATCH 0x01 -#define DETAIL 0x02 + int detail = 0; + int is_id = 0; + int is_router = 0; int i, ret; - struct prefix adv_router, id, prefix; - struct ospf6_route *route; + struct prefix router, id, prefix; - memset (&adv_router, 0, sizeof (struct prefix)); + memset (&router, 0, sizeof (struct prefix)); memset (&id, 0, sizeof (struct prefix)); + memset (&prefix, 0, sizeof (struct prefix)); for (i = 0; i < argc; i++) { - /* set "detail" */ if (! strcmp (argv[i], "detail")) { - SET_FLAG (flag, DETAIL); + detail++; continue; } - /* set "match" */ - if (! strcmp (argv[i], "match")) + if (! is_router) { - SET_FLAG (flag, MATCH); - continue; - } - - if (adv_router.family && id.family) - { - vty_out (vty, "Invalid argument: %s%s", argv[i], VNL); - return CMD_SUCCESS; - } - - if (adv_router.family == 0) - { - ret = str2prefix (argv[i], &adv_router); - if (ret != 1) - { - if (! strcmp (argv[i], "*")) - { - adv_router.family = AF_INET; - adv_router.prefixlen = 0; - ret = 1; - } - } - if (ret != 1) + ret = str2prefix (argv[i], &router); + if (ret == 1 && router.family == AF_INET) { - vty_out (vty, "Invalid Router-ID: %s%s", argv[i], VNL); - return CMD_SUCCESS; + is_router++; + continue; } + vty_out (vty, "Malformed argument: %s%s", argv[i], VNL); + return CMD_SUCCESS; } - else if (id.family == 0) - { - unsigned long val; - char *endptr; + if (! is_id) + { ret = str2prefix (argv[i], &id); - if (ret != 1) - { - val = strtoul (argv[i], &endptr, 0); - if (val != ULONG_MAX && *endptr == '\0') - { - id.u.prefix4.s_addr = val; - ret = 1; - } - } - - if (ret != 1) + if (ret == 1 && id.family == AF_INET) { - vty_out (vty, "Invalid Link state ID: %s%s", argv[i], - VNL); - return CMD_WARNING; + is_id++; + continue; } - } - } - - /* Encode to linkstate prefix */ - if (adv_router.family) - { - if (adv_router.prefixlen == 0 && - id.family && id.prefixlen != IPV4_MAX_BITLEN) - { - vty_out (vty, "Specifying Link State ID by prefix is not allowed%s" - "when specifying Router-ID as wildcard%s", - VNL, VNL); - return CMD_SUCCESS; - } - else if (adv_router.prefixlen != 0 && - adv_router.prefixlen != IPV4_MAX_BITLEN && id.family) - { - vty_out (vty, "Specifying Link State ID is not allowed%s" - "when specifying Router-ID by prefix%s", - VNL, VNL); + vty_out (vty, "Malformed argument: %s%s", argv[i], VNL); return CMD_SUCCESS; } - if (adv_router.prefixlen == 0) - ospf6_linkstate_prefix (0, id.u.prefix4.s_addr, &prefix); - else if (adv_router.prefixlen != IPV4_MAX_BITLEN) - { - ospf6_linkstate_prefix (adv_router.u.prefix4.s_addr, 0, &prefix); - prefix.prefixlen = adv_router.prefixlen; - SET_FLAG (flag, MATCH); - } - else - { - ospf6_linkstate_prefix (adv_router.u.prefix4.s_addr, - id.u.prefix4.s_addr, &prefix); - prefix.prefixlen = adv_router.prefixlen + id.prefixlen; - if (prefix.prefixlen != 64) - SET_FLAG (flag, MATCH); - } - } - - /* give exact match entry */ - if (adv_router.family && adv_router.prefixlen == IPV4_MAX_BITLEN && - id.family && id.prefixlen == IPV4_MAX_BITLEN) - { - route = ospf6_route_lookup (&prefix, table); - if (route) - ospf6_route_show_detail (vty, route); + vty_out (vty, "Malformed argument: %s%s", argv[i], VNL); return CMD_SUCCESS; } - if (CHECK_FLAG (flag, MATCH)) - route = ospf6_route_match_head (&prefix, table); - else - route = ospf6_route_head (table); + if (is_router) + ospf6_linkstate_prefix (router.u.prefix4.s_addr, + id.u.prefix4.s_addr, &prefix); - while (route) - { - if (! adv_router.family || - (CHECK_FLAG (flag, MATCH) && - prefix_match (&prefix, &route->prefix)) || - (adv_router.prefixlen == 0 && id.family && - ospf6_linkstate_prefix_id (&prefix) == - ospf6_linkstate_prefix_id (&route->prefix))) - { - if (CHECK_FLAG (flag, DETAIL)) - ospf6_route_show_detail (vty, route); - else - ospf6_route_show (vty, route); - } - - if (CHECK_FLAG (flag, MATCH)) - route = ospf6_route_match_next (&prefix, route); - else - route = ospf6_route_next (route); - } + if (prefix.family) + ospf6_linkstate_show_table_exact (vty, &prefix, table); + else + ospf6_linkstate_show_table (vty, detail, table); return CMD_SUCCESS; } + void ospf6_brouter_show_header (struct vty *vty) { |