]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: Reduce multiaccess_check_v4 overhead for subgroups 1208/head
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 27 Sep 2017 00:06:13 +0000 (20:06 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 27 Sep 2017 00:06:13 +0000 (20:06 -0400)
Perf results at scale( >1k peers) showed a non-trivial
amount of time spent in bgp_multiaccess_check_v4.  Upon
function examination we are looking up the nexthops
connected node in each call as well as having to unlock
it after each iteration.  Rewrite to lookup the nexthop
node once.

This should reduce the node lookup by aproximately 1/2
which should yield some performance results.  There are
probably better things to do here but would require
deeper thought.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
bgpd/bgp_nexthop.c
bgpd/bgp_nexthop.h
bgpd/bgp_route.c

index 2d05a9e194e0fc9ecce5eff6224ef2d081e2274b..870da22d20572f1214dca3a9389670ab50580473 100644 (file)
@@ -430,6 +430,48 @@ int bgp_multiaccess_check_v4(struct in_addr nexthop, struct peer *peer)
        return (ret);
 }
 
+int bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop,
+                                   struct update_subgroup *subgrp)
+{
+       struct bgp_node *rn1, *rn2;
+       struct peer_af *paf;
+       struct prefix p, np;
+       struct bgp *bgp = NULL;
+
+       np.family = AF_INET;
+       np.prefixlen = IPV4_MAX_BITLEN;
+       np.u.prefix4 = nexthop;
+
+       p.family = AF_INET;
+       p.prefixlen = IPV4_MAX_BITLEN;
+
+       rn1 = rn2 = NULL;
+
+       bgp = SUBGRP_INST(subgrp);
+       rn1 = bgp_node_match(bgp->connected_table[AFI_IP],
+                            &np);
+       if (!rn1)
+               return 0;
+
+       SUBGRP_FOREACH_PEER(subgrp, paf) {
+               p.u.prefix4 = paf->peer->su.sin.sin_addr;
+
+               rn2 = bgp_node_match(bgp->connected_table[AFI_IP],
+                                    &p);
+               if (rn1 == rn2) {
+                       bgp_unlock_node(rn1);
+                       bgp_unlock_node(rn2);
+                       return 1;
+               }
+
+               if (rn2)
+                       bgp_unlock_node(rn2);
+       }
+
+       bgp_unlock_node(rn1);
+       return 0;
+}
+
 static void bgp_show_nexthops_detail(struct vty *vty,
                                     struct bgp *bgp,
                                     struct bgp_nexthop_cache *bnc)
index b482778fdfd427bb7787f3e2f2f99dbb6188994f..2c5b2ab1185c0fb321d2a27e163f500ef8273196 100644 (file)
@@ -82,6 +82,8 @@ extern int bgp_nexthop_lookup(afi_t, struct peer *peer, struct bgp_info *,
                              int *, int *);
 extern void bgp_connected_add(struct bgp *bgp, struct connected *c);
 extern void bgp_connected_delete(struct bgp *bgp, struct connected *c);
+extern int bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop,
+                                          struct update_subgroup *subgrp);
 extern int bgp_multiaccess_check_v4(struct in_addr, struct peer *);
 extern int bgp_config_write_scan_time(struct vty *);
 extern int bgp_nexthop_self(struct bgp *, struct in_addr);
index 5e51418165bb2df113093da0406b4cf3824f2ca0..44b3c5c348565ac4eda6178808f571e2ae4a5bac 100644 (file)
@@ -1319,7 +1319,6 @@ int subgroup_announce_check(struct bgp_node *rn, struct bgp_info *ri,
        struct peer *onlypeer;
        struct bgp *bgp;
        struct attr *riattr;
-       struct peer_af *paf;
        char buf[PREFIX_STRLEN];
        int ret;
        int transparent;
@@ -1710,16 +1709,12 @@ int subgroup_announce_check(struct bgp_node *rn, struct bgp_info *ri,
                         * Note: 3rd party nexthop currently implemented for
                         * IPv4 only.
                         */
-                       SUBGRP_FOREACH_PEER (subgrp, paf) {
-                               if (bgp_multiaccess_check_v4(riattr->nexthop,
-                                                            paf->peer))
-                                       break;
-                       }
-                       if (!paf)
+                       if (!bgp_subgrp_multiaccess_check_v4(riattr->nexthop,
+                                                            subgrp))
                                subgroup_announce_reset_nhop(
                                        (peer_cap_enhe(peer, afi, safi)
-                                                ? AF_INET6
-                                                : p->family),
+                                        ? AF_INET6
+                                        : p->family),
                                        attr);
                }
                /* If IPv6/MP and nexthop does not have any override and happens