From 0b4d50d7bddc70b289cfda422f65e33e05406a18 Mon Sep 17 00:00:00 2001 From: yamt Date: Thu, 7 Apr 2005 12:22:47 +0000 Subject: [PATCH] when doing TSO, avoid to use duplicated ip_id heavily. XXX ip_randomid --- sys/netinet/ip_output.c | 25 ++++++++++++++++++++++--- sys/netinet/ip_var.h | 28 ++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 9993af1f5f05..2520169b4880 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_output.c,v 1.149 2005/03/11 17:07:51 matt Exp $ */ +/* $NetBSD: ip_output.c,v 1.150 2005/04/07 12:22:47 yamt Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -98,7 +98,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.149 2005/03/11 17:07:51 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.150 2005/04/07 12:22:47 yamt Exp $"); #include "opt_pfil_hooks.h" #include "opt_inet.h" @@ -235,7 +235,26 @@ ip_output(struct mbuf *m0, ...) if ((flags & (IP_FORWARDING|IP_RAWOUTPUT)) == 0) { ip->ip_v = IPVERSION; ip->ip_off = htons(0); - ip->ip_id = ip_newid(); + if ((m->m_pkthdr.csum_flags & M_CSUM_TSOv4) == 0) { + ip->ip_id = ip_newid(); + } else { + + /* + * TSO capable interfaces (typically?) increment + * ip_id for each segment. + * "allocate" enough ids here to increase the chance + * for them to be unique. + * + * note that the following calculation is not + * needed to be precise. wasting some ip_id is fine. + */ + + unsigned int segsz = m->m_pkthdr.segsz; + unsigned int datasz = ntohs(ip->ip_len) - hlen; + unsigned int num = howmany(datasz, segsz); + + ip->ip_id = ip_newid_range(num); + } ip->ip_hl = hlen >> 2; ipstat.ips_localout++; } else { diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h index e4729fb2ffed..bad2961ce120 100644 --- a/sys/netinet/ip_var.h +++ b/sys/netinet/ip_var.h @@ -1,4 +1,4 @@ -/* $NetBSD: ip_var.h,v 1.69 2004/12/15 04:25:19 thorpej Exp $ */ +/* $NetBSD: ip_var.h,v 1.70 2005/04/07 12:22:47 yamt Exp $ */ /* * Copyright (c) 1982, 1986, 1993 @@ -263,13 +263,33 @@ static __inline uint16_t ip_newid(void); u_int16_t ip_randomid(void); extern int ip_do_randomid; +/* + * ip_newid_range: "allocate" num contiguous ip_ids. + * + * => return the first id. + */ + +static __inline uint16_t +ip_newid_range(unsigned int num) +{ + uint16_t id; + + if (ip_do_randomid) { + /* XXX ignore num */ + return ip_randomid(); + } + + id = htons(ip_id); + ip_id += num; + + return id; +} + static __inline uint16_t ip_newid(void) { - if (ip_do_randomid) - return ip_randomid(); - return htons(ip_id++); + return ip_newid_range(1); } #endif /* _KERNEL */