aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp/ipoib/ipoib_main.c
diff options
context:
space:
mode:
authorRoland Dreier <roland@purestorage.com>2012-02-07 09:51:21 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-02-29 19:33:45 -0500
commitaca5efd17c1a1ed6303537792517e7352cf74edd (patch)
tree7f05fdb94bc1c48bdaf578e31d94bce00144dbe1 /drivers/infiniband/ulp/ipoib/ipoib_main.c
parentc3e8445f6ec4ad66c5143d6df8528f7440429b91 (diff)
IPoIB: Stop lying about hard_header_len and use skb->cb to stash LL addresses
[ Upstream commit 936d7de3d736e0737542641269436f4b5968e9ef ] Commit a0417fa3a18a ("net: Make qdisc_skb_cb upper size bound explicit.") made it possible for a netdev driver to use skb->cb between its header_ops.create method and its .ndo_start_xmit method. Use this in ipoib_hard_header() to stash away the LL address (GID + QPN), instead of the "ipoib_pseudoheader" hack. This allows IPoIB to stop lying about its hard_header_len, which will let us fix the L2 check for GRO. Signed-off-by: Roland Dreier <roland@purestorage.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/infiniband/ulp/ipoib/ipoib_main.c')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c55
1 files changed, 19 insertions, 36 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index a98c414978e..b811444dcdd 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -658,7 +658,7 @@ static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev)
658} 658}
659 659
660static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, 660static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
661 struct ipoib_pseudoheader *phdr) 661 struct ipoib_cb *cb)
662{ 662{
663 struct ipoib_dev_priv *priv = netdev_priv(dev); 663 struct ipoib_dev_priv *priv = netdev_priv(dev);
664 struct ipoib_path *path; 664 struct ipoib_path *path;
@@ -666,17 +666,15 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
666 666
667 spin_lock_irqsave(&priv->lock, flags); 667 spin_lock_irqsave(&priv->lock, flags);
668 668
669 path = __path_find(dev, phdr->hwaddr + 4); 669 path = __path_find(dev, cb->hwaddr + 4);
670 if (!path || !path->valid) { 670 if (!path || !path->valid) {
671 int new_path = 0; 671 int new_path = 0;
672 672
673 if (!path) { 673 if (!path) {
674 path = path_rec_create(dev, phdr->hwaddr + 4); 674 path = path_rec_create(dev, cb->hwaddr + 4);
675 new_path = 1; 675 new_path = 1;
676 } 676 }
677 if (path) { 677 if (path) {
678 /* put pseudoheader back on for next time */
679 skb_push(skb, sizeof *phdr);
680 __skb_queue_tail(&path->queue, skb); 678 __skb_queue_tail(&path->queue, skb);
681 679
682 if (!path->query && path_rec_start(dev, path)) { 680 if (!path->query && path_rec_start(dev, path)) {
@@ -700,12 +698,10 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
700 be16_to_cpu(path->pathrec.dlid)); 698 be16_to_cpu(path->pathrec.dlid));
701 699
702 spin_unlock_irqrestore(&priv->lock, flags); 700 spin_unlock_irqrestore(&priv->lock, flags);
703 ipoib_send(dev, skb, path->ah, IPOIB_QPN(phdr->hwaddr)); 701 ipoib_send(dev, skb, path->ah, IPOIB_QPN(cb->hwaddr));
704 return; 702 return;
705 } else if ((path->query || !path_rec_start(dev, path)) && 703 } else if ((path->query || !path_rec_start(dev, path)) &&
706 skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) { 704 skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
707 /* put pseudoheader back on for next time */
708 skb_push(skb, sizeof *phdr);
709 __skb_queue_tail(&path->queue, skb); 705 __skb_queue_tail(&path->queue, skb);
710 } else { 706 } else {
711 ++dev->stats.tx_dropped; 707 ++dev->stats.tx_dropped;
@@ -774,16 +770,14 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
774 dev_kfree_skb_any(skb); 770 dev_kfree_skb_any(skb);
775 } 771 }
776 } else { 772 } else {
777 struct ipoib_pseudoheader *phdr = 773 struct ipoib_cb *cb = (struct ipoib_cb *) skb->cb;
778 (struct ipoib_pseudoheader *) skb->data;
779 skb_pull(skb, sizeof *phdr);
780 774
781 if (phdr->hwaddr[4] == 0xff) { 775 if (cb->hwaddr[4] == 0xff) {
782 /* Add in the P_Key for multicast*/ 776 /* Add in the P_Key for multicast*/
783 phdr->hwaddr[8] = (priv->pkey >> 8) & 0xff; 777 cb->hwaddr[8] = (priv->pkey >> 8) & 0xff;
784 phdr->hwaddr[9] = priv->pkey & 0xff; 778 cb->hwaddr[9] = priv->pkey & 0xff;
785 779
786 ipoib_mcast_send(dev, phdr->hwaddr + 4, skb); 780 ipoib_mcast_send(dev, cb->hwaddr + 4, skb);
787 } else { 781 } else {
788 /* unicast GID -- should be ARP or RARP reply */ 782 /* unicast GID -- should be ARP or RARP reply */
789 783
@@ -792,14 +786,14 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
792 ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x %pI6\n", 786 ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x %pI6\n",
793 skb_dst(skb) ? "neigh" : "dst", 787 skb_dst(skb) ? "neigh" : "dst",
794 be16_to_cpup((__be16 *) skb->data), 788 be16_to_cpup((__be16 *) skb->data),
795 IPOIB_QPN(phdr->hwaddr), 789 IPOIB_QPN(cb->hwaddr),
796 phdr->hwaddr + 4); 790 cb->hwaddr + 4);
797 dev_kfree_skb_any(skb); 791 dev_kfree_skb_any(skb);
798 ++dev->stats.tx_dropped; 792 ++dev->stats.tx_dropped;
799 goto unlock; 793 goto unlock;
800 } 794 }
801 795
802 unicast_arp_send(skb, dev, phdr); 796 unicast_arp_send(skb, dev, cb);
803 } 797 }
804 } 798 }
805unlock: 799unlock:
@@ -825,8 +819,6 @@ static int ipoib_hard_header(struct sk_buff *skb,
825 const void *daddr, const void *saddr, unsigned len) 819 const void *daddr, const void *saddr, unsigned len)
826{ 820{
827 struct ipoib_header *header; 821 struct ipoib_header *header;
828 struct dst_entry *dst;
829 struct neighbour *n;
830 822
831 header = (struct ipoib_header *) skb_push(skb, sizeof *header); 823 header = (struct ipoib_header *) skb_push(skb, sizeof *header);
832 824
@@ -834,18 +826,13 @@ static int ipoib_hard_header(struct sk_buff *skb,
834 header->reserved = 0; 826 header->reserved = 0;
835 827
836 /* 828 /*
837 * If we don't have a neighbour structure, stuff the 829 * If we don't have a dst_entry structure, stuff the
838 * destination address onto the front of the skb so we can 830 * destination address into skb->cb so we can figure out where
839 * figure out where to send the packet later. 831 * to send the packet later.
840 */ 832 */
841 dst = skb_dst(skb); 833 if (!skb_dst(skb)) {
842 n = NULL; 834 struct ipoib_cb *cb = (struct ipoib_cb *) skb->cb;
843 if (dst) 835 memcpy(cb->hwaddr, daddr, INFINIBAND_ALEN);
844 n = dst_get_neighbour_raw(dst);
845 if ((!dst || !n) && daddr) {
846 struct ipoib_pseudoheader *phdr =
847 (struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr);
848 memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN);
849 } 836 }
850 837
851 return 0; 838 return 0;
@@ -1021,11 +1008,7 @@ static void ipoib_setup(struct net_device *dev)
1021 1008
1022 dev->flags |= IFF_BROADCAST | IFF_MULTICAST; 1009 dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
1023 1010
1024 /* 1011 dev->hard_header_len = IPOIB_ENCAP_LEN;
1025 * We add in INFINIBAND_ALEN to allow for the destination
1026 * address "pseudoheader" for skbs without neighbour struct.
1027 */
1028 dev->hard_header_len = IPOIB_ENCAP_LEN + INFINIBAND_ALEN;
1029 dev->addr_len = INFINIBAND_ALEN; 1012 dev->addr_len = INFINIBAND_ALEN;
1030 dev->type = ARPHRD_INFINIBAND; 1013 dev->type = ARPHRD_INFINIBAND;
1031 dev->tx_queue_len = ipoib_sendq_size * 2; 1014 dev->tx_queue_len = ipoib_sendq_size * 2;