Message ID | alpine.DEB.2.00.1008261629440.24174@router.home |
---|---|
State | Not Applicable, archived |
Delegated to: | David Miller |
Headers | show |
From: Christoph Lameter <cl@linux.com> Date: Thu, 26 Aug 2010 16:31:14 -0500 (CDT) > @@ -271,6 +271,13 @@ static void ipoib_ib_handle_rx_wc(struct > ipoib_ud_dma_unmap_rx(priv, mapping); > ipoib_ud_skb_put_frags(priv, skb, wc->byte_len); > > + if ((wc->wc_flags & IB_WC_GRH) && > + IN6_IS_ADDR_MULTICAST(&((struct ipv6hdr *)skb->data)->daddr)) > + > + skb->pkt_type = PACKET_MULTICAST; > + else > + skb->pkt_type = PACKET_HOST; I really don't think you can assume there is an ipv6 header here at all. You'll need to parse the encapsulated protocol and process it as ipv4 or ipv6 as needed. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Aug 26, 2010 at 03:15:53PM -0700, David Miller wrote: > From: Christoph Lameter <cl@linux.com> > Date: Thu, 26 Aug 2010 16:31:14 -0500 (CDT) > > > @@ -271,6 +271,13 @@ static void ipoib_ib_handle_rx_wc(struct > > ipoib_ud_dma_unmap_rx(priv, mapping); > > ipoib_ud_skb_put_frags(priv, skb, wc->byte_len); > > > > + if ((wc->wc_flags & IB_WC_GRH) && > > + IN6_IS_ADDR_MULTICAST(&((struct ipv6hdr *)skb->data)->daddr)) > > + > > + skb->pkt_type = PACKET_MULTICAST; > > + else > > + skb->pkt_type = PACKET_HOST; > > I really don't think you can assume there is an ipv6 header here > at all. The 40 bytes at this location are defined by the HW specification to be an IB GRH which has an identical layout to an IPv6 header. Roland is right, it would be clearer to use ib_grh ->dgid Jason -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Index: linux-2.6/drivers/infiniband/ulp/ipoib/ipoib_ib.c =================================================================== --- linux-2.6.orig/drivers/infiniband/ulp/ipoib/ipoib_ib.c 2010-08-26 15:11:34.000000000 -0500 +++ linux-2.6/drivers/infiniband/ulp/ipoib/ipoib_ib.c 2010-08-26 16:29:19.000000000 -0500 @@ -271,6 +271,13 @@ static void ipoib_ib_handle_rx_wc(struct ipoib_ud_dma_unmap_rx(priv, mapping); ipoib_ud_skb_put_frags(priv, skb, wc->byte_len); + if ((wc->wc_flags & IB_WC_GRH) && + IN6_IS_ADDR_MULTICAST(&((struct ipv6hdr *)skb->data)->daddr)) + + skb->pkt_type = PACKET_MULTICAST; + else + skb->pkt_type = PACKET_HOST; + skb_pull(skb, IB_GRH_BYTES); skb->protocol = ((struct ipoib_header *) skb->data)->proto; @@ -281,9 +288,6 @@ static void ipoib_ib_handle_rx_wc(struct dev->stats.rx_bytes += skb->len; skb->dev = dev; - /* XXX get correct PACKET_ type here */ - skb->pkt_type = PACKET_HOST; - if (test_bit(IPOIB_FLAG_CSUM, &priv->flags) && likely(wc->csum_ok)) skb->ip_summed = CHECKSUM_UNNECESSARY; Index: linux-2.6/include/linux/in6.h =================================================================== --- linux-2.6.orig/include/linux/in6.h 2010-08-26 15:11:34.000000000 -0500 +++ linux-2.6/include/linux/in6.h 2010-08-26 16:27:08.000000000 -0500 @@ -53,6 +53,9 @@ extern const struct in6_addr in6addr_lin extern const struct in6_addr in6addr_linklocal_allrouters; #define IN6ADDR_LINKLOCAL_ALLROUTERS_INIT \ { { { 0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2 } } } + +#define IN6_IS_ADDR_MULTICAST(a) ((a)->in6_u.u6_addr8[0] == 0xff) + #endif struct sockaddr_in6 {
Is this better? Subject: [IPoIB] Identify Multicast packets and fix IGMP breakage V2 IGMP processing is broken because the IPOIB does not set the skb->pkt_type the right way for Multicast traffic. All incoming packets are set to PACKET_HOST which means that the igmp_recv() function will ignore the IGMP broadcasts/multicasts. This in turn means that the IGMP timers are firing and are sending information about multicast subscriptions unnecessarily. In a large private network this can cause traffic spikes. Signed-off-by: Christoph Lameter <cl@linux.com> --- drivers/infiniband/ulp/ipoib/ipoib_ib.c | 10 +++++++--- include/linux/in6.h | 3 +++ 2 files changed, 10 insertions(+), 3 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html