]>
Commit | Line | Data |
---|---|---|
a98b00ee MR |
1 | /* |
2 | * BGP Routing table range lookup test | |
3 | * Copyright (C) 2012 OSR. | |
4 | * Copyright (C) 2018 Marcel Röthke (marcel.roethke@haw-hamburg.de), for HAW | |
5 | * Hamburg | |
6 | * | |
7 | * This file is part of FRRouting | |
8 | * | |
9 | * Quagga is free software; you can redistribute it and/or modify it | |
10 | * under the terms of the GNU General Public License as published by the | |
11 | * Free Software Foundation; either version 2, or (at your option) any | |
12 | * later version. | |
13 | * | |
14 | * Quagga is distributed in the hope that it will be useful, but | |
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 | * General Public License for more details. | |
18 | * | |
19 | * You should have received a copy of the GNU General Public License along | |
20 | * with this program; see the file COPYING; if not, write to the Free Software | |
21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
22 | */ | |
23 | ||
24 | #include <zebra.h> | |
25 | ||
26 | #include "prefix.h" | |
27 | #include "table.h" | |
28 | #include "bgpd/bgp_table.h" | |
29 | #include "linklist.h" | |
30 | ||
dcc68b5e MS |
31 | /* Satisfy link requirements from including bgpd.h */ |
32 | struct zebra_privs_t bgpd_privs = {0}; | |
a98b00ee MR |
33 | /* |
34 | * test_node_t | |
35 | * | |
36 | * Information that is kept for each node in the radix tree. | |
37 | */ | |
38 | struct test_node_t { | |
39 | ||
40 | /* | |
41 | * Human readable representation of the string. Allocated using | |
42 | * malloc()/dup(). | |
43 | */ | |
44 | char *prefix_str; | |
45 | }; | |
46 | ||
47 | /* | |
48 | * add_node | |
49 | * | |
50 | * Add the given prefix (passed in as a string) to the given table. | |
51 | */ | |
52 | static void add_node(struct bgp_table *table, const char *prefix_str) | |
53 | { | |
54 | struct prefix_ipv4 p; | |
55 | struct test_node_t *node; | |
9bcb3eef | 56 | struct bgp_dest *dest; |
a98b00ee MR |
57 | |
58 | assert(prefix_str); | |
59 | ||
60 | if (str2prefix_ipv4(prefix_str, &p) <= 0) | |
61 | assert(0); | |
62 | ||
9bcb3eef DS |
63 | dest = bgp_node_get(table, (struct prefix *)&p); |
64 | if (dest->info) { | |
a98b00ee MR |
65 | assert(0); |
66 | return; | |
67 | } | |
68 | ||
69 | node = malloc(sizeof(struct test_node_t)); | |
70 | assert(node); | |
71 | node->prefix_str = strdup(prefix_str); | |
72 | assert(node->prefix_str); | |
9bcb3eef | 73 | dest->info = node; |
a98b00ee MR |
74 | } |
75 | ||
bac31cb8 MR |
76 | static bool prefix_in_array(const struct prefix *p, struct prefix *prefix_array, |
77 | size_t prefix_array_size) | |
a98b00ee | 78 | { |
bac31cb8 MR |
79 | for (size_t i = 0; i < prefix_array_size; ++i) { |
80 | if (prefix_same(p, &prefix_array[i])) | |
81 | return true; | |
a98b00ee | 82 | } |
bac31cb8 | 83 | return false; |
a98b00ee MR |
84 | } |
85 | ||
9bcb3eef | 86 | static void check_lookup_result(struct bgp_dest *match, va_list arglist) |
a98b00ee MR |
87 | { |
88 | char *prefix_str; | |
bac31cb8 MR |
89 | struct prefix *prefixes = NULL; |
90 | size_t prefix_count = 0; | |
a98b00ee | 91 | |
a98b00ee | 92 | while ((prefix_str = va_arg(arglist, char *))) { |
bac31cb8 MR |
93 | ++prefix_count; |
94 | prefixes = realloc(prefixes, sizeof(*prefixes) * prefix_count); | |
a98b00ee | 95 | |
bac31cb8 | 96 | if (str2prefix(prefix_str, &prefixes[prefix_count - 1]) <= 0) |
a98b00ee | 97 | assert(0); |
bac31cb8 | 98 | } |
a98b00ee | 99 | |
bac31cb8 MR |
100 | /* check if the result is empty and if it is allowd to be empty */ |
101 | assert((prefix_count == 0 && !match) || prefix_count > 0); | |
102 | if (!match) | |
103 | return; | |
a98b00ee | 104 | |
9bcb3eef | 105 | struct bgp_dest *dest = match; |
bac31cb8 | 106 | |
9bcb3eef DS |
107 | while ((dest = bgp_route_next_until(dest, match))) { |
108 | const struct prefix *dest_p = bgp_dest_get_prefix(dest); | |
a98b00ee | 109 | |
9bcb3eef DS |
110 | if (bgp_dest_has_bgp_path_info_data(dest) |
111 | && !prefix_in_array(dest_p, prefixes, prefix_count)) { | |
2dbe669b | 112 | printf("prefix %pFX was not expected!\n", dest_p); |
bac31cb8 MR |
113 | assert(0); |
114 | } | |
115 | } | |
a98b00ee MR |
116 | } |
117 | ||
bac31cb8 | 118 | static void do_test(struct bgp_table *table, const char *prefix, ...) |
a98b00ee MR |
119 | { |
120 | va_list arglist; | |
a98b00ee MR |
121 | struct prefix p; |
122 | ||
a98b00ee | 123 | |
bac31cb8 MR |
124 | va_start(arglist, prefix); |
125 | printf("\nDoing lookup for %s\n", prefix); | |
a98b00ee MR |
126 | if (str2prefix(prefix, &p) <= 0) |
127 | assert(0); | |
9bcb3eef | 128 | struct bgp_dest *dest = bgp_table_subtree_lookup(table, &p); |
a98b00ee | 129 | |
9bcb3eef | 130 | check_lookup_result(dest, arglist); |
a98b00ee MR |
131 | |
132 | va_end(arglist); | |
133 | ||
134 | printf("Checks successfull\n"); | |
135 | } | |
136 | ||
137 | /* | |
138 | * test_range_lookup | |
139 | */ | |
140 | static void test_range_lookup(void) | |
141 | { | |
142 | struct bgp_table *table = bgp_table_init(NULL, AFI_IP, SAFI_UNICAST); | |
143 | ||
144 | printf("Testing bgp_table_range_lookup\n"); | |
145 | ||
146 | printf("Setup bgp_table"); | |
147 | const char *prefixes[] = {"1.16.0.0/16", "1.16.128.0/18", | |
148 | "1.16.192.0/18", "1.16.64.0/19", | |
149 | "1.16.160.0/19", "1.16.32.0/20", | |
150 | "1.16.32.0/21", "16.0.0.0/16"}; | |
151 | ||
97b5d752 | 152 | int num_prefixes = array_size(prefixes); |
a98b00ee MR |
153 | |
154 | for (int i = 0; i < num_prefixes; i++) | |
155 | add_node(table, prefixes[i]); | |
156 | ||
bac31cb8 MR |
157 | do_test(table, "1.16.0.0/17", "1.16.64.0/19", "1.16.32.0/20", |
158 | "1.16.32.0/20", "1.16.32.0/21", NULL); | |
159 | do_test(table, "1.16.128.0/17", "1.16.128.0/18", "1.16.192.0/18", | |
a98b00ee MR |
160 | "1.16.160.0/19", NULL); |
161 | ||
bac31cb8 | 162 | do_test(table, "1.16.0.0/16", "1.16.0.0/16", "1.16.128.0/18", |
a98b00ee MR |
163 | "1.16.192.0/18", "1.16.64.0/19", "1.16.160.0/19", |
164 | "1.16.32.0/20", "1.16.32.0/21", NULL); | |
165 | ||
bac31cb8 | 166 | do_test(table, "1.17.0.0/16", NULL); |
a98b00ee | 167 | |
bac31cb8 | 168 | do_test(table, "128.0.0.0/8", NULL); |
a98b00ee | 169 | |
bac31cb8 | 170 | do_test(table, "16.0.0.0/8", "16.0.0.0/16", NULL); |
a98b00ee | 171 | |
bac31cb8 | 172 | do_test(table, "0.0.0.0/2", "1.16.0.0/16", "1.16.128.0/18", |
a98b00ee MR |
173 | "1.16.192.0/18", "1.16.64.0/19", "1.16.160.0/19", |
174 | "1.16.32.0/20", "1.16.32.0/21", "16.0.0.0/16", NULL); | |
175 | } | |
176 | ||
177 | int main(void) | |
178 | { | |
179 | test_range_lookup(); | |
180 | } |