Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 27 Oct 2000 17:09:33 +0300
From:      Ruslan Ermilov <ru@FreeBSD.org>
To:        Darren Reed <darrenr@pobox.com>, Darren Reed <darrenr@FreeBSD.org>
Cc:        net@FreeBSD.org
Subject:   [CFR] IPFILTER patch
Message-ID:  <20001027170933.A36523@sunbay.com>

next in thread | raw e-mail | index | archive | help

--k1lZvvs/B4yU6o8G
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi!

As we discussed yesterday, here are the patches to IPFILTER
that are needed for my upcoming "byte-swapping elimination"
patch.  Sorry, it took a bit more than an hour...

The patch is 99% a clear optimization to an existing code.

We certainly benefit from not doing (ip->ip_off & IP_OFFMASK)
all over the time, since we already have this info stored in
`fin_off' by fr_makefrip().  Also, the (IP_MF|IP_OFFMASK)
check is already indicated by the FI_FRAG flag.

The ip_frag.c code now stores fragment offsets in bytes rather
than in octets.  This allows us to use the `fin_off' field and
eliminate unnecessary use of `<< 3' and `>> 3'.

You may also notice a minor optimization in ipfr_fastroute() IP
fragmentation code.  It is duplicated from the same optimization
I have recently made to ip_output().

When reviewing this modification, please keep in mind that FreeBSD
will shortly preserve the `ip_off' in network byte order, while
`fin_off' will still be made available in host byte order.  That
(I hope) should explain you my intention to replace the `ip_off'
references with `fin_off' ones wherever possible.

<PS>
The diff is against the most recent IPFILTER sources that include
yesterday's import.
</PS>


Cheers,
-- 
Ruslan Ermilov		Oracle Developer/DBA,
ru@sunbay.com		Sunbay Software AG,
ru@FreeBSD.org		FreeBSD committer,
+380.652.512.251	Simferopol, Ukraine

http://www.FreeBSD.org	The Power To Serve
http://www.oracle.com	Enabling The Information Age

--k1lZvvs/B4yU6o8G
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=p

Index: fil.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/fil.c,v
retrieving revision 1.21
diff -u -p -r1.21 fil.c
--- fil.c	2000/10/26 12:33:42	1.21
+++ fil.c	2000/10/27 13:29:07
@@ -227,7 +227,6 @@ fr_info_t *fin;
 	if (v == 4) {
 		fin->fin_id = ip->ip_id;
 		fi->fi_tos = ip->ip_tos;
-		off = (ip->ip_off & IP_OFFMASK) << 3;
 		tcp = (tcphdr_t *)((char *)ip + hlen);
 		(*(((u_short *)fi) + 1)) = (*(((u_short *)ip) + 4));
 		fi->fi_src.i6[1] = 0;
@@ -240,8 +239,10 @@ fr_info_t *fin;
 		fi->fi_daddr = ip->ip_dst.s_addr;
 		p = ip->ip_p;
 		fi->fi_fl = (hlen > sizeof(ip_t)) ? FI_OPTIONS : 0;
-		if (ip->ip_off & 0x3fff)
+		off = ip->ip_off;
+		if (off & (IP_MF|IP_OFFMASK))
 			fi->fi_fl |= FI_FRAG;
+		off <<= 3;
 		plen = ip->ip_len;
 		fin->fin_dlen = plen - hlen;
 	}
