From: Gleb Natapov <gleb@redhat.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH] fix 64 bit issue in slirp
Date: Mon, 12 Jan 2009 16:28:07 +0200 [thread overview]
Message-ID: <20090112142807.GN3267@redhat.com> (raw)
Signed-off-by: Gleb Natapov <gleb@redhat.com>
diff --git a/slirp/ip.h b/slirp/ip.h
index a8cdb0d..3079f90 100644
--- a/slirp/ip.h
+++ b/slirp/ip.h
@@ -183,35 +183,31 @@ struct ip_timestamp {
#define IP_MSS 576 /* default maximum segment size */
-#ifdef HAVE_SYS_TYPES32_H /* Overcome some Solaris 2.x junk */
-#include <sys/types32.h>
-#else
#if SIZEOF_CHAR_P == 4
-typedef caddr_t caddr32_t;
-#else
-typedef u_int32_t caddr32_t;
-#endif
-#endif
-
-#if SIZEOF_CHAR_P == 4
-typedef struct ipq *ipqp_32;
-typedef struct ipasfrag *ipasfragp_32;
+struct mbuf_ptr {
+ struct mbuf *mptr;
+ uint32_t dummy;
+};
#else
-typedef caddr32_t ipqp_32;
-typedef caddr32_t ipasfragp_32;
+struct mbuf_ptr {
+ struct mbuf *mptr;
+};
#endif
+struct qlink {
+ void *next, *prev;
+};
/*
* Overlay for ip header used by other protocols (tcp, udp).
*/
struct ipovly {
- caddr32_t ih_next, ih_prev; /* for protocol sequence q's */
+ struct mbuf_ptr ih_mbuf; /* backpointer to mbuf */
u_int8_t ih_x1; /* (unused) */
u_int8_t ih_pr; /* protocol */
u_int16_t ih_len; /* protocol length */
struct in_addr ih_src; /* source internet address */
struct in_addr ih_dst; /* destination internet address */
-};
+} __attribute__((packed));
/*
* Ip reassembly queue structure. Each fragment
@@ -221,44 +217,30 @@ struct ipovly {
* size 28 bytes
*/
struct ipq {
- ipqp_32 next,prev; /* to other reass headers */
+ struct qlink frag_link; /* to ip headers of fragments */
+ struct qlink ip_link; /* to other reass headers */
u_int8_t ipq_ttl; /* time for reass q to live */
u_int8_t ipq_p; /* protocol of this fragment */
u_int16_t ipq_id; /* sequence id for reassembly */
- ipasfragp_32 ipq_next,ipq_prev;
- /* to ip headers of fragments */
struct in_addr ipq_src,ipq_dst;
};
/*
* Ip header, when holding a fragment.
*
- * Note: ipf_next must be at same offset as ipq_next above
+ * Note: ipf_link must be at same offset as frag_link above
*/
struct ipasfrag {
-#ifdef WORDS_BIGENDIAN
- u_int ip_v:4,
- ip_hl:4;
-#else
- u_int ip_hl:4,
- ip_v:4;
-#endif
- /* BUG : u_int changed to u_int8_t.
- * sizeof(u_int)==4 on linux 2.0
- */
- u_int8_t ipf_mff; /* XXX overlays ip_tos: use low bit
- * to avoid destroying tos (PPPDTRuu);
- * copied from (ip_off&IP_MF) */
- u_int16_t ip_len;
- u_int16_t ip_id;
- u_int16_t ip_off;
- u_int8_t ip_ttl;
- u_int8_t ip_p;
- u_int16_t ip_sum;
- ipasfragp_32 ipf_next; /* next fragment */
- ipasfragp_32 ipf_prev; /* previous fragment */
+ struct qlink ipf_link;
+ struct ip ipf_ip;
};
+#define ipf_off ipf_ip.ip_off
+#define ipf_tos ipf_ip.ip_tos
+#define ipf_len ipf_ip.ip_len
+#define ipf_next ipf_link.next
+#define ipf_prev ipf_link.prev
+
/*
* Structure stored in mbuf in inpcb.ip_options
* and passed to ip_output when ip options are in use.
diff --git a/slirp/ip_input.c b/slirp/ip_input.c
index 73cb00e..116ee45 100644
--- a/slirp/ip_input.c
+++ b/slirp/ip_input.c
@@ -43,6 +43,7 @@
*/
#include <slirp.h>
+#include <osdep.h>
#include "ip_icmp.h"
#ifdef LOG_ENABLED
@@ -51,7 +52,7 @@ struct ipstat ipstat;
struct ipq ipq;
-static struct ip *ip_reass(register struct ipasfrag *ip,
+static struct ip *ip_reass(register struct ip *ip,
register struct ipq *fp);
static void ip_freef(struct ipq *fp);
static void ip_enq(register struct ipasfrag *p,
@@ -65,7 +66,7 @@ static void ip_deq(register struct ipasfrag *p);
void
ip_init()
{
- ipq.next = ipq.prev = (ipqp_32)&ipq;
+ ipq.ip_link.next = ipq.ip_link.prev = &ipq.ip_link;
ip_id = tt.tv_sec & 0xffff;
udp_init();
tcp_init();
@@ -188,18 +189,20 @@ ip_input(m)
*/
if (ip->ip_off &~ IP_DF) {
register struct ipq *fp;
+ struct qlink *l;
/*
* Look for queue of fragments
* of this datagram.
*/
- for (fp = (struct ipq *) ipq.next; fp != &ipq;
- fp = (struct ipq *) fp->next)
- if (ip->ip_id == fp->ipq_id &&
- ip->ip_src.s_addr == fp->ipq_src.s_addr &&
- ip->ip_dst.s_addr == fp->ipq_dst.s_addr &&
- ip->ip_p == fp->ipq_p)
+ for (l = ipq.ip_link.next; l != &ipq.ip_link; l = l->next) {
+ fp = container_of(l, struct ipq, ip_link);
+ if (ip->ip_id == fp->ipq_id &&
+ ip->ip_src.s_addr == fp->ipq_src.s_addr &&
+ ip->ip_dst.s_addr == fp->ipq_dst.s_addr &&
+ ip->ip_p == fp->ipq_p)
goto found;
- fp = 0;
+ }
+ fp = NULL;
found:
/*
@@ -209,9 +212,9 @@ ip_input(m)
*/
ip->ip_len -= hlen;
if (ip->ip_off & IP_MF)
- ((struct ipasfrag *)ip)->ipf_mff |= 1;
+ ip->ip_tos |= 1;
else
- ((struct ipasfrag *)ip)->ipf_mff &= ~1;
+ ip->ip_tos &= ~1;
ip->ip_off <<= 3;
@@ -220,9 +223,9 @@ ip_input(m)
* or if this is not the first fragment,
* attempt reassembly; if it succeeds, proceed.
*/
- if (((struct ipasfrag *)ip)->ipf_mff & 1 || ip->ip_off) {
+ if (ip->ip_tos & 1 || ip->ip_off) {
STAT(ipstat.ips_fragments++);
- ip = ip_reass((struct ipasfrag *)ip, fp);
+ ip = ip_reass(ip, fp);
if (ip == 0)
return;
STAT(ipstat.ips_reassembled++);
@@ -258,6 +261,8 @@ bad:
return;
}
+#define iptofrag(P) ((struct ipasfrag *)(((char*)(P)) - sizeof(struct qlink)))
+#define fragtoip(P) ((struct ip*)(((char*)(P)) + sizeof(struct qlink)))
/*
* Take incoming datagram fragment and try to
* reassemble it into whole datagram. If a chain for
@@ -265,7 +270,7 @@ bad:
* is given as fp; otherwise have to make a chain.
*/
static struct ip *
-ip_reass(register struct ipasfrag *ip, register struct ipq *fp)
+ip_reass(register struct ip *ip, register struct ipq *fp)
{
register struct mbuf *m = dtom(ip);
register struct ipasfrag *q;
@@ -292,13 +297,13 @@ ip_reass(register struct ipasfrag *ip, register struct ipq *fp)
struct mbuf *t;
if ((t = m_get()) == NULL) goto dropfrag;
fp = mtod(t, struct ipq *);
- insque_32(fp, &ipq);
+ insque(&fp->ip_link, &ipq.ip_link);
fp->ipq_ttl = IPFRAGTTL;
fp->ipq_p = ip->ip_p;
fp->ipq_id = ip->ip_id;
- fp->ipq_next = fp->ipq_prev = (ipasfragp_32)fp;
- fp->ipq_src = ((struct ip *)ip)->ip_src;
- fp->ipq_dst = ((struct ip *)ip)->ip_dst;
+ fp->frag_link.next = fp->frag_link.prev = &fp->frag_link;
+ fp->ipq_src = ip->ip_src;
+ fp->ipq_dst = ip->ip_dst;
q = (struct ipasfrag *)fp;
goto insert;
}
@@ -306,9 +311,9 @@ ip_reass(register struct ipasfrag *ip, register struct ipq *fp)
/*
* Find a segment which begins after this one does.
*/
- for (q = (struct ipasfrag *)fp->ipq_next; q != (struct ipasfrag *)fp;
- q = (struct ipasfrag *)q->ipf_next)
- if (q->ip_off > ip->ip_off)
+ for (q = fp->frag_link.next; q != (struct ipasfrag *)&fp->frag_link;
+ q = q->ipf_next)
+ if (q->ipf_off > ip->ip_off)
break;
/*
@@ -316,9 +321,9 @@ ip_reass(register struct ipasfrag *ip, register struct ipq *fp)
* our data already. If so, drop the data from the incoming
* segment. If it provides all of our data, drop us.
*/
- if (q->ipf_prev != (ipasfragp_32)fp) {
- i = ((struct ipasfrag *)(q->ipf_prev))->ip_off +
- ((struct ipasfrag *)(q->ipf_prev))->ip_len - ip->ip_off;
+ if (q->ipf_prev != &fp->frag_link) {
+ struct ipasfrag *pq = q->ipf_prev;
+ i = pq->ipf_off + pq->ipf_len - ip->ip_off;
if (i > 0) {
if (i >= ip->ip_len)
goto dropfrag;
@@ -332,17 +337,18 @@ ip_reass(register struct ipasfrag *ip, register struct ipq *fp)
* While we overlap succeeding segments trim them or,
* if they are completely covered, dequeue them.
*/
- while (q != (struct ipasfrag *)fp && ip->ip_off + ip->ip_len > q->ip_off) {
- i = (ip->ip_off + ip->ip_len) - q->ip_off;
- if (i < q->ip_len) {
- q->ip_len -= i;
- q->ip_off += i;
+ while (q != (struct ipasfrag*)&fp->frag_link &&
+ ip->ip_off + ip->ip_len > q->ipf_off) {
+ i = (ip->ip_off + ip->ip_len) - q->ipf_off;
+ if (i < q->ipf_len) {
+ q->ipf_len -= i;
+ q->ipf_off += i;
m_adj(dtom(q), i);
break;
}
- q = (struct ipasfrag *) q->ipf_next;
- m_freem(dtom((struct ipasfrag *) q->ipf_prev));
- ip_deq((struct ipasfrag *) q->ipf_prev);
+ q = q->ipf_next;
+ m_freem(dtom(q->ipf_prev));
+ ip_deq(q->ipf_prev);
}
insert:
@@ -350,27 +356,26 @@ insert:
* Stick new segment in its place;
* check for complete reassembly.
*/
- ip_enq(ip, (struct ipasfrag *) q->ipf_prev);
+ ip_enq(iptofrag(ip), q->ipf_prev);
next = 0;
- for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp;
- q = (struct ipasfrag *) q->ipf_next) {
- if (q->ip_off != next)
+ for (q = fp->frag_link.next; q != (struct ipasfrag*)&fp->frag_link;
+ q = q->ipf_next) {
+ if (q->ipf_off != next)
return (0);
- next += q->ip_len;
+ next += q->ipf_len;
}
- if (((struct ipasfrag *)(q->ipf_prev))->ipf_mff & 1)
+ if (((struct ipasfrag *)(q->ipf_prev))->ipf_tos & 1)
return (0);
/*
* Reassembly is complete; concatenate fragments.
*/
- q = (struct ipasfrag *) fp->ipq_next;
+ q = fp->frag_link.next;
m = dtom(q);
q = (struct ipasfrag *) q->ipf_next;
- while (q != (struct ipasfrag *)fp) {
- struct mbuf *t;
- t = dtom(q);
+ while (q != (struct ipasfrag*)&fp->frag_link) {
+ struct mbuf *t = dtom(q);
q = (struct ipasfrag *) q->ipf_next;
m_cat(m, t);
}
@@ -381,7 +386,7 @@ insert:
* dequeue and discard fragment reassembly header.
* Make header visible.
*/
- ip = (struct ipasfrag *) fp->ipq_next;
+ q = fp->frag_link.next;
/*
* If the fragments concatenated to an mbuf that's
@@ -393,23 +398,23 @@ insert:
if (m->m_flags & M_EXT) {
int delta;
delta = (char *)ip - m->m_dat;
- ip = (struct ipasfrag *)(m->m_ext + delta);
+ q = (struct ipasfrag *)(m->m_ext + delta);
}
/* DEBUG_ARG("ip = %lx", (long)ip);
* ip=(struct ipasfrag *)m->m_data; */
+ ip = fragtoip(q);
ip->ip_len = next;
- ip->ipf_mff &= ~1;
- ((struct ip *)ip)->ip_src = fp->ipq_src;
- ((struct ip *)ip)->ip_dst = fp->ipq_dst;
- remque_32(fp);
+ ip->ip_tos &= ~1;
+ ip->ip_src = fp->ipq_src;
+ ip->ip_dst = fp->ipq_dst;
+ remque(&fp->ip_link);
(void) m_free(dtom(fp));
- m = dtom(ip);
m->m_len += (ip->ip_hl << 2);
m->m_data -= (ip->ip_hl << 2);
- return ((struct ip *)ip);
+ return ip;
dropfrag:
STAT(ipstat.ips_fragdropped++);
@@ -426,13 +431,12 @@ ip_freef(struct ipq *fp)
{
register struct ipasfrag *q, *p;
- for (q = (struct ipasfrag *) fp->ipq_next; q != (struct ipasfrag *)fp;
- q = p) {
- p = (struct ipasfrag *) q->ipf_next;
+ for (q = fp->frag_link.next; q != (struct ipasfrag*)&fp->frag_link; q = p) {
+ p = q->ipf_next;
ip_deq(q);
m_freem(dtom(q));
}
- remque_32(fp);
+ remque(&fp->ip_link);
(void) m_free(dtom(fp));
}
@@ -445,10 +449,10 @@ ip_enq(register struct ipasfrag *p, register struct ipasfrag *prev)
{
DEBUG_CALL("ip_enq");
DEBUG_ARG("prev = %lx", (long)prev);
- p->ipf_prev = (ipasfragp_32) prev;
+ p->ipf_prev = prev;
p->ipf_next = prev->ipf_next;
- ((struct ipasfrag *)(prev->ipf_next))->ipf_prev = (ipasfragp_32) p;
- prev->ipf_next = (ipasfragp_32) p;
+ ((struct ipasfrag *)(prev->ipf_next))->ipf_prev = p;
+ prev->ipf_next = p;
}
/*
@@ -469,20 +473,21 @@ ip_deq(register struct ipasfrag *p)
void
ip_slowtimo()
{
- register struct ipq *fp;
+ struct qlink *l;
DEBUG_CALL("ip_slowtimo");
- fp = (struct ipq *) ipq.next;
- if (fp == 0)
+ l = ipq.ip_link.next;
+
+ if (l == 0)
return;
- while (fp != &ipq) {
- --fp->ipq_ttl;
- fp = (struct ipq *) fp->next;
- if (((struct ipq *)(fp->prev))->ipq_ttl == 0) {
+ while (l != &ipq.ip_link) {
+ struct ipq *fp = container_of(l, struct ipq, ip_link);
+ l = l->next;
+ if (--fp->ipq_ttl == 0) {
STAT(ipstat.ips_fragtimeout++);
- ip_freef((struct ipq *) fp->prev);
+ ip_freef(fp);
}
}
}
diff --git a/slirp/misc.c b/slirp/misc.c
index 1ec8b55..f558b3c 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -83,39 +83,6 @@ getouraddr()
our_addr.s_addr = loopback_addr.s_addr;
}
-#if SIZEOF_CHAR_P == 8
-
-struct quehead_32 {
- u_int32_t qh_link;
- u_int32_t qh_rlink;
-};
-
-inline void
-insque_32(a, b)
- void *a;
- void *b;
-{
- register struct quehead_32 *element = (struct quehead_32 *) a;
- register struct quehead_32 *head = (struct quehead_32 *) b;
- element->qh_link = head->qh_link;
- head->qh_link = (u_int32_t)element;
- element->qh_rlink = (u_int32_t)head;
- ((struct quehead_32 *)(element->qh_link))->qh_rlink
- = (u_int32_t)element;
-}
-
-inline void
-remque_32(a)
- void *a;
-{
- register struct quehead_32 *element = (struct quehead_32 *) a;
- ((struct quehead_32 *)(element->qh_link))->qh_rlink = element->qh_rlink;
- ((struct quehead_32 *)(element->qh_rlink))->qh_link = element->qh_link;
- element->qh_rlink = 0;
-}
-
-#endif /* SIZEOF_CHAR_P == 8 */
-
struct quehead {
struct quehead *qh_link;
struct quehead *qh_rlink;
diff --git a/slirp/slirp.c b/slirp/slirp.c
index c1361ab..43a8965 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -261,7 +261,7 @@ void slirp_select_fill(int *pnfds,
* in the fragment queue, or there are TCP connections active
*/
do_slowtimo = ((tcb.so_next != &tcb) ||
- ((struct ipasfrag *)&ipq != (struct ipasfrag *)ipq.next));
+ (&ipq.ip_link != ipq.ip_link.next));
for (so = tcb.so_next; so != &tcb; so = so_next) {
so_next = so->so_next;
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 3002e0b..d57fb12 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -266,14 +266,6 @@ void if_start _P((struct ttys *));
void lprint _P((const char *, ...));
-#if SIZEOF_CHAR_P == 4
-# define insque_32 insque
-# define remque_32 remque
-#else
- void insque_32 _P((void *, void *));
- void remque_32 _P((void *));
-#endif
-
#ifndef _WIN32
#include <netdb.h>
#endif
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index 408875e..f324adb 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -71,7 +71,7 @@ tcp_seq tcp_iss; /* tcp initial send seq # */
#ifdef TCP_ACK_HACK
#define TCP_REASS(tp, ti, m, so, flags) {\
if ((ti)->ti_seq == (tp)->rcv_nxt && \
- (tp)->seg_next == (tcpiphdrp_32)(tp) && \
+ tcpfrag_list_empty(tp) && \
(tp)->t_state == TCPS_ESTABLISHED) {\
if (ti->ti_flags & TH_PUSH) \
tp->t_flags |= TF_ACKNOW; \
@@ -94,7 +94,7 @@ tcp_seq tcp_iss; /* tcp initial send seq # */
#else
#define TCP_REASS(tp, ti, m, so, flags) { \
if ((ti)->ti_seq == (tp)->rcv_nxt && \
- (tp)->seg_next == (tcpiphdrp_32)(tp) && \
+ tcpfrag_list_empty(tp) && \
(tp)->t_state == TCPS_ESTABLISHED) { \
tp->t_flags |= TF_DELACK; \
(tp)->rcv_nxt += (ti)->ti_len; \
@@ -134,8 +134,8 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti,
/*
* Find a segment which begins after this one does.
*/
- for (q = (struct tcpiphdr *)tp->seg_next; q != (struct tcpiphdr *)tp;
- q = (struct tcpiphdr *)q->ti_next)
+ for (q = tcpfrag_list_first(tp); !tcpfrag_list_end(q, tp);
+ q = tcpiphdr_next(q))
if (SEQ_GT(q->ti_seq, ti->ti_seq))
break;
@@ -144,9 +144,9 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti,
* our data already. If so, drop the data from the incoming
* segment. If it provides all of our data, drop us.
*/
- if ((struct tcpiphdr *)q->ti_prev != (struct tcpiphdr *)tp) {
+ if (!tcpfrag_list_end(tcpiphdr_prev(q), tp)) {
register int i;
- q = (struct tcpiphdr *)q->ti_prev;
+ q = tcpiphdr_prev(q);
/* conversion to int (in i) handles seq wraparound */
i = q->ti_seq + q->ti_len - ti->ti_seq;
if (i > 0) {
@@ -166,36 +166,36 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti,
ti->ti_len -= i;
ti->ti_seq += i;
}
- q = (struct tcpiphdr *)(q->ti_next);
+ q = tcpiphdr_next(q);
}
STAT(tcpstat.tcps_rcvoopack++);
STAT(tcpstat.tcps_rcvoobyte += ti->ti_len);
- REASS_MBUF(ti) = (mbufp_32) m; /* XXX */
+ ti->ti_mbuf = m;
/*
* While we overlap succeeding segments trim them or,
* if they are completely covered, dequeue them.
*/
- while (q != (struct tcpiphdr *)tp) {
+ while (!tcpfrag_list_end(q, tp)) {
register int i = (ti->ti_seq + ti->ti_len) - q->ti_seq;
if (i <= 0)
break;
if (i < q->ti_len) {
q->ti_seq += i;
q->ti_len -= i;
- m_adj((struct mbuf *) REASS_MBUF(q), i);
+ m_adj(q->ti_mbuf, i);
break;
}
- q = (struct tcpiphdr *)q->ti_next;
- m = (struct mbuf *) REASS_MBUF((struct tcpiphdr *)q->ti_prev);
- remque_32((void *)(q->ti_prev));
+ q = tcpiphdr_next(q);
+ m = tcpiphdr_prev(q)->ti_mbuf;
+ remque(tcpiphdr2qlink(tcpiphdr_prev(q)));
m_freem(m);
}
/*
* Stick new segment in its place.
*/
- insque_32(ti, (void *)(q->ti_prev));
+ insque(tcpiphdr2qlink(ti), tcpiphdr2qlink(tcpiphdr_prev(q)));
present:
/*
@@ -204,17 +204,17 @@ present:
*/
if (!TCPS_HAVEESTABLISHED(tp->t_state))
return (0);
- ti = (struct tcpiphdr *) tp->seg_next;
- if (ti == (struct tcpiphdr *)tp || ti->ti_seq != tp->rcv_nxt)
+ ti = tcpfrag_list_first(tp);
+ if (tcpfrag_list_end(ti, tp) || ti->ti_seq != tp->rcv_nxt)
return (0);
if (tp->t_state == TCPS_SYN_RECEIVED && ti->ti_len)
return (0);
do {
tp->rcv_nxt += ti->ti_len;
flags = ti->ti_flags & TH_FIN;
- remque_32(ti);
- m = (struct mbuf *) REASS_MBUF(ti); /* XXX */
- ti = (struct tcpiphdr *)ti->ti_next;
+ remque(tcpiphdr2qlink(ti));
+ m = ti->ti_mbuf;
+ ti = tcpiphdr_next(ti);
/* if (so->so_state & SS_FCANTRCVMORE) */
if (so->so_state & SS_FCANTSENDMORE)
m_freem(m);
@@ -302,7 +302,8 @@ tcp_input(m, iphlen, inso)
* Checksum extended TCP header and data.
*/
tlen = ((struct ip *)ti)->ip_len;
- ti->ti_next = ti->ti_prev = 0;
+ tcpiphdr2qlink(ti)->next = tcpiphdr2qlink(ti)->prev = 0;
+ memset(&ti->ti_i.ih_mbuf, 0 , sizeof(struct mbuf_ptr));
ti->ti_x1 = 0;
ti->ti_len = htons((u_int16_t)tlen);
len = sizeof(struct ip ) + tlen;
@@ -560,7 +561,7 @@ findso:
return;
}
} else if (ti->ti_ack == tp->snd_una &&
- tp->seg_next == (tcpiphdrp_32)tp &&
+ tcpfrag_list_empty(tp) &&
ti->ti_len <= sbspace(&so->so_rcv)) {
/*
* this is a pure, in-sequence data packet
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 12abebe..b0b72e4 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -73,7 +73,7 @@ tcp_template(tp)
struct socket *so = tp->t_socket;
register struct tcpiphdr *n = &tp->t_template;
- n->ti_next = n->ti_prev = 0;
+ n->ti_mbuf = NULL;
n->ti_x1 = 0;
n->ti_pr = IPPROTO_TCP;
n->ti_len = htons(sizeof (struct tcpiphdr) - sizeof (struct ip));
@@ -156,7 +156,7 @@ tcp_respond(tp, ti, m, ack, seq, flags)
tlen += sizeof (struct tcpiphdr);
m->m_len = tlen;
- ti->ti_next = ti->ti_prev = 0;
+ ti->ti_mbuf = 0;
ti->ti_x1 = 0;
ti->ti_seq = htonl(seq);
ti->ti_ack = htonl(ack);
@@ -196,7 +196,7 @@ tcp_newtcpcb(so)
return ((struct tcpcb *)0);
memset((char *) tp, 0, sizeof(struct tcpcb));
- tp->seg_next = tp->seg_prev = (tcpiphdrp_32)tp;
+ tp->seg_next = tp->seg_prev = (struct tcpiphdr*)tp;
tp->t_maxseg = TCP_MSS;
tp->t_flags = TCP_DO_RFC1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0;
@@ -272,11 +272,11 @@ tcp_close(tp)
DEBUG_ARG("tp = %lx", (long )tp);
/* free the reassembly queue, if any */
- t = (struct tcpiphdr *) tp->seg_next;
- while (t != (struct tcpiphdr *)tp) {
- t = (struct tcpiphdr *)t->ti_next;
- m = (struct mbuf *) REASS_MBUF((struct tcpiphdr *)t->ti_prev);
- remque_32((struct tcpiphdr *) t->ti_prev);
+ t = tcpfrag_list_first(tp);
+ while (!tcpfrag_list_end(t, tp)) {
+ t = tcpiphdr_next(t);
+ m = tcpiphdr_prev(t)->ti_mbuf;
+ remque(tcpiphdr2qlink(tcpiphdr_prev(t)));
m_freem(m);
}
/* It's static */
diff --git a/slirp/tcp_var.h b/slirp/tcp_var.h
index 82380f9..99d18fd 100644
--- a/slirp/tcp_var.h
+++ b/slirp/tcp_var.h
@@ -40,18 +40,12 @@
#include "tcpip.h"
#include "tcp_timer.h"
-#if SIZEOF_CHAR_P == 4
- typedef struct tcpiphdr *tcpiphdrp_32;
-#else
- typedef u_int32_t tcpiphdrp_32;
-#endif
-
/*
* Tcp control block, one per tcp; fields:
*/
struct tcpcb {
- tcpiphdrp_32 seg_next; /* sequencing queue */
- tcpiphdrp_32 seg_prev;
+ struct tcpiphdr *seg_next; /* sequencing queue */
+ struct tcpiphdr *seg_prev;
short t_state; /* state of this connection */
short t_timer[TCPT_NTIMERS]; /* tcp timers */
short t_rxtshift; /* log(2) of rexmt exp. backoff */
@@ -170,21 +164,6 @@ struct tcpcb {
#define TCP_REXMTVAL(tp) \
(((tp)->t_srtt >> TCP_RTT_SHIFT) + (tp)->t_rttvar)
-/* XXX
- * We want to avoid doing m_pullup on incoming packets but that
- * means avoiding dtom on the tcp reassembly code. That in turn means
- * keeping an mbuf pointer in the reassembly queue (since we might
- * have a cluster). As a quick hack, the source & destination
- * port numbers (which are no longer needed once we've located the
- * tcpcb) are overlayed with an mbuf pointer.
- */
-#if SIZEOF_CHAR_P == 4
-typedef struct mbuf *mbufp_32;
-#else
-typedef u_int32_t mbufp_32;
-#endif
-#define REASS_MBUF(ti) (*(mbufp_32 *)&((ti)->ti_t))
-
#ifdef LOG_ENABLED
/*
* TCP statistics.
diff --git a/slirp/tcpip.h b/slirp/tcpip.h
index 82708b0..b98cdb3 100644
--- a/slirp/tcpip.h
+++ b/slirp/tcpip.h
@@ -44,8 +44,7 @@ struct tcpiphdr {
struct ipovly ti_i; /* overlaid ip structure */
struct tcphdr ti_t; /* tcp header */
};
-#define ti_next ti_i.ih_next
-#define ti_prev ti_i.ih_prev
+#define ti_mbuf ti_i.ih_mbuf.mptr
#define ti_x1 ti_i.ih_x1
#define ti_pr ti_i.ih_pr
#define ti_len ti_i.ih_len
@@ -62,6 +61,14 @@ struct tcpiphdr {
#define ti_sum ti_t.th_sum
#define ti_urp ti_t.th_urp
+#define tcpiphdr2qlink(T) ((struct qlink*)(((char*)(T)) - sizeof(struct qlink)))
+#define qlink2tcpiphdr(Q) ((struct tcpiphdr*)(((char*)(Q)) + sizeof(struct qlink)))
+#define tcpiphdr_next(T) qlink2tcpiphdr(tcpiphdr2qlink(T)->next)
+#define tcpiphdr_prev(T) qlink2tcpiphdr(tcpiphdr2qlink(T)->prev)
+#define tcpfrag_list_first(T) qlink2tcpiphdr((T)->seg_next)
+#define tcpfrag_list_end(F, T) (tcpiphdr2qlink(F) == (struct qlink*)(T))
+#define tcpfrag_list_empty(T) ((T)->seg_next == (struct tcpiphdr*)(T))
+
/*
* Just a clean way to get to the first byte
* of the packet
diff --git a/slirp/udp.c b/slirp/udp.c
index ca353b7..c992618 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -136,8 +136,7 @@ udp_input(m, iphlen)
* Checksum extended UDP header and data.
*/
if (UDPCKSUM && uh->uh_sum) {
- ((struct ipovly *)ip)->ih_next = 0;
- ((struct ipovly *)ip)->ih_prev = 0;
+ memset(&((struct ipovly *)ip)->ih_mbuf, 0, sizeof(struct mbuf_ptr));
((struct ipovly *)ip)->ih_x1 = 0;
((struct ipovly *)ip)->ih_len = uh->uh_ulen;
/* keep uh_sum for ICMP reply
@@ -283,7 +282,7 @@ int udp_output2(struct socket *so, struct mbuf *m,
* and addresses and length put into network format.
*/
ui = mtod(m, struct udpiphdr *);
- ui->ui_next = ui->ui_prev = 0;
+ memset(&ui->ui_i.ih_mbuf, 0 , sizeof(struct mbuf_ptr));
ui->ui_x1 = 0;
ui->ui_pr = IPPROTO_UDP;
ui->ui_len = htons(m->m_len - sizeof(struct ip)); /* + sizeof (struct udphdr)); */
diff --git a/slirp/udp.h b/slirp/udp.h
index 4f69b09..e2ca546 100644
--- a/slirp/udp.h
+++ b/slirp/udp.h
@@ -60,8 +60,7 @@ struct udpiphdr {
struct ipovly ui_i; /* overlaid ip structure */
struct udphdr ui_u; /* udp header */
};
-#define ui_next ui_i.ih_next
-#define ui_prev ui_i.ih_prev
+#define ui_mbuf ui_i.ih_mbuf.mptr
#define ui_x1 ui_i.ih_x1
#define ui_pr ui_i.ih_pr
#define ui_len ui_i.ih_len
--
Gleb.
next reply other threads:[~2009-01-12 14:27 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-01-12 14:28 Gleb Natapov [this message]
2009-01-12 14:40 ` [Qemu-devel] [PATCH] fix 64 bit issue in slirp Gleb Natapov
2009-01-12 14:54 ` Blue Swirl
2009-01-12 15:06 ` Gleb Natapov
2009-01-12 16:05 ` Blue Swirl
2009-01-12 19:30 ` malc
2009-01-13 20:00 ` Blue Swirl
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090112142807.GN3267@redhat.com \
--to=gleb@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.