Author: melifaro
Date: Wed Apr 15 13:06:55 2020
New Revision: 359966
URL: https://svnweb.freebsd.org/changeset/base/359966

Log:
  Convert OFED rtable interactions to the new routing KPI.
  
  Reviewed by:  hselasky
  Differential Revision:        https://reviews.freebsd.org/D24387

Modified:
  head/sys/ofed/drivers/infiniband/core/ib_addr.c
  head/sys/ofed/drivers/infiniband/core/ib_cma.c

Modified: head/sys/ofed/drivers/infiniband/core/ib_addr.c
==============================================================================
--- head/sys/ofed/drivers/infiniband/core/ib_addr.c     Wed Apr 15 13:02:13 
2020        (r359965)
+++ head/sys/ofed/drivers/infiniband/core/ib_addr.c     Wed Apr 15 13:06:55 
2020        (r359966)
@@ -44,14 +44,17 @@ __FBSDID("$FreeBSD$");
 #include <linux/workqueue.h>
 #include <linux/module.h>
 #include <net/route.h>
+#include <net/route/nhop.h>
 #include <net/netevent.h>
 #include <rdma/ib_addr.h>
 #include <rdma/ib.h>
 
+#include <netinet/in_fib.h>
 #include <netinet/if_ether.h>
 #include <netinet/ip_var.h>
 #include <netinet6/scope6_var.h>
 #include <netinet6/in6_pcb.h>
+#include <netinet6/in6_fib.h>
 
 #include "core_priv.h"
 
