Commit Graph

79 Commits

Author SHA1 Message Date
ozaki-r c5696d3c25 Rename if_acquire_NOMPSAFE to if_acquire
It can be used in MP-safe ways. So let's remove the confusing postfix.
If it's used in a unsafe way, warn NOMPSAFE in a comment.
2017-02-17 03:57:17 +00:00
christos 35561f6b22 ip6_sprintf -> IN6_PRINT so that we pass the size. 2017-01-16 15:44:46 +00:00
ryo 28f4c24cc2 Make ip6_sprintf(), in_fmtaddr(), lla_snprintf() and icmp6_redirect_diag() mpsafe.
Reviewed by ozaki-r@
2017-01-16 07:33:36 +00:00
ozaki-r 4c25fb2f83 Add rtcache_unref to release points of rtentry stemming from rtcache
In the MP-safe world, a rtentry stemming from a rtcache can be freed at any
points. So we need to protect rtentries somehow say by reference couting or
passive references. Regardless of the method, we need to call some release
function of a rtentry after using it.

The change adds a new function rtcache_unref to release a rtentry. At this
point, this function does nothing because for now we don't add a reference
to a rtentry when we get one from a rtcache. We will add something useful
in a further commit.

This change is a part of changes for MP-safe routing table. It is separated
to avoid one big change that makes difficult to debug by bisecting.
2016-12-08 05:16:33 +00:00
ozaki-r 3de81a8881 CID 1396598, CID 1396634: Fix null pointer dereferences 2016-12-02 00:19:54 +00:00
ozaki-r d0432711b6 Tidy up in6_select*
This change tidies up in6_select* functions, especially
selectroute.

selectroute is annoying because:
- It returns both/either of a rtentry and/or an ifp
  - Yes, it may return only an ifp!
    - It is valid but selectroute shouldn't handle the case
  - Such conditional behavior makes it difficult
    to apply locking/psref thingy
- It may return a rtentry even if error
- It may use opt->ip6po_nextroute rtcache implicitly
  - The caller can know if it is used
    by rtcache_validate(&opt->ip6po_nextroute)
    but it's racy in MP-safe world
  - Even if it uses opt->ip6po_nextroute, it may
    return a rtentry that isn't derived from the rtcache

The change includes:
- Rename selectroute to in6_selectroute
  - Let a remaining caller of selectroute, in6_selectif,
    use in6_selectroute instead
- Let in6_selectroute return only an rtentry
  - If error, it doesn't return an rtentry
  - A caller gets an ifp from a returned rtentry
- Allow in6_selectroute to modify a passed rtcache
  and a caller can know if opt->ip6po_nextroute is
  used via the rtcache
- Let callers (ip6_output and in6_selectif) handle
  the case that only an ifp is required

Inspired by OpenBSD
Proposed on tech-kern and tech-net
LGTM by roy@
2016-11-10 04:13:53 +00:00
ozaki-r c5224ffd07 Pull best address selection code out of in6_selectsrc
No functional change.
2016-10-31 04:57:10 +00:00
ozaki-r 0f3a44863e Fix race condition of in6_selectsrc
in6_selectsrc returned a pointer to in6_addr that wan't guaranteed to be
safe by pserialize (or psref), which was racy. Let callers pass a pointer
to in6_addr and in6_selectsrc copy a result to it inside pserialize
critical sections.
2016-10-31 04:16:25 +00:00
ozaki-r 6e6136eaff Remove unnecessary NULL checks 2016-10-31 02:50:31 +00:00
roy c63a839724 Simplify. 2016-08-26 20:29:31 +00:00
roy 333b0c4c48 Allow explicit binding to detached addresss.
Fixes PR kern/51435.
2016-08-26 19:45:55 +00:00
roy 1893d82b49 White space police. 2016-08-23 19:39:57 +00:00
roy da7a376e71 Sync denied flags. 2016-08-23 19:39:04 +00:00
ozaki-r a403cbd4f5 Apply pserialize and psref to struct ifaddr and its variants
This change makes struct ifaddr and its variants (in_ifaddr and in6_ifaddr)
MP-safe by using pserialize and psref. At this moment, pserialize_perform
and psref_target_destroy are disabled because (1) we don't need them
because of softnet_lock (2) they cause a deadlock because of softnet_lock.
So we'll enable them when we remove softnet_lock in the future.
2016-08-01 03:15:30 +00:00
ozaki-r 8759207c83 Use sin6tosa and sin6tocsa macros
No functional change.
2016-07-15 07:40:09 +00:00
ozaki-r 328b3c6b85 Use ifatoia6 macro
No functional change.
2016-07-15 07:33:41 +00:00
ozaki-r 6cf9fce745 Use pslist(9) for the global in6_ifaddr list
psz and psref will be applied in another commit.

