Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/netinet Use own IPv4 reassembly queue entry structure an...



details:   https://anonhg.NetBSD.org/src/rev/5eefc93e0bcc
branches:  trunk
changeset: 757312:5eefc93e0bcc
user:      rmind <rmind%NetBSD.org@localhost>
date:      Wed Aug 25 00:05:14 2010 +0000

description:
Use own IPv4 reassembly queue entry structure and leave struct ipqent only
for TCP.  Now both struct ipfr_qent, struct ipfr_queue and hashed fragment
queue are abstracted and no longer public.

diffstat:

 sys/netinet/ip_reass.c |  152 +++++++++++++++++++++++-------------------------
 sys/netinet/ip_var.h   |    6 +-
 2 files changed, 74 insertions(+), 84 deletions(-)

diffs (truncated from 302 to 300 lines):

diff -r e3d58cf5e104 -r 5eefc93e0bcc sys/netinet/ip_reass.c
--- a/sys/netinet/ip_reass.c    Tue Aug 24 23:55:04 2010 +0000
+++ b/sys/netinet/ip_reass.c    Wed Aug 25 00:05:14 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip_reass.c,v 1.2 2010/07/19 14:09:45 rmind Exp $       */
+/*     $NetBSD: ip_reass.c,v 1.3 2010/08/25 00:05:14 rmind Exp $       */
 
 /*
  * Copyright (c) 1982, 1986, 1988, 1993
@@ -46,7 +46,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_reass.c,v 1.2 2010/07/19 14:09:45 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_reass.c,v 1.3 2010/08/25 00:05:14 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -73,7 +73,32 @@
 #include <netinet/in_var.h>
 
 /*
- * IP datagram reassembly hashed queues, pool, lock and counters.
+ * IP reassembly queue structures.  Each fragment being reassembled is
+ * attached to one of these structures.  They are timed out after TTL
+ * drops to 0, and may also be reclaimed if memory becomes tight.
+ */
+
+typedef struct ipfr_qent {
+       TAILQ_ENTRY(ipfr_qent)  ipqe_q;
+       struct ip *             ipqe_ip;
+       struct mbuf *           ipqe_m;
+       bool                    ipqe_mff;
+} ipfr_qent_t;
+
+typedef struct ipfr_queue {
+       LIST_ENTRY(ipfr_queue)  ipq_q;          /* to other reass headers */
+       TAILQ_HEAD(, ipfr_qent) ipq_fragq;      /* queue of fragment entries */
+       uint8_t                 ipq_ttl;        /* time for reass q to live */
+       uint8_t                 ipq_p;          /* protocol of this fragment */
+       uint16_t                ipq_id;         /* sequence id for reassembly */
+       struct in_addr          ipq_src;
+       struct in_addr          ipq_dst;
+       uint16_t                ipq_nfrags;     /* frags in this queue entry */
+       uint8_t                 ipq_tos;        /* TOS of this fragment */
+} ipfr_queue_t;
+
+/*
+ * Hash table of IP reassembly queues.
  */
 #define        IPREASS_HASH_SHIFT      6
 #define        IPREASS_HASH_SIZE       (1 << IPREASS_HASH_SHIFT)
@@ -81,52 +106,36 @@
 #define        IPREASS_HASH(x, y) \
        (((((x) & 0xf) | ((((x) >> 8) & 0xf) << 4)) ^ (y)) & IPREASS_HASH_MASK)
 
-struct ipqhead ipq[IPREASS_HASH_SIZE];
-struct pool    ipqent_pool;
-static int     ipq_locked;
+static LIST_HEAD(, ipfr_queue) ip_frags[IPREASS_HASH_SIZE];
+static struct pool     ipqent_pool;
+static int             ipq_locked;
 
-static int     ip_nfragpackets;        /* packets in reass queue */
-static int     ip_nfrags;              /* total fragments in reass queues */
+/* Number of packets in reassembly queue and total number of fragments. */
+static int             ip_nfragpackets;
+static int             ip_nfrags;
 
-static int     ip_maxfragpackets;      /* limit on packets. XXX sysctl */
-static int     ip_maxfrags;            /* limit on fragments. XXX sysctl */
+/* Limits on packet and fragments. */
+static int             ip_maxfragpackets;
+static int             ip_maxfrags;
 
 /*
- * IP reassembly queue structure.  Each fragment being reassembled is
- * attached to one of these structures.  They are timed out after ipq_ttl
- * drops to 0, and may also be reclaimed if memory becomes tight.
+ * Cached copy of nmbclusters.  If nbclusters is different, recalculate
+ * IP parameters derived from nmbclusters.
  */
