summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_vty.c44
-rw-r--r--bgpd/bgpd.c3
-rw-r--r--bgpd/bgpd.h1
-rw-r--r--doc/user/bgp.rst26
-rw-r--r--tests/bgpd/test_peer_attr.c5
-rw-r--r--tests/bgpd/test_peer_attr.py1
-rw-r--r--yang/frr-bgp-neighbor.yang2
7 files changed, 72 insertions, 10 deletions
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 5d6ae589fa..ae2d586de5 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -122,6 +122,10 @@ FRR_CFG_DEFAULT_BOOL(BGP_SOFT_VERSION_CAPABILITY,
{ .val_bool = true, .match_profile = "datacenter", },
{ .val_bool = false },
);
+FRR_CFG_DEFAULT_BOOL(BGP_ENFORCE_FIRST_AS,
+ { .val_bool = false, .match_version = "< 9.1", },
+ { .val_bool = true },
+);
DEFINE_HOOK(bgp_inst_config_write,
(struct bgp *bgp, struct vty *vty),
@@ -615,6 +619,8 @@ int bgp_get_vty(struct bgp **bgp, as_t *as, const char *name,
if (DFLT_BGP_SOFT_VERSION_CAPABILITY)
SET_FLAG((*bgp)->flags,
BGP_FLAG_SOFT_VERSION_CAPABILITY);
+ if (DFLT_BGP_ENFORCE_FIRST_AS)
+ SET_FLAG((*bgp)->flags, BGP_FLAG_ENFORCE_FIRST_AS);
ret = BGP_SUCCESS;
}
@@ -2828,6 +2834,23 @@ DEFUN(no_bgp_ebgp_requires_policy, no_bgp_ebgp_requires_policy_cmd,
return CMD_SUCCESS;
}
+DEFPY(bgp_enforce_first_as,
+ bgp_enforce_first_as_cmd,
+ "[no] bgp enforce-first-as",
+ NO_STR
+ BGP_STR
+ "Enforce the first AS for EBGP routes\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+
+ if (no)
+ UNSET_FLAG(bgp->flags, BGP_FLAG_ENFORCE_FIRST_AS);
+ else
+ SET_FLAG(bgp->flags, BGP_FLAG_ENFORCE_FIRST_AS);
+
+ return CMD_SUCCESS;
+}
+
DEFPY(bgp_lu_uses_explicit_null, bgp_lu_uses_explicit_null_cmd,
"[no] bgp labeled-unicast <explicit-null|ipv4-explicit-null|ipv6-explicit-null>$value",
NO_STR BGP_STR
@@ -17973,8 +17996,13 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
addr);
/* enforce-first-as */
- if (peergroup_flag_check(peer, PEER_FLAG_ENFORCE_FIRST_AS))
- vty_out(vty, " neighbor %s enforce-first-as\n", addr);
+ if (CHECK_FLAG(bgp->flags, BGP_FLAG_ENFORCE_FIRST_AS)) {
+ if (!peergroup_flag_check(peer, PEER_FLAG_ENFORCE_FIRST_AS))
+ vty_out(vty, " no neighbor %s enforce-first-as\n", addr);
+ } else {
+ if (peergroup_flag_check(peer, PEER_FLAG_ENFORCE_FIRST_AS))
+ vty_out(vty, " neighbor %s enforce-first-as\n", addr);
+ }
/* update-source */
if (peergroup_flag_check(peer, PEER_FLAG_UPDATE_SOURCE)) {
@@ -18599,6 +18627,15 @@ int bgp_config_write(struct vty *vty)
? ""
: "no ");
+ /* bgp enforce-first-as */
+ if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_ENFORCE_FIRST_AS) !=
+ SAVE_BGP_ENFORCE_FIRST_AS)
+ vty_out(vty, " %sbgp enforce-first-as\n",
+ CHECK_FLAG(bgp->flags,
+ BGP_FLAG_ENFORCE_FIRST_AS)
+ ? ""
+ : "no ");
+
if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_LU_IPV4_EXPLICIT_NULL) &&
!!CHECK_FLAG(bgp->flags, BGP_FLAG_LU_IPV6_EXPLICIT_NULL))
vty_out(vty, " bgp labeled-unicast explicit-null\n");
@@ -19594,6 +19631,9 @@ void bgp_vty_init(void)
install_element(BGP_NODE, &bgp_ebgp_requires_policy_cmd);
install_element(BGP_NODE, &no_bgp_ebgp_requires_policy_cmd);
+ /* bgp enforce-first-as */
+ install_element(BGP_NODE, &bgp_enforce_first_as_cmd);
+
/* bgp labeled-unicast explicit-null */
install_element(BGP_NODE, &bgp_lu_uses_explicit_null_cmd);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 0a01d71968..6ca0b06450 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -1919,6 +1919,9 @@ struct peer *peer_create(union sockunion *su, const char *conf_if,
}
}
+ if (CHECK_FLAG(bgp->flags, BGP_FLAG_ENFORCE_FIRST_AS))
+ SET_FLAG(peer->flags, PEER_FLAG_ENFORCE_FIRST_AS);
+
/* auto shutdown if configured */
if (bgp->autoshutdown)
peer_flag_set(peer, PEER_FLAG_SHUTDOWN);
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 42e4c167f6..bfaa2e5d72 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -516,6 +516,7 @@ struct bgp {
/* For BGP-LU, force IPv6 local prefixes to use ipv6-explicit-null label */
#define BGP_FLAG_LU_IPV6_EXPLICIT_NULL (1ULL << 34)
#define BGP_FLAG_SOFT_VERSION_CAPABILITY (1ULL << 35)
+#define BGP_FLAG_ENFORCE_FIRST_AS (1ULL << 36)
/* BGP default address-families.
* New peers inherit enabled afi/safis from bgp instance.
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index 43572be07e..f7203a599a 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -527,6 +527,27 @@ Reject routes with AS_SET or AS_CONFED_SET types
This command enables rejection of incoming and outgoing routes having AS_SET or AS_CONFED_SET type.
+Enforce first AS
+----------------
+
+.. clicmd:: bgp enforce-first-as
+
+ To configure a router to deny an update received from an external BGP (eBGP)
+ peer that does not list its autonomous system number at the beginning of
+ the `AS_PATH` in the incoming update, use the ``bgp enforce-first-as`` command
+ in router configuration mode.
+
+ In order to exclude an arbitrary neighbor from this enforcement, use the
+ command ``no neighbor NAME enforce-first-as``. And vice-versa if a global
+ enforcement is disabled, you can override this behavior per neighbor too.
+
+ Default: enabled.
+
+.. note::
+
+ If you have a peering to RS (Route-Server), most likely you MUST disable the
+ first AS enforcement.
+
Suppress duplicate updates
--------------------------
@@ -1526,7 +1547,10 @@ Configuring Peers
Discard updates received from the specified (eBGP) peer if the AS_PATH
attribute does not contain the PEER's ASN as the first AS_PATH segment.
- Default: disabled.
+ You can enable or disable this enforcement globally too using
+ ``bgp enforce-first-as`` command.
+
+ Default: enabled.
.. clicmd:: neighbor PEER extended-optional-parameters
diff --git a/tests/bgpd/test_peer_attr.c b/tests/bgpd/test_peer_attr.c
index bc6eba9069..dd154e3429 100644
--- a/tests/bgpd/test_peer_attr.c
+++ b/tests/bgpd/test_peer_attr.c
@@ -297,11 +297,6 @@ static struct test_peer_attr test_peer_attrs[] = {
.type = PEER_AT_GLOBAL_FLAG,
},
{
- .cmd = "enforce-first-as",
- .u.flag = PEER_FLAG_ENFORCE_FIRST_AS,
- .type = PEER_AT_GLOBAL_FLAG,
- },
- {
.cmd = "local-as",
.peer_cmd = "local-as 1",
.group_cmd = "local-as 2",
diff --git a/tests/bgpd/test_peer_attr.py b/tests/bgpd/test_peer_attr.py
index eb57618434..bd8b06e2f0 100644
--- a/tests/bgpd/test_peer_attr.py
+++ b/tests/bgpd/test_peer_attr.py
@@ -15,7 +15,6 @@ TestFlag.okfail("peer\\capability extended-nexthop")
TestFlag.okfail("peer\\description")
TestFlag.okfail("peer\\disable-connected-check")
TestFlag.okfail("peer\\dont-capability-negotiate")
-TestFlag.okfail("peer\\enforce-first-as")
TestFlag.okfail("peer\\local-as")
TestFlag.okfail("peer\\local-as 1 no-prepend")
TestFlag.okfail("peer\\local-as 1 no-prepend replace-as")
diff --git a/yang/frr-bgp-neighbor.yang b/yang/frr-bgp-neighbor.yang
index 5a4c37974f..b199ab9469 100644
--- a/yang/frr-bgp-neighbor.yang
+++ b/yang/frr-bgp-neighbor.yang
@@ -76,7 +76,7 @@ submodule frr-bgp-neighbor {
leaf enforce-first-as {
type boolean;
- default "false";
+ default "true";
description
"When set to 'true' it will enforce the first AS for EBGP routes.";
}