-
Notifications
You must be signed in to change notification settings - Fork 23
Ifindex nexthop #271
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ifindex nexthop #271
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -227,6 +227,10 @@ static int grout_gr_nexthop_to_frr_nexthop( | |
| *nh_family = AF_INET6; | ||
| memcpy(&nh->gate.ipv6, &gr_nh->ipv6, sz); | ||
| break; | ||
| case GR_AF_UNSPEC: | ||
| nh->type = NEXTHOP_TYPE_IFINDEX; | ||
| *nh_family = AF_UNSPEC; | ||
| break; | ||
| default: | ||
| gr_log_debug("inval nexthop family %u, nexthop not sync", gr_nh->af); | ||
| return -1; | ||
|
|
@@ -294,7 +298,7 @@ static void grout_route_change( | |
| return; | ||
| } | ||
|
|
||
| if (nh_family != family) { | ||
| if (nh_family != AF_UNSPEC && nh_family != family) { | ||
rjarry marked this conversation as resolved.
Show resolved
Hide resolved
Comment on lines
298
to
+301
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Logic bug: comparing the pointer |
||
| gr_log_debug( | ||
| "nexthop family %u different that route family %u nexthop, " | ||
| "ignoring", | ||
|
|
@@ -850,8 +854,11 @@ enum zebra_dplane_result grout_add_del_nexthop(struct zebra_dplane_ctx *ctx) { | |
| gr_log_debug("add nexthop id %u gw %pI6", nh_id, &gr_nh->ipv6); | ||
| break; | ||
| case NEXTHOP_TYPE_IFINDEX: | ||
| gr_log_debug("add nexthop id %u ifindex %u", nh_id, gr_nh->iface_id); | ||
| return ZEBRA_DPLANE_REQUEST_FAILURE; | ||
| // dplane_ctx_get_nhe_afi(ctx) returns AFI_IP for a nexthop with no gateway | ||
| // force to UNSPEC for grout | ||
| gr_nh->af = GR_AF_UNSPEC; | ||
| gr_log_debug("add nexthop id %u with ifindex %u", nh_id, gr_nh->iface_id); | ||
| break; | ||
| default: | ||
| gr_log_err("impossible to add nexthop %u (type %u not supported)", nh_id, nh->type); | ||
| return ZEBRA_DPLANE_REQUEST_FAILURE; | ||
|
|
@@ -890,6 +897,10 @@ void grout_nexthop_change(bool new, struct gr_nexthop *gr_nh) { | |
| return; | ||
| } | ||
|
|
||
| // kernel set INET4 when no gateway, let's do the same | ||
| if (family == AF_UNSPEC) | ||
| family = AF_INET; | ||
|
|
||
| afi = family2afi(family); | ||
| type = origin2zebra(gr_nh->origin, family, false); | ||
| SET_FLAG(nh.flags, NEXTHOP_FLAG_ACTIVE); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| // SPDX-License-Identifier: BSD-3-Clause | ||
| // Copyright (c) 2025 Maxime Leroy, Free Mobile | ||
| // Simple ID allocator built on top of DPDK’s rte_bitmap | ||
| // bit 1 ⇒ ID free | ||
| // bit 0 ⇒ ID reserved | ||
| // single writer, any number of readers | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <gr_errno.h> | ||
|
|
||
| #include <rte_bitmap.h> | ||
| #include <rte_malloc.h> | ||
|
|
||
| #include <stdint.h> | ||
|
|
||
| struct gr_id_pool { | ||
| uint32_t max_ids; | ||
| uint32_t used; | ||
|
Comment on lines
+16
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Member |
||
| // struct rte_bitmap must be aligned on a cache line | ||
| // it's required by rte_bitmap library. | ||
| struct rte_bitmap bmp __rte_cache_aligned; | ||
maxime-leroy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }; | ||
|
|
||
| static inline struct gr_id_pool *gr_id_pool_create(const char *id_pool_name, uint32_t max_ids) { | ||
| size_t p_size, b_size; | ||
| struct gr_id_pool *p; | ||
|
|
||
| b_size = rte_bitmap_get_memory_footprint(max_ids); | ||
| p_size = sizeof(struct gr_id_pool) - sizeof(struct rte_bitmap) + b_size; | ||
|
Comment on lines
+27
to
+30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Potential integer overflow computing |
||
| p = rte_zmalloc(id_pool_name, p_size, RTE_CACHE_LINE_SIZE); | ||
| if (!p) | ||
| return NULL; | ||
|
|
||
| if (!rte_bitmap_init_with_all_set(max_ids, (uint8_t *)&p->bmp, b_size)) { | ||
| rte_free(p); | ||
| return NULL; | ||
| } | ||
|
|
||
| p->max_ids = max_ids; | ||
| p->used = 0; | ||
| return p; | ||
| } | ||
|
|
||
| static inline void gr_id_pool_destroy(struct gr_id_pool *p) { | ||
| if (!p) | ||
| return; | ||
|
|
||
| rte_free(p); | ||
| } | ||
|
|
||
| static inline uint32_t gr_id_pool_used(struct gr_id_pool *p) { | ||
| return p->used; | ||
| } | ||
|
|
||
| static inline uint32_t gr_id_pool_avail(struct gr_id_pool *p) { | ||
| return p->max_ids - p->used; | ||
| } | ||
|
|
||
| // Get the lowest‑numbered free ID; 0 if none | ||
| static inline uint32_t gr_id_pool_get(struct gr_id_pool *p) { | ||
| uint64_t slab = 0; | ||
| uint32_t pos = 0; | ||
| uint32_t bit; | ||
|
|
||
| __rte_bitmap_scan_init(&p->bmp); | ||
maxime-leroy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if (!rte_bitmap_scan(&p->bmp, &pos, &slab)) | ||
| return 0; // pool is full | ||
|
|
||
| bit = pos + rte_ctz64(slab); | ||
| rte_bitmap_clear(&p->bmp, bit); // mark used | ||
|
|
||
| p->used++; | ||
| return bit + 1; | ||
| } | ||
|
|
||
| // Reserve a user‑chosen ID. Returns 0 on success, <0 on error | ||
| static inline int gr_id_pool_book(struct gr_id_pool *p, uint32_t id) { | ||
| if (id == 0 || id > p->max_ids) | ||
| return errno_set(EINVAL); | ||
|
|
||
| // already used | ||
| if (!rte_bitmap_get(&p->bmp, id - 1)) | ||
| return errno_set(EEXIST); | ||
|
|
||
| rte_bitmap_clear(&p->bmp, id - 1); | ||
| p->used++; | ||
| return 0; | ||
| } | ||
|
|
||
| // Put an ID back to the pool | ||
| static inline int gr_id_pool_put(struct gr_id_pool *p, uint32_t id) { | ||
| if (id == 0 || id > p->max_ids) | ||
| return errno_set(EINVAL); | ||
|
|
||
| if (rte_bitmap_get(&p->bmp, id - 1)) | ||
| return errno_set(EALREADY); | ||
|
|
||
| rte_bitmap_set(&p->bmp, id - 1); | ||
| p->used--; | ||
| return 0; | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.