Skip to content

Commit

Permalink
ip: show routes from all vrfs by default
Browse files Browse the repository at this point in the history
Be consistent with `show ip nexthop`, display routes from all VRFs by
default, unless a VRF id is specified. Change the default vrf_id
parameter in the request to UINT16_MAX (meaning "all vrfs").

Add a vrf_id attribute to struct gr_ip4_route and display it in the CLI.

Split route4_list to make counting and listing routes in mutliple VRFs
possible without too much code duplication.

Signed-off-by: Robin Jarry <robin@jarry.cc>
  • Loading branch information
rjarry committed Oct 30, 2024
1 parent c2aa7dd commit fa80f9e
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 15 deletions.
1 change: 1 addition & 0 deletions modules/ip/api/gr_ip4.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ struct gr_ip4_nh {
struct gr_ip4_route {
struct ip4_net dest;
ip4_addr_t nh;
uint16_t vrf_id;
};

#define GR_IP4_MODULE 0xf00d
Expand Down
8 changes: 5 additions & 3 deletions modules/ip/cli/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ static cmd_status_t route4_del(const struct gr_api_client *c, const struct ec_pn
}

static cmd_status_t route4_list(const struct gr_api_client *c, const struct ec_pnode *p) {
struct gr_ip4_route_list_req req = {.vrf_id = UINT16_MAX};
struct libscols_table *table = scols_new_table();
const struct gr_ip4_route_list_resp *resp;
struct gr_ip4_route_list_req req = {0};
char dest[BUFSIZ], nh[BUFSIZ];
void *resp_ptr = NULL;

Expand All @@ -66,6 +66,7 @@ static cmd_status_t route4_list(const struct gr_api_client *c, const struct ec_p
}

resp = resp_ptr;
scols_table_new_column(table, "VRF", 0, 0);
scols_table_new_column(table, "DESTINATION", 0, 0);
scols_table_new_column(table, "NEXT_HOP", 0, 0);
scols_table_set_column_separator(table, " ");
Expand All @@ -75,8 +76,9 @@ static cmd_status_t route4_list(const struct gr_api_client *c, const struct ec_p
const struct gr_ip4_route *route = &resp->routes[i];
ip4_net_format(&route->dest, dest, sizeof(dest));
inet_ntop(AF_INET, &route->nh, nh, sizeof(nh));
scols_line_set_data(line, 0, dest);
scols_line_set_data(line, 1, nh);
scols_line_sprintf(line, 0, "%u", route->vrf_id);
scols_line_set_data(line, 1, dest);
scols_line_set_data(line, 2, nh);
}

scols_print_table(table);
Expand Down
70 changes: 58 additions & 12 deletions modules/ip/control/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,19 +252,15 @@ static struct api_out route4_get(const void *request, void **response) {
return api_out(0, sizeof(*resp));
}

static struct api_out route4_list(const void *request, void **response) {
const struct gr_ip4_route_list_req *req = request;
struct gr_ip4_route_list_resp *resp = NULL;
struct rte_fib *fib = get_fib(req->vrf_id);
static int route4_count(uint16_t vrf_id) {
struct rte_rib_node *rn = NULL;
struct gr_ip4_route *r;
struct rte_fib *fib;
struct rte_rib *rib;
size_t num, len;
uintptr_t nh_id;
uint32_t ip;
int num;

fib = get_fib(vrf_id);
if (fib == NULL)
return api_out(errno, 0);
return -errno;

rib = rte_fib_get_rib(fib);

Expand All @@ -275,9 +271,20 @@ static struct api_out route4_list(const void *request, void **response) {
if (rte_rib_lookup_exact(rib, 0, 0) != NULL)
num++;

len = sizeof(*resp) + num * sizeof(struct gr_ip4_route);
if ((resp = calloc(1, len)) == NULL)
return api_out(ENOMEM, 0);
return num;
}

static void route4_rib_to_api(struct gr_ip4_route_list_resp *resp, uint16_t vrf_id) {
struct rte_rib_node *rn = NULL;
struct gr_ip4_route *r;
struct rte_fib *fib;
struct rte_rib *rib;
uintptr_t nh_id;
uint32_t ip;

fib = get_fib(vrf_id);
assert(fib != NULL);
rib = rte_fib_get_rib(fib);

while ((rn = rte_rib_get_nxt(rib, 0, 0, rn, RTE_RIB_GET_NXT_ALL)) != NULL) {
r = &resp->routes[resp->n_routes++];
Expand All @@ -286,6 +293,7 @@ static struct api_out route4_list(const void *request, void **response) {
rte_rib_get_depth(rn, &r->dest.prefixlen);
r->dest.ip = htonl(ip);
r->nh = nh_id_to_ptr(nh_id)->ip;
r->vrf_id = vrf_id;
}
// FIXME: remove this when rte_rib_get_nxt returns a default route, if any is configured
if ((rn = rte_rib_lookup_exact(rib, 0, 0)) != NULL) {
Expand All @@ -294,7 +302,45 @@ static struct api_out route4_list(const void *request, void **response) {
r->dest.ip = 0;
r->dest.prefixlen = 0;
r->nh = nh_id_to_ptr(nh_id)->ip;
r->vrf_id = vrf_id;
}
}

static struct api_out route4_list(const void *request, void **response) {
const struct gr_ip4_route_list_req *req = request;
struct gr_ip4_route_list_resp *resp = NULL;
size_t num, len;
int n;

if (req->vrf_id == UINT16_MAX) {
num = 0;
for (uint16_t v = 0; v < IP4_MAX_VRFS; v++) {
if (vrf_fibs[v] == NULL)
continue;
if ((n = route4_count(v)) < 0)
return api_out(errno, 0);
num += n;
}
} else {
if ((n = route4_count(req->vrf_id)) < 0)
return api_out(errno, 0);
num = n;
}

len = sizeof(*resp) + num * sizeof(struct gr_ip4_route);
if ((resp = calloc(1, len)) == NULL)
return api_out(ENOMEM, 0);

if (req->vrf_id == UINT16_MAX) {
for (uint16_t v = 0; v < IP4_MAX_VRFS; v++) {
if (vrf_fibs[v] == NULL)
continue;
route4_rib_to_api(resp, v);
}
} else {
route4_rib_to_api(resp, req->vrf_id);
}

*response = resp;

return api_out(0, len);
Expand Down

0 comments on commit fa80f9e

Please sign in to comment.