@@ -514,20 +515,16 @@ void *m;
 {
 	register struct frentry *fr;
 	register fr_ip_t *fi = &fin->fin_fi;
-	int rulen, portcmp = 0, off, skip = 0, logged = 0;
+	int rulen, portcmp = 0, skip = 0, logged = 0;
 	u_32_t passt;
 
 	fr = fin->fin_fr;
 	fin->fin_fr = NULL;
 	fin->fin_rule = 0;
 	fin->fin_group = 0;
-	if (fin->fin_v == 4)
-		off = ip->ip_off & IP_OFFMASK;
-	else
-		off = 0;
 	pass |= (fi->fi_fl << 24);
 
-	if ((fi->fi_fl & FI_TCPUDP) && (fin->fin_dlen > 3) && !off)
+	if ((fi->fi_fl & FI_TCPUDP) && (fin->fin_dlen > 3) && !fin->fin_off)
 		portcmp = 1;
 
 	for (rulen = 0; fr; fr = fr->fr_next, rulen++) {
@@ -654,7 +651,7 @@ void *m;
 			if (!fr_tcpudpchk(&fr->fr_tuc, fin))
 				continue;
 		} else if (fr->fr_icmpm || fr->fr_icmp) {
-			if ((fi->fi_p != IPPROTO_ICMP) || off ||
+			if ((fi->fi_p != IPPROTO_ICMP) || fin->fin_off ||
 			    (fin->fin_dlen < 2))
 				continue;
 			if ((fin->fin_data[0] & fr->fr_icmpm) != fr->fr_icmp) {
Index: ip_fil.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_fil.c,v
retrieving revision 1.24
diff -u -p -r1.24 ip_fil.c
--- ip_fil.c	2000/10/26 12:33:42	1.24
+++ ip_fil.c	2000/10/27 13:29:07
@@ -1286,6 +1286,7 @@ frdest_t *fdp;
 	struct sockaddr_in *dst;
 	struct route iproute;
 	frentry_t *fr;
+	u_short ip_off;
 
 	hlen = fin->fin_hlen;
 	ip = mtod(m0, struct ip *);
@@ -1417,7 +1418,8 @@ frdest_t *fdp;
 	 * Too large for interface; fragment if possible.
 	 * Must be able to put at least 8 bytes per fragment.
 	 */
-	if (ip->ip_off & IP_DF) {
+	ip_off = ip->ip_off;
+	if (ip_off & IP_DF) {
 		error = EMSGSIZE;
 		goto bad;
 	}
@@ -1459,9 +1461,7 @@ frdest_t *fdp;
 			mhip->ip_hl = mhlen >> 2;
 		}
 		m->m_len = mhlen;
-		mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF);
-		if (ip->ip_off & IP_MF)
-			mhip->ip_off |= IP_MF;
+		mhip->ip_off = ((off - hlen) >> 3) + ip_off;
 		if (off + len >= ip->ip_len)
 			len = ip->ip_len - off;
 		else
@@ -1490,7 +1490,7 @@ frdest_t *fdp;
 	 */
 	m_adj(m0, hlen + firstlen - ip->ip_len);
 	ip->ip_len = htons((u_short)(hlen + firstlen));
-	ip->ip_off = htons((u_short)(ip->ip_off | IP_MF));
+	ip->ip_off = htons((u_short)(ip_off | IP_MF));
 	ip->ip_sum = 0;
 	ip->ip_sum = in_cksum(m0, hlen);
 sendorfree:
Index: ip_frag.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_frag.c,v
retrieving revision 1.13
diff -u -p -r1.13 ip_frag.c
--- ip_frag.c	2000/10/26 12:33:42	1.13
+++ ip_frag.c	2000/10/27 13:29:07
@@ -200,7 +200,7 @@ ipfr_t *table[];
 	/*
 	 * Compute the offset of the expected start of the next packet.
 	 */
-	fra->ipfr_off = (ip->ip_off & IP_OFFMASK) + (fin->fin_dlen >> 3);
+	fra->ipfr_off = fin->fin_off + fin->fin_dlen;
 	ATOMIC_INCL(ipfr_stats.ifs_new);
 	ATOMIC_INC32(ipfr_inuse);
 	return fra;
@@ -280,7 +280,6 @@ ipfr_t *table[];
 	for (f = table[idx]; f; f = f->ipfr_next)
 		if (!bcmp((char *)&frag.ipfr_src, (char *)&f->ipfr_src,
 			  IPFR_CMPSZ)) {
-			u_short	atoff, off;
 
 			if (f != table[idx]) {
 				/*
@@ -294,17 +293,15 @@ ipfr_t *table[];
 				f->ipfr_prev = NULL;
 				table[idx] = f;
 			}
-			off = ip->ip_off & IP_OFFMASK;
-			atoff = off + (fin->fin_dlen >> 3);
 			/*
 			 * If we've follwed the fragments, and this is the
 			 * last (in order), shrink expiration time.
 			 */
-			if (off == f->ipfr_off) {
+			if (fin->fin_off == f->ipfr_off) {
 				if (!(ip->ip_off & IP_MF))
 					f->ipfr_ttl = 1;
 				else
-					f->ipfr_off = atoff;
+					f->ipfr_off = fin->fin_off + fin->fin_dlen;
 			}
 			ATOMIC_INCL(ipfr_stats.ifs_hits);
 			return f;
Index: ip_nat.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_nat.c,v
retrieving revision 1.18
diff -u -p -r1.18 ip_nat.c
--- ip_nat.c	2000/10/26 12:33:42	1.18
+++ ip_nat.c	2000/10/27 13:29:07
@@ -1600,7 +1600,7 @@ int dir;
 	ip_t *oip;
 	int flags = 0;
 
-	if ((fin->fin_fi.fi_fl & FI_SHORT) || (ip->ip_off & IP_OFFMASK))
+	if ((fin->fin_fi.fi_fl & FI_SHORT) || fin->fin_off)
 		return NULL;
 	/*
 	 * nat_icmplookup() will return NULL for `defective' packets.
@@ -2105,7 +2105,7 @@ ip_t *ip;
 
 	ft = &np->in_tuc;
 	if (!(fin->fin_fi.fi_fl & FI_TCPUDP) ||
-	    (fin->fin_fi.fi_fl & FI_SHORT) || (ip->ip_off & IP_OFFMASK)) {
+	    (fin->fin_fi.fi_fl & FI_SHORT) || fin->fin_off) {
 		if (ft->ftu_scmp || ft->ftu_dcmp)
 			return 0;
 		return 1;
@@ -2144,7 +2144,7 @@ fr_info_t *fin;
 	else
 		ifp = fin->fin_ifp;
 
-	if (!(ip->ip_off & IP_OFFMASK) && !(fin->fin_fi.fi_fl & FI_SHORT)) {
+	if (!fin->fin_off && !(fin->fin_fi.fi_fl & FI_SHORT)) {
 		if (ip->ip_p == IPPROTO_TCP)
 			nflags = IPN_TCP;
 		else if (ip->ip_p == IPPROTO_UDP)
@@ -2163,7 +2163,7 @@ fr_info_t *fin;
 	if ((ip->ip_p == IPPROTO_ICMP) &&
 	    (nat = nat_icmp(ip, fin, &nflags, NAT_OUTBOUND)))
 		;
-	else if ((ip->ip_off & (IP_OFFMASK|IP_MF)) &&
+	else if ((fin->fin_fi.fi_fl & FI_FRAG) &&
 			(nat = ipfr_nat_knownfrag(ip, fin)))
 		natadd = 0;
 	else if ((nat = nat_outlookup(ifp, nflags, (u_int)ip->ip_p, ip->ip_src,
@@ -2275,7 +2275,7 @@ maskloop:
 #endif
 		ip->ip_src = nat->nat_outip;
 
-		if (!(ip->ip_off & IP_OFFMASK) &&
+		if (!fin->fin_off &&
 		    !(fin->fin_fi.fi_fl & FI_SHORT)) {
 
 			if ((nat->nat_outport != 0) && (nflags & IPN_TCPUDP)) {
@@ -2358,7 +2358,7 @@ fr_info_t *fin;
 	if ((nat_list == NULL) || (ip->ip_v != 4) || (fr_nat_lock))
 		return 0;
 
-	if (!(ip->ip_off & IP_OFFMASK) && !(fin->fin_fi.fi_fl & FI_SHORT)) {
+	if (!fin->fin_off && !(fin->fin_fi.fi_fl & FI_SHORT)) {
 		if (ip->ip_p == IPPROTO_TCP)
 			nflags = IPN_TCP;
 		else if (ip->ip_p == IPPROTO_UDP)
@@ -2379,7 +2379,7 @@ fr_info_t *fin;
 	if ((ip->ip_p == IPPROTO_ICMP) &&
 	    (nat = nat_icmp(ip, fin, &nflags, NAT_INBOUND)))
 		;
-	else if ((ip->ip_off & (IP_OFFMASK|IP_MF)) &&
+	else if ((fin->fin_fi.fi_fl & FI_FRAG) &&
 		 (nat = ipfr_nat_knownfrag(ip, fin)))
 		natadd = 0;
 	else if ((nat = nat_inlookup(fin->fin_ifp, nflags, (u_int)ip->ip_p,
@@ -2475,7 +2475,7 @@ maskloop:
 		else
 			fix_outcksum(&ip->ip_sum, nat->nat_ipsumd);
 #endif
-		if (!(ip->ip_off & IP_OFFMASK) &&
+		if (!fin->fin_off &&
 		    !(fin->fin_fi.fi_fl & FI_SHORT)) {
 
 			if ((nat->nat_inport != 0) && (nflags & IPN_TCPUDP)) {

--k1lZvvs/B4yU6o8G--


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20001027170933.A36523>