1 /*
2  * CLI/command dummy handling tester
3  *
4  * Copyright (C) 2015 by David Lamparter,
5  *                   for Open Source Routing / NetDEF, Inc.
6  *
7  * Quagga is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation; either version 2, or (at your option) any
10  * later version.
11  *
12  * Quagga is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; see the file COPYING; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include <zebra.h>
23 
24 #include "prefix.h"
25 #include "vector.h"
26 #include "vty.h"
27 
28 #include "ospf6d/ospf6_lsa.h"
29 #include "ospf6d/ospf6_lsdb.h"
30 
31 #include "tests/lib/cli/common_cli.h"
32 #include "tests/ospf6d/test_lsdb_clippy.c"
33 
34 static struct ospf6_lsdb *lsdb;
35 
36 static struct ospf6_lsa **lsas = NULL;
37 static size_t lsa_count = 0;
38 
lsa_check_resize(size_t len)39 static void lsa_check_resize(size_t len)
40 {
41 	struct ospf6_lsa **templsas;
42 
43 	if (lsa_count >= len)
44 		return;
45 	templsas = realloc(lsas, len * sizeof(lsas[0]));
46 	if (templsas)
47 		lsas = templsas;
48 	else
49 		return;
50 	memset(lsas + lsa_count, 0, sizeof(lsas[0]) * (len - lsa_count));
51 
52 	lsa_count = len;
53 }
54 
55 DEFPY(lsa_set, lsa_set_cmd,
56       "lsa set (0-999999)$idx {type (0-65535)|id A.B.C.D|adv A.B.C.D}",
57       "LSA\n"
58       "set\n"
59       "LSA index in array\n"
60       "OSPF6 type code\n"
61       "OSPF6 type code\n"
62       "LS-ID\n"
63       "LS-ID\n"
64       "Advertising router\n"
65       "Advertising router\n")
66 {
67 	struct ospf6_lsa_header hdr;
68 	memset(&hdr, 0, sizeof(hdr));
69 	hdr.type = htons(type);
70 	hdr.id = id.s_addr;
71 	hdr.adv_router = adv.s_addr;
72 
73 	lsa_check_resize(idx + 1);
74 	if (lsas[idx])
75 		ospf6_lsa_unlock(lsas[idx]);
76 	lsas[idx] = ospf6_lsa_create_headeronly(&hdr);
77 	ospf6_lsa_lock(lsas[idx]);
78 	return CMD_SUCCESS;
79 }
80 
81 DEFPY(lsa_drop, lsa_drop_cmd,
82       "lsa drop (0-999999)$idx",
83       "LSA\n"
84       "drop reference\n"
85       "LSA index in array\n")
86 {
87 	if ((size_t)idx >= lsa_count)
88 		return CMD_SUCCESS;
89 	if (lsas[idx]->lock != 1)
90 		vty_out(vty, "refcount at %u\n", lsas[idx]->lock);
91 	ospf6_lsa_unlock(lsas[idx]);
92 	lsas[idx] = NULL;
93 	return CMD_SUCCESS;
94 }
95 
96 
97 DEFPY(lsdb_add, lsdb_add_cmd,
98       "lsdb add (0-999999)$idx",
99       "LSDB\n"
100       "insert LSA into LSDB\n"
101       "LSA index in array\n")
102 {
103 	ospf6_lsdb_add(lsas[idx], lsdb);
104 	return CMD_SUCCESS;
105 }
106 
107 DEFPY(lsdb_remove, lsdb_remove_cmd,
108       "lsdb remove (0-999999)$idx",
109       "LSDB\n"
110       "remove LSA from LSDB\n"
111       "LSA index in array\n")
112 {
113 	ospf6_lsdb_remove(lsas[idx], lsdb);
114 	return CMD_SUCCESS;
115 }
116 
lsa_show_oneline(struct vty * vty,struct ospf6_lsa * lsa)117 static void lsa_show_oneline(struct vty *vty, struct ospf6_lsa *lsa)
118 {
119 	char adv_router[64], id[64];
120 
121 	if (!lsa) {
122 		vty_out(vty, "lsa = NULL\n");
123 		return;
124 	}
125 	inet_ntop(AF_INET, &lsa->header->id, id, sizeof(id));
126 	inet_ntop(AF_INET, &lsa->header->adv_router, adv_router,
127 		  sizeof(adv_router));
128 	vty_out(vty, "type %u adv %s id %s\n", ntohs(lsa->header->type),
129 		adv_router, id);
130 }
131 
132 DEFPY(lsdb_walk, lsdb_walk_cmd,
133       "lsdb walk",
134       "LSDB\n"
135       "walk entries\n")
136 {
137 	struct ospf6_lsa *lsa;
138 	unsigned cnt = 0;
139 	for (ALL_LSDB(lsdb, lsa)) {
140 		lsa_show_oneline(vty, lsa);
141 		cnt++;
142 	}
143 	vty_out(vty, "%u entries.\n", cnt);
144 	return CMD_SUCCESS;
145 }
146 
147 DEFPY(lsdb_walk_type, lsdb_walk_type_cmd,
148       "lsdb walk type (0-65535)",
149       "LSDB\n"
150       "walk entries\n"
151       "entry type\n"
152       "entry type\n")
153 {
154 	struct ospf6_lsa *lsa;
155 	unsigned cnt = 0;
156 	type = htons(type);
157 	for (ALL_LSDB_TYPED(lsdb, type, lsa)) {
158 		lsa_show_oneline(vty, lsa);
159 		cnt++;
160 	}
161 	vty_out(vty, "%u entries.\n", cnt);
162 	return CMD_SUCCESS;
163 }
164 
165 DEFPY(lsdb_walk_type_adv, lsdb_walk_type_adv_cmd,
166       "lsdb walk type (0-65535) adv A.B.C.D",
167       "LSDB\n"
168       "walk entries\n"
169       "entry type\n"
170       "entry type\n"
171       "advertising router ID\n"
172       "advertising router ID\n")
173 {
174 	struct ospf6_lsa *lsa;
175 	unsigned cnt = 0;
176 	type = htons(type);
177 	for (ALL_LSDB_TYPED_ADVRTR(lsdb, type, adv.s_addr, lsa)) {
178 		lsa_show_oneline(vty, lsa);
179 		cnt++;
180 	}
181 	vty_out(vty, "%u entries.\n", cnt);
182 	return CMD_SUCCESS;
183 }
184 
185 DEFPY(lsdb_get, lsdb_get_cmd,
186       "lsdb <get-next|get> type (0-65535) adv A.B.C.D id A.B.C.D",
187       "LSDB\n"
188       "get entry's successor\n"
189       "entry type\n"
190       "entry type\n"
191       "advertising router ID\n"
192       "advertising router ID\n"
193       "LS-ID\n"
194       "LS-ID\n")
195 {
196 	struct ospf6_lsa *lsa;
197 	type = htons(type);
198 	if (!strcmp(argv[1]->text, "get-next"))
199 		lsa = ospf6_lsdb_lookup_next(type, id.s_addr, adv.s_addr, lsdb);
200 	else
201 		lsa = ospf6_lsdb_lookup(type, id.s_addr, adv.s_addr, lsdb);
202 	lsa_show_oneline(vty, lsa);
203 	return CMD_SUCCESS;
204 }
205 
206 DEFPY(lsa_refcounts, lsa_refcounts_cmd,
207       "lsa refcounts",
208       "LSA\n"
209       "show reference counts\n")
210 {
211 	for (size_t i = 0; i < lsa_count; i++)
212 		if (lsas[i])
213 			vty_out(vty, "[%zu] %u\n", i, lsas[i]->lock);
214 	return CMD_SUCCESS;
215 }
216 
217 DEFPY(lsdb_create, lsdb_create_cmd,
218       "lsdb create",
219       "LSDB\n"
220       "create LSDB\n")
221 {
222 	if (lsdb)
223 		ospf6_lsdb_delete(lsdb);
224 	lsdb = ospf6_lsdb_create(NULL);
225 	return CMD_SUCCESS;
226 }
227 
228 DEFPY(lsdb_delete, lsdb_delete_cmd,
229       "lsdb delete",
230       "LSDB\n"
231       "delete LSDB\n")
232 {
233 	ospf6_lsdb_delete(lsdb);
234 	lsdb = NULL;
235 	return CMD_SUCCESS;
236 }
237 
238 
239 struct zebra_privs_t ospf6d_privs;
240 
test_init(int argc,char ** argv)241 void test_init(int argc, char **argv)
242 {
243 	ospf6_lsa_init();
244 
245 	install_element(ENABLE_NODE, &lsa_set_cmd);
246 	install_element(ENABLE_NODE, &lsa_refcounts_cmd);
247 	install_element(ENABLE_NODE, &lsa_drop_cmd);
248 
249 	install_element(ENABLE_NODE, &lsdb_create_cmd);
250 	install_element(ENABLE_NODE, &lsdb_delete_cmd);
251 
252 	install_element(ENABLE_NODE, &lsdb_add_cmd);
253 	install_element(ENABLE_NODE, &lsdb_remove_cmd);
254 	install_element(ENABLE_NODE, &lsdb_walk_cmd);
255 	install_element(ENABLE_NODE, &lsdb_walk_type_cmd);
256 	install_element(ENABLE_NODE, &lsdb_walk_type_adv_cmd);
257 	install_element(ENABLE_NODE, &lsdb_get_cmd);
258 }
259