]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_router.c
Merge pull request #12837 from donaldsharp/unlikely_routemap
[mirror_frr.git] / zebra / zebra_router.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
89272910
DS
2/* Zebra Router Code.
3 * Copyright (C) 2018 Cumulus Networks, Inc.
4 * Donald Sharp
89272910
DS
5 */
6#include "zebra.h"
7
1485bbe7
DS
8#include <pthread.h>
9#include "lib/frratomic.h"
10
89272910 11#include "zebra_router.h"
7f0ea8a4 12#include "zebra_pbr.h"
6548050a 13#include "zebra_vxlan.h"
df395600 14#include "zebra_mlag.h"
0eb97b86 15#include "zebra_nhg.h"
4cf4fad1 16#include "zebra_neigh.h"
c317d3f2 17#include "zebra/zebra_tc.h"
526052fb 18#include "debug.h"
cbefb650 19#include "zebra_script.h"
89272910 20
bf8d3d6a 21DEFINE_MTYPE_STATIC(ZEBRA, RIB_TABLE_INFO, "RIB table info");
224ccf29 22DEFINE_MTYPE_STATIC(ZEBRA, ZEBRA_RT_TABLE, "Zebra VRF table");
c1344b54 23
b3f2b590
DS
24struct zebra_router zrouter = {
25 .multipath_num = MULTIPATH_NUM,
526052fb 26 .ipv4_multicast_mode = MCAST_NO_CONFIG,
b3f2b590 27};
89272910
DS
28
29static inline int
30zebra_router_table_entry_compare(const struct zebra_router_table *e1,
31 const struct zebra_router_table *e2);
32
33RB_GENERATE(zebra_router_table_head, zebra_router_table,
34 zebra_router_table_entry, zebra_router_table_entry_compare);
35
36
37static inline int
38zebra_router_table_entry_compare(const struct zebra_router_table *e1,
39 const struct zebra_router_table *e2)
40{
41 if (e1->tableid < e2->tableid)
42 return -1;
43 if (e1->tableid > e2->tableid)
44 return 1;
45 if (e1->ns_id < e2->ns_id)
46 return -1;
47 if (e1->ns_id > e2->ns_id)
48 return 1;
49 if (e1->afi < e2->afi)
50 return -1;
51 if (e1->afi > e2->afi)
52 return 1;
53 return (e1->safi - e2->safi);
54}
55
9d86e091
CS
56struct zebra_router_table *zebra_router_find_zrt(struct zebra_vrf *zvrf,
57 uint32_t tableid, afi_t afi,
58 safi_t safi)
59{
60 struct zebra_router_table finder;
61 struct zebra_router_table *zrt;
62
63 memset(&finder, 0, sizeof(finder));
64 finder.afi = afi;
65 finder.safi = safi;
66 finder.tableid = tableid;
67 finder.ns_id = zvrf->zns->ns_id;
68 zrt = RB_FIND(zebra_router_table_head, &zrouter.tables, &finder);
69
70 return zrt;
71}
89272910
DS
72
73struct route_table *zebra_router_find_table(struct zebra_vrf *zvrf,
74 uint32_t tableid, afi_t afi,
75 safi_t safi)
76{
77 struct zebra_router_table finder;
78 struct zebra_router_table *zrt;
79
80 memset(&finder, 0, sizeof(finder));
81 finder.afi = afi;
82 finder.safi = safi;
83 finder.tableid = tableid;
84 finder.ns_id = zvrf->zns->ns_id;
85 zrt = RB_FIND(zebra_router_table_head, &zrouter.tables, &finder);
86
87 if (zrt)
88 return zrt->table;
89 else
90 return NULL;
91}
92
93struct route_table *zebra_router_get_table(struct zebra_vrf *zvrf,
94 uint32_t tableid, afi_t afi,
95 safi_t safi)
96{
97 struct zebra_router_table finder;
98 struct zebra_router_table *zrt;
630d5962 99 struct rib_table_info *info;
89272910
DS
100
101 memset(&finder, 0, sizeof(finder));
102 finder.afi = afi;
103 finder.safi = safi;
104 finder.tableid = tableid;
105 finder.ns_id = zvrf->zns->ns_id;
106 zrt = RB_FIND(zebra_router_table_head, &zrouter.tables, &finder);
107
108 if (zrt)
109 return zrt->table;
110
224ccf29 111 zrt = XCALLOC(MTYPE_ZEBRA_RT_TABLE, sizeof(*zrt));
89272910
DS
112 zrt->tableid = tableid;
113 zrt->afi = afi;
99b2c423 114 zrt->safi = safi;
89272910
DS
115 zrt->ns_id = zvrf->zns->ns_id;
116 zrt->table =
117 (afi == AFI_IP6) ? srcdest_table_init() : route_table_init();
118
119 info = XCALLOC(MTYPE_RIB_TABLE_INFO, sizeof(*info));
120 info->zvrf = zvrf;
121 info->afi = afi;
ea66cec4 122 info->safi = safi;
b62983cf 123 info->table_id = tableid;
89272910
DS
124 route_table_set_info(zrt->table, info);
125 zrt->table->cleanup = zebra_rtable_node_cleanup;
126
127 RB_INSERT(zebra_router_table_head, &zrouter.tables, zrt);
128 return zrt->table;
129}
130
ac5aa23f
DS
131void zebra_router_show_table_summary(struct vty *vty)
132{
133 struct zebra_router_table *zrt;
134
135 vty_out(vty,
136 "VRF NS ID VRF ID AFI SAFI Table Count\n");
137 vty_out(vty,
138 "---------------------------------------------------------------------------\n");
139 RB_FOREACH (zrt, zebra_router_table_head, &zrouter.tables) {
630d5962 140 struct rib_table_info *info = route_table_get_info(zrt->table);
ac5aa23f
DS
141
142 vty_out(vty, "%-16s%5d %9d %7s %15s %8d %10lu\n", info->zvrf->vrf->name,
143 zrt->ns_id, info->zvrf->vrf->vrf_id,
144 afi2str(zrt->afi), safi2str(zrt->safi),
145 zrt->tableid,
146 zrt->table->count);
147 }
148}
149
89272910
DS
150void zebra_router_sweep_route(void)
151{
152 struct zebra_router_table *zrt;
153
154 RB_FOREACH (zrt, zebra_router_table_head, &zrouter.tables) {
155 if (zrt->ns_id != NS_DEFAULT)
156 continue;
157 rib_sweep_table(zrt->table);
158 }
159}
160
38e40db1
SW
161void zebra_router_sweep_nhgs(void)
162{
163 zebra_nhg_sweep_table(zrouter.nhgs_id);
164}
165
89272910
DS
166static void zebra_router_free_table(struct zebra_router_table *zrt)
167{
168 void *table_info;
169
89272910
DS
170 table_info = route_table_get_info(zrt->table);
171 route_table_finish(zrt->table);
bd4fb615
DS
172 RB_REMOVE(zebra_router_table_head, &zrouter.tables, zrt);
173
89272910 174 XFREE(MTYPE_RIB_TABLE_INFO, table_info);
224ccf29 175 XFREE(MTYPE_ZEBRA_RT_TABLE, zrt);
89272910
DS
176}
177
bd4fb615
DS
178void zebra_router_release_table(struct zebra_vrf *zvrf, uint32_t tableid,
179 afi_t afi, safi_t safi)
180{
181 struct zebra_router_table finder;
182 struct zebra_router_table *zrt;
183
184 memset(&finder, 0, sizeof(finder));
185 finder.afi = afi;
186 finder.safi = safi;
187 finder.tableid = tableid;
188 finder.ns_id = zvrf->zns->ns_id;
189 zrt = RB_FIND(zebra_router_table_head, &zrouter.tables, &finder);
190
191 if (!zrt)
192 return;
193
194 zebra_router_free_table(zrt);
195}
196
1485bbe7
DS
197uint32_t zebra_router_get_next_sequence(void)
198{
199 return 1
200 + atomic_fetch_add_explicit(&zrouter.sequence_num, 1,
201 memory_order_relaxed);
202}
203
526052fb
DS
204void multicast_mode_ipv4_set(enum multicast_mode mode)
205{
206 if (IS_ZEBRA_DEBUG_RIB)
207 zlog_debug("%s: multicast lookup mode set (%d)", __func__,
208 mode);
209 zrouter.ipv4_multicast_mode = mode;
210}
211
212enum multicast_mode multicast_mode_ipv4_get(void)
213{
214 return zrouter.ipv4_multicast_mode;
215}
216
89272910
DS
217void zebra_router_terminate(void)
218{
219 struct zebra_router_table *zrt, *tmp;
220
e16d030c 221 EVENT_OFF(zrouter.sweeper);
c3343a75 222
8a88f815 223 RB_FOREACH_SAFE (zrt, zebra_router_table_head, &zrouter.tables, tmp)
89272910 224 zebra_router_free_table(zrt);
7f0ea8a4 225
489a9614 226 work_queue_free_and_null(&zrouter.ribq);
a310ebc1 227 meta_queue_free(zrouter.mq, NULL);
489a9614 228
6548050a 229 zebra_vxlan_disable();
df395600 230 zebra_mlag_terminate();
4cf4fad1 231 zebra_neigh_terminate();
df395600 232
c25c3ea5 233 /* Free NHE in ID table only since it has unhashable entries as well */
d5795103 234 hash_iterate(zrouter.nhgs_id, zebra_nhg_hash_free_zero_id, NULL);
d8bc11a5
DS
235 hash_clean_and_free(&zrouter.nhgs_id, zebra_nhg_hash_free);
236 hash_clean_and_free(&zrouter.nhgs, NULL);
237
238 hash_clean_and_free(&zrouter.rules_hash, zebra_pbr_rules_free);
239
240 hash_clean_and_free(&zrouter.ipset_entry_hash,
241 zebra_pbr_ipset_entry_free);
242 hash_clean_and_free(&zrouter.ipset_hash, zebra_pbr_ipset_free);
243 hash_clean_and_free(&zrouter.iptable_hash, zebra_pbr_iptable_free);
461c173c
DL
244
245#ifdef HAVE_SCRIPTING
246 zebra_script_destroy();
247#endif
34869809
MS
248
249 /* OS-specific deinit */
250 kernel_router_terminate();
89272910
DS
251}
252
e4876266
DS
253bool zebra_router_notify_on_ack(void)
254{
255 return !zrouter.asic_offloaded || zrouter.notify_on_ack;
256}
257
258void zebra_router_init(bool asic_offload, bool notify_on_ack)
89272910 259{
1485bbe7
DS
260 zrouter.sequence_num = 0;
261
88b0baa6
DS
262 zrouter.allow_delete = false;
263
5ec5a716 264 zrouter.packets_to_process = ZEBRA_ZAPI_PACKETS_TO_PROCESS;
b3d43ff4 265
c9af62e3
DS
266 zrouter.nhg_keep = ZEBRA_DEFAULT_NHG_KEEP_TIMER;
267
6548050a 268 zebra_vxlan_init();
df395600 269 zebra_mlag_init();
4cf4fad1 270 zebra_neigh_init();
df395600 271
7f0ea8a4
DS
272 zrouter.rules_hash = hash_create_size(8, zebra_pbr_rules_hash_key,
273 zebra_pbr_rules_hash_equal,
274 "Rules Hash");
62f20a52
DS
275
276 zrouter.ipset_hash =
277 hash_create_size(8, zebra_pbr_ipset_hash_key,
278 zebra_pbr_ipset_hash_equal, "IPset Hash");
279
280 zrouter.ipset_entry_hash = hash_create_size(
281 8, zebra_pbr_ipset_entry_hash_key,
282 zebra_pbr_ipset_entry_hash_equal, "IPset Hash Entry");
283
284 zrouter.iptable_hash = hash_create_size(8, zebra_pbr_iptable_hash_key,
285 zebra_pbr_iptable_hash_equal,
286 "IPtable Hash Entry");
69171da2
DS
287
288 zrouter.nhgs =
289 hash_create_size(8, zebra_nhg_hash_key, zebra_nhg_hash_equal,
290 "Zebra Router Nexthop Groups");
a95b8020 291 zrouter.nhgs_id =
d9f5b2f5 292 hash_create_size(8, zebra_nhg_id_key, zebra_nhg_hash_id_equal,
a95b8020 293 "Zebra Router Nexthop Groups ID index");
4c56ce1c 294
c317d3f2
SY
295 zrouter.rules_hash =
296 hash_create_size(8, zebra_pbr_rules_hash_key,
297 zebra_pbr_rules_hash_equal, "Rules Hash");
298
299 zrouter.qdisc_hash =
300 hash_create_size(8, zebra_tc_qdisc_hash_key,
301 zebra_tc_qdisc_hash_equal, "TC (qdisc) Hash");
302 zrouter.class_hash = hash_create_size(8, zebra_tc_class_hash_key,
303 zebra_tc_class_hash_equal,
304 "TC (classes) Hash");
305 zrouter.filter_hash = hash_create_size(8, zebra_tc_filter_hash_key,
306 zebra_tc_filter_hash_equal,
307 "TC (filter) Hash");
308
e4876266
DS
309 zrouter.asic_offloaded = asic_offload;
310 zrouter.notify_on_ack = notify_on_ack;
461c173c 311
06525c4f
DS
312 /*
313 * If you start using asic_notification_nexthop_control
314 * come talk to the FRR community about what you are doing
315 * We would like to know.
316 */
317#if CONFDATE > 20251231
318 CPP_NOTICE(
319 "Remove zrouter.asic_notification_nexthop_control as that it's not being maintained or used");
320#endif
321 zrouter.asic_notification_nexthop_control = false;
322
461c173c
DL
323#ifdef HAVE_SCRIPTING
324 zebra_script_init();
325#endif
34869809
MS
326
327 /* OS-specific init */
328 kernel_router_init();
89272910 329}