No functional change intended.
2016-07-04 06:48:14 +00:00
ozaki-r 4badfc204a Make sure returning ifp from in6_select* functions psref-ed
To this end, callers need to pass struct psref to the functions
and the fuctions acquire a reference of ifp with it. In some cases,
we can simply use if_get_byindex, however, in other cases
(say rt->rt_ifp and ia->ifa_ifp), we have no MP-safe way for now.
In order to take a reference anyway we use non MP-safe function
if_acquire_NOMPSAFE for the latter cases. They should be fixed in
the future somehow.
2016-06-21 10:25:27 +00:00
ozaki-r 43c5ab376f Replace ifp of ip_moptions and ip6_moptions with if_index
The motivation is the same as the mbuf's rcvif case; avoid having a pointer
of an ifnet object in ip_moptions and ip6_moptions, which is not MP-safe.

ip_moptions and ip6_moptions can be stored in a PCB for inet or inet6
that's life time is different from ifnet one and so an ifnet object can be
disappeared anytime we get it via them. Thus we need to look up an ifnet
object by if_index every time for safe.
2016-06-21 03:28:27 +00:00
ozaki-r 9f595a90fa Get rid of unnecessary NULL check
It's already checked just some lines above.
2016-05-18 09:32:05 +00:00
christos 5b5956f338 Hook up the addrctl stuff that's already there. 2015-12-12 23:34:25 +00:00
pooka 1c4a50f192 sprinkle _KERNEL_OPT 2015-08-24 22:21:26 +00:00
ozaki-r 2373b55abc Introduce in6_selecthlim_rt to consolidate an idiom for rt->rt_ifp
It consolidates a scattered routine:
(rt = rtcache_validate(&in6p->in6p_route)) != NULL ? rt->rt_ifp : NULL
2015-04-27 02:59:44 +00:00
roy 9daa8a6db0 Add net.inet6.ip6.prefer_tempaddr sysctl knob so that we can prefer
IPv6 temporary addresses as the source address.

Fixes PR kern/47100 based on a patch by Dieter Roelants.
2015-01-20 21:27:36 +00:00
matt 6f1589d59d Don't use C++ keyword as variable.
Use different prefix for nd6_prefixctl members than for nd6_prefix members.
2014-09-05 06:08:15 +00:00
rmind bc9504c95e Replace open-coded access (and boundary checking) of ifindex2ifnet with
if_byindex() function.
2014-05-17 21:26:20 +00:00
christos 84f52095ad rename rfc6056 -> portalgo, requested by yamt 2012-06-25 15:28:38 +00:00
christos 5ec72efbaa Add inet6 part of the rfc6056 code contributed by Vlad Balan as part of
Google SoC-2011
2011-09-24 17:22:14 +00:00
dholland ebbcc1e872 Add missing $NetBSD$ header. 2011-05-17 04:39:57 +00:00
dyoung c2e43be1c5 Reduces the resources demanded by TCP sessions in TIME_WAIT-state using
methods called Vestigial Time-Wait (VTW) and Maximum Segment Lifetime
Truncation (MSLT).

MSLT and VTW were contributed by Coyote Point Systems, Inc.

Even after a TCP session enters the TIME_WAIT state, its corresponding
socket and protocol control blocks (PCBs) stick around until the TCP
Maximum Segment Lifetime (MSL) expires.  On a host whose workload
necessarily creates and closes down many TCP sockets, the sockets & PCBs
for TCP sessions in TIME_WAIT state amount to many megabytes of dead
weight in RAM.

Maximum Segment Lifetimes Truncation (MSLT) assigns each TCP session to
a class based on the nearness of the peer.  Corresponding to each class
is an MSL, and a session uses the MSL of its class.  The classes are
loopback (local host equals remote host), local (local host and remote
host are on the same link/subnet), and remote (local host and remote
host communicate via one or more gateways).  Classes corresponding to
nearer peers have lower MSLs by default: 2 seconds for loopback, 10
seconds for local, 60 seconds for remote.  Loopback and local sessions
expire more quickly when MSLT is used.

