]> git.proxmox.com Git - mirror_frr.git/blame - tests/ospfd/common.c
Merge pull request #13321 from louis-6wind/doc-affinitymap
[mirror_frr.git] / tests / ospfd / common.c
CommitLineData
7fd0729f
G
1#include <zebra.h>
2
3#include "lib/stream.h"
4#include "lib/vty.h"
5#include "lib/mpls.h"
6#include "lib/if.h"
66dc21bb 7#include "lib/table.h"
7fd0729f
G
8
9#include "ospfd/ospfd.h"
66dc21bb 10#include "ospfd/ospf_route.h"
7fd0729f
G
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"
17
18#include "common.h"
19
cd9d0537 20struct event_loop *master;
7fd0729f
G
21struct zebra_privs_t ospfd_privs;
22
23
24struct ospf_topology *test_find_topology(const char *name)
25{
26 if (strmatch(name, "topo1"))
27 return &topo1;
28 else if (strmatch(name, "topo2"))
29 return &topo2;
30 else if (strmatch(name, "topo3"))
31 return &topo3;
385a1e07
G
32 else if (strmatch(name, "topo4"))
33 return &topo4;
bdcfd34a
G
34 else if (strmatch(name, "topo5"))
35 return &topo5;
7fd0729f
G
36
37 return NULL;
38}
39
66dc21bb
G
40int sort_paths(const void **path1, const void **path2)
41{
42 const struct ospf_path *p1 = *path1;
43 const struct ospf_path *p2 = *path2;
44
45 return (p1->nexthop.s_addr - p2->nexthop.s_addr);
46}
47
48void print_route_table(struct vty *vty, struct route_table *rt)
49{
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];
56
57 for (rn = route_top(rt); rn; rn = route_next(rn)) {
58 if ((or = rn->info) == NULL)
59 continue;
60
61 vty_out(vty, "N %-18pFX %-15pI4 %d\n", &rn->p,
62 & or->u.std.area_id, or->cost);
63
64 list_sort(or->paths, sort_paths);
65
66 for (ALL_LIST_ELEMENTS_RO(or->paths, pnode, path)) {
67 if (path->nexthop.s_addr == 0)
68 continue;
69
70 vty_out(vty, " -> %pI4 with adv router %pI4",
71 &path->nexthop, &path->adv_router);
72
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,
6712f624
SW
77 MPLS_LABEL_STRLEN,
78 ZEBRA_LSP_NONE, true);
66dc21bb
G
79 vty_out(vty, " and backup path %s", buf);
80 }
81 vty_out(vty, "\n");
82 }
83 }
84}
85
7fd0729f
G
86struct ospf_test_node *test_find_node(struct ospf_topology *topology,
87 const char *hostname)
88{
89 for (int i = 0; topology->nodes[i].hostname[0]; i++)
90 if (strmatch(hostname, topology->nodes[i].hostname))
91 return &topology->nodes[i];
92
93 return NULL;
94}
95
96static 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)
100{
101 struct ospf_area *area;
102 struct in_addr router_id;
103 struct in_addr adj_router_id;
104 struct prefix_ipv4 prefix;
105 struct in_addr data;
106 struct stream *s;
107 struct lsa_header *lsah;
108 struct ospf_lsa *new;
109 int length;
110 unsigned long putp;
111 uint16_t link_count;
112 struct ospf_test_node *tfound_adj_node;
113 struct ospf_test_adj *tadj;
114 bool is_self_lsa = false;
115
116 area = ospf->backbone;
117 inet_aton(tnode->router_id, &router_id);
118
119 if (strncmp(root->router_id, tnode->router_id, 256) == 0)
120 is_self_lsa = true;
121
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);
125
126 stream_putc(s, router_lsa_flags(area));
127 stream_putc(s, 0);
128
129 putp = stream_get_endp(s);
130 stream_putw(s, 0);
131
132 for (link_count = 0; tnode->adjacencies[link_count].hostname[0];
133 link_count++) {
134 tadj = &tnode->adjacencies[link_count];
135 tfound_adj_node = test_find_node(topology, tadj->hostname);
136 str2prefix_ipv4(tnode->adjacencies[link_count].network,
137 &prefix);
138
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);
143
144 masklen2ip(prefix.prefixlen, &data);
145 link_info_set(&s, prefix.prefix, data, LSA_LINK_TYPE_STUB, 0,
146 tadj->metric);
147 }
148
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);
153
154 /* Take twice the link count (for P2P and stub) plus the local stub */
155 stream_putw_at(s, putp, (2 * link_count) + 1);
156
157 length = stream_get_endp(s);
158 lsah = (struct lsa_header *)STREAM_DATA(s);
159 lsah->length = htons(length);
160
161 new = ospf_lsa_new_and_data(length);
162 new->area = area;
163 new->vrf_id = area->ospf->vrf_id;
164
165 if (is_self_lsa)
166 SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
167
168 memcpy(new->data, lsah, length);
169 stream_free(s);
170
171 ospf_lsdb_add(area->lsdb, new);
172
173 if (is_self_lsa) {
174 ospf_lsa_unlock(&area->router_lsa_self);
175 area->router_lsa_self = ospf_lsa_lock(new);
176 }
177}
178
cc1725bd
G
179static void inject_sr_db_entry(struct vty *vty, struct ospf_test_node *tnode,
180 struct ospf_topology *topology)
7fd0729f 181{
cc1725bd
G
182 struct ospf_test_node *tfound_adj_node;
183 struct ospf_test_adj *tadj;
7fd0729f 184 struct in_addr router_id;
cc1725bd 185 struct in_addr remote_id;
7fd0729f
G
186 struct sr_node *srn;
187 struct sr_prefix *srp;
cc1725bd
G
188 struct sr_link *srl;
189 int link_count;
7fd0729f
G
190
191 inet_aton(tnode->router_id, &router_id);
192
193 srn = ospf_sr_node_create(&router_id);
194
195 srn->srgb.range_size = 8000;
196 srn->srgb.lower_bound = 16000;
197 srn->msd = 16;
198
cc1725bd
G
199 srn->srlb.range_size = 1000;
200 srn->srlb.lower_bound = 15000;
7fd0729f 201
cc1725bd
G
202 /* Prefix SID */
203 srp = XCALLOC(MTYPE_OSPF_SR_PARAMS, sizeof(struct sr_prefix));
7fd0729f
G
204 srp->adv_router = router_id;
205 srp->sid = tnode->label;
206 srp->srn = srn;
207
208 listnode_add(srn->ext_prefix, srp);
cc1725bd
G
209
210 /* Adjacency SIDs for all adjacencies */
211 for (link_count = 0; tnode->adjacencies[link_count].hostname[0];
212 link_count++) {
213 tadj = &tnode->adjacencies[link_count];
214 tfound_adj_node = test_find_node(topology, tadj->hostname);
215
216 srl = XCALLOC(MTYPE_OSPF_SR_PARAMS, sizeof(struct sr_link));
217 srl->adv_router = router_id;
218
219 inet_aton(tfound_adj_node->router_id, &remote_id);
220 srl->remote_id = remote_id;
221
222 srl->type = ADJ_SID;
223 srl->sid[0] = srn->srlb.lower_bound + tadj->label;
224 srl->srn = srn;
225
226 listnode_add(srn->ext_link, srl);
227 }
7fd0729f
G
228}
229
230int topology_load(struct vty *vty, struct ospf_topology *topology,
231 struct ospf_test_node *root, struct ospf *ospf)
232{
233 struct ospf_test_node *tnode;
234
235 for (int i = 0; topology->nodes[i].hostname[0]; i++) {
236 tnode = &topology->nodes[i];
237
238 /* Inject a router LSA for each node, used for SPF */
239 inject_router_lsa(vty, ospf, topology, root, tnode);
240
241 /*
242 * SR information could also be inected via LSAs, but directly
243 * filling the SR DB with labels is just easier.
244 */
cc1725bd 245 inject_sr_db_entry(vty, tnode, topology);
7fd0729f
G
246 }
247
248 return 0;
249}