Skip to content

Commit c20fa97

Browse files
committed
zebra: Create Singleton nhg's without weights
Currently FRR when it has two nexthop groups: A nexthop 1 weight 5 nexthop 2 weight 6 nexthop 3 weight 7 B nexthop 1 weight 3 nexthop 2 weight 4 nexthop 3 weight 5 We end up with 5 singleton nexthops and two groups: ID: 181818168 (sharp) RefCnt: 1 Uptime: 00:04:52 VRF: default Valid, Installed Depends: (69) (70) (71) via 192.168.119.1, enp13s0 (vrf default), weight 182 via 192.168.119.2, enp13s0 (vrf default), weight 218 via 192.168.119.3, enp13s0 (vrf default), weight 255 ID: 181818169 (sharp) RefCnt: 1 Uptime: 00:02:08 VRF: default Valid, Installed Depends: (71) (127) (128) via 192.168.119.1, enp13s0 (vrf default), weight 127 via 192.168.119.2, enp13s0 (vrf default), weight 170 via 192.168.119.3, enp13s0 (vrf default), weight 255 id 69 via 192.168.119.1 dev enp13s0 scope link proto 194 id 70 via 192.168.119.2 dev enp13s0 scope link proto 194 id 71 via 192.168.119.3 dev enp13s0 scope link proto 194 id 127 via 192.168.119.1 dev enp13s0 scope link proto 194 id 128 via 192.168.119.2 dev enp13s0 scope link proto 194 id 181818168 group 69,182/70,218/71,255 proto 194 id 181818169 group 71,255/127,127/128,170 proto 194 This is not a desirable state to be in. If you have a link flapping in the network and weights are changing rapidly you end up with a large number of singleton nexthops that are being used by the nexthop groups. This fills up asic space and clutters the table. Additionally singleton nexthops cannot have any weight and the fact that you attempt to create a singleton nexthop with different weights means nothing to the linux kernel( or any asic dplane ). Let's modify the code to always create the singleton nexthops without a weight and then just creating the NHG's that use the singletons with the appropriate weight. ID: 181818168 (sharp) RefCnt: 1 Uptime: 00:00:32 VRF: default Valid, Installed Depends: (22) (24) (28) via 192.168.119.1, enp13s0 (vrf default), weight 182 via 192.168.119.2, enp13s0 (vrf default), weight 218 via 192.168.119.3, enp13s0 (vrf default), weight 255 ID: 181818169 (sharp) RefCnt: 1 Uptime: 00:00:14 VRF: default Valid, Installed Depends: (22) (24) (28) via 192.168.119.1, enp13s0 (vrf default), weight 153 via 192.168.119.2, enp13s0 (vrf default), weight 204 via 192.168.119.3, enp13s0 (vrf default), weight 255 id 22 via 192.168.119.1 dev enp13s0 scope link proto 194 id 24 via 192.168.119.2 dev enp13s0 scope link proto 194 id 28 via 192.168.119.3 dev enp13s0 scope link proto 194 id 181818168 group 22,182/24,218/28,255 proto 194 id 181818169 group 22,153/24,204/28,255 proto 194 Signed-off-by: Donald Sharp <[email protected]>
1 parent b8e24a0 commit c20fa97

File tree

1 file changed

+43
-5
lines changed

1 file changed

+43
-5
lines changed