Vestigial Time-Wait (VTW) replaces a TIME_WAIT session's PCB/socket
dead weight with a compact representation of the session, called a
"vestigial PCB".  VTW data structures are designed to be very fast and
memory-efficient: for fast insertion and lookup of vestigial PCBs,
the PCBs are stored in a hash table that is designed to minimize the
number of cacheline visits per lookup/insertion.  The memory both
for vestigial PCBs and for elements of the PCB hashtable come from
fixed-size pools, and linked data structures exploit this to conserve
memory by representing references with a narrow index/offset from the
start of a pool instead of a pointer.  When space for new vestigial PCBs
runs out, VTW makes room by discarding old vestigial PCBs, oldest first.
VTW cooperates with MSLT.

It may help to think of VTW as a "FIN cache" by analogy to the SYN
cache.

A 2.8-GHz Pentium 4 running a test workload that creates TIME_WAIT
sessions as fast as it can is approximately 17% idle when VTW is active
versus 0% idle when VTW is inactive.  It has 103 megabytes more free RAM
when VTW is active (approximately 64k vestigial PCBs are created) than
when it is inactive.
2011-05-03 18:28:44 +00:00
pooka 21e6fa78da Remove declaration of unused extern struct ifnet loif[NLOOP], which
was already removed once, but brought back in a wholesale import.
While here, mop up the #ifdef __SomeotherOS__ noise.
2009-05-25 22:49:23 +00:00
elad b15203315e Implicit EPERM -> explicit EACCES.
Requested by ad@ and yamt@.
2009-05-12 22:22:46 +00:00
elad 3c1f169a59 Commit changes to netinet6/in6_src.c, forgot in previous commit:
http://mail-index.netbsd.org/source-changes/2009/04/30/msg220547.html

Make in_pcbsetport() set the port number selected before passing "sin" to
kauth(9).
2009-04-30 20:26:09 +00:00
cegger c363a9cb62 bzero -> memset 2009-03-18 16:00:08 +00:00
christos 461a86f9bd merge christos-time_t 2009-01-11 02:45:45 +00:00
cegger 9b87d582bd kill MALLOC and FREE macros. 2008-12-17 20:51:31 +00:00
thorpej 0dd41b37de Make ip6 and icmp6 stats per-cpu. 2008-04-15 03:57:04 +00:00
thorpej 3f466bce48 Change IPv6 stats from a structure to an array of uint64_t's.
Note: This is ABI-compatible with the old ip6stat structure; old netstat
binaries will continue to work properly.
2008-04-08 23:37:43 +00:00
matt c939552209 Convert to ansi definitions from old-style definitons.
Remember that func() is not ansi, func(void) is.
2008-02-27 19:40:56 +00:00
yamt 5e36d79445 in6_pcbsetport: add missing htons. (fixes ephemeral port allocation.) 2007-11-26 08:12:33 +00:00
dyoung d072fd0fb9 Replace rote sockaddr_in6 initializations (memset(), set sa6_family,
sa6_len, and sa6_add) with sockaddr_in6_init() calls.

De-__P().  Constify.  KNF.  Shorten a staircase.  Change bcmp() to
memcmp().

Extract subroutine in6_setzoneid() from in6_setscope(), for re-use
soon.
2007-10-24 06:37:20 +00:00
christos 72cfe7327b Ansify + add a few comments, from Karl Sjödahl 2007-05-23 17:14:59 +00:00
dyoung 72f0a6dfb0 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.

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);
        void 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.
2007-05-02 20:40:22 +00:00
christos 53524e44ef Kill caddr_t; there will be some MI fallout, but it will be fixed shortly. 2007-03-04 05:59:00 +00:00
dyoung 5493f188c7 KNF: de-__P, bzero -> memset, bcmp -> memcmp. Remove extraneous
parentheses in return statements.

Cosmetic: don't open-code TAILQ_FOREACH().

Cosmetic: change types of variables to avoid oodles of casts: in
   in6_src.c, avoid casts by changing several route_in6 pointers
   to struct route pointers.  Remove unnecessary casts to caddr_t
   elsewhere.

