diff options
Diffstat (limited to 'net/ipv6/mcast.c')
-rw-r--r-- | net/ipv6/mcast.c | 58 |
1 files changed, 30 insertions, 28 deletions
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 12b7c27ce5ce..844642682b83 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -75,10 +75,10 @@ static struct in6_addr mld2_all_mcr = MLD2_ALL_MCR_INIT; static void igmp6_join_group(struct ifmcaddr6 *ma); static void igmp6_leave_group(struct ifmcaddr6 *ma); -static void igmp6_timer_handler(unsigned long data); +static void igmp6_timer_handler(struct timer_list *t); -static void mld_gq_timer_expire(unsigned long data); -static void mld_ifc_timer_expire(unsigned long data); +static void mld_gq_timer_expire(struct timer_list *t); +static void mld_ifc_timer_expire(struct timer_list *t); static void mld_ifc_event(struct inet6_dev *idev); static void mld_add_delrec(struct inet6_dev *idev, struct ifmcaddr6 *pmc); static void mld_del_delrec(struct inet6_dev *idev, struct ifmcaddr6 *pmc); @@ -839,7 +839,7 @@ static struct ifmcaddr6 *mca_alloc(struct inet6_dev *idev, if (!mc) return NULL; - setup_timer(&mc->mca_timer, igmp6_timer_handler, (unsigned long)mc); + timer_setup(&mc->mca_timer, igmp6_timer_handler, 0); mc->mca_addr = *addr; mc->idev = idev; /* reference taken by caller */ @@ -1682,16 +1682,16 @@ static int grec_size(struct ifmcaddr6 *pmc, int type, int gdel, int sdel) } static struct sk_buff *add_grhead(struct sk_buff *skb, struct ifmcaddr6 *pmc, - int type, struct mld2_grec **ppgr) + int type, struct mld2_grec **ppgr, unsigned int mtu) { - struct net_device *dev = pmc->idev->dev; struct mld2_report *pmr; struct mld2_grec *pgr; - if (!skb) - skb = mld_newpack(pmc->idev, dev->mtu); - if (!skb) - return NULL; + if (!skb) { + skb = mld_newpack(pmc->idev, mtu); + if (!skb) + return NULL; + } pgr = skb_put(skb, sizeof(struct mld2_grec)); pgr->grec_type = type; pgr->grec_auxwords = 0; @@ -1714,10 +1714,15 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, struct mld2_grec *pgr = NULL; struct ip6_sf_list *psf, *psf_next, *psf_prev, **psf_list; int scount, stotal, first, isquery, truncate; + unsigned int mtu; if (pmc->mca_flags & MAF_NOREPORT) return skb; + mtu = READ_ONCE(dev->mtu); + if (mtu < IPV6_MIN_MTU) + return skb; + isquery = type == MLD2_MODE_IS_INCLUDE || type == MLD2_MODE_IS_EXCLUDE; truncate = type == MLD2_MODE_IS_EXCLUDE || @@ -1738,7 +1743,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) { if (skb) mld_sendpack(skb); - skb = mld_newpack(idev, dev->mtu); + skb = mld_newpack(idev, mtu); } } first = 1; @@ -1774,12 +1779,12 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, pgr->grec_nsrcs = htons(scount); if (skb) mld_sendpack(skb); - skb = mld_newpack(idev, dev->mtu); + skb = mld_newpack(idev, mtu); first = 1; scount = 0; } if (first) { - skb = add_grhead(skb, pmc, type, &pgr); + skb = add_grhead(skb, pmc, type, &pgr, mtu); first = 0; } if (!skb) @@ -1814,7 +1819,7 @@ empty_source: mld_sendpack(skb); skb = NULL; /* add_grhead will get a new one */ } - skb = add_grhead(skb, pmc, type, &pgr); + skb = add_grhead(skb, pmc, type, &pgr, mtu); } } if (pgr) @@ -2083,9 +2088,9 @@ void ipv6_mc_dad_complete(struct inet6_dev *idev) } } -static void mld_dad_timer_expire(unsigned long data) +static void mld_dad_timer_expire(struct timer_list *t) { - struct inet6_dev *idev = (struct inet6_dev *)data; + struct inet6_dev *idev = from_timer(idev, t, mc_dad_timer); mld_send_initial_cr(idev); if (idev->mc_dad_count) { @@ -2432,18 +2437,18 @@ static void igmp6_leave_group(struct ifmcaddr6 *ma) } } -static void mld_gq_timer_expire(unsigned long data) +static void mld_gq_timer_expire(struct timer_list *t) { - struct inet6_dev *idev = (struct inet6_dev *)data; + struct inet6_dev *idev = from_timer(idev, t, mc_gq_timer); idev->mc_gq_running = 0; mld_send_report(idev, NULL); in6_dev_put(idev); } -static void mld_ifc_timer_expire(unsigned long data) +static void mld_ifc_timer_expire(struct timer_list *t) { - struct inet6_dev *idev = (struct inet6_dev *)data; + struct inet6_dev *idev = from_timer(idev, t, mc_ifc_timer); mld_send_cr(idev); if (idev->mc_ifc_count) { @@ -2462,9 +2467,9 @@ static void mld_ifc_event(struct inet6_dev *idev) mld_ifc_start_timer(idev, 1); } -static void igmp6_timer_handler(unsigned long data) +static void igmp6_timer_handler(struct timer_list *t) { - struct ifmcaddr6 *ma = (struct ifmcaddr6 *) data; + struct ifmcaddr6 *ma = from_timer(ma, t, mca_timer); if (mld_in_v1_mode(ma->idev)) igmp6_send(&ma->mca_addr, ma->idev->dev, ICMPV6_MGM_REPORT); @@ -2552,14 +2557,11 @@ void ipv6_mc_init_dev(struct inet6_dev *idev) write_lock_bh(&idev->lock); spin_lock_init(&idev->mc_lock); idev->mc_gq_running = 0; - setup_timer(&idev->mc_gq_timer, mld_gq_timer_expire, - (unsigned long)idev); + timer_setup(&idev->mc_gq_timer, mld_gq_timer_expire, 0); idev->mc_tomb = NULL; idev->mc_ifc_count = 0; - setup_timer(&idev->mc_ifc_timer, mld_ifc_timer_expire, - (unsigned long)idev); - setup_timer(&idev->mc_dad_timer, mld_dad_timer_expire, - (unsigned long)idev); + timer_setup(&idev->mc_ifc_timer, mld_ifc_timer_expire, 0); + timer_setup(&idev->mc_dad_timer, mld_dad_timer_expire, 0); ipv6_mc_reset(idev); write_unlock_bh(&idev->lock); } |