]> git.proxmox.com Git - mirror_frr.git/blob - lib/nexthop_group.h
Merge pull request #13649 from donaldsharp/unlock_the_node_or_else
[mirror_frr.git] / lib / nexthop_group.h
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Nexthop Group structure definition.
4 * Copyright (C) 2018 Cumulus Networks, Inc.
5 * Donald Sharp
6 */
7
8 #ifndef __NEXTHOP_GROUP__
9 #define __NEXTHOP_GROUP__
10
11 #include <vty.h>
12 #include "json.h"
13
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17
18 struct nhg_resilience {
19 uint16_t buckets;
20 uint32_t idle_timer;
21 uint32_t unbalanced_timer;
22 uint64_t unbalanced_time;
23 };
24
25 /*
26 * What is a nexthop group?
27 *
28 * A nexthop group is a collection of nexthops that make up
29 * the ECMP path for the route.
30 *
31 * This module provides a proper abstraction to this idea.
32 */
33 struct nexthop_group {
34 struct nexthop *nexthop;
35
36 struct nhg_resilience nhgr;
37 };
38
39 struct nexthop_group *nexthop_group_new(void);
40 void nexthop_group_delete(struct nexthop_group **nhg);
41
42 void nexthop_group_copy(struct nexthop_group *to,
43 const struct nexthop_group *from);
44
45 /*
46 * Copy a list of nexthops in 'nh' to an nhg, enforcing canonical sort order
47 */
48 void nexthop_group_copy_nh_sorted(struct nexthop_group *nhg,
49 const struct nexthop *nh);
50
51 void copy_nexthops(struct nexthop **tnh, const struct nexthop *nh,
52 struct nexthop *rparent);
53
54 uint32_t nexthop_group_hash_no_recurse(const struct nexthop_group *nhg);
55 uint32_t nexthop_group_hash(const struct nexthop_group *nhg);
56 void nexthop_group_mark_duplicates(struct nexthop_group *nhg);
57
58 /* Add a nexthop to a list, enforcing the canonical sort order. */
59 void nexthop_group_add_sorted(struct nexthop_group *nhg,
60 struct nexthop *nexthop);
61
62 /* The following for loop allows to iterate over the nexthop
63 * structure of routes.
64 *
65 * head: The pointer to the first nexthop in the chain.
66 *
67 * nexthop: The pointer to the current nexthop, either in the
68 * top-level chain or in a resolved chain.
69 */
70 #define ALL_NEXTHOPS(head, nhop) \
71 (nhop) = (head.nexthop); \
72 (nhop); \
73 (nhop) = nexthop_next(nhop)
74
75 #define ALL_NEXTHOPS_PTR(head, nhop) \
76 (nhop) = ((head)->nexthop); \
77 (nhop); \
78 (nhop) = nexthop_next(nhop)
79
80
81 #define NHGC_NAME_SIZE 80
82
83 struct nexthop_group_cmd {
84
85 RB_ENTRY(nexthop_group_cmd) nhgc_entry;
86
87 char name[NHGC_NAME_SIZE];
88
89 /* Name of group containing backup nexthops (if set) */
90 char backup_list_name[NHGC_NAME_SIZE];
91
92 struct nexthop_group nhg;
93
94 struct list *nhg_list;
95
96 QOBJ_FIELDS;
97 };
98 RB_HEAD(nhgc_entry_head, nexthp_group_cmd);
99 RB_PROTOTYPE(nhgc_entry_head, nexthop_group_cmd, nhgc_entry,
100 nexthop_group_cmd_compare)
101 DECLARE_QOBJ_TYPE(nexthop_group_cmd);
102
103 /*
104 * Initialize nexthop_groups. If you are interested in when
105 * a nexthop_group is added/deleted/modified, then set the
106 * appropriate callback functions to handle it in your
107 * code
108 *
109 * create - The creation of the nexthop group
110 * modify - Modification of the nexthop group when not changing a nexthop
111 * ( resilience as an example )
112 * add_nexthop - A nexthop is added to the NHG
113 * del_nexthop - A nexthop is deleted from the NHG
114 * destroy - The NHG is deleted
115 */
116 void nexthop_group_init(
117 void (*create)(const char *name),
118 void (*modify)(const struct nexthop_group_cmd *nhgc),
119 void (*add_nexthop)(const struct nexthop_group_cmd *nhgc,
120 const struct nexthop *nhop),
121 void (*del_nexthop)(const struct nexthop_group_cmd *nhgc,
122 const struct nexthop *nhop),
123 void (*destroy)(const char *name));
124
125 void nexthop_group_enable_vrf(struct vrf *vrf);
126 void nexthop_group_disable_vrf(struct vrf *vrf);
127 void nexthop_group_interface_state_change(struct interface *ifp,
128 ifindex_t oldifindex);
129
130 extern struct nexthop *nexthop_exists(const struct nexthop_group *nhg,
131 const struct nexthop *nh);
132 /* This assumes ordered */
133 extern bool nexthop_group_equal_no_recurse(const struct nexthop_group *nhg1,
134 const struct nexthop_group *nhg2);
135
136 /* This assumes ordered */
137 extern bool nexthop_group_equal(const struct nexthop_group *nhg1,
138 const struct nexthop_group *nhg2);
139
140 extern struct nexthop_group_cmd *nhgc_find(const char *name);
141
142 extern void nexthop_group_write_nexthop_simple(struct vty *vty,
143 const struct nexthop *nh,
144 char *altifname);
145 extern void nexthop_group_write_nexthop(struct vty *vty,
146 const struct nexthop *nh);
147
148 extern void nexthop_group_json_nexthop(json_object *j,
149 const struct nexthop *nh);
150
151 /* Return the number of nexthops in this nhg */
152 extern uint8_t nexthop_group_nexthop_num(const struct nexthop_group *nhg);
153 extern uint8_t
154 nexthop_group_nexthop_num_no_recurse(const struct nexthop_group *nhg);
155 extern uint8_t
156 nexthop_group_active_nexthop_num(const struct nexthop_group *nhg);
157 extern uint8_t
158 nexthop_group_active_nexthop_num_no_recurse(const struct nexthop_group *nhg);
159
160 extern bool nexthop_group_has_label(const struct nexthop_group *nhg);
161
162 #ifdef __cplusplus
163 }
164 #endif
165
166 #endif