Pave the way for eliminating address family-specific route caches:
   soon, struct route will not embed a sockaddr, but it will hold
   a reference to an external sockaddr, instead.  We will set the
   destination sockaddr using rtcache_setdst().  (I created a stub
   for it, but it isn't used anywhere, yet.)  rtcache_free() will
   free the sockaddr.  I have extracted from rtcache_free() a helper
   subroutine, rtcache_clear().  rtcache_clear() will "forget" a
   cached route, but it will not forget the destination by releasing
   the sockaddr.  I use rtcache_clear() instead of rtcache_free()
   in rtcache_update(), because rtcache_update() is not supposed
   to forget the destination.

Constify:

   1 Introduce const accessor for route->ro_dst, rtcache_getdst().

   2 Constify the 'dst' argument to ifnet->if_output().  This
     led me to constify a lot of code called by output routines.

   3 Constify the sockaddr argument to protosw->pr_ctlinput.  This
     led me to constify a lot of code called by ctlinput routines.

   4 Introduce const macros for converting from a generic sockaddr
     to family-specific sockaddrs, e.g., sockaddr_in: satocsin6,
     satocsin, et cetera.
2007-02-17 22:34:07 +00:00
elad b2eb9a5389 Consistent usage of KAUTH_GENERIC_ISSUSER. 2007-01-04 19:07:03 +00:00
joerg eb04733c4e Introduce new helper functions to abstract the route caching.
rtcache_init and rtcache_init_noclone lookup ro_dst and store
the result in ro_rt, taking care of the reference counting and
calling the domain specific route cache.
rtcache_free checks if a route was cashed and frees the reference.
rtcache_copy copies ro_dst of the given struct route, checking that
enough space is available and incrementing the reference count of the
cached rtentry if necessary.
rtcache_check validates that the cached route is still up. If it isn't,
it tries to look it up again. Afterwards ro_rt is either a valid again
or NULL.
rtcache_copy is used internally.

Adjust to callers of rtalloc/rtflush in the tree to check the sanity of
ro_dst first (if necessary). If it doesn't fit the expectations, free
the cache, otherwise check if the cached route is still valid. After
that combination, a single check for ro_rt == NULL is enough to decide
whether a new lookup needs to be done with a different ro_dst.
Make the route checking in gre stricter by repeating the loop check
after revalidation.
Remove some unused RADIX_MPATH code in in6_src.c. The logic is slightly
changed here to first validate the route and check RTF_GATEWAY
afterwards. This is sementically equivalent though.
etherip doesn't need sc_route_expire similiar to the gif changes from
dyoung@ earlier.

Based on the earlier patch from dyoung@, reviewed and discussed with
him.
2006-12-15 21:18:52 +00:00
dyoung c308b1c661 Here are various changes designed to protect against bad IPv4
routing caused by stale route caches (struct route).  Route caches
are sprinkled throughout PCBs, the IP fast-forwarding table, and
IP tunnel interfaces (gre, gif, stf).

Stale IPv6 and ISO route caches will be treated by separate patches.

Thank you to Christoph Badura for suggesting the general approach
to invalidating route caches that I take here.

Here are the details:

Add hooks to struct domain for tracking and for invalidating each
domain's route caches: dom_rtcache, dom_rtflush, and dom_rtflushall.

Introduce helper subroutines, rtflush(ro) for invalidating a route
cache, rtflushall(family) for invalidating all route caches in a
routing domain, and rtcache(ro) for notifying the domain of a new
cached route.

Chain together all IPv4 route caches where ro_rt != NULL.  Provide
in_rtcache() for adding a route to the chain.  Provide in_rtflush()
and in_rtflushall() for invalidating IPv4 route caches.  In
in_rtflush(), set ro_rt to NULL, and remove the route from the
chain.  In in_rtflushall(), walk the chain and remove every route
cache.

In rtrequest1(), call rtflushall() to invalidate route caches when
a route is added.

In gif(4), discard the workaround for stale caches that involves
expiring them every so often.

Replace the pattern 'RTFREE(ro->ro_rt); ro->ro_rt = NULL;' with a
call to rtflush(ro).

Update ipflow_fastforward() and all other users of route caches so
that they expect a cached route, ro->ro_rt, to turn to NULL.

Take care when moving a 'struct route' to rtflush() the source and
to rtcache() the destination.

In domain initializers, use .dom_xxx tags.

KNF here and there.
2006-12-09 05:33:04 +00:00
dyoung 3b46d8b708 Use the queue(3) macros instead of open-coding them. Shorten
staircases.  Remove unnecessary casts.  Where appropriate, s/8/NBBY/.
De-__P().  KNF.

No functional changes intended.
2006-12-02 18:59:17 +00:00
christos 168cd830d2 __unused removal on arguments; approved by core. 2006-11-16 01:32:37 +00:00