Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 01 May 1998 21:29:37 -0500
From:      Chris Csanady <ccsanady@friley585.res.iastate.edu>
To:        Garrett Wollman <wollman@khavrinen.lcs.mit.edu>
Cc:        mike@smith.net.au, freebsd-net@FreeBSD.ORG
Subject:   Re: Fwd: NetBSD network code improvements 
Message-ID:  <199805020229.VAA04136@friley585.res.iastate.edu>
In-Reply-To: Your message of "Fri, 01 May 1998 16:43:38 EDT." <199805012043.QAA09515@khavrinen.lcs.mit.edu> 

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

><<On Fri, 01 May 1998 12:35:02 -0700, Mike Smith <mike@smith.net.au> said:
>
>> I'm not sure that making it optional would be taking best advantage of 
>> it.  If it's a standard performance-enhancing feature, we'd be best off 
>> adopting it as such, in line with our out-of-the-box philosophy, no?
>
>The code which will give the best performance on a router is not
>necessarily the code which will give the best performance on a host.
>Ergo, we should optimize for the common case.

I'd have to apree with this.  Honestly, their IP fast forwarding code
bothers me a bit.  It looks like they use a more complex data structure
than is needed, that takes more overhead in the common case to manage it.
My main objection though is that this code adds a slowtimo--something that
we should probably look at purging from the kernel altogether.  It seems
that it would be better to have the routing code participate more often,
rather than walking the entire cache every slowtimo to reap ipflows, etc.

I have included the ip_input() function from Van Jacobsons experimental
stack as a reference.  It uses an extremely simple cache, that requires
little memory and only a handful of instructions that manage it.  This
code should actually have *very* low overhead even in the common case.

I would prefer that the code were modeled after something closer to this.


Chris Csanady

/*
 * Copyright (C) 1992 by Van Jacobson
 * All rights reserved.
 */
#define HASH_BITS 11
#define HASH_SIZE (1 << HASH_BITS)
#define HASH(dst) (((dst) ^ ((dst) >> HASH_BITS)) & (HASH_SIZE-1))

struct ipfwd_cache {
        u_long dst;             /* ip address of final destination */
        struct  rtentry *rt;    /* route to get there (forwarding) */
} ipfwd_cache[HASH_SIZE];


ip_input(p, ifp)
        register struct pbuf *p;
        register struct ifnet *ifp;
{
        register struct ip *ip = ptod(p, struct ip *);
        register u_int len = p->p_len;
        register u_int dst;
        register struct ipfwd_cache *cache;
        register struct rtentry *rt;
        register int i;
        extern int ip_fill_fwd_cache();

        if (len < sizeof(struct ip)) {
                ipstat.ips_tooshort++;
                goto bad;
        }

        if (len != ntohs(ip->ip_len)) {
                if (len < ntohs(ip->ip_len)) {
                        ipstat.ips_toosmall++;
                        goto bad;
                }
                len = ntohs(ip->ip_len);
                p->p_len = len;
        }

        if (*(char *)ip != ((IPVERSION << 4) | sizeof(struct ip)/4)) {
                if (ip->ip_v != IPVERSION) {
                        ipstat.ips_badver++;
                        goto bad;
                }
                i = ip->ip_hl << 2;
                if (i > len || i < sizeof(struct ip)) {
                        ipstat.ips_badhlen++;
                        goto bad;
                }
                if ((dst = ip_do_options(p, ip)) == 0)
                        goto bad;
        } else
                dst = ip->ip_dst.s_addr;

        cache = &ipfwd_cache[HASH(dst)];
        if (cache->dst != dst) {
                if (ip_fill_fwd_cache(p, dst, cache))
                        goto bad;
                if (ifp == rt->ifp)
                        ip_send_redirect(p, ip, rt);
        }

        if (rt = cache->rt)  {
                i = ip->ip_ttl;
                if (--i <= 0) {
                        ip_send_time_exceeded(p);
                        return;
                }
                ip->ip_ttl = i;
                i = (int)ip->ip_sum + 256;
                ip->ip_sum = i + (i >> 16);
                ifp = rt->rt_ifp;
                if (ifp->if_mtu < len) {
                        /* fragment and send packet */
                } else if (p = (ifp->if_pmove)(ifp, p))
                        (rt->rt_output)(rt, p);
        } else {
                i = ip->ip_hl << 2;
                p->p_data += i;
                p->p_len -= i;
                (ip_protosw[ip->ip_p])(p, ip);
        }
        return;
}




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?199805020229.VAA04136>