]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: associate listener with the appropriate bgp instance
authorPat Ruddy <pat@voltanet.io>
Tue, 21 Jul 2020 14:03:41 +0000 (15:03 +0100)
committerPat Ruddy <pat@voltanet.io>
Tue, 1 Sep 2020 08:42:26 +0000 (09:42 +0100)
When setting authentication on a BGP peer in a VRF the listener is
looked up from a global list. However there is no check that the
listener is the one associated with the VRF being configured. This
can result in the wrong listener beiong configured with a password,
leaving the intended listener in an open authentication state.
To simplify this lookup stash a pointer to the bgp instance in
the listener on creating (in the same way as is done for NS-based
VRFS).

Signed-off-by: Pat Ruddy <pat@voltanet.io>
bgpd/bgp_network.c
bgpd/bgp_network.h
bgpd/bgpd.c

index c324f259baf133a3d35f1efebec1818e3364cc80..cae11ae7bdd91f70e4e05e0486ef8adf470e1959 100644 (file)
@@ -160,12 +160,26 @@ static int bgp_md5_set_password(struct peer *peer, const char *password)
         */
        frr_with_privs(&bgpd_privs) {
                for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, listener))
-                       if (listener->su.sa.sa_family
-                           == peer->su.sa.sa_family) {
+                       if (listener->su.sa.sa_family ==
+                           peer->su.sa.sa_family) {
                                uint16_t prefixlen =
                                        peer->su.sa.sa_family == AF_INET
-                                               ? IPV4_MAX_PREFIXLEN
-                                               : IPV6_MAX_PREFIXLEN;
+                                       ? IPV4_MAX_PREFIXLEN
+                                       : IPV6_MAX_PREFIXLEN;
+
+                               /*
+                                * if we have stored a BGP vrf instance in the
+                                * listener it must match the bgp instance in
+                                * the peer otherwise the peer bgp instance
+                                * must be the default vrf or a view instance
+                                */
+                               if (!listener->bgp) {
+                                       if (peer->bgp->vrf_id != VRF_DEFAULT
+                                           && peer->bgp->inst_type
+                                                      != BGP_INSTANCE_TYPE_VIEW)
+                                               continue;
+                               } else if (listener->bgp != peer->bgp)
+                                       continue;
 
                                ret = bgp_md5_set_socket(listener->fd,
                                                         &peer->su, prefixlen,
@@ -176,7 +190,7 @@ static int bgp_md5_set_password(struct peer *peer, const char *password)
        return ret;
 }
 
-int bgp_md5_set_prefix(struct prefix *p, const char *password)
+int bgp_md5_set_prefix(struct bgp *bgp, struct prefix *p, const char *password)
 {
        int ret = 0;
        union sockunion su;
@@ -186,7 +200,9 @@ int bgp_md5_set_prefix(struct prefix *p, const char *password)
        /* Set or unset the password on the listen socket(s). */
        frr_with_privs(&bgpd_privs) {
                for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, listener))
-                       if (listener->su.sa.sa_family == p->family) {
+                       if (listener->su.sa.sa_family == p->family
+                           && ((bgp->vrf_id == VRF_DEFAULT)
+                               || (listener->bgp == bgp))) {
                                prefix2sockunion(p, &su);
                                ret = bgp_md5_set_socket(listener->fd, &su,
                                                         p->prefixlen,
@@ -198,9 +214,9 @@ int bgp_md5_set_prefix(struct prefix *p, const char *password)
        return ret;
 }
 
-int bgp_md5_unset_prefix(struct prefix *p)
+int bgp_md5_unset_prefix(struct bgp *bgp, struct prefix *p)
 {
-       return bgp_md5_set_prefix(p, NULL);
+       return bgp_md5_set_prefix(bgp, p, NULL);
 }
 
 int bgp_md5_set(struct peer *peer)
@@ -812,8 +828,9 @@ static int bgp_listener(int sock, struct sockaddr *sa, socklen_t salen,
        listener->fd = sock;
        listener->name = XSTRDUP(MTYPE_BGP_LISTENER, bgp->name);
 
-       /* this socket needs a change of ns. record bgp back pointer */
-       if (bgp->vrf_id != VRF_DEFAULT && vrf_is_backend_netns())
+       /* this socket is in a vrf record bgp back pointer */
+       if (bgp->vrf_id != VRF_DEFAULT
+           && bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
                listener->bgp = bgp;
 
        memcpy(&listener->su, sa, salen);
index 018efbc08ee7274f31abbbed34f6ae20cf65a185..0b5cc175230f789f7994d81f60b84fed2f231126 100644 (file)
@@ -31,8 +31,9 @@ extern void bgp_close(void);
 extern int bgp_connect(struct peer *);
 extern int bgp_getsockname(struct peer *);
 
-extern int bgp_md5_set_prefix(struct prefix *p, const char *password);
-extern int bgp_md5_unset_prefix(struct prefix *p);
+extern int bgp_md5_set_prefix(struct bgp *bgp, struct prefix *p,
+                             const char *password);
+extern int bgp_md5_unset_prefix(struct bgp *bgp, struct prefix *p);
 extern int bgp_md5_set(struct peer *);
 extern int bgp_md5_unset(struct peer *);
 extern int bgp_set_socket_ttl(struct peer *, int fd);
index aade3f0404c481410e4effd3caa3faa7982acae2..c19f7077279992d8cfd1cc02f530886692bc94fc 100644 (file)
@@ -2668,7 +2668,7 @@ int peer_group_listen_range_add(struct peer_group *group, struct prefix *range)
 
        /* Update passwords for new ranges */
        if (group->conf->password)
-               bgp_md5_set_prefix(prefix, group->conf->password);
+               bgp_md5_set_prefix(group->bgp, prefix, group->conf->password);
 
        return 0;
 }
@@ -2715,7 +2715,7 @@ int peer_group_listen_range_del(struct peer_group *group, struct prefix *range)
 
        /* Remove passwords for deleted ranges */
        if (group->conf->password)
-               bgp_md5_unset_prefix(prefix);
+               bgp_md5_unset_prefix(group->bgp, prefix);
 
        return 0;
 }
@@ -5621,9 +5621,9 @@ int peer_password_set(struct peer *peer, const char *password)
        struct prefix *lr;
 
        for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP], ln, lr))
-               bgp_md5_set_prefix(lr, password);
+               bgp_md5_set_prefix(peer->bgp, lr, password);
        for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP6], ln, lr))
-               bgp_md5_set_prefix(lr, password);
+               bgp_md5_set_prefix(peer->bgp, lr, password);
 
        return ret;
 }
@@ -5659,7 +5659,6 @@ int peer_password_unset(struct peer *peer)
                /* Attempt to uninstall password on socket. */
                if (!BGP_PEER_SU_UNSPEC(peer))
                        bgp_md5_unset(peer);
-
                /* Skip peer-group mechanics for regular peers. */
                return 0;
        }
@@ -5694,9 +5693,9 @@ int peer_password_unset(struct peer *peer)
        struct prefix *lr;
 
        for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP], ln, lr))
-               bgp_md5_unset_prefix(lr);
+               bgp_md5_unset_prefix(peer->bgp, lr);
        for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP6], ln, lr))
-               bgp_md5_unset_prefix(lr);
+               bgp_md5_unset_prefix(peer->bgp, lr);
 
        return 0;
 }