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 vty_out(vty
, "%pFX: Nexthops: %u Updates: %u\n", &nht
->p
,
65 nht
->nhop_num
, nht
->updates
);
68 PREDECL_RBTREE_UNIQ(sharp_nhg_rb
);
71 struct sharp_nhg_rb_item mylistitem
;
75 #define NHG_NAME_LEN 256
76 char name
[NHG_NAME_LEN
];
81 static uint32_t nhg_id
;
83 static uint32_t sharp_get_next_nhid(void)
85 zlog_debug("NHG ID assigned: %u", nhg_id
);
89 struct sharp_nhg_rb_head nhg_head
;
91 static int sharp_nhg_compare_func(const struct sharp_nhg
*a
,
92 const struct sharp_nhg
*b
)
94 return strncmp(a
->name
, b
->name
, NHG_NAME_LEN
);
97 DECLARE_RBTREE_UNIQ(sharp_nhg_rb
, struct sharp_nhg
, mylistitem
,
98 sharp_nhg_compare_func
);
100 static struct sharp_nhg
*sharp_nhgroup_find_id(uint32_t id
)
102 struct sharp_nhg
*lookup
;
104 /* Yea its just a for loop, I don't want add complexity
105 * to sharpd with another RB tree for just IDs
108 frr_each (sharp_nhg_rb
, &nhg_head
, lookup
) {
109 if (lookup
->id
== id
)
116 static void sharp_nhgroup_add_cb(const char *name
)
118 struct sharp_nhg
*snhg
;
120 snhg
= XCALLOC(MTYPE_NHG
, sizeof(*snhg
));
121 snhg
->id
= sharp_get_next_nhid();
122 strlcpy(snhg
->name
, name
, sizeof(snhg
->name
));
124 sharp_nhg_rb_add(&nhg_head
, snhg
);
127 static void sharp_nhgroup_add_nexthop_cb(const struct nexthop_group_cmd
*nhgc
,
128 const struct nexthop
*nhop
)
130 struct sharp_nhg lookup
;
131 struct sharp_nhg
*snhg
;
132 struct nexthop_group_cmd
*bnhgc
= NULL
;
134 strlcpy(lookup
.name
, nhgc
->name
, sizeof(lookup
.name
));
135 snhg
= sharp_nhg_rb_find(&nhg_head
, &lookup
);
137 if (nhgc
->backup_list_name
[0])
138 bnhgc
= nhgc_find(nhgc
->backup_list_name
);
140 nhg_add(snhg
->id
, &nhgc
->nhg
, (bnhgc
? &bnhgc
->nhg
: NULL
));
143 static void sharp_nhgroup_del_nexthop_cb(const struct nexthop_group_cmd
*nhgc
,
144 const struct nexthop
*nhop
)
146 struct sharp_nhg lookup
;
147 struct sharp_nhg
*snhg
;
148 struct nexthop_group_cmd
*bnhgc
= NULL
;
150 strlcpy(lookup
.name
, nhgc
->name
, sizeof(lookup
.name
));
151 snhg
= sharp_nhg_rb_find(&nhg_head
, &lookup
);
153 if (nhgc
->backup_list_name
[0])
154 bnhgc
= nhgc_find(nhgc
->backup_list_name
);
156 nhg_add(snhg
->id
, &nhgc
->nhg
, (bnhgc
? &bnhgc
->nhg
: NULL
));
159 static void sharp_nhgroup_delete_cb(const char *name
)
161 struct sharp_nhg lookup
;
162 struct sharp_nhg
*snhg
;
164 strlcpy(lookup
.name
, name
, sizeof(lookup
.name
));
165 snhg
= sharp_nhg_rb_find(&nhg_head
, &lookup
);
170 sharp_nhg_rb_del(&nhg_head
, snhg
);
171 XFREE(MTYPE_NHG
, snhg
);
174 uint32_t sharp_nhgroup_get_id(const char *name
)
176 struct sharp_nhg lookup
;
177 struct sharp_nhg
*snhg
;
179 strlcpy(lookup
.name
, name
, sizeof(lookup
.name
));
180 snhg
= sharp_nhg_rb_find(&nhg_head
, &lookup
);
187 void sharp_nhgroup_id_set_installed(uint32_t id
, bool installed
)
189 struct sharp_nhg
*snhg
;
191 snhg
= sharp_nhgroup_find_id(id
);
193 zlog_debug("%s: nhg %u not found", __func__
, id
);
197 snhg
->installed
= installed
;
200 bool sharp_nhgroup_id_is_installed(uint32_t id
)
202 struct sharp_nhg
*snhg
;
204 snhg
= sharp_nhgroup_find_id(id
);
206 zlog_debug("%s: nhg %u not found", __func__
, id
);
210 return snhg
->installed
;
213 void sharp_nhgroup_init(void)
215 sharp_nhg_rb_init(&nhg_head
);
216 nhg_id
= zclient_get_nhg_start(ZEBRA_ROUTE_SHARP
);
218 nexthop_group_init(sharp_nhgroup_add_cb
, sharp_nhgroup_add_nexthop_cb
,
219 sharp_nhgroup_del_nexthop_cb
,
220 sharp_nhgroup_delete_cb
);