Page MenuHomeFreeBSD

D19622.id55769.diff
No OneTemporary

D19622.id55769.diff

Index: sys/netinet/ip_reass.c
===================================================================
--- sys/netinet/ip_reass.c
+++ sys/netinet/ip_reass.c
@@ -46,7 +46,10 @@
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/sysctl.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/if_var.h>
#include <net/rss_config.h>
#include <net/netisr.h>
#include <net/vnet.h>
@@ -606,6 +609,40 @@
}
}
+/*
+ * Drain off all datagram fragments belonging to
+ * the given network interface.
+ */
+static void
+ipreass_cleanup(struct ifnet *ifp)
+{
+ struct ipq *temp;
+ struct ipq *fp;
+ int i;
+
+ CURVNET_SET_QUIET(ifp->if_vnet);
+
+ for (i = 0; i < IPREASS_NHASH; i++) {
+ IPQ_LOCK(i);
+
+ /* Scan fragment list. */
+ TAILQ_FOREACH_SAFE(fp, &V_ipq[i].head, ipq_list, temp) {
+ struct mbuf *mb = fp->ipq_frags;
+
+ while (mb != NULL) {
+ if (mb->m_pkthdr.rcvif == ifp) {
+ ipq_drop(&V_ipq[i], fp);
+ break;
+ }
+ mb = mb->m_nextpkt;
+ }
+ }
+ IPQ_UNLOCK(i);
+ }
+ CURVNET_RESTORE();
+}
+EVENTHANDLER_DEFINE(ifnet_departure_event, ipreass_cleanup, NULL, 0);
+
#ifdef VIMAGE
/*
* Destroy IP reassembly structures.
Index: sys/netinet6/frag6.c
===================================================================
--- sys/netinet6/frag6.c
+++ sys/netinet6/frag6.c
@@ -81,7 +81,7 @@
static void frag6_insque_head(struct ip6q *, struct ip6q *,
uint32_t bucket);
static void frag6_remque(struct ip6q *, uint32_t bucket);
-static void frag6_freef(struct ip6q *, uint32_t bucket);
+static void frag6_freef(struct ip6q *, uint32_t bucket, int send_icmp);
struct ip6qbucket {
struct ip6q ip6q;
@@ -594,7 +594,7 @@
if (af6->ip6af_off != next) {
if (q6->ip6q_nfrag > V_ip6_maxfragsperpacket) {
IP6STAT_ADD(ip6s_fragdropped, q6->ip6q_nfrag);
- frag6_freef(q6, hash);
+ frag6_freef(q6, hash, 1);
}
IP6Q_UNLOCK(hash);
return IPPROTO_DONE;
@@ -604,7 +604,7 @@
if (af6->ip6af_up->ip6af_mff) {
if (q6->ip6q_nfrag > V_ip6_maxfragsperpacket) {
IP6STAT_ADD(ip6s_fragdropped, q6->ip6q_nfrag);
- frag6_freef(q6, hash);
+ frag6_freef(q6, hash, 1);
}
IP6Q_UNLOCK(hash);
return IPPROTO_DONE;
@@ -731,7 +731,7 @@
* associated datagrams.
*/
static void
-frag6_freef(struct ip6q *q6, uint32_t bucket)
+frag6_freef(struct ip6q *q6, uint32_t bucket, int send_icmp)
{
struct ip6asfrag *af6, *down6;
@@ -748,7 +748,7 @@
* Return ICMP time exceeded error for the 1st fragment.
* Just free other fragments.
*/
- if (af6->ip6af_off == 0) {
+ if (af6->ip6af_off == 0 && send_icmp != 0) {
struct ip6_hdr *ip6;
/* adjust pointer */
@@ -864,7 +864,7 @@
IP6STAT_ADD(ip6s_fragtimeout,
q6->ip6q_prev->ip6q_nfrag);
/* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
- frag6_freef(q6->ip6q_prev, i);
+ frag6_freef(q6->ip6q_prev, i, 1);
}
}
/*
@@ -883,7 +883,7 @@
IP6STAT_ADD(ip6s_fragoverflow,
q6->ip6q_prev->ip6q_nfrag);
/* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
- frag6_freef(head->ip6q_prev, i);
+ frag6_freef(head->ip6q_prev, i, 1);
}
IP6Q_UNLOCK(i);
}
@@ -901,7 +901,7 @@
IP6STAT_ADD(ip6s_fragoverflow,
q6->ip6q_prev->ip6q_nfrag);
/* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
- frag6_freef(head->ip6q_prev, i);
+ frag6_freef(head->ip6q_prev, i, 1);
}
IP6Q_UNLOCK(i);
i = (i + 1) % IP6REASS_NHASH;
@@ -931,7 +931,7 @@
while (head->ip6q_next != head) {
IP6STAT_INC(ip6s_fragdropped);
/* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
- frag6_freef(head->ip6q_next, i);
+ frag6_freef(head->ip6q_next, i, 1);
}
IP6Q_UNLOCK(i);
}
@@ -940,6 +940,46 @@
VNET_LIST_RUNLOCK_NOSLEEP();
}
+/*
+ * Drain off all datagram fragments belonging to
+ * the given network interface.
+ */
+static void
+frag6_cleanup(struct ifnet *ifp)
+{
+ struct ip6asfrag *af6;
+ struct ip6q *head;
+ struct ip6q *q6n;
+ struct ip6q *q6;
+ int i;
+
+ CURVNET_SET_QUIET(ifp->if_vnet);
+ for (i = 0; i < IP6REASS_NHASH; i++) {
+ IP6Q_LOCK(i);
+
+ head = IP6Q_HEAD(i);
+
+ /* Scan fragment list. */
+ for (q6 = head->ip6q_next; q6 != head; q6 = q6n) {
+ q6n = q6->ip6q_next;
+
+ for (af6 = q6->ip6q_down; af6 != (struct ip6asfrag *)q6;
+ af6 = af6->ip6af_down) {
+ struct mbuf *m = IP6_REASS_MBUF(af6);
+
+ if (m->m_pkthdr.rcvif == ifp) {
+ IP6STAT_INC(ip6s_fragdropped);
+ frag6_freef(q6, i, 0);
+ break;
+ }
+ }
+ }
+ IP6Q_UNLOCK(i);
+ }
+ CURVNET_RESTORE();
+}
+EVENTHANDLER_DEFINE(ifnet_departure_event, frag6_cleanup, NULL, 0);
+
int
ip6_deletefraghdr(struct mbuf *m, int offset, int wait)
{

File Metadata

Mime Type
text/plain
Expires
Sat, Dec 21, 4:23 PM (16 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15543191
Default Alt Text
D19622.id55769.diff (4 KB)

Event Timeline