Whamcloud - gitweb
LU-13779 lnet: Correct asymmetric route detection 49/39349/7
authorChris Horn <chris.horn@hpe.com>
Fri, 10 Jul 2020 17:33:50 +0000 (12:33 -0500)
committerOleg Drokin <green@whamcloud.com>
Wed, 10 Mar 2021 08:02:46 +0000 (08:02 +0000)
Failure to lookup the remote net for LNET_NIDNET(src_nid) indicates an
asymmetric route, but we do not drop the message in this case. Another
problem with this code is that there is no guarantee that we'll have a
route->lr_lnet that matches the net of ni->ni_nid.

We can move the asymmetric route detection to after we have looked up
the lpni of from_nid. Then, we can look at just the routes associated
with the gateway that owns the lpni. If one of those routes has
lr_net == LNET_NIDNET(src_nid), then the route is symmetrical.

Fixes: 4932febc12 ("LU-11894 lnet: check for asymmetrical route messages")
Test-Parameters: trivial
HPE-bug-id: LUS-9087
Signed-off-by: Chris Horn <chris.horn@hpe.com>
Change-Id: I8044d3f53e6f000c1e4d7c4e34b3b21afe0f9711
Reviewed-on: https://review.whamcloud.com/39349
Reviewed-by: Neil Brown <neilb@suse.de>
Reviewed-by: Sebastien Buisson <sbuisson@ddn.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lnet/lnet/lib-move.c

index 3f0f07c..73b4636 100644 (file)
@@ -4573,61 +4573,6 @@ lnet_parse(struct lnet_ni *ni, struct lnet_hdr *hdr, lnet_nid_t from_nid,
                goto drop;
        }
 
-       if (lnet_drop_asym_route && for_me &&
-           LNET_NIDNET(src_nid) != LNET_NIDNET(from_nid)) {
-               struct lnet_net *net;
-               struct lnet_remotenet *rnet;
-               bool found = true;
-
-               /* we are dealing with a routed message,
-                * so see if route to reach src_nid goes through from_nid
-                */
-               lnet_net_lock(cpt);
-               net = lnet_get_net_locked(LNET_NIDNET(ni->ni_nid));
-               if (!net) {
-                       lnet_net_unlock(cpt);
-                       CERROR("net %s not found\n",
-                              libcfs_net2str(LNET_NIDNET(ni->ni_nid)));
-                       return -EPROTO;
-               }
-
-               rnet = lnet_find_rnet_locked(LNET_NIDNET(src_nid));
-               if (rnet) {
-                       struct lnet_peer *gw = NULL;
-                       struct lnet_peer_ni *lpni = NULL;
-                       struct lnet_route *route;
-
-                       list_for_each_entry(route, &rnet->lrn_routes, lr_list) {
-                               found = false;
-                               gw = route->lr_gateway;
-                               if (route->lr_lnet != net->net_id)
-                                       continue;
-                               /*
-                                * if the nid is one of the gateway's NIDs
-                                * then this is a valid gateway
-                                */
-                               while ((lpni = lnet_get_next_peer_ni_locked(gw,
-                                               NULL, lpni)) != NULL) {
-                                       if (lpni->lpni_nid == from_nid) {
-                                               found = true;
-                                               break;
-                                       }
-                               }
-                       }
-               }
-               lnet_net_unlock(cpt);
-               if (!found) {
-                       /* we would not use from_nid to route a message to
-                        * src_nid
-                        * => asymmetric routing detected but forbidden
-                        */
-                       CERROR("%s, src %s: Dropping asymmetrical route %s\n",
-                              libcfs_nid2str(from_nid),
-                              libcfs_nid2str(src_nid), lnet_msgtyp2str(type));
-                       goto drop;
-               }
-       }
-
        msg = lnet_msg_alloc();
        if (msg == NULL) {
                CERROR("%s, src %s: Dropping %s (out of memory)\n",
@@ -4678,6 +4623,33 @@ lnet_parse(struct lnet_ni *ni, struct lnet_hdr *hdr, lnet_nid_t from_nid,
                goto drop;
        }
 
+       if (lnet_drop_asym_route && for_me &&
+           LNET_NIDNET(src_nid) != LNET_NIDNET(from_nid)) {
+               __u32 src_net_id = LNET_NIDNET(src_nid);
+               struct lnet_peer *gw = lpni->lpni_peer_net->lpn_peer;
+               struct lnet_route *route;
+               bool found = false;
+
+               list_for_each_entry(route, &gw->lp_routes, lr_gwlist) {
+                       if (route->lr_net == src_net_id) {
+                               found = true;
+                               break;
+                       }
+               }
+               if (!found) {
+                       lnet_net_unlock(cpt);
+                       /* we would not use from_nid to route a message to
+                        * src_nid
+                        * => asymmetric routing detected but forbidden
+                        */
+                       CERROR("%s, src %s: Dropping asymmetrical route %s\n",
+                              libcfs_nid2str(from_nid),
+                              libcfs_nid2str(src_nid), lnet_msgtyp2str(type));
+                       lnet_msg_free(msg);
+                       goto drop;
+               }
+       }
+
        if (the_lnet.ln_routing)
                lpni->lpni_last_alive = ktime_get_seconds();