Discussion:
RFC [patch]: unify route cache
(too old to reply)
David Young
2007-04-25 03:52:26 UTC
Permalink
I have made a bunch of changes to our networking stacks in order to
eliminate address family-specific route caches (struct route, struct
route_in6, struct route_iso), replacing all caches with a struct route.
The principle benefit of this change is that all of the protocol
families can benefit from route cache-invalidation, which is necessary
for correct routing. Route-cache invalidation fixes an ancient PR,
kern/3508, at long last; it fixes various other PRs, also.

Patches at <ftp://cuw.ojctech.com/cuw/netbsd-1da8c563/ro_sa.patch>.
Please help me by testing!

Discussions with and ideas from Joerg Sonnenberger influenced this
work tremendously. Of course, all design oversights and bugs are mine.

DETAILS

1 I added to each address family a pool of sockaddrs. I have introduced
routines for allocating, copying, and duplicating, and freeing
sockaddrs:

struct sockaddr *sockaddr_alloc(sa_family_t af, int flags);
struct sockaddr *sockaddr_copy(struct sockaddr *dst,
const struct sockaddr *src);
struct sockaddr *sockaddr_dup(const struct sockaddr *src, int flags);
struct sockaddr *sockaddr_free(struct sockaddr *sa);

sockaddr_alloc() returns either a sockaddr from the pool belonging to
the specified family, or NULL if the pool is exhausted. The returned
sockaddr has the right size for that family; sa_family and sa_len fields
are initialized to the family and sockaddr length---e.g., sa_family
= AF_INET and sa_len = sizeof(struct sockaddr_in). sockaddr_free()
puts the given sockaddr back into its family's pool.

sockaddr_dup() and sockaddr_copy() work analogously to strdup() and
strcpy(), respectively. sockaddr_copy() KASSERTs that the family of
the destination and source sockaddrs are alike.

The 'flags' argumet for sockaddr_alloc() and sockaddr_dup() is passed
directly to pool_get(9).

2 I added routines for initializing sockaddrs in each address family,
sockaddr_in_init(), sockaddr_in6_init(), sockaddr_iso_init(), etc.
They are fairly self-explanatory.

3 structs route_in6 and route_iso are no more. All protocol families use
struct route. I have changed the route cache, 'struct route', so
that it does not contain storage space for a sockaddr. Instead,
struct route points to a sockaddr coming from the pool the sockaddr
belongs to. I added a new method to struct route, rtcache_setdst(),
for setting the cache destination:

int rtcache_setdst(struct route *, const struct sockaddr *);

rtcache_setdst() returns 0 on success, or ENOMEM if no memory is
available to create the sockaddr storage.

It is now possible for rtcache_getdst() to return NULL if, say,
rtcache_setdst() failed. I check the return value for NULL everywhere
in the kernel.

4 Each routing domain (struct domain) has a list of live route caches,
dom_rtcache. rtflushall(sa_family_t af) looks up the domain indicated
by 'af', walks the domain's list of route caches and invalidates
each one.

TESTING

So far, IPv4 and IPv6 networking work fine in my rigorous wireless router
application. I will test gre, stf, and pf, soon. I need your help to
test IP Filter, AppleTalk, ISO, or Bluetooth networking for regressions.

TODO

Manual pages.

Dave
--
David Young OJC Technologies
***@ojctech.com Urbana, IL * (217) 278-3933

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Joerg Sonnenberger
2007-04-25 05:52:37 UTC
Permalink
Post by David Young
struct sockaddr *sockaddr_alloc(sa_family_t af, int flags);
struct sockaddr *sockaddr_copy(struct sockaddr *dst,
const struct sockaddr *src);
struct sockaddr *sockaddr_dup(const struct sockaddr *src, int flags);
struct sockaddr *sockaddr_free(struct sockaddr *sa);
As we force maximum size allocations for the sockaddr, sockaddr_copy can
return void? I don't think the return value makes real sense for that.

sockaddr_free is actually returning void already.
Post by David Young
3 structs route_in6 and route_iso are no more. All protocol families use
struct route. I have changed the route cache, 'struct route', so
that it does not contain storage space for a sockaddr. Instead,
struct route points to a sockaddr coming from the pool the sockaddr
belongs to. I added a new method to struct route, rtcache_setdst(),
Long term I'd prefer if we can get the pools waitok-safe, but that's
outside the scope.

Thanks, David.

Joerg

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Loading...