summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorae <ae@FreeBSD.org>2015-12-08 07:43:12 +0000
committerae <ae@FreeBSD.org>2015-12-08 07:43:12 +0000
commit58974a9f1d6e1285884033deebac6f9ab99b4c06 (patch)
tree8912ec092feb2d8abc81c3f05302717e8c144512 /sys/netinet
parent0f5a92c989e527a15042aa0cb356fd0cb1359152 (diff)
downloadFreeBSD-src-58974a9f1d6e1285884033deebac6f9ab99b4c06.zip
FreeBSD-src-58974a9f1d6e1285884033deebac6f9ab99b4c06.tar.gz
MFC r291579:
In the same way fix the problem described in r291578 for IGMPv3. In case when router has a lot of multicast groups, the reply can take several packets due to MTU limitation. Also we have a limit IGMP_MAX_RESPONSE_BURST == 4, that limits the number of packets we send in one shot. Then we recalculate the timer value and schedule the remaining packets for sending. The problem is that when we call igmp_v3_dispatch_general_query() to send remaining packets, we queue new reply in the same mbuf queue. And when number of packets is bigger than IGMP_MAX_RESPONSE_BURST, we get endless reply of IGMPv3 reports. To fix this, add the check for remaining packets in the queue.
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/igmp.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/sys/netinet/igmp.c b/sys/netinet/igmp.c
index c138f14..34a60a8 100644
--- a/sys/netinet/igmp.c
+++ b/sys/netinet/igmp.c
@@ -3327,6 +3327,15 @@ igmp_v3_dispatch_general_query(struct igmp_ifinfo *igi)
KASSERT(igi->igi_version == IGMP_VERSION_3,
("%s: called when version %d", __func__, igi->igi_version));
+ /*
+ * Check that there are some packets queued. If so, send them first.
+ * For large number of groups the reply to general query can take
+ * many packets, we should finish sending them before starting of
+ * queuing the new reply.
+ */
+ if (igi->igi_gq.ifq_head != NULL)
+ goto send;
+
ifp = igi->igi_ifp;
IF_ADDR_RLOCK(ifp);
@@ -3362,6 +3371,7 @@ igmp_v3_dispatch_general_query(struct igmp_ifinfo *igi)
}
IF_ADDR_RUNLOCK(ifp);
+send:
loop = (igi->igi_flags & IGIF_LOOPBACK) ? 1 : 0;
igmp_dispatch_queue(&igi->igi_gq, IGMP_MAX_RESPONSE_BURST, loop);
OpenPOWER on IntegriCloud