From owner-freebsd-net Fri Oct 27 7:10:22 2000 Delivered-To: freebsd-net@freebsd.org Received: from whale.sunbay.crimea.ua (whale.sunbay.crimea.ua [212.110.138.65]) by hub.freebsd.org (Postfix) with ESMTP id DDEA437B4C5; Fri, 27 Oct 2000 07:10:02 -0700 (PDT) Received: (from ru@localhost) by whale.sunbay.crimea.ua (8.11.0/8.11.0) id e9RE9X036938; Fri, 27 Oct 2000 17:09:33 +0300 (EEST) (envelope-from ru) Date: Fri, 27 Oct 2000 17:09:33 +0300 From: Ruslan Ermilov To: Darren Reed , Darren Reed Cc: net@FreeBSD.org Subject: [CFR] IPFILTER patch Message-ID: <20001027170933.A36523@sunbay.com> Mail-Followup-To: Darren Reed , Darren Reed , net@FreeBSD.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="k1lZvvs/B4yU6o8G" Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-net@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org --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. The diff is against the most recent IPFILTER sources that include yesterday's import. 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