FBSD: Call CURVNET_SET/CURVNET_RESTORE for VIMAGE 80/12580/6
authorTim Creech <tcreech@tcreech.com>
Sun, 5 Mar 2017 23:18:01 +0000 (18:18 -0500)
committerBenjamin Kaduk <kaduk@mit.edu>
Sun, 25 Aug 2019 22:50:43 +0000 (18:50 -0400)
In commit 9703b023 (FBSD: VIMAGE support), we changed a couple of our
variable references to their V_* equivalents, to accommodate kernels
with VIMAGE turned on. This allows us to build, but causes us to crash
whenever we hit that code when VIMAGE is enabled, because the relevant
macros reference 'curvnet', which is NULL outside of networking code.

What we're supposed to do is to set 'curvnet' before entering
networking code by calling 'CURVNET_SET(xxx)', and reset it afterwards
by calling 'CURVNET_RESTORE()'. We must make exactly one _RESTORE call
for each _SET, and they are supposed to be run at the same level of
scope.

So to avoid the crashes, make the relevant CURVNET_* calls whenever we
look at networking info. We currently only do this in a few places:

- In afs_SetServerPrefs, to try to detect if a given server address is
  in the same network as one our local interfaces (V_in_ifaddrhead)

- In rxi_GetIFInfo, for some MTU-related info (V_ifnet)

- In rxi_FindIfnet, for some MTU-related info (ifa_ifwithnet)

As for what vnet we actually set 'curvnet' to, we could set it to the
vnet of the current thread (TD_TO_VNET(curthread)), or we could set it
to the vnet of an associated network object (a socket, an interface,
etc). Since all of our network-related code goes through Rx, in this
commit we set curvnet to the vnet of the Rx socket
(rx_socket->so_vnet).

Note that VIMAGE is optional in 11-RELEASE, but is turned on by
default in 12.0-RELEASE. For more information, see:
https://wiki.freebsd.org/VIMAGE/porting-to-vimage

[adeason@dson.org: Reworded commit message; moved some code around.]

Change-Id: If631b8942d7ee5cfe38a8f0c32b282d015f0bf35
Reviewed-on: https://gerrit.openafs.org/12580
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Tested-by: Benjamin Kaduk <kaduk@mit.edu>

src/afs/afs_server.c
src/rx/rx_kcommon.c

index d8414d6..bd5f262 100644 (file)
@@ -1354,16 +1354,22 @@ afs_SetServerPrefs(struct srvAddr *const sa)
            TAILQ_FOREACH(ifa, &ifn->if_addrhead, ifa_link) {
                afsi_SetServerIPRank(sa, ifa);
     }}}
+#elif defined(AFS_FBSD80_ENV)
+    {
+       struct in_ifaddr *ifa;
+       CURVNET_SET(rx_socket->so_vnet);
+       TAILQ_FOREACH(ifa, &V_in_ifaddrhead, ia_link) {
+           afsi_SetServerIPRank(sa, &ifa->ia_ifa);
+       }
+       CURVNET_RESTORE();
+    }
 #elif defined(AFS_FBSD_ENV)
     {
        struct in_ifaddr *ifa;
-#if defined(AFS_FBSD80_ENV)
-         TAILQ_FOREACH(ifa, &V_in_ifaddrhead, ia_link) {
-#else
-         TAILQ_FOREACH(ifa, &in_ifaddrhead, ia_link) {
-#endif
+       TAILQ_FOREACH(ifa, &in_ifaddrhead, ia_link) {
            afsi_SetServerIPRank(sa, &ifa->ia_ifa);
-    }}
+       }
+    }
 #elif defined(AFS_OBSD_ENV)
     {
        extern struct in_ifaddrhead in_ifaddr;
index c2cc187..f5167ca 100644 (file)
@@ -659,6 +659,7 @@ rxi_GetIFInfo(void)
 #else
 #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
 #if defined(AFS_FBSD80_ENV)
+    CURVNET_SET(rx_socket->so_vnet);
     TAILQ_FOREACH(ifn, &V_ifnet, if_link) {
 #else
     TAILQ_FOREACH(ifn, &ifnet, if_link) {
@@ -720,6 +721,11 @@ rxi_GetIFInfo(void)
            myNetAddrs[l] = addrs[l];
        }
     }
+
+#ifdef AFS_FBSD80_ENV
+    CURVNET_RESTORE();
+#endif
+
     return different;
 }
 
@@ -730,6 +736,11 @@ rxi_FindIfnet(afs_uint32 addr, afs_uint32 * maskp)
 {
     struct sockaddr_in s, sr;
     rx_ifaddr_t ifad;
+    rx_ifnet_t ret;
+
+#ifdef AFS_FBSD80_ENV
+    CURVNET_SET(rx_socket->so_vnet);
+#endif
 
     s.sin_family = AF_INET;
     s.sin_addr.s_addr = addr;
@@ -739,7 +750,14 @@ rxi_FindIfnet(afs_uint32 addr, afs_uint32 * maskp)
        rx_ifaddr_netmask(ifad, (struct sockaddr *)&sr, sizeof(sr));
        *maskp = sr.sin_addr.s_addr;
     }
-    return (ifad ? rx_ifaddr_ifnet(ifad) : NULL);
+
+    ret = (ifad ? rx_ifaddr_ifnet(ifad) : NULL);
+
+#ifdef AFS_FBSD80_ENV
+    CURVNET_RESTORE();
+#endif
+
+    return ret;
 }
 
 #else /* DARWIN || XBSD */