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

bgpd: Match routes by type under route-maps #3102

Merged
merged 1 commit into from Oct 2, 2018
Jump to file or symbol
Failed to load files and symbols.
+247 −0
Diff settings

Always

Just for now

bgpd: Match routes by type under route-maps

Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
  • Loading branch information...
ton31337 committed Sep 28, 2018
commit 61ad901e57049995709bcffe1ffaee65a9927a00
Copy path View file
@@ -548,6 +548,45 @@ struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd = {
route_match_ip_next_hop_prefix_list_compile,
route_match_ip_next_hop_prefix_list_free};
/* `match ip next-hop type <blackhole>' */
static route_map_result_t
route_match_ip_next_hop_type(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object)
{
struct bgp_info *bgp_info;
if (type == RMAP_BGP && prefix->family == AF_INET) {
bgp_info = (struct bgp_info *)object;
if (!bgp_info || !bgp_info->attr)
return RMAP_DENYMATCH;
/* If nexthop interface's index can't be resolved and nexthop is
set to any address then mark it as type `blackhole`.
This logic works for matching kernel/static routes like:
`ip route add blackhole 10.0.0.1`. */
if (bgp_info->attr->nexthop.s_addr == INADDR_ANY

This comment has been minimized.

@srimohans

srimohans Oct 1, 2018

Contributor

Adding a comment here would be helpful explaining the logic for this check. Without the knowledge of #1388, it may be little difficult for the user to follow.

&& !bgp_info->attr->nh_ifindex)
return RMAP_MATCH;
}
return RMAP_NOMATCH;
}
static void *route_match_ip_next_hop_type_compile(const char *arg)
{
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
}
static void route_match_ip_next_hop_type_free(void *rule)
{
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
}
static struct route_map_rule_cmd route_match_ip_next_hop_type_cmd = {
"ip next-hop type", route_match_ip_next_hop_type,
route_match_ip_next_hop_type_compile,
route_match_ip_next_hop_type_free};
/* `match ip route-source prefix-list PREFIX_LIST' */
static route_map_result_t
@@ -2372,6 +2411,53 @@ struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd = {
route_match_ipv6_address_prefix_list_compile,
route_match_ipv6_address_prefix_list_free};
/* `match ipv6 next-hop type <TYPE>' */
static route_map_result_t
route_match_ipv6_next_hop_type(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object)
{
struct bgp_info *bgp_info;
struct in6_addr *addr = rule;
if (type == RMAP_BGP && prefix->family == AF_INET6) {
bgp_info = (struct bgp_info *)object;
if (!bgp_info || !bgp_info->attr)
return RMAP_DENYMATCH;
if (IPV6_ADDR_SAME(&bgp_info->attr->mp_nexthop_global, addr)
&& !bgp_info->attr->nh_ifindex)
return RMAP_MATCH;
}
return RMAP_NOMATCH;
}
static void *route_match_ipv6_next_hop_type_compile(const char *arg)
{
struct in6_addr *address;
int ret;
address = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct in6_addr));
ret = inet_pton(AF_INET6, "::0", address);
if (!ret) {
XFREE(MTYPE_ROUTE_MAP_COMPILED, address);
return NULL;
}
return address;
}
static void route_match_ipv6_next_hop_type_free(void *rule)
{
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
}
struct route_map_rule_cmd route_match_ipv6_next_hop_type_cmd = {
"ipv6 next-hop type", route_match_ipv6_next_hop_type,
route_match_ipv6_next_hop_type_compile,
route_match_ipv6_next_hop_type_free};
/* `set ipv6 nexthop global IP_ADDRESS' */
/* Set nexthop to object. ojbect must be pointer to struct attr. */
@@ -4645,12 +4731,18 @@ void bgp_route_map_init(void)
route_map_match_ip_next_hop_prefix_list_hook(generic_match_add);
route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete);
route_map_match_ip_next_hop_type_hook(generic_match_add);
route_map_no_match_ip_next_hop_type_hook(generic_match_delete);
route_map_match_ipv6_address_hook(generic_match_add);
route_map_no_match_ipv6_address_hook(generic_match_delete);
route_map_match_ipv6_address_prefix_list_hook(generic_match_add);
route_map_no_match_ipv6_address_prefix_list_hook(generic_match_delete);
route_map_match_ipv6_next_hop_type_hook(generic_match_add);
route_map_no_match_ipv6_next_hop_type_hook(generic_match_delete);
route_map_match_metric_hook(generic_match_add);
route_map_no_match_metric_hook(generic_match_delete);
@@ -4676,6 +4768,7 @@ void bgp_route_map_init(void)
route_map_install_match(&route_match_ip_route_source_cmd);
route_map_install_match(&route_match_ip_address_prefix_list_cmd);
route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd);
route_map_install_match(&route_match_ip_next_hop_type_cmd);
route_map_install_match(&route_match_ip_route_source_prefix_list_cmd);
route_map_install_match(&route_match_aspath_cmd);
route_map_install_match(&route_match_community_cmd);
@@ -4791,6 +4884,7 @@ void bgp_route_map_init(void)
route_map_install_match(&route_match_ipv6_address_cmd);
route_map_install_match(&route_match_ipv6_next_hop_cmd);
route_map_install_match(&route_match_ipv6_address_prefix_list_cmd);
route_map_install_match(&route_match_ipv6_next_hop_type_cmd);
route_map_install_set(&route_set_ipv6_nexthop_global_cmd);
route_map_install_set(&route_set_ipv6_nexthop_prefer_global_cmd);
route_map_install_set(&route_set_ipv6_nexthop_local_cmd);
Copy path View file
@@ -111,6 +111,20 @@ struct route_map_match_set_hooks {
const char *arg,
route_map_event_t type);
/* match ip next hop type */
int (*match_ip_next_hop_type)(struct vty *vty,
struct route_map_index *index,
const char *command,
const char *arg,
route_map_event_t type);
/* no match ip next hop type */
int (*no_match_ip_next_hop_type)(struct vty *vty,
struct route_map_index *index,
const char *command,
const char *arg,
route_map_event_t type);
/* match ipv6 address */
int (*match_ipv6_address)(struct vty *vty,
struct route_map_index *index,
@@ -138,6 +152,19 @@ struct route_map_match_set_hooks {
const char *arg,
route_map_event_t type);
/* match ipv6 next-hop type */
int (*match_ipv6_next_hop_type)(struct vty *vty,
struct route_map_index *index,
const char *command,
const char *arg,
route_map_event_t type);
/* no match ipv6next-hop type */
int (*no_match_ipv6_next_hop_type)(struct vty *vty,
struct route_map_index *index,
const char *command, const char *arg,
route_map_event_t type);
/* match metric */
int (*match_metric)(struct vty *vty, struct route_map_index *index,
const char *command, const char *arg,
@@ -275,6 +302,22 @@ void route_map_no_match_ip_next_hop_prefix_list_hook(int (*func)(
rmap_match_set_hook.no_match_ip_next_hop_prefix_list = func;
}
/* match ip next hop type */
void route_map_match_ip_next_hop_type_hook(int (*func)(
struct vty *vty, struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type))
{
rmap_match_set_hook.match_ip_next_hop_type = func;
}
/* no match ip next hop type */
void route_map_no_match_ip_next_hop_type_hook(int (*func)(
struct vty *vty, struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type))
{
rmap_match_set_hook.no_match_ip_next_hop_type = func;
}
/* match ipv6 address */
void route_map_match_ipv6_address_hook(int (*func)(
struct vty *vty, struct route_map_index *index, const char *command,
@@ -308,6 +351,22 @@ void route_map_no_match_ipv6_address_prefix_list_hook(int (*func)(
rmap_match_set_hook.no_match_ipv6_address_prefix_list = func;
}
/* match ipv6 next-hop type */
void route_map_match_ipv6_next_hop_type_hook(int (*func)(
struct vty *vty, struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type))
{
rmap_match_set_hook.match_ipv6_next_hop_type = func;
}
/* no match ipv6 next-hop type */
void route_map_no_match_ipv6_next_hop_type_hook(int (*func)(
struct vty *vty, struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type))
{
rmap_match_set_hook.no_match_ipv6_next_hop_type = func;
}
/* match metric */
void route_map_match_metric_hook(int (*func)(
struct vty *vty, struct route_map_index *index, const char *command,
@@ -2028,6 +2087,45 @@ DEFUN (no_match_ip_next_hop_prefix_list,
return CMD_SUCCESS;
}
DEFUN(match_ip_next_hop_type, match_ip_next_hop_type_cmd,
"match ip next-hop type <blackhole>",
MATCH_STR IP_STR
"Match next-hop address of route\n"
"Match entries by type\n"
"Blackhole\n")
{
int idx_word = 4;
VTY_DECLVAR_CONTEXT(route_map_index, index);
if (rmap_match_set_hook.match_ip_next_hop_type)
return rmap_match_set_hook.match_ip_next_hop_type(
vty, index, "ip next-hop type", argv[idx_word]->arg,
RMAP_EVENT_MATCH_ADDED);
return CMD_SUCCESS;
}
DEFUN(no_match_ip_next_hop_type, no_match_ip_next_hop_type_cmd,
"no match ip next-hop type [<blackhole>]",
NO_STR MATCH_STR IP_STR
"Match next-hop address of route\n"
"Match entries by type\n"
"Blackhole\n")
{
int idx_word = 5;
VTY_DECLVAR_CONTEXT(route_map_index, index);
if (rmap_match_set_hook.no_match_ip_next_hop) {
if (argc <= idx_word)
return rmap_match_set_hook.no_match_ip_next_hop(
vty, index, "ip next-hop type", NULL,
RMAP_EVENT_MATCH_DELETED);
return rmap_match_set_hook.no_match_ip_next_hop(
vty, index, "ip next-hop type", argv[idx_word]->arg,
RMAP_EVENT_MATCH_DELETED);
}
return CMD_SUCCESS;
}
DEFUN (match_ipv6_address,
match_ipv6_address_cmd,
@@ -2106,6 +2204,39 @@ DEFUN (no_match_ipv6_address_prefix_list,
return CMD_SUCCESS;
}
DEFUN(match_ipv6_next_hop_type, match_ipv6_next_hop_type_cmd,
"match ipv6 next-hop type <blackhole>",
MATCH_STR IPV6_STR
"Match address of route\n"
"Match entries by type\n"
"Blackhole\n")
{
int idx_word = 4;
VTY_DECLVAR_CONTEXT(route_map_index, index);
if (rmap_match_set_hook.match_ipv6_next_hop_type)
return rmap_match_set_hook.match_ipv6_next_hop_type(
vty, index, "ipv6 next-hop type", argv[idx_word]->arg,
RMAP_EVENT_MATCH_ADDED);
return CMD_SUCCESS;
}
DEFUN(no_match_ipv6_next_hop_type, no_match_ipv6_next_hop_type_cmd,
"no match ipv6 next-hop type [<blackhole>]",
NO_STR MATCH_STR IPV6_STR
"Match address of route\n"
"Match entries by type\n"
"Blackhole\n")
{
int idx_word = 5;
VTY_DECLVAR_CONTEXT(route_map_index, index);
if (rmap_match_set_hook.no_match_ipv6_next_hop_type)
return rmap_match_set_hook.no_match_ipv6_next_hop_type(
vty, index, "ipv6 next-hop type", argv[idx_word]->arg,
RMAP_EVENT_MATCH_DELETED);
return CMD_SUCCESS;
}
DEFUN (match_metric,
match_metric_cmd,
@@ -2873,12 +3004,18 @@ void route_map_init(void)
install_element(RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
install_element(RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
install_element(RMAP_NODE, &match_ip_next_hop_type_cmd);
install_element(RMAP_NODE, &no_match_ip_next_hop_type_cmd);
install_element(RMAP_NODE, &match_ipv6_address_cmd);
install_element(RMAP_NODE, &no_match_ipv6_address_cmd);
install_element(RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
install_element(RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
install_element(RMAP_NODE, &match_ipv6_next_hop_type_cmd);
install_element(RMAP_NODE, &no_match_ipv6_next_hop_type_cmd);
install_element(RMAP_NODE, &match_metric_cmd);
install_element(RMAP_NODE, &no_match_metric_cmd);
Copy path View file
@@ -283,6 +283,14 @@ extern void route_map_match_ip_next_hop_prefix_list_hook(int (*func)(
extern void route_map_no_match_ip_next_hop_prefix_list_hook(int (*func)(
struct vty *vty, struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type));
/* match ip next hop type */
extern void route_map_match_ip_next_hop_type_hook(int (*func)(
struct vty *vty, struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type));
/* no match ip next hop type */
extern void route_map_no_match_ip_next_hop_type_hook(int (*func)(
struct vty *vty, struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type));
/* match ipv6 address */
extern void route_map_match_ipv6_address_hook(int (*func)(
struct vty *vty, struct route_map_index *index, const char *command,
@@ -299,6 +307,14 @@ extern void route_map_match_ipv6_address_prefix_list_hook(int (*func)(
extern void route_map_no_match_ipv6_address_prefix_list_hook(int (*func)(
struct vty *vty, struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type));
/* match ipv6 next-hop type */
extern void route_map_match_ipv6_next_hop_type_hook(int (*func)(
struct vty *vty, struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type));
/* no match ipv6 next-hop type */
extern void route_map_no_match_ipv6_next_hop_type_hook(int (*func)(
struct vty *vty, struct route_map_index *index, const char *command,
const char *arg, route_map_event_t type));
/* match metric */
extern void route_map_match_metric_hook(int (*func)(
struct vty *vty, struct route_map_index *index, const char *command,
ProTip! Use n and p to navigate between commits in a pull request.