-struct ipq {
-       LIST_ENTRY(ipq) ipq_q;          /* to other reass headers */
-       uint8_t         ipq_ttl;        /* time for reass q to live */
-       uint8_t         ipq_p;          /* protocol of this fragment */
-       uint16_t        ipq_id;         /* sequence id for reassembly */
-       struct ipqehead ipq_fragq;      /* to ip fragment queue */
-       struct in_addr  ipq_src;
-       struct in_addr  ipq_dst;
-       uint16_t        ipq_nfrags;     /* frags in this queue entry */
-       uint8_t         ipq_tos;        /* TOS of this fragment */
-};
-
-/*
- * Cached copy of nmbclusters. If nbclusters is different,
- * recalculate IP parameters derived from nmbclusters.
- */
-static int     ip_nmbclusters;                 /* copy of nmbclusters */
+static int             ip_nmbclusters;
 
 /*
  * IP reassembly TTL machinery for multiplicative drop.
  */
-static u_int   fragttl_histo[IPFRAGTTL + 1];
+static u_int           fragttl_histo[IPFRAGTTL + 1];
 
-void           sysctl_ip_reass_setup(void);
-static void    ip_nmbclusters_changed(void);
+void                   sysctl_ip_reass_setup(void);
+static void            ip_nmbclusters_changed(void);
 
-static struct ipq *    ip_reass_lookup(struct ip *, u_int *);
-static struct mbuf *   ip_reass(struct ipqent *, struct ipq *, u_int);
+static struct mbuf *   ip_reass(ipfr_qent_t *, ipfr_queue_t *, u_int);
 static u_int           ip_reass_ttl_decr(u_int ticks);
 static void            ip_reass_drophalf(void);
-static void            ip_freef(struct ipq *);
+static void            ip_freef(ipfr_queue_t *);
 
 /*
  * ip_reass_init:
@@ -138,11 +147,11 @@
 {
        int i;
 
-       pool_init(&ipqent_pool, sizeof(struct ipqent), 0, 0, 0, "ipqepl",
+       pool_init(&ipqent_pool, sizeof(ipfr_qent_t), 0, 0, 0, "ipqepl",
            NULL, IPL_VM);
 
        for (i = 0; i < IPREASS_HASH_SIZE; i++) {
-               LIST_INIT(&ipq[i]);
+               LIST_INIT(&ip_frags[i]);
        }
        ip_maxfragpackets = 200;
        ip_maxfrags = 0;
@@ -255,34 +264,6 @@
 #define        IPQ_UNLOCK()            ipq_unlock()
 
 /*
- * ip_reass_lookup:
- *
- *     Look for queue of fragments of this datagram.
- */
-static struct ipq *
-ip_reass_lookup(struct ip *ip, u_int *hashp)
-{
-       struct ipq *fp;
-       u_int hash;
-
-       IPQ_LOCK();
-       hash = IPREASS_HASH(ip->ip_src.s_addr, ip->ip_id);
-       LIST_FOREACH(fp, &ipq[hash], ipq_q) {
-               if (ip->ip_id != fp->ipq_id)
-                       continue;
-               if (!in_hosteq(ip->ip_src, fp->ipq_src))
-                       continue;
-               if (!in_hosteq(ip->ip_dst, fp->ipq_dst))
-                       continue;
-               if (ip->ip_p != fp->ipq_p)
-                       continue;
-               break;
-       }
-       *hashp = hash;
-       return fp;
-}
-
-/*
  * ip_reass:
  *
  *     Take incoming datagram fragment and try to reassemble it into whole
@@ -290,12 +271,11 @@
  *     then it is given as 'fp'; otherwise have to make a chain.
  */
 struct mbuf *
-ip_reass(struct ipqent *ipqe, struct ipq *fp, u_int hash)
+ip_reass(ipfr_qent_t *ipqe, ipfr_queue_t *fp, const u_int hash)
 {
-       struct ipqhead *ipqhead = &ipq[hash];
        const int hlen = ipqe->ipqe_ip->ip_hl << 2;
        struct mbuf *m = ipqe->ipqe_m, *t;
-       struct ipqent *nq, *p, *q;
+       ipfr_qent_t *nq, *p, *q;
        struct ip *ip;
        int i, next, s;
 
@@ -338,11 +318,11 @@
                        goto dropfrag;
                }
                ip_nfragpackets++;
-               fp = malloc(sizeof(struct ipq), M_FTABLE, M_NOWAIT);
+               fp = malloc(sizeof(ipfr_queue_t), M_FTABLE, M_NOWAIT);
                if (fp == NULL) {
                        goto dropfrag;
                }
