]>
Commit | Line | Data |
---|---|---|
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 | 34 | |
bf8d3d6a DL |
35 | DEFINE_MTYPE_STATIC(SHARPD, NH_TRACKER, "Nexthop Tracker"); |
36 | DEFINE_MTYPE_STATIC(SHARPD, NHG, "Nexthop Group"); | |
86da53ab DS |
37 | |
38 | struct 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 | ||
58 | void sharp_nh_tracker_dump(struct vty *vty) | |
59 | { | |
60 | struct listnode *node; | |
61 | struct sharp_nh_tracker *nht; | |
62 | ||
2dbe669b DA |
63 | for (ALL_LIST_ELEMENTS_RO(sg.nhs, node, nht)) |
64 | vty_out(vty, "%pFX: Nexthops: %u Updates: %u\n", &nht->p, | |
65 | nht->nhop_num, nht->updates); | |
86da53ab | 66 | } |
569e87c0 DS |
67 | |
68 | PREDECL_RBTREE_UNIQ(sharp_nhg_rb); | |
69 | ||
70 | struct sharp_nhg { | |
71 | struct sharp_nhg_rb_item mylistitem; | |
72 | ||
73 | uint32_t id; | |
74 | ||
2b442f69 DS |
75 | #define NHG_NAME_LEN 256 |
76 | char name[NHG_NAME_LEN]; | |
2053061b SW |
77 | |
78 | bool installed; | |
569e87c0 DS |
79 | }; |
80 | ||
81 | static uint32_t nhg_id; | |
82 | ||
83 | static uint32_t sharp_get_next_nhid(void) | |
84 | { | |
612fcc5e | 85 | zlog_debug("NHG ID assigned: %u", nhg_id); |
569e87c0 DS |
86 | return nhg_id++; |
87 | } | |
88 | ||
89 | struct sharp_nhg_rb_head nhg_head; | |
90 | ||
91 | static int sharp_nhg_compare_func(const struct sharp_nhg *a, | |
92 | const struct sharp_nhg *b) | |
93 | { | |
2b442f69 | 94 | return strncmp(a->name, b->name, NHG_NAME_LEN); |
569e87c0 DS |
95 | } |
96 | ||
97 | DECLARE_RBTREE_UNIQ(sharp_nhg_rb, struct sharp_nhg, mylistitem, | |
98 | sharp_nhg_compare_func); | |
99 | ||
2053061b SW |
100 | static struct sharp_nhg *sharp_nhgroup_find_id(uint32_t id) |
101 | { | |
102 | struct sharp_nhg *lookup; | |
103 | ||
104 | /* Yea its just a for loop, I don't want add complexity | |
105 | * to sharpd with another RB tree for just IDs | |
106 | */ | |
107 | ||
ff9aca4f | 108 | frr_each (sharp_nhg_rb, &nhg_head, lookup) { |
2053061b SW |
109 | if (lookup->id == id) |
110 | return lookup; | |
111 | } | |
112 | ||
113 | return NULL; | |
114 | } | |
115 | ||
569e87c0 DS |
116 | static void sharp_nhgroup_add_cb(const char *name) |
117 | { | |
118 | struct sharp_nhg *snhg; | |
119 | ||
120 | snhg = XCALLOC(MTYPE_NHG, sizeof(*snhg)); | |
121 | snhg->id = sharp_get_next_nhid(); | |
73937edb | 122 | strlcpy(snhg->name, name, sizeof(snhg->name)); |
569e87c0 DS |
123 | |
124 | sharp_nhg_rb_add(&nhg_head, snhg); | |
569e87c0 DS |
125 | } |
126 | ||
127 | static void sharp_nhgroup_add_nexthop_cb(const struct nexthop_group_cmd *nhgc, | |
128 | const struct nexthop *nhop) | |
129 | { | |
130 | struct sharp_nhg lookup; | |
131 | struct sharp_nhg *snhg; | |
21735352 | 132 | struct nexthop_group_cmd *bnhgc = NULL; |
569e87c0 | 133 | |
73937edb | 134 | strlcpy(lookup.name, nhgc->name, sizeof(lookup.name)); |
569e87c0 DS |
135 | snhg = sharp_nhg_rb_find(&nhg_head, &lookup); |
136 | ||
21735352 SW |
137 | if (nhgc->backup_list_name[0]) |
138 | bnhgc = nhgc_find(nhgc->backup_list_name); | |
139 | ||
140 | nhg_add(snhg->id, &nhgc->nhg, (bnhgc ? &bnhgc->nhg : NULL)); | |
569e87c0 DS |
141 | } |
142 | ||
143 | static void sharp_nhgroup_del_nexthop_cb(const struct nexthop_group_cmd *nhgc, | |
144 | const struct nexthop *nhop) | |
145 | { | |
146 | struct sharp_nhg lookup; | |
147 | struct sharp_nhg *snhg; | |
21735352 | 148 | struct nexthop_group_cmd *bnhgc = NULL; |
569e87c0 | 149 | |
73937edb | 150 | strlcpy(lookup.name, nhgc->name, sizeof(lookup.name)); |
569e87c0 DS |
151 | snhg = sharp_nhg_rb_find(&nhg_head, &lookup); |
152 | ||
21735352 SW |
153 | if (nhgc->backup_list_name[0]) |
154 | bnhgc = nhgc_find(nhgc->backup_list_name); | |
155 | ||
156 | nhg_add(snhg->id, &nhgc->nhg, (bnhgc ? &bnhgc->nhg : NULL)); | |
569e87c0 DS |
157 | } |
158 | ||
159 | static void sharp_nhgroup_delete_cb(const char *name) | |
160 | { | |
161 | struct sharp_nhg lookup; | |
162 | struct sharp_nhg *snhg; | |
163 | ||
73937edb | 164 | strlcpy(lookup.name, name, sizeof(lookup.name)); |
569e87c0 DS |
165 | snhg = sharp_nhg_rb_find(&nhg_head, &lookup); |
166 | if (!snhg) | |
167 | return; | |
168 | ||
cc6a0d7d | 169 | nhg_del(snhg->id); |
569e87c0 DS |
170 | sharp_nhg_rb_del(&nhg_head, snhg); |
171 | XFREE(MTYPE_NHG, snhg); | |
569e87c0 DS |
172 | } |
173 | ||
174 | uint32_t sharp_nhgroup_get_id(const char *name) | |
175 | { | |
176 | struct sharp_nhg lookup; | |
177 | struct sharp_nhg *snhg; | |
178 | ||
73937edb | 179 | strlcpy(lookup.name, name, sizeof(lookup.name)); |
569e87c0 DS |
180 | snhg = sharp_nhg_rb_find(&nhg_head, &lookup); |
181 | if (!snhg) | |
182 | return 0; | |
183 | ||
184 | return snhg->id; | |
185 | } | |
186 | ||
2053061b SW |
187 | void sharp_nhgroup_id_set_installed(uint32_t id, bool installed) |
188 | { | |
189 | struct sharp_nhg *snhg; | |
190 | ||
191 | snhg = sharp_nhgroup_find_id(id); | |
192 | if (!snhg) { | |
193 | zlog_debug("%s: nhg %u not found", __func__, id); | |
194 | return; | |
195 | } | |
196 | ||
197 | snhg->installed = installed; | |
198 | } | |
199 | ||
200 | bool sharp_nhgroup_id_is_installed(uint32_t id) | |
201 | { | |
202 | struct sharp_nhg *snhg; | |
203 | ||
204 | snhg = sharp_nhgroup_find_id(id); | |
205 | if (!snhg) { | |
206 | zlog_debug("%s: nhg %u not found", __func__, id); | |
207 | return false; | |
208 | } | |
209 | ||
210 | return snhg->installed; | |
211 | } | |
212 | ||
569e87c0 DS |
213 | void sharp_nhgroup_init(void) |
214 | { | |
215 | sharp_nhg_rb_init(&nhg_head); | |
216 | nhg_id = zclient_get_nhg_start(ZEBRA_ROUTE_SHARP); | |
217 | ||
218 | nexthop_group_init(sharp_nhgroup_add_cb, sharp_nhgroup_add_nexthop_cb, | |
219 | sharp_nhgroup_del_nexthop_cb, | |
cc6a0d7d | 220 | sharp_nhgroup_delete_cb); |
569e87c0 | 221 | } |