#include "lib/vty.h"
#include "lib/mpls.h"
#include "lib/if.h"
+#include "lib/table.h"
#include "ospfd/ospfd.h"
+#include "ospfd/ospf_route.h"
#include "ospfd/ospf_spf.h"
#include "ospfd/ospf_flood.h"
#include "ospfd/ospf_lsa.h"
#include "common.h"
-struct thread_master *master;
+struct event_master *master;
struct zebra_privs_t ospfd_privs;
return &topo2;
else if (strmatch(name, "topo3"))
return &topo3;
+ else if (strmatch(name, "topo4"))
+ return &topo4;
+ else if (strmatch(name, "topo5"))
+ return &topo5;
return NULL;
}
+int sort_paths(const void **path1, const void **path2)
+{
+ const struct ospf_path *p1 = *path1;
+ const struct ospf_path *p2 = *path2;
+
+ return (p1->nexthop.s_addr - p2->nexthop.s_addr);
+}
+
+void print_route_table(struct vty *vty, struct route_table *rt)
+{
+ struct route_node *rn;
+ struct ospf_route * or ;
+ struct listnode *pnode;
+ struct ospf_path *path;
+ struct mpls_label_stack *label_stack;
+ char buf[MPLS_LABEL_STRLEN];
+
+ for (rn = route_top(rt); rn; rn = route_next(rn)) {
+ if ((or = rn->info) == NULL)
+ continue;
+
+ vty_out(vty, "N %-18pFX %-15pI4 %d\n", &rn->p,
+ & or->u.std.area_id, or->cost);
+
+ list_sort(or->paths, sort_paths);
+
+ for (ALL_LIST_ELEMENTS_RO(or->paths, pnode, path)) {
+ if (path->nexthop.s_addr == 0)
+ continue;
+
+ vty_out(vty, " -> %pI4 with adv router %pI4",
+ &path->nexthop, &path->adv_router);
+
+ if (path->srni.backup_label_stack) {
+ label_stack = path->srni.backup_label_stack;
+ mpls_label2str(label_stack->num_labels,
+ label_stack->label, buf,
+ MPLS_LABEL_STRLEN,
+ ZEBRA_LSP_NONE, true);
+ vty_out(vty, " and backup path %s", buf);
+ }
+ vty_out(vty, "\n");
+ }
+ }
+}
+
struct ospf_test_node *test_find_node(struct ospf_topology *topology,
const char *hostname)
{
}
}
-static void inject_sr_db_entry(struct vty *vty, struct ospf_test_node *tnode)
+static void inject_sr_db_entry(struct vty *vty, struct ospf_test_node *tnode,
+ struct ospf_topology *topology)
{
+ struct ospf_test_node *tfound_adj_node;
+ struct ospf_test_adj *tadj;
struct in_addr router_id;
+ struct in_addr remote_id;
struct sr_node *srn;
struct sr_prefix *srp;
+ struct sr_link *srl;
+ int link_count;
inet_aton(tnode->router_id, &router_id);
srn->srgb.lower_bound = 16000;
srn->msd = 16;
- srp = XCALLOC(MTYPE_OSPF_SR_PARAMS, sizeof(struct sr_prefix));
+ srn->srlb.range_size = 1000;
+ srn->srlb.lower_bound = 15000;
+ /* Prefix SID */
+ srp = XCALLOC(MTYPE_OSPF_SR_PARAMS, sizeof(struct sr_prefix));
srp->adv_router = router_id;
srp->sid = tnode->label;
srp->srn = srn;
listnode_add(srn->ext_prefix, srp);
+
+ /* Adjacency SIDs for all adjacencies */
+ for (link_count = 0; tnode->adjacencies[link_count].hostname[0];
+ link_count++) {
+ tadj = &tnode->adjacencies[link_count];
+ tfound_adj_node = test_find_node(topology, tadj->hostname);
+
+ srl = XCALLOC(MTYPE_OSPF_SR_PARAMS, sizeof(struct sr_link));
+ srl->adv_router = router_id;
+
+ inet_aton(tfound_adj_node->router_id, &remote_id);
+ srl->remote_id = remote_id;
+
+ srl->type = ADJ_SID;
+ srl->sid[0] = srn->srlb.lower_bound + tadj->label;
+ srl->srn = srn;
+
+ listnode_add(srn->ext_link, srl);
+ }
}
int topology_load(struct vty *vty, struct ospf_topology *topology,
* SR information could also be inected via LSAs, but directly
* filling the SR DB with labels is just easier.
*/
- inject_sr_db_entry(vty, tnode);
+ inject_sr_db_entry(vty, tnode, topology);
}
return 0;