@@ -275,11 +278,13 @@ static int addr4_resolve(struct sockaddr_in *src_in,
        struct sockaddr_in dst_tmp = *dst_in;
        in_port_t src_port;
        struct sockaddr *saddr = NULL;
-       struct rtentry *rte;
+       struct nhop_object *nh;
        struct ifnet *ifp;
        int error;
        int type;
 
+       NET_EPOCH_ASSERT();
+
        /* set VNET, if any */
        CURVNET_SET(addr->net);
 
@@ -293,8 +298,7 @@ static int addr4_resolve(struct sockaddr_in *src_in,
                type |= ADDR_DST_ANY;
 
        /*
-        * Make sure the socket address length field
-        * is set, else rtalloc1() will fail.
+        * Make sure the socket address length field is set.
         */
        dst_tmp.sin_len = sizeof(dst_tmp);
 
@@ -303,16 +307,11 @@ static int addr4_resolve(struct sockaddr_in *src_in,
        case ADDR_VALID:
        case ADDR_SRC_ANY:
                /* regular destination route lookup */
-               rte = rtalloc1((struct sockaddr *)&dst_tmp, 1, 0);
-               if (rte == NULL) {
+               nh = fib4_lookup(RT_DEFAULT_FIB, dst_tmp.sin_addr,0,NHR_NONE,0);
+               if (nh == NULL) {
                        error = EHOSTUNREACH;
                        goto done;
-               } else if (rte->rt_ifp == NULL || RT_LINK_IS_UP(rte->rt_ifp) == 
0) {
-                       RTFREE_LOCKED(rte);
-                       error = EHOSTUNREACH;
-                       goto done;
                }
-               RT_UNLOCK(rte);
                break;
        default:
                error = ENETUNREACH;
@@ -332,14 +331,14 @@ static int addr4_resolve(struct sockaddr_in *src_in,
                /* check source interface */
                if (ifp == NULL) {
                        error = ENETUNREACH;
-                       goto error_rt_free;
+                       goto done;
                } else if (ifp->if_flags & IFF_LOOPBACK) {
                        /*
                         * Source address cannot be a loopback device.
                         */
                        error = EHOSTUNREACH;
                        goto error_put_ifp;
-               } else if (rte->rt_ifp->if_flags & IFF_LOOPBACK) {
+               } else if (nh->nh_ifp->if_flags & IFF_LOOPBACK) {
                        if (memcmp(&src_in->sin_addr, &dst_in->sin_addr,
                            sizeof(src_in->sin_addr))) {
                                /*
@@ -352,9 +351,9 @@ static int addr4_resolve(struct sockaddr_in *src_in,
                        }
                        /* get destination network interface from route */
                        dev_put(ifp);
-                       ifp = rte->rt_ifp;
+                       ifp = nh->nh_ifp;
                        dev_hold(ifp);
-               } else if (ifp != rte->rt_ifp) {
+               } else if (ifp != nh->nh_ifp) {
                        /*
                         * Source and destination interfaces are
                         * different.
@@ -365,13 +364,13 @@ static int addr4_resolve(struct sockaddr_in *src_in,
                break;
        case ADDR_SRC_ANY:
                /* check for loopback device */
-               if (rte->rt_ifp->if_flags & IFF_LOOPBACK)
+               if (nh->nh_ifp->if_flags & IFF_LOOPBACK)
                        saddr = (struct sockaddr *)&dst_tmp;
                else
-                       saddr = rte->rt_ifa->ifa_addr;
+                       saddr = nh->nh_ifa->ifa_addr;
 
                /* get destination network interface from route */
-               ifp = rte->rt_ifp;
+               ifp = nh->nh_ifp;
                dev_hold(ifp);
                break;
        default:
@@ -386,7 +385,7 @@ static int addr4_resolve(struct sockaddr_in *src_in,
                    ifp->if_addrlen, MAX_ADDR_LEN);
                error = 0;
        } else if (IN_MULTICAST(ntohl(dst_tmp.sin_addr.s_addr))) {
-               bool is_gw = (rte->rt_flags & RTF_GATEWAY) != 0;
+               bool is_gw = (nh->nh_flags & NHF_GATEWAY) != 0;
                error = addr_resolve_multi(edst, ifp, (struct sockaddr 
*)&dst_tmp);
                if (error != 0)
                        goto error_put_ifp;
@@ -396,10 +395,10 @@ static int addr4_resolve(struct sockaddr_in *src_in,
                memset(edst, 0, MAX_ADDR_LEN);
                error = 0;
        } else {
-               bool is_gw = (rte->rt_flags & RTF_GATEWAY) != 0;
+               bool is_gw = (nh->nh_flags & NHF_GATEWAY) != 0;
                memset(edst, 0, MAX_ADDR_LEN);
                error = arpresolve(ifp, is_gw, NULL, is_gw ?
-                   rte->rt_gateway : (const struct sockaddr *)&dst_tmp,
+                   &nh->gw_sa : (const struct sockaddr *)&dst_tmp,
                    edst, NULL, NULL);
                if (error != 0)
                        goto error_put_ifp;
@@ -416,17 +415,12 @@ static int addr4_resolve(struct sockaddr_in *src_in,
                src_in->sin_port = src_port;    /* preserve port number */
        }
 
-       if (rte != NULL)
-               RTFREE(rte);
-
        *ifpp = ifp;
 
        goto done;
 
 error_put_ifp:
        dev_put(ifp);
-error_rt_free:
-       RTFREE(rte);
 done:
        CURVNET_RESTORE();
 
@@ -460,11 +454,13 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
        struct sockaddr_in6 dst_tmp = *dst_in;
        in_port_t src_port;
        struct sockaddr *saddr = NULL;
-       struct rtentry *rte;
+       struct nhop_object *nh;
        struct ifnet *ifp;
        int error;
        int type;
 
+       NET_EPOCH_ASSERT();
+
        /* set VNET, if any */
        CURVNET_SET(addr->net);
 
@@ -478,14 +474,13 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
                type |= ADDR_DST_ANY;
 
        /*
-        * Make sure the socket address length field
-        * is set, else rtalloc1() will fail.
+        * Make sure the socket address length field is set.
         */
        dst_tmp.sin6_len = sizeof(dst_tmp);
 
        /*
-        * Make sure the scope ID gets embedded, else rtalloc1() will
-        * resolve to the loopback interface.
+        * Make sure the scope ID gets embedded, else nd6_resolve() will
+        * not find the record.
         */
        dst_tmp.sin6_scope_id = addr->bound_dev_if;
        sa6_embedscope(&dst_tmp, 0);
@@ -502,16 +497,12 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
                /* FALLTHROUGH */
        case ADDR_SRC_ANY:
                /* regular destination route lookup */
-               rte = rtalloc1((struct sockaddr *)&dst_tmp, 1, 0);
-               if (rte == NULL) {
+               nh = fib6_lookup(RT_DEFAULT_FIB, &dst_in->sin6_addr,
+                   addr->bound_dev_if, NHR_NONE, 0);
+               if (nh == NULL) {
                        error = EHOSTUNREACH;
                        goto done;
-               } else if (rte->rt_ifp == NULL || RT_LINK_IS_UP(rte->rt_ifp) == 
0) {
-                       RTFREE_LOCKED(rte);
-                       error = EHOSTUNREACH;
-                       goto done;
                }
-               RT_UNLOCK(rte);
                break;
        default:
                error = ENETUNREACH;
@@ -531,14 +522,14 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
                /* check source interface */
                if (ifp == NULL) {
                        error = ENETUNREACH;
-                       goto error_rt_free;
+                       goto done;
                } else if (ifp->if_flags & IFF_LOOPBACK) {
                        /*
                         * Source address cannot be a loopback device.
                         */
                        error = EHOSTUNREACH;
                        goto error_put_ifp;
-               } else if (rte->rt_ifp->if_flags & IFF_LOOPBACK) {
+               } else if (nh->nh_ifp->if_flags & IFF_LOOPBACK) {
                        if (memcmp(&src_in->sin6_addr, &dst_in->sin6_addr,
                            sizeof(src_in->sin6_addr))) {
                                /*
@@ -551,9 +542,9 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
                        }
                        /* get destination network interface from route */
                        dev_put(ifp);
-                       ifp = rte->rt_ifp;
+                       ifp = nh->nh_ifp;
                        dev_hold(ifp);
-               } else if (ifp != rte->rt_ifp) {
+               } else if (ifp != nh->nh_ifp) {
                        /*
                         * Source and destination interfaces are
                         * different.
@@ -564,13 +555,13 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
                break;
        case ADDR_SRC_ANY:
                /* check for loopback device */
-               if (rte->rt_ifp->if_flags & IFF_LOOPBACK)
+               if (nh->nh_ifp->if_flags & IFF_LOOPBACK)
                        saddr = (struct sockaddr *)&dst_tmp;
                else
-                       saddr = rte->rt_ifa->ifa_addr;
+                       saddr = nh->nh_ifa->ifa_addr;
 
                /* get destination network interface from route */
-               ifp = rte->rt_ifp;
+               ifp = nh->nh_ifp;
                dev_hold(ifp);
                break;
        default:
@@ -581,21 +572,21 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
         * Step 3 - resolve destination MAC address
         */
        if (IN6_IS_ADDR_MULTICAST(&dst_tmp.sin6_addr)) {
-               bool is_gw = (rte->rt_flags & RTF_GATEWAY) != 0;
+               bool is_gw = (nh->nh_flags & NHF_GATEWAY) != 0;
                error = addr_resolve_multi(edst, ifp,
                    (struct sockaddr *)&dst_tmp);
                if (error != 0)
                        goto error_put_ifp;
                else if (is_gw)
                        addr->network = RDMA_NETWORK_IPV6;
-       } else if (rte->rt_ifp->if_flags & IFF_LOOPBACK) {
+       } else if (nh->nh_ifp->if_flags & IFF_LOOPBACK) {
                memset(edst, 0, MAX_ADDR_LEN);
                error = 0;
        } else {
-               bool is_gw = (rte->rt_flags & RTF_GATEWAY) != 0;
+               bool is_gw = (nh->nh_flags & NHF_GATEWAY) != 0;
                memset(edst, 0, MAX_ADDR_LEN);
                error = nd6_resolve(ifp, is_gw, NULL, is_gw ?
-                   rte->rt_gateway : (const struct sockaddr *)&dst_tmp,
+                   &nh->gw_sa : (const struct sockaddr *)&dst_tmp,
                    edst, NULL, NULL);
                if (error != 0)
                        goto error_put_ifp;
@@ -612,17 +603,12 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
                src_in->sin6_port = src_port;   /* preserve port number */
        }
 
-       if (rte != NULL)
-               RTFREE(rte);
-
        *ifpp = ifp;
 
        goto done;
 
 error_put_ifp:
        dev_put(ifp);
-error_rt_free:
-       RTFREE(rte);
 done:
        CURVNET_RESTORE();
 

Modified: head/sys/ofed/drivers/infiniband/core/ib_cma.c
==============================================================================
--- head/sys/ofed/drivers/infiniband/core/ib_cma.c      Wed Apr 15 13:02:13 
2020        (r359965)
+++ head/sys/ofed/drivers/infiniband/core/ib_cma.c      Wed Apr 15 13:06:55 
2020        (r359966)
@@ -50,10 +50,14 @@ __FBSDID("$FreeBSD$");
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <net/route.h>
+#include <net/route/nhop.h>
 
 #include <net/tcp.h>
 #include <net/ipv6.h>
 
+#include <netinet/in_fib.h>
+
+#include <netinet6/in6_fib.h>
 #include <netinet6/scope6_var.h>
 #include <netinet6/ip6_var.h>
 
@@ -1351,11 +1355,10 @@ static bool validate_ipv4_net_dev(struct net_device *n
                                  const struct sockaddr_in *src_addr)
 {
 #ifdef INET
-       struct sockaddr_in src_tmp = *src_addr;
        __be32 daddr = dst_addr->sin_addr.s_addr,
               saddr = src_addr->sin_addr.s_addr;
        struct net_device *dst_dev;
-       struct rtentry *rte;
+       struct nhop_object *nh;
        bool ret;
 
        if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr) ||
@@ -1378,20 +1381,12 @@ static bool validate_ipv4_net_dev(struct net_device *n
        if (saddr == daddr)
                return true;
 
-       /*
-        * Make sure the socket address length field
-        * is set, else rtalloc1() will fail.
-        */
-       src_tmp.sin_len = sizeof(src_tmp);
-
        CURVNET_SET(net_dev->if_vnet);
-       rte = rtalloc1((struct sockaddr *)&src_tmp, 1, 0);
-       if (rte != NULL) {
-               ret = (rte->rt_ifp == net_dev);
-               RTFREE_LOCKED(rte);
-       } else {
+       nh = fib4_lookup(RT_DEFAULT_FIB, src_addr->sin_addr, 0, NHR_NONE, 0);
+       if (nh != NULL)
+               ret = (nh->nh_ifp == net_dev);
+       else
                ret = false;
-       }
        CURVNET_RESTORE();
        return ret;
 #else
@@ -1407,7 +1402,7 @@ static bool validate_ipv6_net_dev(struct net_device *n
        struct sockaddr_in6 src_tmp = *src_addr;
        struct sockaddr_in6 dst_tmp = *dst_addr;
        struct net_device *dst_dev;
-       struct rtentry *rte;
+       struct nhop_object *nh;
        bool ret;
 
        dst_dev = ip6_dev_find(net_dev->if_vnet, dst_tmp.sin6_addr,
@@ -1422,15 +1417,8 @@ static bool validate_ipv6_net_dev(struct net_device *n
        CURVNET_SET(net_dev->if_vnet);
 
        /*
-        * Make sure the socket address length field
-        * is set, else rtalloc1() will fail.
+        * Make sure the scope ID gets embedded.
         */
-       src_tmp.sin6_len = sizeof(src_tmp);
-
-       /*
-        * Make sure the scope ID gets embedded, else rtalloc1() will
-        * resolve to the loopback interface.
-        */
        src_tmp.sin6_scope_id = net_dev->if_index;
        sa6_embedscope(&src_tmp, 0);
 
@@ -1446,13 +1434,12 @@ static bool validate_ipv6_net_dev(struct net_device *n
                ret = true;
        } else {
                /* non-loopback case */
-               rte = rtalloc1((struct sockaddr *)&src_tmp, 1, 0);
-               if (rte != NULL) {
-                       ret = (rte->rt_ifp == net_dev);
-                       RTFREE_LOCKED(rte);
-               } else {
+               nh = fib6_lookup(RT_DEFAULT_FIB, &src_addr->sin6_addr,
+                   net_dev->if_index, NHR_NONE, 0);
+               if (nh != NULL)
+                       ret = (nh->nh_ifp == net_dev);
+               else
                        ret = false;
-               }
        }
        CURVNET_RESTORE();
        return ret;
@@ -1512,6 +1499,7 @@ static struct net_device *cma_get_net_dev(struct ib_cm
                        *src_addr = (struct sockaddr *)&src_addr_storage;
        struct net_device *net_dev;
        const union ib_gid *gid = req->has_gid ? &req->local_gid : NULL;
+       struct epoch_tracker et;
        int err;
 
        err = cma_save_ip_info(listen_addr, src_addr, ib_event,
@@ -1530,10 +1518,13 @@ static struct net_device *cma_get_net_dev(struct ib_cm
        if (!net_dev)
                return ERR_PTR(-ENODEV);
 
+       NET_EPOCH_ENTER(et);
        if (!validate_net_dev(net_dev, listen_addr, src_addr)) {
+               NET_EPOCH_EXIT(et);
                dev_put(net_dev);
                return ERR_PTR(-EHOSTUNREACH);
        }
+       NET_EPOCH_EXIT(et);
 
        return net_dev;
 }
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to