]> git.proxmox.com Git - mirror_frr.git/blob - sharpd/sharp_nht.c
Merge pull request #12760 from opensourcerouting/fix/switch_to_pr_for_commitlint
[mirror_frr.git] / sharpd / sharp_nht.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * SHARP - code to track nexthops
4 * Copyright (C) Cumulus Networks, Inc.
5 * Donald Sharp
6 */
7 #include <zebra.h>
8
9 #include "memory.h"
10 #include "nexthop.h"
11 #include "nexthop_group.h"
12 #include "vty.h"
13 #include "typesafe.h"
14 #include "zclient.h"
15
16 #include "sharp_nht.h"
17 #include "sharp_globals.h"
18 #include "sharp_zebra.h"
19
20 DEFINE_MTYPE_STATIC(SHARPD, NH_TRACKER, "Nexthop Tracker");
21 DEFINE_MTYPE_STATIC(SHARPD, NHG, "Nexthop Group");
22
23 struct sharp_nh_tracker *sharp_nh_tracker_get(struct prefix *p)
24 {
25 struct listnode *node;
26 struct sharp_nh_tracker *nht;
27
28 for (ALL_LIST_ELEMENTS_RO(sg.nhs, node, nht)) {
29 if (prefix_same(&nht->p, p))
30 break;
31 }
32
33 if (nht)
34 return nht;
35
36 nht = XCALLOC(MTYPE_NH_TRACKER, sizeof(*nht));
37 prefix_copy(&nht->p, p);
38
39 listnode_add(sg.nhs, nht);
40 return nht;
41 }
42
43 void sharp_nh_tracker_dump(struct vty *vty)
44 {
45 struct listnode *node;
46 struct sharp_nh_tracker *nht;
47
48 for (ALL_LIST_ELEMENTS_RO(sg.nhs, node, nht))
49 vty_out(vty, "%pFX: Nexthops: %u Updates: %u\n", &nht->p,
50 nht->nhop_num, nht->updates);
51 }
52
53 PREDECL_RBTREE_UNIQ(sharp_nhg_rb);
54
55 struct sharp_nhg {
56 struct sharp_nhg_rb_item mylistitem;
57
58 uint32_t id;
59
60 #define NHG_NAME_LEN 256
61 char name[NHG_NAME_LEN];
62
63 bool installed;
64 };
65
66 static uint32_t nhg_id;
67
68 static uint32_t sharp_get_next_nhid(void)
69 {
70 zlog_debug("NHG ID assigned: %u", nhg_id);
71 return nhg_id++;
72 }
73
74 struct sharp_nhg_rb_head nhg_head;
75
76 static int sharp_nhg_compare_func(const struct sharp_nhg *a,
77 const struct sharp_nhg *b)
78 {
79 return strncmp(a->name, b->name, NHG_NAME_LEN);
80 }
81
82 DECLARE_RBTREE_UNIQ(sharp_nhg_rb, struct sharp_nhg, mylistitem,
83 sharp_nhg_compare_func);
84
85 static struct sharp_nhg *sharp_nhgroup_find_id(uint32_t id)
86 {
87 struct sharp_nhg *lookup;
88
89 /* Yea its just a for loop, I don't want add complexity
90 * to sharpd with another RB tree for just IDs
91 */
92
93 frr_each (sharp_nhg_rb, &nhg_head, lookup) {
94 if (lookup->id == id)
95 return lookup;
96 }
97
98 return NULL;
99 }
100
101 static void sharp_nhgroup_add_cb(const char *name)
102 {
103 struct sharp_nhg *snhg;
104
105 snhg = XCALLOC(MTYPE_NHG, sizeof(*snhg));
106 snhg->id = sharp_get_next_nhid();
107 strlcpy(snhg->name, name, sizeof(snhg->name));
108
109 sharp_nhg_rb_add(&nhg_head, snhg);
110 }
111
112 static void sharp_nhgroup_modify_cb(const struct nexthop_group_cmd *nhgc)
113 {
114 struct sharp_nhg lookup;
115 struct sharp_nhg *snhg;
116 struct nexthop_group_cmd *bnhgc = NULL;
117
118 strlcpy(lookup.name, nhgc->name, sizeof(lookup.name));
119 snhg = sharp_nhg_rb_find(&nhg_head, &lookup);
120
121 if (!nhgc->nhg.nexthop)
122 return;
123
124 if (nhgc->backup_list_name[0])
125 bnhgc = nhgc_find(nhgc->backup_list_name);
126
127 nhg_add(snhg->id, &nhgc->nhg, (bnhgc ? &bnhgc->nhg : NULL));
128 }
129
130 static void sharp_nhgroup_add_nexthop_cb(const struct nexthop_group_cmd *nhgc,
131 const struct nexthop *nhop)
132 {
133 struct sharp_nhg lookup;
134 struct sharp_nhg *snhg;
135 struct nexthop_group_cmd *bnhgc = NULL;
136
137 strlcpy(lookup.name, nhgc->name, sizeof(lookup.name));
138 snhg = sharp_nhg_rb_find(&nhg_head, &lookup);
139
140 if (nhgc->backup_list_name[0])
141 bnhgc = nhgc_find(nhgc->backup_list_name);
142
143 nhg_add(snhg->id, &nhgc->nhg, (bnhgc ? &bnhgc->nhg : NULL));
144 }
145
146 static void sharp_nhgroup_del_nexthop_cb(const struct nexthop_group_cmd *nhgc,
147 const struct nexthop *nhop)
148 {
149 struct sharp_nhg lookup;
150 struct sharp_nhg *snhg;
151 struct nexthop_group_cmd *bnhgc = NULL;
152
153 strlcpy(lookup.name, nhgc->name, sizeof(lookup.name));
154 snhg = sharp_nhg_rb_find(&nhg_head, &lookup);
155
156 if (nhgc->backup_list_name[0])
157 bnhgc = nhgc_find(nhgc->backup_list_name);
158
159 nhg_add(snhg->id, &nhgc->nhg, (bnhgc ? &bnhgc->nhg : NULL));
160 }
161
162 static void sharp_nhgroup_delete_cb(const char *name)
163 {
164 struct sharp_nhg lookup;
165 struct sharp_nhg *snhg;
166
167 strlcpy(lookup.name, name, sizeof(lookup.name));
168 snhg = sharp_nhg_rb_find(&nhg_head, &lookup);
169 if (!snhg)
170 return;
171
172 nhg_del(snhg->id);
173 sharp_nhg_rb_del(&nhg_head, snhg);
174 XFREE(MTYPE_NHG, snhg);
175 }
176
177 uint32_t sharp_nhgroup_get_id(const char *name)
178 {
179 struct sharp_nhg lookup;
180 struct sharp_nhg *snhg;
181
182 strlcpy(lookup.name, name, sizeof(lookup.name));
183 snhg = sharp_nhg_rb_find(&nhg_head, &lookup);
184 if (!snhg)
185 return 0;
186
187 return snhg->id;
188 }
189
190 void sharp_nhgroup_id_set_installed(uint32_t id, bool installed)
191 {
192 struct sharp_nhg *snhg;
193
194 snhg = sharp_nhgroup_find_id(id);
195 if (!snhg) {
196 zlog_debug("%s: nhg %u not found", __func__, id);
197 return;
198 }
199
200 snhg->installed = installed;
201 }
202
203 bool sharp_nhgroup_id_is_installed(uint32_t id)
204 {
205 struct sharp_nhg *snhg;
206
207 snhg = sharp_nhgroup_find_id(id);
208 if (!snhg) {
209 zlog_debug("%s: nhg %u not found", __func__, id);
210 return false;
211 }
212
213 return snhg->installed;
214 }
215
216 void sharp_nhgroup_init(void)
217 {
218 sharp_nhg_rb_init(&nhg_head);
219 nhg_id = zclient_get_nhg_start(ZEBRA_ROUTE_SHARP);
220
221 nexthop_group_init(sharp_nhgroup_add_cb, sharp_nhgroup_modify_cb,
222 sharp_nhgroup_add_nexthop_cb,
223 sharp_nhgroup_del_nexthop_cb,
224 sharp_nhgroup_delete_cb);
225 }