diff options
Diffstat (limited to 'ospfd/ospf_route.c')
| -rw-r--r-- | ospfd/ospf_route.c | 83 |
1 files changed, 51 insertions, 32 deletions
diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c index 590122e223..7cfcaf14be 100644 --- a/ospfd/ospf_route.c +++ b/ospfd/ospf_route.c @@ -71,15 +71,31 @@ struct ospf_path *ospf_path_new(void) static struct ospf_path *ospf_path_dup(struct ospf_path *path) { struct ospf_path *new; + int memsize; new = ospf_path_new(); memcpy(new, path, sizeof(struct ospf_path)); + /* optional TI-LFA backup paths */ + if (path->srni.backup_label_stack) { + memsize = sizeof(struct mpls_label_stack) + + (sizeof(mpls_label_t) + * path->srni.backup_label_stack->num_labels); + new->srni.backup_label_stack = + XCALLOC(MTYPE_OSPF_PATH, memsize); + memcpy(new->srni.backup_label_stack, + path->srni.backup_label_stack, memsize); + } + return new; } void ospf_path_free(struct ospf_path *op) { + /* optional TI-LFA backup paths */ + if (op->srni.backup_label_stack) + XFREE(MTYPE_OSPF_PATH, op->srni.backup_label_stack); + XFREE(MTYPE_OSPF_PATH, op); } @@ -140,6 +156,35 @@ static int ospf_route_exist_new_table(struct route_table *rt, return 1; } +static int ospf_route_backup_path_same(struct sr_nexthop_info *srni1, + struct sr_nexthop_info *srni2) +{ + struct mpls_label_stack *ls1, *ls2; + uint8_t label_count; + + ls1 = srni1->backup_label_stack; + ls2 = srni2->backup_label_stack; + + if (!ls1 && !ls2) + return 1; + + if ((ls1 && !ls2) || (!ls1 && ls2)) + return 0; + + if (ls1->num_labels != ls2->num_labels) + return 0; + + for (label_count = 0; label_count < ls1->num_labels; label_count++) { + if (ls1->label[label_count] != ls2->label[label_count]) + return 0; + } + + if (!IPV4_ADDR_SAME(&srni1->backup_nexthop, &srni2->backup_nexthop)) + return 0; + + return 1; +} + /* If a prefix and a nexthop match any route in the routing table, then return 1, otherwise return 0. */ int ospf_route_match_same(struct route_table *rt, struct prefix_ipv4 *prefix, @@ -180,6 +225,11 @@ int ospf_route_match_same(struct route_table *rt, struct prefix_ipv4 *prefix, return 0; if (op->ifindex != newop->ifindex) return 0; + + /* check TI-LFA backup paths */ + if (!ospf_route_backup_path_same(&op->srni, + &newop->srni)) + return 0; } return 1; } else if (prefix_same(&rn->p, (struct prefix *)prefix)) @@ -664,38 +714,6 @@ void ospf_route_table_dump(struct route_table *rt) zlog_debug("========================================"); } -void ospf_route_table_print(struct vty *vty, struct route_table *rt) -{ - struct route_node *rn; - struct ospf_route * or ; - struct listnode *pnode; - struct ospf_path *path; - - vty_out(vty, "========== OSPF routing table ==========\n"); - for (rn = route_top(rt); rn; rn = route_next(rn)) - if ((or = rn->info) != NULL) { - if (or->type == OSPF_DESTINATION_NETWORK) { - vty_out(vty, "N %-18pFX %-15pI4 %s %d\n", - &rn->p, & or->u.std.area_id, - ospf_path_type_str[or->path_type], - or->cost); - for (ALL_LIST_ELEMENTS_RO(or->paths, pnode, - path)) - if (path->nexthop.s_addr != INADDR_ANY) - vty_out(vty, " -> %pI4\n", - &path->nexthop); - else - vty_out(vty, " -> %s\n", - "directly connected"); - } else - vty_out(vty, "R %-18pI4 %-15pI4 %s %d\n", - &rn->p.u.prefix4, & or->u.std.area_id, - ospf_path_type_str[or->path_type], - or->cost); - } - vty_out(vty, "========================================\n"); -} - /* This is 16.4.1 implementation. o Intra-area paths using non-backbone areas are always the most preferred. o The other paths, intra-area backbone paths and inter-area paths, @@ -802,6 +820,7 @@ void ospf_route_copy_nexthops_from_vertex(struct ospf_area *area, || area->spf_dry_run) { path = ospf_path_new(); path->nexthop = nexthop->router; + path->adv_router = v->id; if (oi) { path->ifindex = oi->ifp->ifindex; |
