| Age | Commit message (Collapse) | Author |
|
Discussed on tech-kern:
https://mail-index.netbsd.org/tech-kern/2023/02/23/msg028729.html
|
|
|
|
|
|
address. Implemented by ozaki-r@n.o.
A route that has a gateway is on a connected route can be invalid if the
connected route is deleted, i.e., an associated address is removed.
Traditionally NetBSD doesn't sweep such a route on the address removal. Sending
packets over the route fails with "No route to host". Also the route holds an
orphan ifaddr as rt_ifa that is destructed say by in_purgeaddr.
If the same address is assgined again in such a state, there can be two
different ifaddr objects with the same address. Until recently it's not a
big problem because we can send packets anyway. However after MP-ification
of the network stack, we can't send packets because we strictly check if rt_ifa
(i.e., the (old) ifaddr) is valid.
This change automatically removes such routes on a removal of an associated
address to avoid keeping inconsistent routes.
|
|
(except dom_ifqueues itself, until the next kernel version bump).
It's no longer used now that nothing uses the legacy netisr mechanism.
|
|
|
|
Rather than excplicitly referencing ip_pktq and ip6_pktq in if_detach(),
instead add all pktqueues to a global list. This list is then used in
the new pktq_ifdetach() function to issue a barrier on all pktqueues.
Note that the performance of this list is not critical; it will seldom
be accessed (then pktqueues are created/destroyed and when network
interfaces are detached), and so a simple synchronization strategy using
a rwlock is sufficient.
|
|
calls; pktq_barrier() doesn't remove packets from the queue, it waits
for the packets enqueued before the barrier to drain. This, in turn,
may cause the protocols to gain additional references to the interface
that's detaching. By draining the queues first, we ensure that no
additional references will be taken after calling pr_purgeif().
|
|
Provide a new pktq_sysctl_setup() function that attaches standard
pktq sysctl nodes below a specified parent node, with either a
fixed node ID or CTL_CREATE to dynamically assign node IDs. Make
all of the sysctl handlers private to pktqueue.c, and remove the
INET- and INET6-specific pktqueue sysctl code from net/if.c.
|
|
|
|
|
|
|
|
|
|
Fixes crash on detach.
|
|
|
|
For interfaces that use if_watchdog, this forces it to be called at
the next tick.
|
|
This is necessary to make mii_down and the *_init/stop routines that
call it to sleep waiting for MII callouts on other CPUs.
Mark the workqueue and callout MP-safe; only take the kernel lock
around the callback.
No kernel bump despite change to struct ifnet because the change is
ABI-compatible and using the callout outside net/if.c has never been
kosher.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sys_ioctl validates the data pointer according to the command's size
and direction. But userland may ioctl commands other than
OSIOCGIFCONF or OOSIOCGIFCONF -- and if userland passes an IOC_VOID
command, the argument is passed through verbatim and may be null.
Reported-by: syzbot+19b1bf83e5481273eafc@syzkaller.appspotmail.com
https://syzkaller.appspot.com/bug?id=f4c91a7dcd31901c80d91af6ed01456faf0a7286
Reported-by: syzbot+442c033feb784d055185@syzkaller.appspotmail.com
https://syzkaller.appspot.com/bug?id=4a3a4b92dbe9695046ff17a5474cef52aed23e0b
Reported-by: syzbot+4c87d0cdf7025741ea7a@syzkaller.appspotmail.com
https://syzkaller.appspot.com/bug?id=3e5f42c998e43ad42da40dec3c7873e6aae187e4
|
|
|
|
|
|
This just goes through my recent reference count membar audit and
changes membar_exit to membar_release and membar_enter to
membar_acquire -- this should make everything cheaper on most CPUs
without hurting correctness, because membar_acquire is generally
cheaper than membar_enter.
|
|
If two threads are using an object that is freed when the reference
count goes to zero, we need to ensure that all memory operations
related to the object happen before freeing the object.
Using an atomic_dec_uint_nv(&refcnt) == 0 ensures that only one
thread takes responsibility for freeing, but it's not enough to
ensure that the other thread's memory operations happen before the
freeing.
Consider:
Thread A Thread B
obj->foo = 42; obj->baz = 73;
mumble(&obj->bar); grumble(&obj->quux);
/* membar_exit(); */ /* membar_exit(); */
atomic_dec -- not last atomic_dec -- last
/* membar_enter(); */
KASSERT(invariant(obj->foo,
obj->bar));
free_stuff(obj);
The memory barriers ensure that
obj->foo = 42;
mumble(&obj->bar);
in thread A happens before
KASSERT(invariant(obj->foo, obj->bar));
free_stuff(obj);
in thread B. Without them, this ordering is not guaranteed.
So in general it is necessary to do
membar_exit();
if (atomic_dec_uint_nv(&obj->refcnt) != 0)
return;
membar_enter();
to release a reference, for the `last one out hit the lights' style
of reference counting. (This is in contrast to the style where one
thread blocks new references and then waits under a lock for existing
ones to drain with a condvar -- no membar needed thanks to mutex(9).)
I searched for atomic_dec to find all these. Obviously we ought to
have a better abstraction for this because there's so much copypasta.
This is a stop-gap measure to fix actual bugs until we have that. It
would be nice if an abstraction could gracefully handle the different
styles of reference counting in use -- some years ago I drafted an
API for this, but making it cover everything got a little out of hand
(particularly with struct vnode::v_usecount) and I ended up setting
it aside to work on psref/localcount instead for better scalability.
I got bored of adding #ifdef __HAVE_ATOMIC_AS_MEMBAR everywhere, so I
only put it on things that look performance-critical on 5sec review.
We should really adopt membar_enter_preatomic/membar_exit_postatomic
or something (except they are applicable only to atomic r/m/w, not to
atomic_load/store_*, making the naming annoying) and get rid of all
the ifdefs.
|
|
Meant only for multicast addition/deletion operations, nothing else.
|
|
|
|
Exception: Not for SIOCADDMULTI/SIOCDELMULTI, for which it is the
driver's responsibility to take internal locks. Typically this is
already done via struct ethercom::ec_lock.
|
|
|
|
These are wrappers, suitable for inserting appropriate kasserts
regarding the API's locking contract, for the corresponding functions
in struct ifnet.
Since these are intended to commit configuration changes to the
interface, which may involve resetting the device, the caller should
hold IFNET_LOCK. However, I can't straightforwardly prove that all
callers do yet, so the assertion is disabled for now.
|
|
that was used for updating link-state of vlan I/F
The obsoleted function is replaced with
ifnet::if_linkstate_hooks
|
|
|
|
|
|
|
|
|
|
agr(4) and lagg(4) can not be used on the same interface so that
if_agrprivate and if_lagg are not used at the same time.
For resolve this wasteful, if_lagg is used in not only lagg(4)
but also agr(4).
After this modification, if_lagg has 3 states:
1. if_lagg == NULL
- Both agr(4) and lagg(4) are not running on the interface
2. if_lagg != NULL && ifp->if_type != IFT_IEEE8023ADLAG
- agr(4) is running on the I/F
3. if_lagg != NULL && ifp->if_type == IFT_IEEE8023ADLAG
- lagg(4) is running on the I/F
|
|
|
|
|
|
|
|
suggested by Jared McNeill which sets if_stop to a stub function
which means that more than just the pmf is protected from the NULL call.
|
|
percpu_alloc can't fail.
Author: Maya Rashish <maya@NetBSD.org>
Committer: Taylor R Campbell <riastradh@NetBSD.org>
|
|
- FreeBSD's lagg(4) based implementation
- MP-safe and MP-scalable
|
|
This flag was only set for virtual interfaces.
All virtual interfaces have a means of knowing if they are going to work
or not and as such now support link state changes.
If we want this flag back, it should be used as an indicator that
the interfaces does not support link state changes that userland can use
so it can make a decision on what to do when the link state is UNKNOWN.
|
|
The exact flow is detatch addresses, join bridge and then mark detached
addresses as tentative.
This ensures that Duplicate Address Detection for the joining interface
are performed across all members of the bridge.
|
|
If any member is LINK_STATE_UP then it's LINK_STATE_UP.
Otherwise if any member is LINK_STATE_UNKNOWN then it's LINK_STATE_UNKNOWN.
Otherwise it's LINK_STATE_DOWN.
|
|
|
|
Link state changes are not dependant on the interface being up, but we also
need to guard against more link state changes being scheduled when the
interface is being detached.
We do this by clearing the link queue but keeping if_link_sheduled = true.
We can check for this in both if_link_state_change() and
if_link_state_change_work() to abort early as there is no point in doing
anything if the interface is being detached because if_down() is called
in if_detach() after the workqueue has been drained to the same overall
effect.
|