3 #include "lib/stream.h"
9 #include "ospfd/ospfd.h"
10 #include "ospfd/ospf_route.h"
11 #include "ospfd/ospf_spf.h"
12 #include "ospfd/ospf_flood.h"
13 #include "ospfd/ospf_lsa.h"
14 #include "ospfd/ospf_lsdb.h"
15 #include "ospfd/ospf_interface.h"
16 #include "ospfd/ospf_sr.h"
20 struct thread_master
*master
;
21 struct zebra_privs_t ospfd_privs
;
24 struct ospf_topology
*test_find_topology(const char *name
)
26 if (strmatch(name
, "topo1"))
28 else if (strmatch(name
, "topo2"))
30 else if (strmatch(name
, "topo3"))
32 else if (strmatch(name
, "topo4"))
34 else if (strmatch(name
, "topo5"))
40 int sort_paths(const void **path1
, const void **path2
)
42 const struct ospf_path
*p1
= *path1
;
43 const struct ospf_path
*p2
= *path2
;
45 return (p1
->nexthop
.s_addr
- p2
->nexthop
.s_addr
);
48 void print_route_table(struct vty
*vty
, struct route_table
*rt
)
50 struct route_node
*rn
;
51 struct ospf_route
* or ;
52 struct listnode
*pnode
;
53 struct ospf_path
*path
;
54 struct mpls_label_stack
*label_stack
;
55 char buf
[MPLS_LABEL_STRLEN
];
57 for (rn
= route_top(rt
); rn
; rn
= route_next(rn
)) {
58 if ((or = rn
->info
) == NULL
)
61 vty_out(vty
, "N %-18pFX %-15pI4 %d\n", &rn
->p
,
62 & or->u
.std
.area_id
, or->cost
);
64 list_sort(or->paths
, sort_paths
);
66 for (ALL_LIST_ELEMENTS_RO(or->paths
, pnode
, path
)) {
67 if (path
->nexthop
.s_addr
== 0)
70 vty_out(vty
, " -> %pI4 with adv router %pI4",
71 &path
->nexthop
, &path
->adv_router
);
73 if (path
->srni
.backup_label_stack
) {
74 label_stack
= path
->srni
.backup_label_stack
;
75 mpls_label2str(label_stack
->num_labels
,
76 label_stack
->label
, buf
,
78 ZEBRA_LSP_NONE
, true);
79 vty_out(vty
, " and backup path %s", buf
);
86 struct ospf_test_node
*test_find_node(struct ospf_topology
*topology
,
89 for (int i
= 0; topology
->nodes
[i
].hostname
[0]; i
++)
90 if (strmatch(hostname
, topology
->nodes
[i
].hostname
))
91 return &topology
->nodes
[i
];
96 static void inject_router_lsa(struct vty
*vty
, struct ospf
*ospf
,
97 struct ospf_topology
*topology
,
98 struct ospf_test_node
*root
,
99 struct ospf_test_node
*tnode
)
101 struct ospf_area
*area
;
102 struct in_addr router_id
;
103 struct in_addr adj_router_id
;
104 struct prefix_ipv4 prefix
;
107 struct lsa_header
*lsah
;
108 struct ospf_lsa
*new;
112 struct ospf_test_node
*tfound_adj_node
;
113 struct ospf_test_adj
*tadj
;
114 bool is_self_lsa
= false;
116 area
= ospf
->backbone
;
117 inet_aton(tnode
->router_id
, &router_id
);
119 if (strncmp(root
->router_id
, tnode
->router_id
, 256) == 0)
122 s
= stream_new(OSPF_MAX_LSA_SIZE
);
123 lsa_header_set(s
, LSA_OPTIONS_GET(area
) | LSA_OPTIONS_NSSA_GET(area
),
124 OSPF_ROUTER_LSA
, router_id
, router_id
);
126 stream_putc(s
, router_lsa_flags(area
));
129 putp
= stream_get_endp(s
);
132 for (link_count
= 0; tnode
->adjacencies
[link_count
].hostname
[0];
134 tadj
= &tnode
->adjacencies
[link_count
];
135 tfound_adj_node
= test_find_node(topology
, tadj
->hostname
);
136 str2prefix_ipv4(tnode
->adjacencies
[link_count
].network
,
139 inet_aton(tfound_adj_node
->router_id
, &adj_router_id
);
140 data
.s_addr
= prefix
.prefix
.s_addr
;
141 link_info_set(&s
, adj_router_id
, data
,
142 LSA_LINK_TYPE_POINTOPOINT
, 0, tadj
->metric
);
144 masklen2ip(prefix
.prefixlen
, &data
);
145 link_info_set(&s
, prefix
.prefix
, data
, LSA_LINK_TYPE_STUB
, 0,
149 /* Don't forget the node itself (just a stub) */
150 str2prefix_ipv4(tnode
->router_id
, &prefix
);
151 data
.s_addr
= 0xffffffff;
152 link_info_set(&s
, prefix
.prefix
, data
, LSA_LINK_TYPE_STUB
, 0, 0);
154 /* Take twice the link count (for P2P and stub) plus the local stub */
155 stream_putw_at(s
, putp
, (2 * link_count
) + 1);
157 length
= stream_get_endp(s
);
158 lsah
= (struct lsa_header
*)STREAM_DATA(s
);
159 lsah
->length
= htons(length
);
161 new = ospf_lsa_new_and_data(length
);
163 new->vrf_id
= area
->ospf
->vrf_id
;
166 SET_FLAG(new->flags
, OSPF_LSA_SELF
| OSPF_LSA_SELF_CHECKED
);
168 memcpy(new->data
, lsah
, length
);
171 ospf_lsdb_add(area
->lsdb
, new);
174 ospf_lsa_unlock(&area
->router_lsa_self
);
175 area
->router_lsa_self
= ospf_lsa_lock(new);
179 static void inject_sr_db_entry(struct vty
*vty
, struct ospf_test_node
*tnode
,
180 struct ospf_topology
*topology
)
182 struct ospf_test_node
*tfound_adj_node
;
183 struct ospf_test_adj
*tadj
;
184 struct in_addr router_id
;
185 struct in_addr remote_id
;
187 struct sr_prefix
*srp
;
191 inet_aton(tnode
->router_id
, &router_id
);
193 srn
= ospf_sr_node_create(&router_id
);
195 srn
->srgb
.range_size
= 8000;
196 srn
->srgb
.lower_bound
= 16000;
199 srn
->srlb
.range_size
= 1000;
200 srn
->srlb
.lower_bound
= 15000;
203 srp
= XCALLOC(MTYPE_OSPF_SR_PARAMS
, sizeof(struct sr_prefix
));
204 srp
->adv_router
= router_id
;
205 srp
->sid
= tnode
->label
;
208 listnode_add(srn
->ext_prefix
, srp
);
210 /* Adjacency SIDs for all adjacencies */
211 for (link_count
= 0; tnode
->adjacencies
[link_count
].hostname
[0];
213 tadj
= &tnode
->adjacencies
[link_count
];
214 tfound_adj_node
= test_find_node(topology
, tadj
->hostname
);
216 srl
= XCALLOC(MTYPE_OSPF_SR_PARAMS
, sizeof(struct sr_link
));
217 srl
->adv_router
= router_id
;
219 inet_aton(tfound_adj_node
->router_id
, &remote_id
);
220 srl
->remote_id
= remote_id
;
223 srl
->sid
[0] = srn
->srlb
.lower_bound
+ tadj
->label
;
226 listnode_add(srn
->ext_link
, srl
);
230 int topology_load(struct vty
*vty
, struct ospf_topology
*topology
,
231 struct ospf_test_node
*root
, struct ospf
*ospf
)
233 struct ospf_test_node
*tnode
;
235 for (int i
= 0; topology
->nodes
[i
].hostname
[0]; i
++) {
236 tnode
= &topology
->nodes
[i
];
238 /* Inject a router LSA for each node, used for SPF */
239 inject_router_lsa(vty
, ospf
, topology
, root
, tnode
);
242 * SR information could also be inected via LSAs, but directly
243 * filling the SR DB with labels is just easier.
245 inject_sr_db_entry(vty
, tnode
, topology
);