]> git.proxmox.com Git - mirror_frr.git/blob - zebra/zebra_router.c
Merge pull request #4350 from patrasar/pim_sg_expiry
[mirror_frr.git] / zebra / zebra_router.c
1 /* Zebra Router Code.
2 * Copyright (C) 2018 Cumulus Networks, Inc.
3 * Donald Sharp
4 *
5 * This file is part of FRR.
6 *
7 * FRR 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 * FRR 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
18 * along with FRR; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22 #include "zebra.h"
23
24 #include <pthread.h>
25 #include "lib/frratomic.h"
26
27 #include "zebra_router.h"
28 #include "zebra_memory.h"
29 #include "zebra_pbr.h"
30 #include "zebra_vxlan.h"
31 #include "zebra_mlag.h"
32
33 struct zebra_router zrouter = {
34 .multipath_num = MULTIPATH_NUM,
35 };
36
37 static inline int
38 zebra_router_table_entry_compare(const struct zebra_router_table *e1,
39 const struct zebra_router_table *e2);
40
41 RB_GENERATE(zebra_router_table_head, zebra_router_table,
42 zebra_router_table_entry, zebra_router_table_entry_compare);
43
44
45 static inline int
46 zebra_router_table_entry_compare(const struct zebra_router_table *e1,
47 const struct zebra_router_table *e2)
48 {
49 if (e1->tableid < e2->tableid)
50 return -1;
51 if (e1->tableid > e2->tableid)
52 return 1;
53 if (e1->ns_id < e2->ns_id)
54 return -1;
55 if (e1->ns_id > e2->ns_id)
56 return 1;
57 if (e1->afi < e2->afi)
58 return -1;
59 if (e1->afi > e2->afi)
60 return 1;
61 return (e1->safi - e2->safi);
62 }
63
64
65 struct route_table *zebra_router_find_table(struct zebra_vrf *zvrf,
66 uint32_t tableid, afi_t afi,
67 safi_t safi)
68 {
69 struct zebra_router_table finder;
70 struct zebra_router_table *zrt;
71
72 memset(&finder, 0, sizeof(finder));
73 finder.afi = afi;
74 finder.safi = safi;
75 finder.tableid = tableid;
76 finder.ns_id = zvrf->zns->ns_id;
77 zrt = RB_FIND(zebra_router_table_head, &zrouter.tables, &finder);
78
79 if (zrt)
80 return zrt->table;
81 else
82 return NULL;
83 }
84
85 struct route_table *zebra_router_get_table(struct zebra_vrf *zvrf,
86 uint32_t tableid, afi_t afi,
87 safi_t safi)
88 {
89 struct zebra_router_table finder;
90 struct zebra_router_table *zrt;
91 rib_table_info_t *info;
92
93 memset(&finder, 0, sizeof(finder));
94 finder.afi = afi;
95 finder.safi = safi;
96 finder.tableid = tableid;
97 finder.ns_id = zvrf->zns->ns_id;
98 zrt = RB_FIND(zebra_router_table_head, &zrouter.tables, &finder);
99
100 if (zrt)
101 return zrt->table;
102
103 zrt = XCALLOC(MTYPE_ZEBRA_NS, sizeof(*zrt));
104 zrt->tableid = tableid;
105 zrt->afi = afi;
106 zrt->safi = safi;
107 zrt->ns_id = zvrf->zns->ns_id;
108 zrt->table =
109 (afi == AFI_IP6) ? srcdest_table_init() : route_table_init();
110
111 info = XCALLOC(MTYPE_RIB_TABLE_INFO, sizeof(*info));
112 info->zvrf = zvrf;
113 info->afi = afi;
114 info->safi = safi;
115 route_table_set_info(zrt->table, info);
116 zrt->table->cleanup = zebra_rtable_node_cleanup;
117
118 RB_INSERT(zebra_router_table_head, &zrouter.tables, zrt);
119 return zrt->table;
120 }
121
122 void zebra_router_show_table_summary(struct vty *vty)
123 {
124 struct zebra_router_table *zrt;
125
126 vty_out(vty,
127 "VRF NS ID VRF ID AFI SAFI Table Count\n");
128 vty_out(vty,
129 "---------------------------------------------------------------------------\n");
130 RB_FOREACH (zrt, zebra_router_table_head, &zrouter.tables) {
131 rib_table_info_t *info = route_table_get_info(zrt->table);
132
133 vty_out(vty, "%-16s%5d %9d %7s %15s %8d %10lu\n", info->zvrf->vrf->name,
134 zrt->ns_id, info->zvrf->vrf->vrf_id,
135 afi2str(zrt->afi), safi2str(zrt->safi),
136 zrt->tableid,
137 zrt->table->count);
138 }
139 }
140
141 void zebra_router_sweep_route(void)
142 {
143 struct zebra_router_table *zrt;
144
145 RB_FOREACH (zrt, zebra_router_table_head, &zrouter.tables) {
146 if (zrt->ns_id != NS_DEFAULT)
147 continue;
148 rib_sweep_table(zrt->table);
149 }
150 }
151
152 static void zebra_router_free_table(struct zebra_router_table *zrt)
153 {
154 void *table_info;
155
156 table_info = route_table_get_info(zrt->table);
157 route_table_finish(zrt->table);
158 RB_REMOVE(zebra_router_table_head, &zrouter.tables, zrt);
159
160 XFREE(MTYPE_RIB_TABLE_INFO, table_info);
161 XFREE(MTYPE_ZEBRA_NS, zrt);
162 }
163
164 void zebra_router_release_table(struct zebra_vrf *zvrf, uint32_t tableid,
165 afi_t afi, safi_t safi)
166 {
167 struct zebra_router_table finder;
168 struct zebra_router_table *zrt;
169
170 memset(&finder, 0, sizeof(finder));
171 finder.afi = afi;
172 finder.safi = safi;
173 finder.tableid = tableid;
174 finder.ns_id = zvrf->zns->ns_id;
175 zrt = RB_FIND(zebra_router_table_head, &zrouter.tables, &finder);
176
177 if (!zrt)
178 return;
179
180 zebra_router_free_table(zrt);
181 }
182
183 uint32_t zebra_router_get_next_sequence(void)
184 {
185 return 1
186 + atomic_fetch_add_explicit(&zrouter.sequence_num, 1,
187 memory_order_relaxed);
188 }
189
190 void zebra_router_terminate(void)
191 {
192 struct zebra_router_table *zrt, *tmp;
193
194 RB_FOREACH_SAFE (zrt, zebra_router_table_head, &zrouter.tables, tmp)
195 zebra_router_free_table(zrt);
196
197 work_queue_free_and_null(&zrouter.ribq);
198 meta_queue_free(zrouter.mq);
199
200 zebra_vxlan_disable();
201 zebra_mlag_terminate();
202
203 hash_clean(zrouter.rules_hash, zebra_pbr_rules_free);
204 hash_free(zrouter.rules_hash);
205
206 hash_clean(zrouter.ipset_entry_hash, zebra_pbr_ipset_entry_free),
207 hash_clean(zrouter.ipset_hash, zebra_pbr_ipset_free);
208 hash_free(zrouter.ipset_hash);
209 hash_free(zrouter.ipset_entry_hash);
210 hash_clean(zrouter.iptable_hash, zebra_pbr_iptable_free);
211 hash_free(zrouter.iptable_hash);
212 }
213
214 void zebra_router_init(void)
215 {
216 zrouter.sequence_num = 0;
217
218 zrouter.packets_to_process = ZEBRA_ZAPI_PACKETS_TO_PROCESS;
219
220 zebra_vxlan_init();
221 zebra_mlag_init();
222
223 zrouter.rules_hash = hash_create_size(8, zebra_pbr_rules_hash_key,
224 zebra_pbr_rules_hash_equal,
225 "Rules Hash");
226
227 zrouter.ipset_hash =
228 hash_create_size(8, zebra_pbr_ipset_hash_key,
229 zebra_pbr_ipset_hash_equal, "IPset Hash");
230
231 zrouter.ipset_entry_hash = hash_create_size(
232 8, zebra_pbr_ipset_entry_hash_key,
233 zebra_pbr_ipset_entry_hash_equal, "IPset Hash Entry");
234
235 zrouter.iptable_hash = hash_create_size(8, zebra_pbr_iptable_hash_key,
236 zebra_pbr_iptable_hash_equal,
237 "IPtable Hash Entry");
238 }