]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: Allow using remote-as the same as local-as
authorDonatas Abraitis <donatas@opensourcerouting.org>
Thu, 29 Sep 2022 16:09:13 +0000 (19:09 +0300)
committerDonatas Abraitis <donatas@opensourcerouting.org>
Thu, 29 Sep 2022 18:13:40 +0000 (21:13 +0300)
As an example, Arista EOS allows this behavior.

Configuration something like:

```
 neighbor PG peer-group
 neighbor PG remote-as 65001
 neighbor PG local-as 65001
 neighbor 192.168.10.124 peer-group PG
```

Or without peer-group.

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
bgpd/bgp_vty.c
bgpd/bgpd.c
bgpd/bgpd.h

index 82c9d9667cbe25aebea1767e25009a1a9a12c4fd..e784702aaba3f4670d8747a5309a31d1f8a6416a 100644 (file)
@@ -873,9 +873,6 @@ int bgp_vty_return(struct vty *vty, enum bgp_create_error_code ret)
        case BGP_ERR_REMOVE_PRIVATE_AS:
                str = "remove-private-AS cannot be configured for IBGP peers";
                break;
-       case BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP:
-               str = "Local-AS allowed only for EBGP peers";
-               break;
        case BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS:
                str = "Cannot have local-as same as BGP AS number";
                break;
@@ -936,9 +933,6 @@ int bgp_vty_return(struct vty *vty, enum bgp_create_error_code ret)
        case BGP_ERR_AF_UNCONFIGURED:
                str = "AFI/SAFI specified is not currently configured.";
                break;
-       case BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS:
-               str = "AS specified for local as is the same as the remote as and this is not allowed.";
-               break;
        case BGP_ERR_INVALID_AS:
                str = "Confederation AS specified is the same AS as our AS.";
                break;
