diff options
Diffstat (limited to 'net/ipv6/mcast.c')
-rw-r--r-- | net/ipv6/mcast.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index fc6d7d143f2c..844642682b83 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -1682,16 +1682,16 @@ static int grec_size(struct ifmcaddr6 *pmc, int type, int gdel, int sdel) | |||
1682 | } | 1682 | } |
1683 | 1683 | ||
1684 | static struct sk_buff *add_grhead(struct sk_buff *skb, struct ifmcaddr6 *pmc, | 1684 | static struct sk_buff *add_grhead(struct sk_buff *skb, struct ifmcaddr6 *pmc, |
1685 | int type, struct mld2_grec **ppgr) | 1685 | int type, struct mld2_grec **ppgr, unsigned int mtu) |
1686 | { | 1686 | { |
1687 | struct net_device *dev = pmc->idev->dev; | ||
1688 | struct mld2_report *pmr; | 1687 | struct mld2_report *pmr; |
1689 | struct mld2_grec *pgr; | 1688 | struct mld2_grec *pgr; |
1690 | 1689 | ||
1691 | if (!skb) | 1690 | if (!skb) { |
1692 | skb = mld_newpack(pmc->idev, dev->mtu); | 1691 | skb = mld_newpack(pmc->idev, mtu); |
1693 | if (!skb) | 1692 | if (!skb) |
1694 | return NULL; | 1693 | return NULL; |
1694 | } | ||
1695 | pgr = skb_put(skb, sizeof(struct mld2_grec)); | 1695 | pgr = skb_put(skb, sizeof(struct mld2_grec)); |
1696 | pgr->grec_type = type; | 1696 | pgr->grec_type = type; |
1697 | pgr->grec_auxwords = 0; | 1697 | pgr->grec_auxwords = 0; |
@@ -1714,10 +1714,15 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, | |||
1714 | struct mld2_grec *pgr = NULL; | 1714 | struct mld2_grec *pgr = NULL; |
1715 | struct ip6_sf_list *psf, *psf_next, *psf_prev, **psf_list; | 1715 | struct ip6_sf_list *psf, *psf_next, *psf_prev, **psf_list; |
1716 | int scount, stotal, first, isquery, truncate; | 1716 | int scount, stotal, first, isquery, truncate; |
1717 | unsigned int mtu; | ||
1717 | 1718 | ||
1718 | if (pmc->mca_flags & MAF_NOREPORT) | 1719 | if (pmc->mca_flags & MAF_NOREPORT) |
1719 | return skb; | 1720 | return skb; |
1720 | 1721 | ||
1722 | mtu = READ_ONCE(dev->mtu); | ||
1723 | if (mtu < IPV6_MIN_MTU) | ||
1724 | return skb; | ||
1725 | |||
1721 | isquery = type == MLD2_MODE_IS_INCLUDE || | 1726 | isquery = type == MLD2_MODE_IS_INCLUDE || |
1722 | type == MLD2_MODE_IS_EXCLUDE; | 1727 | type == MLD2_MODE_IS_EXCLUDE; |
1723 | truncate = type == MLD2_MODE_IS_EXCLUDE || | 1728 | truncate = type == MLD2_MODE_IS_EXCLUDE || |
@@ -1738,7 +1743,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, | |||
1738 | AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) { | 1743 | AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) { |
1739 | if (skb) | 1744 | if (skb) |
1740 | mld_sendpack(skb); | 1745 | mld_sendpack(skb); |
1741 | skb = mld_newpack(idev, dev->mtu); | 1746 | skb = mld_newpack(idev, mtu); |
1742 | } | 1747 | } |
1743 | } | 1748 | } |
1744 | first = 1; | 1749 | first = 1; |
@@ -1774,12 +1779,12 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, | |||
1774 | pgr->grec_nsrcs = htons(scount); | 1779 | pgr->grec_nsrcs = htons(scount); |
1775 | if (skb) | 1780 | if (skb) |
1776 | mld_sendpack(skb); | 1781 | mld_sendpack(skb); |
1777 | skb = mld_newpack(idev, dev->mtu); | 1782 | skb = mld_newpack(idev, mtu); |
1778 | first = 1; | 1783 | first = 1; |
1779 | scount = 0; | 1784 | scount = 0; |
1780 | } | 1785 | } |
1781 | if (first) { | 1786 | if (first) { |
1782 | skb = add_grhead(skb, pmc, type, &pgr); | 1787 | skb = add_grhead(skb, pmc, type, &pgr, mtu); |
1783 | first = 0; | 1788 | first = 0; |
1784 | } | 1789 | } |
1785 | if (!skb) | 1790 | if (!skb) |
@@ -1814,7 +1819,7 @@ empty_source: | |||
1814 | mld_sendpack(skb); | 1819 | mld_sendpack(skb); |
1815 | skb = NULL; /* add_grhead will get a new one */ | 1820 | skb = NULL; /* add_grhead will get a new one */ |
1816 | } | 1821 | } |
1817 | skb = add_grhead(skb, pmc, type, &pgr); | 1822 | skb = add_grhead(skb, pmc, type, &pgr, mtu); |
1818 | } | 1823 | } |
1819 | } | 1824 | } |
1820 | if (pgr) | 1825 | if (pgr) |