Skip to content
  • Benjamin Poirier's avatar
    mld, igmp: Fix reserved tailroom calculation · 1837b2e2
    Benjamin Poirier authored
    The current reserved_tailroom calculation fails to take hlen and tlen into
    account.
    
    skb:
    [__hlen__|__data____________|__tlen___|__extra__]
    ^                                               ^
    head                                            skb_end_offset
    
    In this representation, hlen + data + tlen is the size passed to alloc_skb.
    "extra" is the extra space made available in __alloc_skb because of
    rounding up by kmalloc. We can reorder the representation like so:
    
    [__hlen__|__data____________|__extra__|__tlen___]
    ^                                               ^
    head                                            skb_end_offset
    
    The maximum space available for ip headers and payload without
    fragmentation is min(mtu, data + extra). Therefore,
    reserved_tailroom
    = data + extra + tlen - min(mtu, data + extra)
    = skb_end_offset - hlen - min(mtu, skb_end_offset - hlen - tlen)
    = skb_tailroom - min(mtu, skb_tailroom - tlen) ; after skb_reserve(hlen)
    
    Compare the second line to the current expression:
    reserved_tailroom = skb_end_offset - min(mtu, skb_end_offset)
    and we can see that hlen and tlen are not taken into account.
    
    The min() in the third line can be expanded into:
    if mtu < skb_tailroom - tlen:
    	reserved_tailroom = skb_tailroom - mtu
    else:
    	reserved_tailroom = tlen
    
    Depending on hlen, tlen, mtu and the number of multicast address records,
    the current code may output skbs that have less tailroom than
    dev->needed_tailroom or it may output more skbs than needed because not all
    space available is used.
    
    Fixes: 4c672e4b
    
     ("ipv6: mld: fix add_grhead skb_over_panic for devs with large MTUs")
    Signed-off-by: default avatarBenjamin Poirier <bpoirier@suse.com>
    Acked-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
    Acked-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    1837b2e2