index 749e46ebe9db9ef2bd0d891f67b52a72551564ea..433493384b2f30bc1f3e9d343488dbb7e57b7cf9 100644 (file)
@@ -997,9 +997,15 @@ void peer_af_flag_inherit(struct peer *peer, afi_t afi, safi_t safi,
 static inline enum bgp_peer_sort peer_calc_sort(struct peer *peer)
 {
        struct bgp *bgp;
+       as_t local_as;
 
        bgp = peer->bgp;
 
+       if (peer->change_local_as)
+               local_as = peer->change_local_as;
+       else
+               local_as = peer->local_as;
+
        /* Peer-group */
        if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
                if (peer->as_type == AS_INTERNAL)
@@ -1010,8 +1016,8 @@ static inline enum bgp_peer_sort peer_calc_sort(struct peer *peer)
 
                else if (peer->as_type == AS_SPECIFIED && peer->as) {
                        assert(bgp);
-                       return (bgp->as == peer->as ? BGP_PEER_IBGP
-                                                   : BGP_PEER_EBGP);
+                       return (local_as == peer->as ? BGP_PEER_IBGP
+                                                    : BGP_PEER_EBGP);
                }
 
                else {
@@ -1028,17 +1034,17 @@ static inline enum bgp_peer_sort peer_calc_sort(struct peer *peer)
 
        /* Normal peer */
        if (bgp && CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
-               if (peer->local_as == 0)
+               if (local_as == 0)
                        return BGP_PEER_INTERNAL;
 
-               if (peer->local_as == peer->as) {
+               if (local_as == peer->as) {
                        if (bgp->as == bgp->confed_id) {
-                               if (peer->local_as == bgp->as)
+                               if (local_as == bgp->as)
                                        return BGP_PEER_IBGP;
                                else
                                        return BGP_PEER_EBGP;
                        } else {
-                               if (peer->local_as == bgp->confed_id)
+                               if (local_as == bgp->confed_id)
                                        return BGP_PEER_EBGP;
                                else
                                        return BGP_PEER_IBGP;
@@ -1056,8 +1062,7 @@ static inline enum bgp_peer_sort peer_calc_sort(struct peer *peer)
                            && (peer->group->conf->as_type != AS_UNSPECIFIED)) {
                                if (peer->group->conf->as_type
                                    == AS_SPECIFIED) {
-                                       if (peer->local_as
-                                           == peer->group->conf->as)
+                                       if (local_as == peer->group->conf->as)
                                                return BGP_PEER_IBGP;
                                        else
                                                return BGP_PEER_EBGP;
@@ -1073,9 +1078,8 @@ static inline enum bgp_peer_sort peer_calc_sort(struct peer *peer)
                        return (peer->as_type == AS_INTERNAL ? BGP_PEER_IBGP
                                                             : BGP_PEER_EBGP);
 
-               return (peer->local_as == 0
-                               ? BGP_PEER_INTERNAL
-                               : peer->local_as == peer->as ? BGP_PEER_IBGP
+               return (local_as == 0 ? BGP_PEER_INTERNAL
+                                     : local_as == peer->as ? BGP_PEER_IBGP
                                                             : BGP_PEER_EBGP);
        }
 }
@@ -1885,14 +1889,6 @@ void peer_as_change(struct peer *peer, as_t as, int as_specified)
                UNSET_FLAG(peer->af_flags[AFI_L2VPN][SAFI_EVPN],
                           PEER_FLAG_REFLECTOR_CLIENT);
        }
-
-       /* local-as reset */
-       if (newtype != BGP_PEER_EBGP) {
-               peer->change_local_as = 0;
-               peer_flag_unset(peer, PEER_FLAG_LOCAL_AS);
-               peer_flag_unset(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND);
-               peer_flag_unset(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS);
-       }
 }
 
 /* If peer does not exist, create new one.  If peer already exists,
@@ -3018,17 +3014,6 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer,
                        /* ebgp-multihop reset */
                        if (gtype == BGP_PEER_IBGP)
                                group->conf->ttl = MAXTTL;
-
-                       /* local-as reset */
-                       if (gtype != BGP_PEER_EBGP) {
-                               group->conf->change_local_as = 0;
-                               peer_flag_unset(group->conf,
-                                               PEER_FLAG_LOCAL_AS);
-                               peer_flag_unset(group->conf,
-                                               PEER_FLAG_LOCAL_AS_NO_PREPEND);
-                               peer_flag_unset(group->conf,
-                                               PEER_FLAG_LOCAL_AS_REPLACE_AS);
-                       }
                }
 
                SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
@@ -6109,17 +6094,10 @@ int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend,
        struct bgp *bgp = peer->bgp;
        struct peer *member;
        struct listnode *node, *nnode;
-       enum bgp_peer_sort ptype = peer_sort(peer);
-
-       if (ptype != BGP_PEER_EBGP && ptype != BGP_PEER_INTERNAL)
-               return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP;
 
        if (bgp->as == as)
                return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS;
 
-       if (peer->as == as)
-               return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS;
-
        /* Save previous flag states. */
        old_no_prepend =
                !!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
@@ -6135,6 +6113,7 @@ int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend,
            && old_replace_as == replace_as)
                return 0;
        peer->change_local_as = as;
+       (void)peer_sort(peer);
 
        /* Check if handling a regular peer. */
        if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
index f6162f33e460e7e58a24a3bc1db4e7ba6f477329..b6efac9a7f409a884c55e54abdf2f41d827fffed 100644 (file)
@@ -2004,13 +2004,11 @@ enum bgp_create_error_code {
        BGP_ERR_AF_UNCONFIGURED = -15,
        BGP_ERR_SOFT_RECONFIG_UNCONFIGURED = -16,
        BGP_ERR_INSTANCE_MISMATCH = -17,
-       BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP = -18,
        BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS = -19,
        BGP_ERR_TCPSIG_FAILED = -20,
        BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK = -21,
        BGP_ERR_NO_IBGP_WITH_TTLHACK = -22,
        BGP_ERR_NO_INTERFACE_CONFIG = -23,
-       BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS = -24,
        BGP_ERR_AS_OVERRIDE = -25,
        BGP_ERR_INVALID_DYNAMIC_NEIGHBORS_LIMIT = -26,
        BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_EXISTS = -27,