]> git.proxmox.com Git - mirror_frr.git/blame - sharpd/sharp_nht.c
Merge pull request #7330 from donaldsharp/zebra_use_after_free
[mirror_frr.git] / sharpd / sharp_nht.c
CommitLineData
86da53ab
DS
1/*
2 * SHARP - code to track nexthops
3 * Copyright (C) Cumulus Networks, Inc.
4 * Donald Sharp
5 *
6 * This file is part of FRR.
7 *
8 * FRR is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2, or (at your option) any
11 * later version.
12 *
13 * FRR is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; see the file COPYING; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22#include <zebra.h>
23
24#include "memory.h"
25#include "nexthop.h"
26#include "nexthop_group.h"
27#include "vty.h"
569e87c0
DS
28#include "typesafe.h"
29#include "zclient.h"
86da53ab
DS
30
31#include "sharp_nht.h"
32#include "sharp_globals.h"
569e87c0 33#include "sharp_zebra.h"
86da53ab
DS
34
35DEFINE_MTYPE_STATIC(SHARPD, NH_TRACKER, "Nexthop Tracker")
569e87c0 36DEFINE_MTYPE_STATIC(SHARPD, NHG, "Nexthop Group")
86da53ab
DS
37
38struct sharp_nh_tracker *sharp_nh_tracker_get(struct prefix *p)
39{
40 struct listnode *node;
41 struct sharp_nh_tracker *nht;
42
43 for (ALL_LIST_ELEMENTS_RO(sg.nhs, node, nht)) {
44 if (prefix_same(&nht->p, p))
45 break;
46 }
47
48 if (nht)
49 return nht;
50
51 nht = XCALLOC(MTYPE_NH_TRACKER, sizeof(*nht));
52 prefix_copy(&nht->p, p);
53
54 listnode_add(sg.nhs, nht);
55 return nht;
56}
57
58void sharp_nh_tracker_dump(struct vty *vty)
59{
60 struct listnode *node;
61 struct sharp_nh_tracker *nht;
62
63 for (ALL_LIST_ELEMENTS_RO(sg.nhs, node, nht)) {
64 char buf[PREFIX_STRLEN];
65
66 vty_out(vty, "%s: Nexthops: %u Updates: %u\n",
67 prefix2str(&nht->p, buf, sizeof(buf)),
68 nht->nhop_num,
69 nht->updates);
70 }
71}
569e87c0
DS
72
73PREDECL_RBTREE_UNIQ(sharp_nhg_rb);
74
75struct sharp_nhg {
76 struct sharp_nhg_rb_item mylistitem;
77
78 uint32_t id;
79
80 char name[256];
2053061b
SW
81
82 bool installed;
569e87c0
DS
83};
84
85static uint32_t nhg_id;
86
87static uint32_t sharp_get_next_nhid(void)
88{
612fcc5e 89 zlog_debug("NHG ID assigned: %u", nhg_id);
569e87c0
DS
90 return nhg_id++;
91}
92
93struct sharp_nhg_rb_head nhg_head;
94
95static int sharp_nhg_compare_func(const struct sharp_nhg *a,
96 const struct sharp_nhg *b)
97{
98 return strncmp(a->name, b->name, strlen(a->name));
99}
100
101DECLARE_RBTREE_UNIQ(sharp_nhg_rb, struct sharp_nhg, mylistitem,
102 sharp_nhg_compare_func);
103
2053061b
SW
104static struct sharp_nhg *sharp_nhgroup_find_id(uint32_t id)
105{
106 struct sharp_nhg *lookup;
107
108 /* Yea its just a for loop, I don't want add complexity
109 * to sharpd with another RB tree for just IDs
110 */
111
ff9aca4f 112 frr_each (sharp_nhg_rb, &nhg_head, lookup) {
2053061b
SW
113 if (lookup->id == id)
114 return lookup;
115 }
116
117 return NULL;
118}
119
569e87c0
DS
120static void sharp_nhgroup_add_cb(const char *name)
121{
122 struct sharp_nhg *snhg;
123
124 snhg = XCALLOC(MTYPE_NHG, sizeof(*snhg));
125 snhg->id = sharp_get_next_nhid();
73937edb 126 strlcpy(snhg->name, name, sizeof(snhg->name));
569e87c0
DS
127
128 sharp_nhg_rb_add(&nhg_head, snhg);
569e87c0
DS
129}
130
131static void sharp_nhgroup_add_nexthop_cb(const struct nexthop_group_cmd *nhgc,
132 const struct nexthop *nhop)
133{
134 struct sharp_nhg lookup;
135 struct sharp_nhg *snhg;
21735352 136 struct nexthop_group_cmd *bnhgc = NULL;
569e87c0 137
73937edb 138 strlcpy(lookup.name, nhgc->name, sizeof(lookup.name));
569e87c0
DS
139 snhg = sharp_nhg_rb_find(&nhg_head, &lookup);
140
21735352
SW
141 if (nhgc->backup_list_name[0])
142 bnhgc = nhgc_find(nhgc->backup_list_name);
143
144 nhg_add(snhg->id, &nhgc->nhg, (bnhgc ? &bnhgc->nhg : NULL));
569e87c0
DS
145}
146
147static void sharp_nhgroup_del_nexthop_cb(const struct nexthop_group_cmd *nhgc,
148 const struct nexthop *nhop)
149{
150 struct sharp_nhg lookup;
151 struct sharp_nhg *snhg;
21735352 152 struct nexthop_group_cmd *bnhgc = NULL;
569e87c0 153
73937edb 154 strlcpy(lookup.name, nhgc->name, sizeof(lookup.name));
569e87c0
DS
155 snhg = sharp_nhg_rb_find(&nhg_head, &lookup);
156
21735352
SW
157 if (nhgc->backup_list_name[0])
158 bnhgc = nhgc_find(nhgc->backup_list_name);
159
160 nhg_add(snhg->id, &nhgc->nhg, (bnhgc ? &bnhgc->nhg : NULL));
569e87c0
DS
161}
162
163static void sharp_nhgroup_delete_cb(const char *name)
164{
165 struct sharp_nhg lookup;
166 struct sharp_nhg *snhg;
167
73937edb 168 strlcpy(lookup.name, name, sizeof(lookup.name));
569e87c0
DS
169 snhg = sharp_nhg_rb_find(&nhg_head, &lookup);
170 if (!snhg)
171 return;
172
cc6a0d7d 173 nhg_del(snhg->id);
569e87c0
DS
174 sharp_nhg_rb_del(&nhg_head, snhg);
175 XFREE(MTYPE_NHG, snhg);
569e87c0
DS
176}
177
178uint32_t sharp_nhgroup_get_id(const char *name)
179{
180 struct sharp_nhg lookup;
181 struct sharp_nhg *snhg;
182
73937edb 183 strlcpy(lookup.name, name, sizeof(lookup.name));
569e87c0
DS
184 snhg = sharp_nhg_rb_find(&nhg_head, &lookup);
185 if (!snhg)
186 return 0;
187
188 return snhg->id;
189}
190
2053061b
SW
191void sharp_nhgroup_id_set_installed(uint32_t id, bool installed)
192{
193 struct sharp_nhg *snhg;
194
195 snhg = sharp_nhgroup_find_id(id);
196 if (!snhg) {
197 zlog_debug("%s: nhg %u not found", __func__, id);
198 return;
199 }
200
201 snhg->installed = installed;
202}
203
204bool sharp_nhgroup_id_is_installed(uint32_t id)
205{
206 struct sharp_nhg *snhg;
207
208 snhg = sharp_nhgroup_find_id(id);
209 if (!snhg) {
210 zlog_debug("%s: nhg %u not found", __func__, id);
211 return false;
212 }
213
214 return snhg->installed;
215}
216
569e87c0
DS
217void sharp_nhgroup_init(void)
218{
219 sharp_nhg_rb_init(&nhg_head);
220 nhg_id = zclient_get_nhg_start(ZEBRA_ROUTE_SHARP);
221
222 nexthop_group_init(sharp_nhgroup_add_cb, sharp_nhgroup_add_nexthop_cb,
223 sharp_nhgroup_del_nexthop_cb,
cc6a0d7d 224 sharp_nhgroup_delete_cb);
569e87c0 225}