Skip to content

Commit

Permalink
0002-linux-cp-Added-routing-for-prefixes-with-no-paths-av.patch
Browse files Browse the repository at this point in the history
  • Loading branch information
garyachy committed Jul 22, 2024
1 parent 7ad2c8b commit a988cfd
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 5 deletions.
16 changes: 16 additions & 0 deletions src/plugins/linux-cp/lcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,22 @@ lcp_get_netlink_processing_active (void)
return lcpm->netlink_processing_active;
}

void
lcp_set_route_no_paths (u8 is_del)
{
lcp_main_t *lcpm = &lcp_main;

lcpm->route_no_paths = (is_del != 0);
}

u8
lcp_get_route_no_paths (void)
{
lcp_main_t *lcpm = &lcp_main;

return lcpm->route_no_paths;
}

/*
* fd.io coding-style-patch-verification: ON
*
Expand Down
7 changes: 7 additions & 0 deletions src/plugins/linux-cp/lcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ typedef struct lcp_main_s
u8 test_mode; /* Set when Unit testing */
u8 netlink_processing_active; /* Set while a batch of Netlink messages are
being processed */
u8 route_no_paths; /* Add routes with no paths as local */
} lcp_main_t;

extern lcp_main_t lcp_main;
Expand Down Expand Up @@ -61,6 +62,12 @@ u8 lcp_get_del_dynamic_on_link_down (void);
void lcp_set_netlink_processing_active (u8 is_processing);
u8 lcp_get_netlink_processing_active (void);

/**
* Get/Set whether to install routes with no paths as local
*/
void lcp_set_route_no_paths (u8 is_del);
u8 lcp_get_route_no_paths (void);

#endif

/*
Expand Down
14 changes: 13 additions & 1 deletion src/plugins/linux-cp/lcp_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,17 @@ lcp_param_command_fn (vlib_main_t *vm, unformat_input_t *input,
return clib_error_return (0, "unknown input `%U'",
format_unformat_error, line_input);
}
else if (unformat (line_input, "route-no-paths"))
{
if (unformat (line_input, "on") || unformat (line_input, "enable"))
lcp_set_route_no_paths (1 /* is_del */);
else if (unformat (line_input, "off") ||
unformat (line_input, "disable"))
lcp_set_route_no_paths (0 /* is_del */);
else
return clib_error_return (0, "unknown input `%U'",
format_unformat_error, line_input);
}
else
return clib_error_return (0, "unknown input `%U'",
format_unformat_error, line_input);
Expand All @@ -204,7 +215,8 @@ lcp_param_command_fn (vlib_main_t *vm, unformat_input_t *input,
VLIB_CLI_COMMAND (lcp_param_command, static) = {
.path = "lcp param",
.short_help = "lcp param [del-static-on-link-down (on|enable|off|disable)] "
"[del-dynamic-on-link-down (on|enable|off|disable)]",
"[del-dynamic-on-link-down (on|enable|off|disable)] "
"[route-no-paths (on|enable|off|disable)]",
.function = lcp_param_command_fn,
};

Expand Down
4 changes: 4 additions & 0 deletions src/plugins/linux-cp/lcp_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ lcp_itf_pair_show (u32 phy_sw_if_index)
lcp_get_del_static_on_link_down () ? "on" : "off");
vlib_cli_output (vm, "lcp del-dynamic-on-link-down %s\n",
lcp_get_del_dynamic_on_link_down () ? "on" : "off");
vlib_cli_output (vm, "lcp route-no-paths %s\n",
lcp_get_route_no_paths () ? "on" : "off");

if (phy_sw_if_index == ~0)
{
Expand Down Expand Up @@ -579,6 +581,8 @@ lcp_itf_pair_config (vlib_main_t *vm, unformat_input_t *input)
lcp_set_del_static_on_link_down (1 /* is_del */);
else if (unformat (input, "del-dynamic-on-link-down"))
lcp_set_del_dynamic_on_link_down (1 /* is_del */);
else if (unformat (input, "route-no-paths"))
lcp_set_route_no_paths (1 /* is_del */);
else
return clib_error_return (0, "interfaces not found");
}
Expand Down
21 changes: 17 additions & 4 deletions src/plugins/linux-cp/lcp_router.c
Original file line number Diff line number Diff line change
Expand Up @@ -1167,7 +1167,7 @@ lcp_router_route_path_add_special (struct rtnl_route *rr,
{
fib_route_path_t *path;

if (rtnl_route_get_type (rr) < RTN_BLACKHOLE)
if (rtnl_route_get_type (rr) < RTN_BLACKHOLE && !(lcp_get_route_no_paths ()))
return;

/* if it already has a path, it does not need us to add one */
Expand All @@ -1176,8 +1176,21 @@ lcp_router_route_path_add_special (struct rtnl_route *rr,

vec_add2 (ctx->paths, path, 1);

path->frp_flags = FIB_ROUTE_PATH_FLAG_NONE | ctx->type_flags;
path->frp_sw_if_index = ~0;
/* If there are no paths, and `lcp param route-no-paths` is enabled
* we need to add an extra local path. This allows punting traffic
* with destinations available only via kernel */
if (lcp_get_route_no_paths ())
{
path->frp_flags = FIB_ROUTE_PATH_LOCAL | ctx->type_flags;
} else {
path->frp_flags = FIB_ROUTE_PATH_FLAG_NONE | ctx->type_flags;
}

/* Do not add interface to routes from kernel */
if (rtnl_route_get_protocol (rr) != RTPROT_KERNEL) {
path->frp_sw_if_index = ~0;
}

path->frp_proto = fib_proto_to_dpo (ctx->route_proto);
path->frp_preference = ctx->preference;

Expand Down Expand Up @@ -1335,7 +1348,7 @@ lcp_router_route_add (struct rtnl_route *rr, int is_replace)

nlt = lcp_router_table_add_or_lock (table_id, pfx.fp_proto);
/* Skip any kernel routes and IPv6 LL or multicast routes */
if (rproto == RTPROT_KERNEL ||
if ((rproto == RTPROT_KERNEL && !(lcp_get_route_no_paths ())) ||
(FIB_PROTOCOL_IP6 == pfx.fp_proto &&
(ip6_address_is_multicast (&pfx.fp_addr.ip6) ||
ip6_address_is_link_local_unicast (&pfx.fp_addr.ip6))))
Expand Down

0 comments on commit a988cfd

Please sign in to comment.