]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd: Move 'enforce-first-as' from global to peer
authorPascal Mathis <mail@pascalmathis.com>
Thu, 17 May 2018 20:51:35 +0000 (22:51 +0200)
committerPascal Mathis <mail@pascalmathis.com>
Sat, 19 May 2018 12:43:42 +0000 (14:43 +0200)
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 <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 <mail@pascalmathis.com>
bgpd/bgp_attr.c
bgpd/bgp_vty.c
bgpd/bgpd.c
bgpd/bgpd.h

index 276a7054e37ae4007de403875b4f9ca32d191bad..9fc819b96264ce4da55320c39daa33db14fbd538 100644 (file)
@@ -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)",
index f4f4e63264e2af2bee7c02c0a809b62f03dd4032..da38098014819ec8edfc0b17403353a968db2a3a 100644 (file)
@@ -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 <A.B.C.D|X:X::X:X|WORD> 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 <A.B.C.D|X:X::X:X|WORD> 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 <A.B.C.D|X:X::X:X|WORD> 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);
index 71707b6afa8ebae15eddf9651686d73451e496d5..3d610214211153b80158c3a27e31c2865f3aa9c4 100644 (file)
@@ -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)
index 340851e8d90ce1c3544ed556ecd23860eb47d9df..0c6bfcdc37eb5b009e369b9bd9a7d1f05b636d8d 100644 (file)
@@ -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;