libcxgb,iw_cxgb4,cxgbit: add cxgb_find_route6()
[cascardo/linux.git] / drivers / target / iscsi / cxgbit / cxgbit_cm.c
index 0ae0b13..e961ac4 100644 (file)
@@ -24,6 +24,7 @@
 #include <net/ip6_route.h>
 #include <net/addrconf.h>
 
+#include <libcxgb_cm.h>
 #include "cxgbit.h"
 #include "clip_tbl.h"
 
@@ -789,109 +790,6 @@ void _cxgbit_free_csk(struct kref *kref)
        kfree(csk);
 }
 
-static void
-cxgbit_get_tuple_info(struct cpl_pass_accept_req *req, int *iptype,
-                     __u8 *local_ip, __u8 *peer_ip, __be16 *local_port,
-                     __be16 *peer_port)
-{
-       u32 eth_len = ETH_HDR_LEN_G(be32_to_cpu(req->hdr_len));
-       u32 ip_len = IP_HDR_LEN_G(be32_to_cpu(req->hdr_len));
-       struct iphdr *ip = (struct iphdr *)((u8 *)(req + 1) + eth_len);
-       struct ipv6hdr *ip6 = (struct ipv6hdr *)((u8 *)(req + 1) + eth_len);
-       struct tcphdr *tcp = (struct tcphdr *)
-                             ((u8 *)(req + 1) + eth_len + ip_len);
-
-       if (ip->version == 4) {
-               pr_debug("%s saddr 0x%x daddr 0x%x sport %u dport %u\n",
-                        __func__,
-                        ntohl(ip->saddr), ntohl(ip->daddr),
-                        ntohs(tcp->source),
-                        ntohs(tcp->dest));
-               *iptype = 4;
-               memcpy(peer_ip, &ip->saddr, 4);
-               memcpy(local_ip, &ip->daddr, 4);
-       } else {
-               pr_debug("%s saddr %pI6 daddr %pI6 sport %u dport %u\n",
-                        __func__,
-                        ip6->saddr.s6_addr, ip6->daddr.s6_addr,
-                        ntohs(tcp->source),
-                        ntohs(tcp->dest));
-               *iptype = 6;
-               memcpy(peer_ip, ip6->saddr.s6_addr, 16);
-               memcpy(local_ip, ip6->daddr.s6_addr, 16);
-       }
-
-       *peer_port = tcp->source;
-       *local_port = tcp->dest;
-}
-
-static int
-cxgbit_our_interface(struct cxgbit_device *cdev, struct net_device *egress_dev)
-{
-       u8 i;
-
-       egress_dev = cxgbit_get_real_dev(egress_dev);
-       for (i = 0; i < cdev->lldi.nports; i++)
-               if (cdev->lldi.ports[i] == egress_dev)
-                       return 1;
-       return 0;
-}
-
-static struct dst_entry *
-cxgbit_find_route6(struct cxgbit_device *cdev, __u8 *local_ip, __u8 *peer_ip,
-                  __be16 local_port, __be16 peer_port, u8 tos,
-                  __u32 sin6_scope_id)
-{
-       struct dst_entry *dst = NULL;
-
-       if (IS_ENABLED(CONFIG_IPV6)) {
-               struct flowi6 fl6;
-
-               memset(&fl6, 0, sizeof(fl6));
-               memcpy(&fl6.daddr, peer_ip, 16);
-               memcpy(&fl6.saddr, local_ip, 16);
-               if (ipv6_addr_type(&fl6.daddr) & IPV6_ADDR_LINKLOCAL)
-                       fl6.flowi6_oif = sin6_scope_id;
-               dst = ip6_route_output(&init_net, NULL, &fl6);
-               if (!dst)
-                       goto out;
-               if (!cxgbit_our_interface(cdev, ip6_dst_idev(dst)->dev) &&
-                   !(ip6_dst_idev(dst)->dev->flags & IFF_LOOPBACK)) {
-                       dst_release(dst);
-                       dst = NULL;
-               }
-       }
-out:
-       return dst;
-}
-
-static struct dst_entry *
-cxgbit_find_route(struct cxgbit_device *cdev, __be32 local_ip, __be32 peer_ip,
-                 __be16 local_port, __be16 peer_port, u8 tos)
-{
-       struct rtable *rt;
-       struct flowi4 fl4;
-       struct neighbour *n;
-
-       rt = ip_route_output_ports(&init_net, &fl4, NULL, peer_ip,
-                                  local_ip,
-                                  peer_port, local_port, IPPROTO_TCP,
-                                  tos, 0);
-       if (IS_ERR(rt))
-               return NULL;
-       n = dst_neigh_lookup(&rt->dst, &peer_ip);
-       if (!n)
-               return NULL;
-       if (!cxgbit_our_interface(cdev, n->dev) &&
-           !(n->dev->flags & IFF_LOOPBACK)) {
-               neigh_release(n);
-               dst_release(&rt->dst);
-               return NULL;
-       }
-       neigh_release(n);
-       return &rt->dst;
-}
-
 static void cxgbit_set_tcp_window(struct cxgbit_sock *csk, struct port_info *pi)
 {
        unsigned int linkspeed;
@@ -1340,8 +1238,8 @@ cxgbit_pass_accept_req(struct cxgbit_device *cdev, struct sk_buff *skb)
                goto rel_skb;
        }
 
-       cxgbit_get_tuple_info(req, &iptype, local_ip, peer_ip,
-                             &local_port, &peer_port);
+       cxgb_get_4tuple(req, cdev->lldi.adapter_type, &iptype, local_ip,
+                       peer_ip, &local_port, &peer_port);
 
        /* Find output route */
        if (iptype == 4)  {
@@ -1350,21 +1248,23 @@ cxgbit_pass_accept_req(struct cxgbit_device *cdev, struct sk_buff *skb)
                         , __func__, cnp, tid,
                         local_ip, peer_ip, ntohs(local_port),
                         ntohs(peer_port), peer_mss);
-               dst = cxgbit_find_route(cdev, *(__be32 *)local_ip,
-                                       *(__be32 *)peer_ip,
-                                       local_port, peer_port,
-                                       PASS_OPEN_TOS_G(ntohl(req->tos_stid)));
+               dst = cxgb_find_route(&cdev->lldi, cxgbit_get_real_dev,
+                                     *(__be32 *)local_ip,
+                                     *(__be32 *)peer_ip,
+                                     local_port, peer_port,
+                                     PASS_OPEN_TOS_G(ntohl(req->tos_stid)));
        } else {
                pr_debug("%s parent sock %p tid %u laddr %pI6 raddr %pI6 "
                         "lport %d rport %d peer_mss %d\n"
                         , __func__, cnp, tid,
                         local_ip, peer_ip, ntohs(local_port),
                         ntohs(peer_port), peer_mss);
-               dst = cxgbit_find_route6(cdev, local_ip, peer_ip,
-                                        local_port, peer_port,
-                                        PASS_OPEN_TOS_G(ntohl(req->tos_stid)),
-                                        ((struct sockaddr_in6 *)
-                                        &cnp->com.local_addr)->sin6_scope_id);
+               dst = cxgb_find_route6(&cdev->lldi, cxgbit_get_real_dev,
+                                      local_ip, peer_ip,
+                                      local_port, peer_port,
+                                      PASS_OPEN_TOS_G(ntohl(req->tos_stid)),
+                                      ((struct sockaddr_in6 *)
+                                       &cnp->com.local_addr)->sin6_scope_id);
        }
        if (!dst) {
                pr_err("%s - failed to find dst entry!\n",