From 47cbc09b639026bcda9d03bc7fb5e48d87aee6c8 Mon Sep 17 00:00:00 2001 From: Pascal Mathis Date: Thu, 17 May 2018 22:51:35 +0200 Subject: [PATCH] bgpd: Move 'enforce-first-as' from global to peer This commit moves the command 'bgp enforce-first-as' from global BGP instance configuration to peer/neighbor configuration, which can now be changed by executing '[no] neighbor enforce-first-as'. End users can now enforce sane first-AS checking on regular sessions while e.g. disabling the checks on routeserver sessions, which usually strip away their own AS number from the path. To ensure backwards-compatibility, a migration routine was added which automatically sets the 'enforce-first-as' flag on all configured neighbors if the old global setting was activated. The old global command immediately disappears after running the migration routine once. Signed-off-by: Pascal Mathis --- bgpd/bgp_attr.c | 3 +-- bgpd/bgp_vty.c | 50 ++++++++++++++++++++++++++++++++++++++++++------- bgpd/bgpd.c | 28 +++++++++++++++++++++++---- bgpd/bgpd.h | 7 ++++--- 4 files changed, 72 insertions(+), 16 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 276a7054e3..9fc819b962 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1177,7 +1177,6 @@ static bgp_attr_parse_ret_t bgp_attr_aspath_check(struct peer *const peer, * not right. * So do the checks later, i.e. here */ - struct bgp *bgp = peer->bgp; struct aspath *aspath; /* Confederation sanity check. */ @@ -1192,7 +1191,7 @@ static bgp_attr_parse_ret_t bgp_attr_aspath_check(struct peer *const peer, } /* First AS check for EBGP. */ - if (bgp != NULL && bgp_flag_check(bgp, BGP_FLAG_ENFORCE_FIRST_AS)) { + if (CHECK_FLAG(peer->flags, PEER_FLAG_ENFORCE_FIRST_AS)) { if (peer->sort == BGP_PEER_EBGP && !aspath_firstas_check(attr->aspath, peer->as)) { zlog_err("%s incorrect first AS (must be %u)", diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index f4f4e63264..da38098014 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -1991,7 +1991,11 @@ DEFUN (no_bgp_fast_external_failover, } /* "bgp enforce-first-as" configuration. */ -DEFUN (bgp_enforce_first_as, +#if defined(VERSION_TYPE_DEV) && CONFDATE > 20180517 +CPP_NOTICE("bgpd: remove deprecated '[no] bgp enforce-first-as' commands") +#endif + +DEFUN_DEPRECATED (bgp_enforce_first_as, bgp_enforce_first_as_cmd, "bgp enforce-first-as", BGP_STR @@ -1999,12 +2003,11 @@ DEFUN (bgp_enforce_first_as, { VTY_DECLVAR_CONTEXT(bgp, bgp); bgp_flag_set(bgp, BGP_FLAG_ENFORCE_FIRST_AS); - bgp_clear_star_soft_in(vty, bgp->name); return CMD_SUCCESS; } -DEFUN (no_bgp_enforce_first_as, +DEFUN_DEPRECATED (no_bgp_enforce_first_as, no_bgp_enforce_first_as_cmd, "no bgp enforce-first-as", NO_STR @@ -2013,7 +2016,6 @@ DEFUN (no_bgp_enforce_first_as, { VTY_DECLVAR_CONTEXT(bgp, bgp); bgp_flag_unset(bgp, BGP_FLAG_ENFORCE_FIRST_AS); - bgp_clear_star_soft_in(vty, bgp->name); return CMD_SUCCESS; } @@ -3449,7 +3451,7 @@ ALIAS_HIDDEN(no_neighbor_set_peer_group, no_neighbor_set_peer_group_hidden_cmd, "Peer-group name\n") static int peer_flag_modify_vty(struct vty *vty, const char *ip_str, - uint16_t flag, int set) + uint32_t flag, int set) { int ret; struct peer *peer; @@ -3481,13 +3483,13 @@ static int peer_flag_modify_vty(struct vty *vty, const char *ip_str, return bgp_vty_return(vty, ret); } -static int peer_flag_set_vty(struct vty *vty, const char *ip_str, uint16_t flag) +static int peer_flag_set_vty(struct vty *vty, const char *ip_str, uint32_t flag) { return peer_flag_modify_vty(vty, ip_str, flag, 1); } static int peer_flag_unset_vty(struct vty *vty, const char *ip_str, - uint16_t flag) + uint32_t flag) { return peer_flag_modify_vty(vty, ip_str, flag, 0); } @@ -4584,6 +4586,36 @@ DEFUN (no_neighbor_disable_connected_check, PEER_FLAG_DISABLE_CONNECTED_CHECK); } + +/* enforce-first-as */ +DEFUN (neighbor_enforce_first_as, + neighbor_enforce_first_as_cmd, + "neighbor enforce-first-as", + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Enforce the first AS for EBGP routes\n") +{ + int idx_peer = 1; + + return peer_flag_set_vty(vty, argv[idx_peer]->arg, + PEER_FLAG_ENFORCE_FIRST_AS); +} + +DEFUN (no_neighbor_enforce_first_as, + no_neighbor_enforce_first_as_cmd, + "no neighbor enforce-first-as", + NO_STR + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Enforce the first AS for EBGP routes\n") +{ + int idx_peer = 2; + + return peer_flag_unset_vty(vty, argv[idx_peer]->arg, + PEER_FLAG_ENFORCE_FIRST_AS); +} + + DEFUN (neighbor_description, neighbor_description_cmd, "neighbor description LINE...", @@ -12980,6 +13012,10 @@ void bgp_vty_init(void) install_element(BGP_NODE, &neighbor_disable_connected_check_cmd); install_element(BGP_NODE, &no_neighbor_disable_connected_check_cmd); + /* "neighbor enforce-first-as" commands. */ + install_element(BGP_NODE, &neighbor_enforce_first_as_cmd); + install_element(BGP_NODE, &no_neighbor_enforce_first_as_cmd); + /* "neighbor description" commands. */ install_element(BGP_NODE, &neighbor_description_cmd); install_element(BGP_NODE, &no_neighbor_description_cmd); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 71707b6afa..3d61021421 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3805,6 +3805,7 @@ static const struct peer_flag_action peer_flag_action_list[] = { {PEER_FLAG_DYNAMIC_CAPABILITY, 0, peer_change_reset}, {PEER_FLAG_DISABLE_CONNECTED_CHECK, 0, peer_change_reset}, {PEER_FLAG_CAPABILITY_ENHE, 0, peer_change_reset}, + {PEER_FLAG_ENFORCE_FIRST_AS, 0, peer_change_reset_in}, {0, 0, 0}}; static const struct peer_flag_action peer_af_flag_action_list[] = { @@ -6747,6 +6748,14 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp, } } + /* enforce-first-as */ + if (CHECK_FLAG(peer->flags, PEER_FLAG_ENFORCE_FIRST_AS)) { + if (!peer_group_active(peer) + || !CHECK_FLAG(g_peer->flags, PEER_FLAG_ENFORCE_FIRST_AS)) { + vty_out(vty, " neighbor %s enforce-first-as\n", addr); + } + } + /* update-source */ if (peer->update_if) { if (!peer_group_active(peer) || !g_peer->update_if @@ -7293,6 +7302,12 @@ static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi, vty_endframe(vty, " exit-address-family\n"); } +/* clang-format off */ +#if defined(VERSION_TYPE_DEV) && CONFDATE > 20180517 +CPP_NOTICE("bgpd: remove 'bgp enforce-first-as' config migration from bgp_config_write") +#endif +/* clang-format on */ + int bgp_config_write(struct vty *vty) { int write = 0; @@ -7328,6 +7343,15 @@ int bgp_config_write(struct vty *vty) if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) continue; + /* Migrate deprecated 'bgp enforce-first-as' + * config to 'neighbor * enforce-first-as' configs + */ + if (bgp_flag_check(bgp, BGP_FLAG_ENFORCE_FIRST_AS)) { + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) + peer_flag_set(peer, PEER_FLAG_ENFORCE_FIRST_AS); + bgp_flag_unset(bgp, BGP_FLAG_ENFORCE_FIRST_AS); + } + /* Router bgp ASN */ vty_out(vty, "router bgp %u", bgp->as); @@ -7426,10 +7450,6 @@ int bgp_config_write(struct vty *vty) vty_out(vty, "\n"); } - /* BGP enforce-first-as. */ - if (bgp_flag_check(bgp, BGP_FLAG_ENFORCE_FIRST_AS)) - vty_out(vty, " bgp enforce-first-as\n"); - /* BGP deterministic-med. */ if (!!bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED) != DFLT_BGP_DETERMINISTIC_MED) diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 340851e8d9..0c6bfcdc37 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -826,13 +826,14 @@ struct peer { #define PEER_FLAG_DISABLE_CONNECTED_CHECK (1 << 6) /* disable-connected-check */ #define PEER_FLAG_LOCAL_AS_NO_PREPEND (1 << 7) /* local-as no-prepend */ #define PEER_FLAG_LOCAL_AS_REPLACE_AS (1 << 8) /* local-as no-prepend replace-as */ -#define PEER_FLAG_DELETE (1 << 9) /* mark the peer for deleting */ -#define PEER_FLAG_CONFIG_NODE (1 << 10) /* the node to update configs on */ +#define PEER_FLAG_DELETE (1 << 9) /* mark the peer for deleting */ +#define PEER_FLAG_CONFIG_NODE (1 << 10) /* the node to update configs on */ #define PEER_FLAG_LONESOUL (1 << 11) #define PEER_FLAG_DYNAMIC_NEIGHBOR (1 << 12) /* dynamic neighbor */ #define PEER_FLAG_CAPABILITY_ENHE (1 << 13) /* Extended next-hop (rfc 5549)*/ #define PEER_FLAG_IFPEER_V6ONLY (1 << 14) /* if-based peer is v6 only */ -#define PEER_FLAG_IS_RFAPI_HD (1 << 15) /* attached to rfapi HD */ +#define PEER_FLAG_IS_RFAPI_HD (1 << 15) /* attached to rfapi HD */ +#define PEER_FLAG_ENFORCE_FIRST_AS (1 << 16) /* enforce-first-as */ /* outgoing message sent in CEASE_ADMIN_SHUTDOWN notify */ char *tx_shutdown_message; -- 2.39.5