un-wanted route(4) messages.
Inspired by the ROUTE_MSGFILTER equivalent in OpenBSD,
but with an API which allows the full range of potential message types.
- Include "opt_*.h" only if _KERNEL_OPT is defined
- Allow encapinit to be called twice (by ifinit and ipe4_attach)
- ifinit didn't call encapinit if IPSEC is enabled (ipe4_attach called
it instead), however, on a rump kernel ipe4_attach may not be called
even if IPSEC is enabled. So we need to allow ifinit to call it anyway
- Setup sysctls in ipsec_attach explicitly instead of using SYSCTL_SETUP
- Call ip6flow_invalidate_all in key_spdadd only if in6_present
- It's possible that a rump kernel loads the ipsec library but not
the inet6 library
Unfortunately callers of ifp->if_ioctl (if_addr_init, if_flags_set
and if_mcast_op) may or may not hold if_ioctl_lock, so we have to
hold the lock only if it's not held.
It is protected by KERNEL_LOCK in soo_ioctl() between "ioctl destory" and
other ioctls. And, it is protected by encap_lock() between "ioctl destroy"
and Rx. However, it was not protected between "ioctl destroy" and Tx.
That is,
+ CPU#A
- do "ifconfig l2tpX destroy"
- call l2tp_clone_destroy()
- done l2tp_delete_tunnel()
+ CPU#B
- begin l2tp output processing
- call l2tp_transmit()
- done l2tp_getref_variant()
+ CPU#A
- done kmem_free(sc->l2tp_var, )
+ CPU#B
- access to sc->l2tp_var after free
pointed out by s-yamaguchi@IIJ, thanks.
This change needs a tweak in route_output_change to unbreak route
change commands (e.g., route change -inet6 default -reject).
PR kern/52077 (s-yamaguchi@IIJ and ozaki-r@)
For unknown reasons, IPv6 multicast addresses are linked to a first
IPv6 address assigned to an interface. Due to the design, when removing
a first address having multicast addresses, we need to save them to
somewhere and later restore them once a new IPv6 address is activated.
mkludge stuffs support the operations.
This change links multicast addresses to an interface directly and
throws the kludge away.
Note that as usual some obsolete member variables remain for kvm(3)
users. And also sysctl net.inet6.multicast_kludge remains to avoid
breaking old ifmcstat.
TODO: currently ifnet has a list of in6_multi but obviously the list
should be protocol independent. Provide a common structure (if_multi
or something) to handle in6_multi and in_multi together as well as
ifaddr does for in_ifaddr and in6_ifaddr.