IB/rxe: Fix sending out loopback packet on netdev interface.
authorParav Pandit <pandit.parav@gmail.com>
Wed, 28 Sep 2016 20:24:42 +0000 (20:24 +0000)
committerDoug Ledford <dledford@redhat.com>
Thu, 6 Oct 2016 17:50:04 +0000 (13:50 -0400)
Both prepare4 and prepare6 sets loopback mask in pkt_info structure
instance of skb.  The xmit_packet and other requester side functions
use a pkt_info struct from the stack without the proper mask.  This
results in sending out the packet to the actual netdev device and
loopback functionality is broken.

Modify prepare() to pass its correctly marked pkt_info struct to
prepare4() and prepare6() instead of them using SKB_TO_PKT(skb) and
getting an incorrectly set mask.

Verified with perftest applications.

Signed-off-by: Parav Pandit <pandit.parav@gmail.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/sw/rxe/rxe_net.c

index eedf2f1cafdfa56f1db4223ebe42aaa74d51f4c9..549aa84f9f9fcbcc76038c03708d2b714798d733 100644 (file)
@@ -350,14 +350,14 @@ static void prepare_ipv6_hdr(struct dst_entry *dst, struct sk_buff *skb,
        ip6h->payload_len = htons(skb->len - sizeof(*ip6h));
 }
 
-static int prepare4(struct rxe_dev *rxe, struct sk_buff *skb, struct rxe_av *av)
+static int prepare4(struct rxe_dev *rxe, struct rxe_pkt_info *pkt,
+                   struct sk_buff *skb, struct rxe_av *av)
 {
        struct dst_entry *dst;
        bool xnet = false;
        __be16 df = htons(IP_DF);
        struct in_addr *saddr = &av->sgid_addr._sockaddr_in.sin_addr;
        struct in_addr *daddr = &av->dgid_addr._sockaddr_in.sin_addr;
-       struct rxe_pkt_info *pkt = SKB_TO_PKT(skb);
 
        dst = rxe_find_route4(rxe->ndev, saddr, daddr);
        if (!dst) {
@@ -376,12 +376,12 @@ static int prepare4(struct rxe_dev *rxe, struct sk_buff *skb, struct rxe_av *av)
        return 0;
 }
 
-static int prepare6(struct rxe_dev *rxe, struct sk_buff *skb, struct rxe_av *av)
+static int prepare6(struct rxe_dev *rxe, struct rxe_pkt_info *pkt,
+                   struct sk_buff *skb, struct rxe_av *av)
 {
        struct dst_entry *dst;
        struct in6_addr *saddr = &av->sgid_addr._sockaddr_in6.sin6_addr;
        struct in6_addr *daddr = &av->dgid_addr._sockaddr_in6.sin6_addr;
-       struct rxe_pkt_info *pkt = SKB_TO_PKT(skb);
 
        dst = rxe_find_route6(rxe->ndev, saddr, daddr);
        if (!dst) {
@@ -408,9 +408,9 @@ static int prepare(struct rxe_dev *rxe, struct rxe_pkt_info *pkt,
        struct rxe_av *av = rxe_get_av(pkt);
 
        if (av->network_type == RDMA_NETWORK_IPV4)
-               err = prepare4(rxe, skb, av);
+               err = prepare4(rxe, pkt, skb, av);
        else if (av->network_type == RDMA_NETWORK_IPV6)
-               err = prepare6(rxe, skb, av);
+               err = prepare6(rxe, pkt, skb, av);
 
        *crc = rxe_icrc_hdr(pkt, skb);