2 * SHARP - code to track nexthops
3 * Copyright (C) Cumulus Networks, Inc.
6 * This file is part of FRR.
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
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.
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
26 #include "nexthop_group.h"
31 #include "sharp_nht.h"
32 #include "sharp_globals.h"
33 #include "sharp_zebra.h"
35 DEFINE_MTYPE_STATIC(SHARPD
, NH_TRACKER
, "Nexthop Tracker")
36 DEFINE_MTYPE_STATIC(SHARPD
, NHG
, "Nexthop Group")
38 struct sharp_nh_tracker
*sharp_nh_tracker_get(struct prefix
*p
)
40 struct listnode
*node
;
41 struct sharp_nh_tracker
*nht
;
43 for (ALL_LIST_ELEMENTS_RO(sg
.nhs
, node
, nht
)) {
44 if (prefix_same(&nht
->p
, p
))
51 nht
= XCALLOC(MTYPE_NH_TRACKER
, sizeof(*nht
));
52 prefix_copy(&nht
->p
, p
);
54 listnode_add(sg
.nhs
, nht
);
58 void sharp_nh_tracker_dump(struct vty
*vty
)
60 struct listnode
*node
;
61 struct sharp_nh_tracker
*nht
;
63 for (ALL_LIST_ELEMENTS_RO(sg
.nhs
, node
, nht
)) {
64 char buf
[PREFIX_STRLEN
];
66 vty_out(vty
, "%s: Nexthops: %u Updates: %u\n",
67 prefix2str(&nht
->p
, buf
, sizeof(buf
)),
73 PREDECL_RBTREE_UNIQ(sharp_nhg_rb
);
76 struct sharp_nhg_rb_item mylistitem
;
85 static uint32_t nhg_id
;
87 static uint32_t sharp_get_next_nhid(void)
89 zlog_debug("NHG ID assigned: %u", nhg_id
);
93 struct sharp_nhg_rb_head nhg_head
;
95 static int sharp_nhg_compare_func(const struct sharp_nhg
*a
,
96 const struct sharp_nhg
*b
)
98 return strncmp(a
->name
, b
->name
, strlen(a
->name
));
101 DECLARE_RBTREE_UNIQ(sharp_nhg_rb
, struct sharp_nhg
, mylistitem
,
102 sharp_nhg_compare_func
);
104 static struct sharp_nhg
*sharp_nhgroup_find_id(uint32_t id
)
106 struct sharp_nhg
*lookup
;
108 /* Yea its just a for loop, I don't want add complexity
109 * to sharpd with another RB tree for just IDs
112 frr_each (sharp_nhg_rb
, &nhg_head
, lookup
) {
113 if (lookup
->id
== id
)
120 static void sharp_nhgroup_add_cb(const char *name
)
122 struct sharp_nhg
*snhg
;
124 snhg
= XCALLOC(MTYPE_NHG
, sizeof(*snhg
));
125 snhg
->id
= sharp_get_next_nhid();
126 strlcpy(snhg
->name
, name
, sizeof(snhg
->name
));
128 sharp_nhg_rb_add(&nhg_head
, snhg
);
131 static void sharp_nhgroup_add_nexthop_cb(const struct nexthop_group_cmd
*nhgc
,
132 const struct nexthop
*nhop
)
134 struct sharp_nhg lookup
;
135 struct sharp_nhg
*snhg
;
136 struct nexthop_group_cmd
*bnhgc
= NULL
;
138 strlcpy(lookup
.name
, nhgc
->name
, sizeof(lookup
.name
));
139 snhg
= sharp_nhg_rb_find(&nhg_head
, &lookup
);
141 if (nhgc
->backup_list_name
[0])
142 bnhgc
= nhgc_find(nhgc
->backup_list_name
);
144 nhg_add(snhg
->id
, &nhgc
->nhg
, (bnhgc
? &bnhgc
->nhg
: NULL
));
147 static void sharp_nhgroup_del_nexthop_cb(const struct nexthop_group_cmd
*nhgc
,
148 const struct nexthop
*nhop
)
150 struct sharp_nhg lookup
;
151 struct sharp_nhg
*snhg
;
152 struct nexthop_group_cmd
*bnhgc
= NULL
;
154 strlcpy(lookup
.name
, nhgc
->name
, sizeof(lookup
.name
));
155 snhg
= sharp_nhg_rb_find(&nhg_head
, &lookup
);
157 if (nhgc
->backup_list_name
[0])
158 bnhgc
= nhgc_find(nhgc
->backup_list_name
);
160 nhg_add(snhg
->id
, &nhgc
->nhg
, (bnhgc
? &bnhgc
->nhg
: NULL
));
163 static void sharp_nhgroup_delete_cb(const char *name
)
165 struct sharp_nhg lookup
;
166 struct sharp_nhg
*snhg
;
168 strlcpy(lookup
.name
, name
, sizeof(lookup
.name
));
169 snhg
= sharp_nhg_rb_find(&nhg_head
, &lookup
);
174 sharp_nhg_rb_del(&nhg_head
, snhg
);
175 XFREE(MTYPE_NHG
, snhg
);
178 uint32_t sharp_nhgroup_get_id(const char *name
)
180 struct sharp_nhg lookup
;
181 struct sharp_nhg
*snhg
;
183 strlcpy(lookup
.name
, name
, sizeof(lookup
.name
));
184 snhg
= sharp_nhg_rb_find(&nhg_head
, &lookup
);
191 void sharp_nhgroup_id_set_installed(uint32_t id
, bool installed
)
193 struct sharp_nhg
*snhg
;
195 snhg
= sharp_nhgroup_find_id(id
);
197 zlog_debug("%s: nhg %u not found", __func__
, id
);
201 snhg
->installed
= installed
;
204 bool sharp_nhgroup_id_is_installed(uint32_t id
)
206 struct sharp_nhg
*snhg
;
208 snhg
= sharp_nhgroup_find_id(id
);
210 zlog_debug("%s: nhg %u not found", __func__
, id
);
214 return snhg
->installed
;
217 void sharp_nhgroup_init(void)
219 sharp_nhg_rb_init(&nhg_head
);
220 nhg_id
= zclient_get_nhg_start(ZEBRA_ROUTE_SHARP
);
222 nexthop_group_init(sharp_nhgroup_add_cb
, sharp_nhgroup_add_nexthop_cb
,
223 sharp_nhgroup_del_nexthop_cb
,
224 sharp_nhgroup_delete_cb
);