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. */
|
/* Route map apply. */
|
||||||
if (rmap) {
|
if (rmap) {
|
||||||
memset(&rmap_path, 0, sizeof(struct bgp_path_info));
|
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 (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
|
||||||
if (peer->sort == BGP_PEER_IBGP
|
if (peer->sort == BGP_PEER_IBGP
|
||||||
|| peer->sort == BGP_PEER_CONFED) {
|
|| 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,
|
static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
|
||||||
safi_t safi)
|
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_route_all(struct peer *);
|
||||||
extern void bgp_clear_adj_in(struct peer *, afi_t, safi_t);
|
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 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,
|
extern struct bgp_node *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
|
||||||
safi_t safi, struct prefix *p,
|
safi_t safi, struct prefix *p,
|
||||||
|
@ -1860,6 +1860,29 @@ DEFUN (no_bgp_always_compare_med,
|
|||||||
return CMD_SUCCESS;
|
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. */
|
/* "bgp deterministic-med" configuration. */
|
||||||
DEFUN (bgp_deterministic_med,
|
DEFUN (bgp_deterministic_med,
|
||||||
bgp_deterministic_med_cmd,
|
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",
|
json_addr, "routeMapForOutgoingAdvertisements",
|
||||||
filter->map[RMAP_OUT].name);
|
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 */
|
/* unsuppress-map */
|
||||||
if (filter->usmap.name)
|
if (filter->usmap.name)
|
||||||
json_object_string_add(json_addr,
|
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].map ? "*" : "",
|
||||||
filter->map[RMAP_OUT].name);
|
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 */
|
/* unsuppress-map */
|
||||||
if (filter->usmap.name)
|
if (filter->usmap.name)
|
||||||
vty_out(vty,
|
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, &bgp_always_compare_med_cmd);
|
||||||
install_element(BGP_NODE, &no_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 */
|
/* "bgp deterministic-med" commands */
|
||||||
install_element(BGP_NODE, &bgp_deterministic_med_cmd);
|
install_element(BGP_NODE, &bgp_deterministic_med_cmd);
|
||||||
install_element(BGP_NODE, &no_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->stalepath_time = BGP_DEFAULT_STALEPATH_TIME;
|
||||||
bgp->dynamic_neighbors_limit = BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT;
|
bgp->dynamic_neighbors_limit = BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT;
|
||||||
bgp->dynamic_neighbors_count = 0;
|
bgp->dynamic_neighbors_count = 0;
|
||||||
|
bgp->ebgp_requires_policy = DEFAULT_EBGP_POLICY_DISABLED;
|
||||||
#if DFLT_BGP_IMPORT_CHECK
|
#if DFLT_BGP_IMPORT_CHECK
|
||||||
bgp_flag_set(bgp, BGP_FLAG_IMPORT_CHECK);
|
bgp_flag_set(bgp, BGP_FLAG_IMPORT_CHECK);
|
||||||
#endif
|
#endif
|
||||||
@ -7577,6 +7578,11 @@ int bgp_config_write(struct vty *vty)
|
|||||||
if (bgp_flag_check(bgp, BGP_FLAG_ALWAYS_COMPARE_MED))
|
if (bgp_flag_check(bgp, BGP_FLAG_ALWAYS_COMPARE_MED))
|
||||||
vty_out(vty, " bgp always-compare-med\n");
|
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. */
|
/* BGP default ipv4-unicast. */
|
||||||
if (bgp_flag_check(bgp, BGP_FLAG_NO_DEFAULT_IPV4))
|
if (bgp_flag_check(bgp, BGP_FLAG_NO_DEFAULT_IPV4))
|
||||||
vty_out(vty, " no bgp default ipv4-unicast\n");
|
vty_out(vty, " no bgp default ipv4-unicast\n");
|
||||||
|
@ -487,6 +487,11 @@ struct bgp {
|
|||||||
/* EVPN enable - advertise local VNIs and their MACs etc. */
|
/* EVPN enable - advertise local VNIs and their MACs etc. */
|
||||||
int advertise_all_vni;
|
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;
|
struct bgp_evpn_info *evpn_info;
|
||||||
|
|
||||||
/* EVPN - use RFC 8365 to auto-derive RT */
|
/* EVPN - use RFC 8365 to auto-derive RT */
|
||||||
|
Loading…
Reference in New Issue
Block a user