Skip to content

Added routing for prefixes with no paths #70

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

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading