mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-08 01:15:12 +00:00
bgpd: bgpd-route-map-match-interface.patch
BGP: Add match interface support to BGP route-map. Currently, BGP route maps don't support interface match. This is a problem for commands such as redistribite connected that cannot exclude routes from specific interfaces (such as mgmt interfaces).
This commit is contained in:
parent
503006bc2a
commit
bc41314335
@ -109,6 +109,7 @@ struct attr
|
|||||||
struct in_addr nexthop;
|
struct in_addr nexthop;
|
||||||
u_int32_t med;
|
u_int32_t med;
|
||||||
u_int32_t local_pref;
|
u_int32_t local_pref;
|
||||||
|
u_int32_t nh_ifindex;
|
||||||
|
|
||||||
/* Path origin attribute */
|
/* Path origin attribute */
|
||||||
u_char origin;
|
u_char origin;
|
||||||
|
@ -5592,7 +5592,7 @@ ALIAS (no_ipv6_aggregate_address_summary_only,
|
|||||||
/* Redistribute route treatment. */
|
/* Redistribute route treatment. */
|
||||||
void
|
void
|
||||||
bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
|
bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
|
||||||
const struct in6_addr *nexthop6,
|
const struct in6_addr *nexthop6, unsigned int ifindex,
|
||||||
u_int32_t metric, u_char type)
|
u_int32_t metric, u_char type)
|
||||||
{
|
{
|
||||||
struct bgp *bgp;
|
struct bgp *bgp;
|
||||||
@ -5610,6 +5610,7 @@ bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
|
|||||||
bgp_attr_default_set (&attr, BGP_ORIGIN_INCOMPLETE);
|
bgp_attr_default_set (&attr, BGP_ORIGIN_INCOMPLETE);
|
||||||
if (nexthop)
|
if (nexthop)
|
||||||
attr.nexthop = *nexthop;
|
attr.nexthop = *nexthop;
|
||||||
|
attr.nh_ifindex = ifindex;
|
||||||
|
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
if (nexthop6)
|
if (nexthop6)
|
||||||
|
@ -216,7 +216,7 @@ extern int bgp_nlri_parse (struct peer *, struct attr *, struct bgp_nlri *);
|
|||||||
extern int bgp_maximum_prefix_overflow (struct peer *, afi_t, safi_t, int);
|
extern int bgp_maximum_prefix_overflow (struct peer *, afi_t, safi_t, int);
|
||||||
|
|
||||||
extern void bgp_redistribute_add (struct prefix *, const struct in_addr *,
|
extern void bgp_redistribute_add (struct prefix *, const struct in_addr *,
|
||||||
const struct in6_addr *,
|
const struct in6_addr *, unsigned int ifindex,
|
||||||
u_int32_t, u_char);
|
u_int32_t, u_char);
|
||||||
extern void bgp_redistribute_delete (struct prefix *, u_char);
|
extern void bgp_redistribute_delete (struct prefix *, u_char);
|
||||||
extern void bgp_redistribute_withdraw (struct bgp *, afi_t, int);
|
extern void bgp_redistribute_withdraw (struct bgp *, afi_t, int);
|
||||||
|
@ -64,7 +64,7 @@ o Cisco route-map
|
|||||||
|
|
||||||
match as-path : Done
|
match as-path : Done
|
||||||
community : Done
|
community : Done
|
||||||
interface : Not yet
|
interface : Done
|
||||||
ip address : Done
|
ip address : Done
|
||||||
ip next-hop : Done
|
ip next-hop : Done
|
||||||
ip route-source : Done
|
ip route-source : Done
|
||||||
@ -951,6 +951,58 @@ struct route_map_rule_cmd route_match_probability_cmd =
|
|||||||
route_match_probability_free
|
route_match_probability_free
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* `match interface IFNAME' */
|
||||||
|
/* Match function should return 1 if match is success else return
|
||||||
|
zero. */
|
||||||
|
static route_map_result_t
|
||||||
|
route_match_interface (void *rule, struct prefix *prefix,
|
||||||
|
route_map_object_t type, void *object)
|
||||||
|
{
|
||||||
|
struct interface *ifp;
|
||||||
|
struct nexthop *nexthop;
|
||||||
|
struct bgp_info *info;
|
||||||
|
|
||||||
|
if (type == RMAP_BGP)
|
||||||
|
{
|
||||||
|
info = object;
|
||||||
|
|
||||||
|
if (!info || !info->attr)
|
||||||
|
return RMAP_NOMATCH;
|
||||||
|
|
||||||
|
ifp = if_lookup_by_name ((char *)rule);
|
||||||
|
|
||||||
|
if (ifp == NULL || ifp->ifindex != info->attr->nh_ifindex)
|
||||||
|
return RMAP_NOMATCH;
|
||||||
|
|
||||||
|
return RMAP_MATCH;
|
||||||
|
}
|
||||||
|
return RMAP_NOMATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Route map `interface' match statement. `arg' should be
|
||||||
|
interface name. */
|
||||||
|
static void *
|
||||||
|
route_match_interface_compile (const char *arg)
|
||||||
|
{
|
||||||
|
return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free route map's compiled `interface' value. */
|
||||||
|
static void
|
||||||
|
route_match_interface_free (void *rule)
|
||||||
|
{
|
||||||
|
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Route map commands for ip address matching. */
|
||||||
|
struct route_map_rule_cmd route_match_interface_cmd =
|
||||||
|
{
|
||||||
|
"interface",
|
||||||
|
route_match_interface,
|
||||||
|
route_match_interface_compile,
|
||||||
|
route_match_interface_free
|
||||||
|
};
|
||||||
|
|
||||||
/* } */
|
/* } */
|
||||||
|
|
||||||
/* `set ip next-hop IP_ADDRESS' */
|
/* `set ip next-hop IP_ADDRESS' */
|
||||||
@ -3361,6 +3413,40 @@ ALIAS (no_match_origin,
|
|||||||
"local IGP\n"
|
"local IGP\n"
|
||||||
"unknown heritage\n")
|
"unknown heritage\n")
|
||||||
|
|
||||||
|
DEFUN (match_interface,
|
||||||
|
match_interface_cmd,
|
||||||
|
"match interface WORD",
|
||||||
|
MATCH_STR
|
||||||
|
"Match first hop interface of route\n"
|
||||||
|
"Interface name\n")
|
||||||
|
{
|
||||||
|
return bgp_route_match_add (vty, vty->index, "interface", argv[0],
|
||||||
|
RMAP_EVENT_MATCH_ADDED);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN (no_match_interface,
|
||||||
|
no_match_interface_cmd,
|
||||||
|
"no match interface",
|
||||||
|
NO_STR
|
||||||
|
MATCH_STR
|
||||||
|
"Match first hop interface of route\n")
|
||||||
|
{
|
||||||
|
if (argc == 0)
|
||||||
|
return bgp_route_match_delete (vty, vty->index, "interface", NULL,
|
||||||
|
RMAP_EVENT_MATCH_DELETED);
|
||||||
|
|
||||||
|
return bgp_route_match_delete (vty, vty->index, "interface", argv[0],
|
||||||
|
RMAP_EVENT_MATCH_DELETED);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALIAS (no_match_interface,
|
||||||
|
no_match_interface_val_cmd,
|
||||||
|
"no match interface WORD",
|
||||||
|
NO_STR
|
||||||
|
MATCH_STR
|
||||||
|
"Match first hop interface of route\n"
|
||||||
|
"Interface name\n")
|
||||||
|
|
||||||
DEFUN (set_ip_nexthop,
|
DEFUN (set_ip_nexthop,
|
||||||
set_ip_nexthop_cmd,
|
set_ip_nexthop_cmd,
|
||||||
"set ip next-hop A.B.C.D",
|
"set ip next-hop A.B.C.D",
|
||||||
@ -4334,6 +4420,7 @@ bgp_route_map_init (void)
|
|||||||
route_map_install_match (&route_match_metric_cmd);
|
route_map_install_match (&route_match_metric_cmd);
|
||||||
route_map_install_match (&route_match_origin_cmd);
|
route_map_install_match (&route_match_origin_cmd);
|
||||||
route_map_install_match (&route_match_probability_cmd);
|
route_map_install_match (&route_match_probability_cmd);
|
||||||
|
route_map_install_match (&route_match_interface_cmd);
|
||||||
|
|
||||||
route_map_install_set (&route_set_ip_nexthop_cmd);
|
route_map_install_set (&route_set_ip_nexthop_cmd);
|
||||||
route_map_install_set (&route_set_local_pref_cmd);
|
route_map_install_set (&route_set_local_pref_cmd);
|
||||||
@ -4398,6 +4485,9 @@ bgp_route_map_init (void)
|
|||||||
install_element (RMAP_NODE, &match_probability_cmd);
|
install_element (RMAP_NODE, &match_probability_cmd);
|
||||||
install_element (RMAP_NODE, &no_match_probability_cmd);
|
install_element (RMAP_NODE, &no_match_probability_cmd);
|
||||||
install_element (RMAP_NODE, &no_match_probability_val_cmd);
|
install_element (RMAP_NODE, &no_match_probability_val_cmd);
|
||||||
|
install_element (RMAP_NODE, &match_interface_cmd);
|
||||||
|
install_element (RMAP_NODE, &no_match_interface_cmd);
|
||||||
|
install_element (RMAP_NODE, &no_match_interface_val_cmd);
|
||||||
|
|
||||||
install_element (RMAP_NODE, &set_ip_nexthop_cmd);
|
install_element (RMAP_NODE, &set_ip_nexthop_cmd);
|
||||||
install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
|
install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
|
||||||
|
@ -380,6 +380,7 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
|
|||||||
struct zapi_ipv4 api;
|
struct zapi_ipv4 api;
|
||||||
struct in_addr nexthop;
|
struct in_addr nexthop;
|
||||||
struct prefix_ipv4 p;
|
struct prefix_ipv4 p;
|
||||||
|
unsigned int ifindex;
|
||||||
|
|
||||||
s = zclient->ibuf;
|
s = zclient->ibuf;
|
||||||
nexthop.s_addr = 0;
|
nexthop.s_addr = 0;
|
||||||
@ -404,7 +405,7 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
|
|||||||
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
|
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
|
||||||
{
|
{
|
||||||
api.ifindex_num = stream_getc (s);
|
api.ifindex_num = stream_getc (s);
|
||||||
stream_getl (s); /* ifindex, unused */
|
ifindex = stream_getl (s); /* ifindex, unused */
|
||||||
}
|
}
|
||||||
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
|
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
|
||||||
api.distance = stream_getc (s);
|
api.distance = stream_getc (s);
|
||||||
@ -425,7 +426,7 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
|
|||||||
inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
|
inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
|
||||||
api.metric);
|
api.metric);
|
||||||
}
|
}
|
||||||
bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL,
|
bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL, ifindex,
|
||||||
api.metric, api.type);
|
api.metric, api.type);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -456,6 +457,7 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
|
|||||||
struct zapi_ipv6 api;
|
struct zapi_ipv6 api;
|
||||||
struct in6_addr nexthop;
|
struct in6_addr nexthop;
|
||||||
struct prefix_ipv6 p;
|
struct prefix_ipv6 p;
|
||||||
|
unsigned int ifindex;
|
||||||
|
|
||||||
s = zclient->ibuf;
|
s = zclient->ibuf;
|
||||||
memset (&nexthop, 0, sizeof (struct in6_addr));
|
memset (&nexthop, 0, sizeof (struct in6_addr));
|
||||||
@ -480,7 +482,7 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
|
|||||||
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
|
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
|
||||||
{
|
{
|
||||||
api.ifindex_num = stream_getc (s);
|
api.ifindex_num = stream_getc (s);
|
||||||
stream_getl (s); /* ifindex, unused */
|
ifindex = stream_getl (s); /* ifindex, unused */
|
||||||
}
|
}
|
||||||
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
|
if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
|
||||||
api.distance = stream_getc (s);
|
api.distance = stream_getc (s);
|
||||||
@ -507,7 +509,7 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
|
|||||||
inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
|
inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])),
|
||||||
api.metric);
|
api.metric);
|
||||||
}
|
}
|
||||||
bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop,
|
bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop, ifindex,
|
||||||
api.metric, api.type);
|
api.metric, api.type);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user