zebra/zebra_nhg.c

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1417,6 +1417,11 @@ static struct nhg_hash_entry *depends_find_singleton(const struct nexthop *nh,
14171417
*/
14181418
nexthop_copy_no_recurse(&lookup, nh, NULL);
14191419

1420+
/*
1421+
* So this is to intentionally cause the singleton nexthop
1422+
* to be created with a weight of 1.
1423+
*/
1424+
lookup.weight = 1;
14201425
nhe = zebra_nhg_find_nexthop(0, &lookup, afi, type, from_dplane);
14211426

14221427
/* The copy may have allocated labels; free them if necessary. */
@@ -3010,13 +3015,14 @@ int nexthop_active_update(struct route_node *rn, struct route_entry *re)
30103015
* I'm pretty sure we only allow ONE level of group within group currently.
30113016
* But making this recursive just in case that ever changes.
30123017
*/
3013-
static uint8_t zebra_nhg_nhe2grp_internal(struct nh_grp *grp,
3014-
uint8_t curr_index,
3018+
static uint8_t zebra_nhg_nhe2grp_internal(struct nh_grp *grp, uint8_t curr_index,
30153019
struct nhg_hash_entry *nhe,
3020+
struct nhg_hash_entry *original,
30163021
int max_num)
30173022
{
30183023
struct nhg_connected *rb_node_dep = NULL;
30193024
struct nhg_hash_entry *depend = NULL;
3025+
struct nexthop *nexthop;
30203026
uint8_t i = curr_index;
30213027

30223028
frr_each(nhg_connected_tree, &nhe->nhg_depends, rb_node_dep) {
@@ -3043,8 +3049,11 @@ static uint8_t zebra_nhg_nhe2grp_internal(struct nh_grp *grp,
30433049

30443050
if (!zebra_nhg_depends_is_empty(depend)) {
30453051
/* This is a group within a group */
3046-
i = zebra_nhg_nhe2grp_internal(grp, i, depend, max_num);
3052+
i = zebra_nhg_nhe2grp_internal(grp, i, depend, nhe,
3053+
max_num);
30473054
} else {
3055+
bool found;
3056+
30483057
if (!CHECK_FLAG(depend->flags, NEXTHOP_GROUP_VALID)) {
30493058
if (IS_ZEBRA_DEBUG_RIB_DETAILED
30503059
|| IS_ZEBRA_DEBUG_NHG)
@@ -3085,8 +3094,37 @@ static uint8_t zebra_nhg_nhe2grp_internal(struct nh_grp *grp,
30853094
continue;
30863095
}
30873096

3097+
/*
3098+
* So we need to create the nexthop group with
3099+
* the appropriate weights. The nexthops weights
3100+
* are stored in the fully resolved nexthops for
3101+
* the nhg so we need to find the appropriate
3102+
* nexthop associated with this and set the weight
3103+
* appropriately
3104+
*/
3105+
found = false;
3106+
for (ALL_NEXTHOPS_PTR(&original->nhg, nexthop)) {
3107+
if (CHECK_FLAG(nexthop->flags,
3108+
NEXTHOP_FLAG_RECURSIVE))
3109+
continue;
3110+
3111+
if (nexthop_cmp_no_weight(depend->nhg.nexthop,
3112+
nexthop) != 0)
3113+
continue;
3114+
3115+
found = true;
3116+
break;
3117+
}
3118+
3119+
if (!found) {
3120+
if (IS_ZEBRA_DEBUG_RIB_DETAILED ||
3121+
IS_ZEBRA_DEBUG_NHG)
3122+
zlog_debug("%s: Nexthop ID (%u) unable to find nexthop in Nexthop Gropu Entry, something is terribly wrong",
3123+
__func__, depend->id);
3124+
continue;
3125+
}
30883126
grp[i].id = depend->id;
3089-
grp[i].weight = depend->nhg.nexthop->weight;
3127+
grp[i].weight = nexthop->weight;
30903128
i++;
30913129
}
30923130
}
@@ -3110,7 +3148,7 @@ uint8_t zebra_nhg_nhe2grp(struct nh_grp *grp, struct nhg_hash_entry *nhe,
31103148
int max_num)
31113149
{
31123150
/* Call into the recursive function */
3113-
return zebra_nhg_nhe2grp_internal(grp, 0, nhe, max_num);
3151+
return zebra_nhg_nhe2grp_internal(grp, 0, nhe, nhe, max_num);
31143152
}
31153153

31163154
void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe)

0 commit comments

Comments
 (0)