-               LIST_INSERT_HEAD(ipqhead, fp, ipq_q);
+               LIST_INSERT_HEAD(&ip_frags[hash], fp, ipq_q);
                fp->ipq_nfrags = 1;
                fp->ipq_ttl = IPFRAGTTL;
                fp->ipq_p = ipqe->ipqe_ip->ip_p;
@@ -510,9 +490,9 @@
  *     Free a fragment reassembly header and all associated datagrams.
  */
 static void
-ip_freef(struct ipq *fp)
+ip_freef(ipfr_queue_t *fp)
 {
-       struct ipqent *q, *p;
+       ipfr_qent_t *q, *p;
        u_int nfrags = 0;
        int s;
 
@@ -550,14 +530,14 @@
 ip_reass_ttl_decr(u_int ticks)
 {
        u_int nfrags, median, dropfraction, keepfraction;
-       struct ipq *fp, *nfp;
+       ipfr_queue_t *fp, *nfp;
        int i;
 
        nfrags = 0;
        memset(fragttl_histo, 0, sizeof(fragttl_histo));
 
        for (i = 0; i < IPREASS_HASH_SIZE; i++) {
-               for (fp = LIST_FIRST(&ipq[i]); fp != NULL; fp = nfp) {
+               for (fp = LIST_FIRST(&ip_frags[i]); fp != NULL; fp = nfp) {
                        fp->ipq_ttl = ((fp->ipq_ttl <= ticks) ?
                            0 : fp->ipq_ttl - ticks);
                        nfp = LIST_NEXT(fp, ipq_q);
@@ -660,8 +640,8 @@
 
                i = dropscanidx;
                while (ip_nfragpackets > ip_maxfragpackets && wrapped == 0) {
-                       while (LIST_FIRST(&ipq[i]) != NULL) {
-                               ip_freef(LIST_FIRST(&ipq[i]));
+                       while (LIST_FIRST(&ip_frags[i]) != NULL) {
+                               ip_freef(LIST_FIRST(&ip_frags[i]));
                        }
                        if (++i >= IPREASS_HASH_SIZE) {
                                i = 0;
@@ -691,12 +671,24 @@
 int
 ip_reass_packet(struct mbuf *m, struct ip *ip, bool mff, struct mbuf **m_final)
 {
-       struct ipq *fp;
-       struct ipqent *ipqe;
+       ipfr_queue_t *fp;
+       ipfr_qent_t *ipqe;
        u_int hash;
 
        /* Look for queue of fragments of this datagram. */
-       fp = ip_reass_lookup(ip, &hash);
+       IPQ_LOCK();
+       hash = IPREASS_HASH(ip->ip_src.s_addr, ip->ip_id);
+       LIST_FOREACH(fp, &ip_frags[hash], ipq_q) {
+               if (ip->ip_id != fp->ipq_id)
+                       continue;
+               if (!in_hosteq(ip->ip_src, fp->ipq_src))
+                       continue;
+               if (!in_hosteq(ip->ip_dst, fp->ipq_dst))
+                       continue;
+               if (ip->ip_p != fp->ipq_p)
+                       continue;
+               break;
+       }
 
        /* Make sure that TOS matches previous fragments. */
        if (fp && fp->ipq_tos != ip->ip_tos) {
diff -r e3d58cf5e104 -r 5eefc93e0bcc sys/netinet/ip_var.h
--- a/sys/netinet/ip_var.h      Tue Aug 24 23:55:04 2010 +0000
+++ b/sys/netinet/ip_var.h      Wed Aug 25 00:05:14 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip_var.h,v 1.94 2010/07/19 19:16:45 rmind Exp $        */
+/*     $NetBSD: ip_var.h,v 1.95 2010/08/25 00:05:14 rmind Exp $        */
 
 /*
  * Copyright (c) 1982, 1986, 1993
@@ -49,7 +49,7 @@
 } __packed;
 
 /*
- * Ip (reassembly or sequence) queue structures.
+ * IP sequence queue structure.
  *
  * XXX -- The following explains why the ipqe_m field is here, for TCP's use:
  * We want to avoid doing m_pullup on incoming packets but that
@@ -77,7 +77,6 @@
        u_int32_t ipqe_len;
        u_int32_t ipqe_flags;
 };
-#define        ipqe_ip         _ipqe_u1._ip
 #define        ipqe_tcp        _ipqe_u1._tcp
 
 /*
@@ -161,7 +160,6 @@
 
 extern struct domain inetdomain;
 
-extern LIST_HEAD(ipqhead, ipq) ipq[];  /* ip reass. queue */
 extern int   ip_defttl;                        /* default IP ttl */



Home | Main Index | Thread Index | Old Index