Author: hselasky
Date: Tue Jul 17 08:59:34 2018
New Revision: 336367
URL: https://svnweb.freebsd.org/changeset/base/336367

Log:
  Add native FreeBSD support for multicast in ibcore.
  
  This change adds support for registering multicast addresses,
  both IPv4 and IPv6.
  
  MFC after:            1 week
  Sponsored by:         Mellanox Technologies

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     Tue Jul 17 08:54:40 
2018        (r336366)
+++ head/sys/ofed/drivers/infiniband/core/ib_addr.c     Tue Jul 17 08:59:34 
2018        (r336367)
@@ -346,9 +346,12 @@ 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;
                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_IPV4;
        } else if (ifp->if_flags & IFF_LOOPBACK) {
                memset(edst, 0, MAX_ADDR_LEN);
                error = 0;
@@ -360,7 +363,7 @@ static int addr4_resolve(struct sockaddr_in *src_in,
                    edst, NULL, NULL);
                if (error != 0)
                        goto error_put_ifp;
-               else if (is_gw != 0)
+               else if (is_gw)
                        addr->network = RDMA_NETWORK_IPV4;
        }
 
@@ -515,10 +518,13 @@ 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;
                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) {
                memset(edst, 0, MAX_ADDR_LEN);
                error = 0;
@@ -530,7 +536,7 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
                    edst, NULL, NULL);
                if (error != 0)
                        goto error_put_ifp;
-               else if (is_gw != 0)
+               else if (is_gw)
                        addr->network = RDMA_NETWORK_IPV6;
        }
 

Modified: head/sys/ofed/drivers/infiniband/core/ib_cma.c
==============================================================================
--- head/sys/ofed/drivers/infiniband/core/ib_cma.c      Tue Jul 17 08:54:40 
2018        (r336366)
+++ head/sys/ofed/drivers/infiniband/core/ib_cma.c      Tue Jul 17 08:59:34 
2018        (r336367)
@@ -427,6 +427,30 @@ static inline void cma_set_ip_ver(struct cma_hdr *hdr,
        hdr->ip_version = (ip_ver << 4) | (hdr->ip_version & 0xF);
 }
 
+static int cma_igmp_send(struct net_device *ndev, const union ib_gid *mgid, 
bool join)
+{
+       int retval;
+
+       if (ndev) {
+               union {
+                       struct sockaddr sock;
+                       struct sockaddr_storage storage;
+               } addr;
+
+               rdma_gid2ip(&addr.sock, mgid);
+
+               CURVNET_SET_QUIET(ndev->if_vnet);
+               if (join)
+                       retval = -if_addmulti(ndev, &addr.sock, NULL);
+               else
+                       retval = -if_delmulti(ndev, &addr.sock);
+               CURVNET_RESTORE();
+       } else {
+               retval = -ENODEV;
+       }
+       return retval;
+}
+
 static void _cma_attach_to_dev(struct rdma_id_private *id_priv,
                               struct cma_device *cma_dev)
 {
@@ -1621,6 +1645,9 @@ static void cma_leave_mc_groups(struct rdma_id_private
                                        ndev = dev_get_by_index(dev_addr->net,
                                                                
dev_addr->bound_dev_if);
                                if (ndev) {
+                                       cma_igmp_send(ndev,
+                                                     
&mc->multicast.ib->rec.mgid,
+                                                     false);
                                        dev_put(ndev);
                                }
                        }
@@ -4024,7 +4051,10 @@ static int cma_iboe_join_multicast(struct rdma_id_priv
                if (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP) {
                        mc->multicast.ib->rec.hop_limit = IPV6_DEFAULT_HOPLIMIT;
                        if (!send_only) {
-                               mc->igmp_joined = true;
+                               err = cma_igmp_send(ndev, 
&mc->multicast.ib->rec.mgid,
+                                                   true);
+                               if (!err)
+                                       mc->igmp_joined = true;
                        }
                }
        } else {
@@ -4129,6 +4159,9 @@ void rdma_leave_multicast(struct rdma_cm_id *id, struc
                                                ndev = 
dev_get_by_index(dev_addr->net,
                                                                        
dev_addr->bound_dev_if);
                                        if (ndev) {
+                                               cma_igmp_send(ndev,
+                                                             
&mc->multicast.ib->rec.mgid,
+                                                             false);
                                                dev_put(ndev);
                                        }
                                        mc->igmp_joined = false;
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to