mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 04:26:12 +00:00
Merge pull request #3746 from ton31337/feature/rfc_8212
bgpd: Implement RFC8212
This commit is contained in:
commit
cbcaac3fb1
@ -1224,6 +1224,20 @@ static int bgp_input_modifier(struct peer *peer, struct prefix *p,
|
||||
}
|
||||
}
|
||||
|
||||
/* RFC 8212 to prevent route leaks.
|
||||
* This specification intends to improve this situation by requiring the
|
||||
* explicit configuration of both BGP Import and Export Policies for any
|
||||
* External BGP (EBGP) session such as customers, peers, or
|
||||
* confederation boundaries for all enabled address families. Through
|
||||
* codification of the aforementioned requirement, operators will
|
||||
* benefit from consistent behavior across different BGP
|
||||
* implementations.
|
||||
*/
|
||||
if (peer->bgp->ebgp_requires_policy
|
||||
== DEFAULT_EBGP_POLICY_ENABLED)
|
||||
if (!bgp_inbound_policy_exists(peer, filter))
|
||||
return RMAP_DENY;
|
||||
|
||||
/* Route map apply. */
|
||||
if (rmap) {
|
||||
memset(&rmap_path, 0, sizeof(struct bgp_path_info));
|
||||
@ -1777,6 +1791,20 @@ int subgroup_announce_check(struct bgp_node *rn, struct bgp_path_info *pi,
|
||||
}
|
||||
}
|
||||
|
||||
/* RFC 8212 to prevent route leaks.
|
||||
* This specification intends to improve this situation by requiring the
|
||||
* explicit configuration of both BGP Import and Export Policies for any
|
||||
* External BGP (EBGP) session such as customers, peers, or
|
||||
* confederation boundaries for all enabled address families. Through
|
||||
* codification of the aforementioned requirement, operators will
|
||||
* benefit from consistent behavior across different BGP
|
||||
* implementations.
|
||||
*/
|
||||
if (peer->bgp->ebgp_requires_policy
|
||||
== DEFAULT_EBGP_POLICY_ENABLED)
|
||||
if (!bgp_outbound_policy_exists(peer, filter))
|
||||
return 0;
|
||||
|
||||
if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
|
||||
if (peer->sort == BGP_PEER_IBGP
|
||||
|| peer->sort == BGP_PEER_CONFED) {
|
||||
@ -4160,6 +4188,26 @@ void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
|
||||
}
|
||||
}
|
||||
|
||||
int bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
|
||||
{
|
||||
if (peer->sort == BGP_PEER_EBGP
|
||||
&& (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
|
||||
|| FILTER_LIST_OUT_NAME(filter)
|
||||
|| DISTRIBUTE_OUT_NAME(filter)))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
|
||||
{
|
||||
if (peer->sort == BGP_PEER_EBGP
|
||||
&& (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
|
||||
|| FILTER_LIST_IN_NAME(filter)
|
||||
|| DISTRIBUTE_IN_NAME(filter)))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
|
||||
safi_t safi)
|
||||
{
|
||||
|
@ -357,6 +357,8 @@ extern void bgp_clear_route(struct peer *, afi_t, safi_t);
|
||||
extern void bgp_clear_route_all(struct peer *);
|
||||
extern void bgp_clear_adj_in(struct peer *, afi_t, safi_t);
|
||||
extern void bgp_clear_stale_route(struct peer *, afi_t, safi_t);
|
||||
extern int bgp_outbound_policy_exists(struct peer *, struct bgp_filter *);
|
||||
extern int bgp_inbound_policy_exists(struct peer *, struct bgp_filter *);
|
||||
|
||||
extern struct bgp_node *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
|
||||
safi_t safi, struct prefix *p,
|
||||
|
@ -1860,6 +1860,29 @@ DEFUN (no_bgp_always_compare_med,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
DEFUN(bgp_ebgp_requires_policy, bgp_ebgp_requires_policy_cmd,
|
||||
"bgp ebgp-requires-policy",
|
||||
"BGP specific commands\n"
|
||||
"Require in and out policy for eBGP peers (RFC8212)\n")
|
||||
{
|
||||
VTY_DECLVAR_CONTEXT(bgp, bgp);
|
||||
bgp->ebgp_requires_policy = DEFAULT_EBGP_POLICY_ENABLED;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(no_bgp_ebgp_requires_policy, no_bgp_ebgp_requires_policy_cmd,
|
||||
"no bgp ebgp-requires-policy",
|
||||
NO_STR
|
||||
"BGP specific commands\n"
|
||||
"Require in and out policy for eBGP peers (RFC8212)\n")
|
||||
{
|
||||
VTY_DECLVAR_CONTEXT(bgp, bgp);
|
||||
bgp->ebgp_requires_policy = DEFAULT_EBGP_POLICY_DISABLED;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* "bgp deterministic-med" configuration. */
|
||||
DEFUN (bgp_deterministic_med,
|
||||
bgp_deterministic_med_cmd,
|
||||
@ -8829,6 +8852,20 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi,
|
||||
json_addr, "routeMapForOutgoingAdvertisements",
|
||||
filter->map[RMAP_OUT].name);
|
||||
|
||||
/* ebgp-requires-policy (inbound) */
|
||||
if (p->bgp->ebgp_requires_policy == DEFAULT_EBGP_POLICY_ENABLED
|
||||
&& !bgp_inbound_policy_exists(p, filter))
|
||||
json_object_string_add(
|
||||
json_addr, "inboundEbgpRequiresPolicy",
|
||||
"Inbound updates discarded due to missing policy");
|
||||
|
||||
/* ebgp-requires-policy (outbound) */
|
||||
if (p->bgp->ebgp_requires_policy == DEFAULT_EBGP_POLICY_ENABLED
|
||||
&& (!bgp_outbound_policy_exists(p, filter)))
|
||||
json_object_string_add(
|
||||
json_addr, "outboundEbgpRequiresPolicy",
|
||||
"Outbound updates discarded due to missing policy");
|
||||
|
||||
/* unsuppress-map */
|
||||
if (filter->usmap.name)
|
||||
json_object_string_add(json_addr,
|
||||
@ -9105,6 +9142,18 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi,
|
||||
filter->map[RMAP_OUT].map ? "*" : "",
|
||||
filter->map[RMAP_OUT].name);
|
||||
|
||||
/* ebgp-requires-policy (inbound) */
|
||||
if (p->bgp->ebgp_requires_policy == DEFAULT_EBGP_POLICY_ENABLED
|
||||
&& !bgp_inbound_policy_exists(p, filter))
|
||||
vty_out(vty,
|
||||
" Inbound updates discarded due to missing policy\n");
|
||||
|
||||
/* ebgp-requires-policy (outbound) */
|
||||
if (p->bgp->ebgp_requires_policy == DEFAULT_EBGP_POLICY_ENABLED
|
||||
&& !bgp_outbound_policy_exists(p, filter))
|
||||
vty_out(vty,
|
||||
" Outbound updates discarded due to missing policy\n");
|
||||
|
||||
/* unsuppress-map */
|
||||
if (filter->usmap.name)
|
||||
vty_out(vty,
|
||||
@ -12823,6 +12872,10 @@ void bgp_vty_init(void)
|
||||
install_element(BGP_NODE, &bgp_always_compare_med_cmd);
|
||||
install_element(BGP_NODE, &no_bgp_always_compare_med_cmd);
|
||||
|
||||
/* bgp ebgp-requires-policy */
|
||||
install_element(BGP_NODE, &bgp_ebgp_requires_policy_cmd);
|
||||
install_element(BGP_NODE, &no_bgp_ebgp_requires_policy_cmd);
|
||||
|
||||
/* "bgp deterministic-med" commands */
|
||||
install_element(BGP_NODE, &bgp_deterministic_med_cmd);
|
||||
install_element(BGP_NODE, &no_bgp_deterministic_med_cmd);
|
||||
|
@ -2936,6 +2936,7 @@ static struct bgp *bgp_create(as_t *as, const char *name,
|
||||
bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME;
|
||||
bgp->dynamic_neighbors_limit = BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT;
|
||||
bgp->dynamic_neighbors_count = 0;
|
||||
bgp->ebgp_requires_policy = DEFAULT_EBGP_POLICY_DISABLED;
|
||||
#if DFLT_BGP_IMPORT_CHECK
|
||||
bgp_flag_set(bgp, BGP_FLAG_IMPORT_CHECK);
|
||||
#endif
|
||||
@ -7577,6 +7578,11 @@ int bgp_config_write(struct vty *vty)
|
||||
if (bgp_flag_check(bgp, BGP_FLAG_ALWAYS_COMPARE_MED))
|
||||
vty_out(vty, " bgp always-compare-med\n");
|
||||
|
||||
/* RFC8212 default eBGP policy. */
|
||||
if (bgp->ebgp_requires_policy
|
||||
== DEFAULT_EBGP_POLICY_ENABLED)
|
||||
vty_out(vty, " bgp ebgp-requires-policy\n");
|
||||
|
||||
/* BGP default ipv4-unicast. */
|
||||
if (bgp_flag_check(bgp, BGP_FLAG_NO_DEFAULT_IPV4))
|
||||
vty_out(vty, " no bgp default ipv4-unicast\n");
|
||||
|
@ -487,6 +487,11 @@ struct bgp {
|
||||
/* EVPN enable - advertise local VNIs and their MACs etc. */
|
||||
int advertise_all_vni;
|
||||
|
||||
/* RFC 8212 - prevent route leaks. */
|
||||
int ebgp_requires_policy;
|
||||
#define DEFAULT_EBGP_POLICY_DISABLED 0
|
||||
#define DEFAULT_EBGP_POLICY_ENABLED 1
|
||||
|
||||
struct bgp_evpn_info *evpn_info;
|
||||
|
||||
/* EVPN - use RFC 8365 to auto-derive RT */
|
||||
|
Loading…
Reference in New Issue
Block a user