ifnet: Properly protect if_multiaddrs using ifnet serializers
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Tue, 13 May 2014 13:59:18 +0000 (21:59 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 18 May 2014 08:22:03 +0000 (16:22 +0800)
commit72659ed0ae74f217471476f10385924812a91186
tree6ea805078c86db3f440fd111cde36c554dfb866b
parent8a3a1024a981313b605e4bddb8b46c6b8f00e0cd
ifnet: Properly protect if_multiaddrs using ifnet serializers

- Protect ifnet.if_multiaddrs using ifnet serializers.  Add some
  comment in the places, where only main serailizer is necessary.
- Fix if_delallmulti().  Using TAILQ_FOREACH_MUTABLE is incorrect for
  deleting an ifmultiaddr from ifnet.if_multiaddrs.  Since deleting one
  ifmultiaddr may cause additional ifmultiaddr deletion (e.g. the AF_LINK
  ifmultiaddr for AF_INET ifmultiaddr).
- Change IN_LOOKUP_MULTI and IN6_LOOKUP_MULTI macros into inline
  functions.
- Redispatch multicast IP packets to netisr0 for further processing.
  Software based IP packet hash function is changed.  And hash value
  fixup for multicast IP packets is added to the beginning of ip_input();
  this is mainly for IP packets, whose hash is calculated by hardware.
- For wlan's multicast hardware filter updating, we no longer need to
  release wlan serializer and mess up w/ the if_ioctl setting.

In netisr0, read and test ifma_refcount for AF_INET ifmultiaddr is MPSAFE
w/o ifnet serializers, since its ifma_refcount is only altered in netisr0.

In netisr0, any operation on in_multi, which is obtained from the
corresponding ifmuliaddr's ifma_protospec, is MPSAFE w/o ifnet
serializers, since ifmultiaddr for AF_INET is only set and cleared in
netisr0.

While I'm here also redispatch IP packets w/o hash to the proper netisrs,
on ip_input() path.  And unnecessary critical sections in
in_{add,del}multi() are removed.
19 files changed:
sys/net/if.c
sys/net/if_var.h
sys/net/vlan/if_vlan.c
sys/netinet/igmp.c
sys/netinet/in.c
sys/netinet/in_var.h
sys/netinet/ip_demux.c
sys/netinet/ip_input.c
sys/netinet/ip_output.c
sys/netinet6/in6.c
sys/netinet6/in6_ifattach.c
sys/netinet6/in6_var.h
sys/netinet6/ip6_mroute.c
sys/netinet6/ip6_output.c
sys/netinet6/mld6.c
sys/netinet6/nd6.c
sys/netproto/802_11/wlan/ieee80211_ioctl.c
sys/netproto/ipsec/key.c
sys/netproto/key/key.c