2 * Copyright (C) 2018 Cumulus Networks, Inc.
5 * This file is part of FRR.
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
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.
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
25 #include "lib/frratomic.h"
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"
33 struct zebra_router zrouter
= {
34 .multipath_num
= MULTIPATH_NUM
,
38 zebra_router_table_entry_compare(const struct zebra_router_table
*e1
,
39 const struct zebra_router_table
*e2
);
41 RB_GENERATE(zebra_router_table_head
, zebra_router_table
,
42 zebra_router_table_entry
, zebra_router_table_entry_compare
);
46 zebra_router_table_entry_compare(const struct zebra_router_table
*e1
,
47 const struct zebra_router_table
*e2
)
49 if (e1
->tableid
< e2
->tableid
)
51 if (e1
->tableid
> e2
->tableid
)
53 if (e1
->ns_id
< e2
->ns_id
)
55 if (e1
->ns_id
> e2
->ns_id
)
57 if (e1
->afi
< e2
->afi
)
59 if (e1
->afi
> e2
->afi
)
61 return (e1
->safi
- e2
->safi
);
65 struct route_table
*zebra_router_find_table(struct zebra_vrf
*zvrf
,
66 uint32_t tableid
, afi_t afi
,
69 struct zebra_router_table finder
;
70 struct zebra_router_table
*zrt
;
72 memset(&finder
, 0, sizeof(finder
));
75 finder
.tableid
= tableid
;
76 finder
.ns_id
= zvrf
->zns
->ns_id
;
77 zrt
= RB_FIND(zebra_router_table_head
, &zrouter
.tables
, &finder
);
85 struct route_table
*zebra_router_get_table(struct zebra_vrf
*zvrf
,
86 uint32_t tableid
, afi_t afi
,
89 struct zebra_router_table finder
;
90 struct zebra_router_table
*zrt
;
91 rib_table_info_t
*info
;
93 memset(&finder
, 0, sizeof(finder
));
96 finder
.tableid
= tableid
;
97 finder
.ns_id
= zvrf
->zns
->ns_id
;
98 zrt
= RB_FIND(zebra_router_table_head
, &zrouter
.tables
, &finder
);
103 zrt
= XCALLOC(MTYPE_ZEBRA_NS
, sizeof(*zrt
));
104 zrt
->tableid
= tableid
;
107 zrt
->ns_id
= zvrf
->zns
->ns_id
;
109 (afi
== AFI_IP6
) ? srcdest_table_init() : route_table_init();
111 info
= XCALLOC(MTYPE_RIB_TABLE_INFO
, sizeof(*info
));
115 route_table_set_info(zrt
->table
, info
);
116 zrt
->table
->cleanup
= zebra_rtable_node_cleanup
;
118 RB_INSERT(zebra_router_table_head
, &zrouter
.tables
, zrt
);
122 void zebra_router_show_table_summary(struct vty
*vty
)
124 struct zebra_router_table
*zrt
;
127 "VRF NS ID VRF ID AFI SAFI Table Count\n");
129 "---------------------------------------------------------------------------\n");
130 RB_FOREACH (zrt
, zebra_router_table_head
, &zrouter
.tables
) {
131 rib_table_info_t
*info
= route_table_get_info(zrt
->table
);
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
),
141 void zebra_router_sweep_route(void)
143 struct zebra_router_table
*zrt
;
145 RB_FOREACH (zrt
, zebra_router_table_head
, &zrouter
.tables
) {
146 if (zrt
->ns_id
!= NS_DEFAULT
)
148 rib_sweep_table(zrt
->table
);
152 static void zebra_router_free_table(struct zebra_router_table
*zrt
)
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
);
160 XFREE(MTYPE_RIB_TABLE_INFO
, table_info
);
161 XFREE(MTYPE_ZEBRA_NS
, zrt
);
164 void zebra_router_release_table(struct zebra_vrf
*zvrf
, uint32_t tableid
,
165 afi_t afi
, safi_t safi
)
167 struct zebra_router_table finder
;
168 struct zebra_router_table
*zrt
;
170 memset(&finder
, 0, sizeof(finder
));
173 finder
.tableid
= tableid
;
174 finder
.ns_id
= zvrf
->zns
->ns_id
;
175 zrt
= RB_FIND(zebra_router_table_head
, &zrouter
.tables
, &finder
);
180 zebra_router_free_table(zrt
);
183 uint32_t zebra_router_get_next_sequence(void)
186 + atomic_fetch_add_explicit(&zrouter
.sequence_num
, 1,
187 memory_order_relaxed
);
190 void zebra_router_terminate(void)
192 struct zebra_router_table
*zrt
, *tmp
;
194 RB_FOREACH_SAFE (zrt
, zebra_router_table_head
, &zrouter
.tables
, tmp
)
195 zebra_router_free_table(zrt
);
197 work_queue_free_and_null(&zrouter
.ribq
);
198 meta_queue_free(zrouter
.mq
);
200 zebra_vxlan_disable();
201 zebra_mlag_terminate();
203 hash_clean(zrouter
.rules_hash
, zebra_pbr_rules_free
);
204 hash_free(zrouter
.rules_hash
);
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
);
214 void zebra_router_init(void)
216 zrouter
.sequence_num
= 0;
218 zrouter
.packets_to_process
= ZEBRA_ZAPI_PACKETS_TO_PROCESS
;
223 zrouter
.rules_hash
= hash_create_size(8, zebra_pbr_rules_hash_key
,
224 zebra_pbr_rules_hash_equal
,
228 hash_create_size(8, zebra_pbr_ipset_hash_key
,
229 zebra_pbr_ipset_hash_equal
, "IPset Hash");
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");
235 zrouter
.iptable_hash
= hash_create_size(8, zebra_pbr_iptable_hash_key
,
236 zebra_pbr_iptable_hash_equal
,
237 "IPtable Hash Entry");