diff options
Diffstat (limited to 'ospf6d/ospf6_route.c')
| -rw-r--r-- | ospf6d/ospf6_route.c | 94 |
1 files changed, 75 insertions, 19 deletions
diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index 0a026785f4..cd3139d28a 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -284,12 +284,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 +308,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++; } } @@ -404,7 +453,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 +464,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 +484,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; @@ -1137,6 +1189,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; @@ -1264,10 +1317,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) { |
