diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-03-29 17:18:49 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-03-29 17:18:49 -0500 |
commit | e02a4cabfcb9a999b74a2e2e6f13ffcb7ff2d606 (patch) | |
tree | 2f3db60be4c57eca2a4c3ab3f3122dcf1ec0c624 /net | |
parent | 600511e86babe3727264a0883a3a264f6fb6caf5 (diff) | |
parent | f3cab8a0b1a772dc8b055b7affa567a366627c9e (diff) | |
download | op-kernel-dev-e02a4cabfcb9a999b74a2e2e6f13ffcb7ff2d606.zip op-kernel-dev-e02a4cabfcb9a999b74a2e2e6f13ffcb7ff2d606.tar.gz |
Merge branch 'master'
Diffstat (limited to 'net')
182 files changed, 2026 insertions, 1244 deletions
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 697ac55e..7b1eb9a 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -1819,6 +1819,22 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) return rc; } + +#ifdef CONFIG_COMPAT +static int atalk_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) +{ + /* + * All Appletalk ioctls except SIOCATALKDIFADDR are standard. And + * SIOCATALKDIFADDR is handled by upper layer as well, so there is + * nothing to do. Eventually SIOCATALKDIFADDR should be moved + * here so there is no generic SIOCPROTOPRIVATE translation in the + * system. + */ + return -ENOIOCTLCMD; +} +#endif + + static struct net_proto_family atalk_family_ops = { .family = PF_APPLETALK, .create = atalk_create, @@ -1836,6 +1852,9 @@ static const struct proto_ops SOCKOPS_WRAPPED(atalk_dgram_ops) = { .getname = atalk_getname, .poll = datagram_poll, .ioctl = atalk_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = atalk_compat_ioctl, +#endif .listen = sock_no_listen, .shutdown = sock_no_shutdown, .setsockopt = sock_no_setsockopt, diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index fb031fe..469eda0 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -238,6 +238,9 @@ unsigned int bt_sock_poll(struct file * file, struct socket *sock, poll_table *w if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) mask |= POLLERR; + if (sk->sk_shutdown & RCV_SHUTDOWN) + mask |= POLLRDHUP; + if (sk->sk_shutdown == SHUTDOWN_MASK) mask |= POLLHUP; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 9106354..a49a697 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -73,23 +73,23 @@ DEFINE_RWLOCK(hci_cb_list_lock); struct hci_proto *hci_proto[HCI_MAX_PROTO]; /* HCI notifiers list */ -static struct notifier_block *hci_notifier; +static ATOMIC_NOTIFIER_HEAD(hci_notifier); /* ---- HCI notifications ---- */ int hci_register_notifier(struct notifier_block *nb) { - return notifier_chain_register(&hci_notifier, nb); + return atomic_notifier_chain_register(&hci_notifier, nb); } int hci_unregister_notifier(struct notifier_block *nb) { - return notifier_chain_unregister(&hci_notifier, nb); + return atomic_notifier_chain_unregister(&hci_notifier, nb); } static void hci_notify(struct hci_dev *hdev, int event) { - notifier_call_chain(&hci_notifier, event, hdev); + atomic_notifier_call_chain(&hci_notifier, event, hdev); } /* ---- HCI requests ---- */ diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c index 8934a54..a7ba0cc 100644 --- a/net/bridge/br_stp_bpdu.c +++ b/net/bridge/br_stp_bpdu.c @@ -19,6 +19,7 @@ #include <linux/llc.h> #include <net/llc.h> #include <net/llc_pdu.h> +#include <asm/unaligned.h> #include "br_private.h" #include "br_private_stp.h" @@ -59,12 +60,12 @@ static inline void br_set_ticks(unsigned char *dest, int j) { unsigned long ticks = (STP_HZ * j)/ HZ; - *((__be16 *) dest) = htons(ticks); + put_unaligned(htons(ticks), (__be16 *)dest); } static inline int br_get_ticks(const unsigned char *src) { - unsigned long ticks = ntohs(*(__be16 *)src); + unsigned long ticks = ntohs(get_unaligned((__be16 *)src)); return (ticks * HZ + STP_HZ - 1) / STP_HZ; } diff --git a/net/bridge/netfilter/ebt_802_3.c b/net/bridge/netfilter/ebt_802_3.c index 468ebdf..d42f63f 100644 --- a/net/bridge/netfilter/ebt_802_3.c +++ b/net/bridge/netfilter/ebt_802_3.c @@ -58,16 +58,16 @@ static struct ebt_match filter_802_3 = .me = THIS_MODULE, }; -static int __init init(void) +static int __init ebt_802_3_init(void) { return ebt_register_match(&filter_802_3); } -static void __exit fini(void) +static void __exit ebt_802_3_fini(void) { ebt_unregister_match(&filter_802_3); } -module_init(init); -module_exit(fini); +module_init(ebt_802_3_init); +module_exit(ebt_802_3_fini); MODULE_LICENSE("GPL"); diff --git a/net/bridge/netfilter/ebt_among.c b/net/bridge/netfilter/ebt_among.c index 5a1f5e3..a614485 100644 --- a/net/bridge/netfilter/ebt_among.c +++ b/net/bridge/netfilter/ebt_among.c @@ -213,16 +213,16 @@ static struct ebt_match filter_among = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ebt_among_init(void) { return ebt_register_match(&filter_among); } -static void __exit fini(void) +static void __exit ebt_among_fini(void) { ebt_unregister_match(&filter_among); } -module_init(init); -module_exit(fini); +module_init(ebt_among_init); +module_exit(ebt_among_fini); MODULE_LICENSE("GPL"); diff --git a/net/bridge/netfilter/ebt_arp.c b/net/bridge/netfilter/ebt_arp.c index b94c48c..a6c81d9 100644 --- a/net/bridge/netfilter/ebt_arp.c +++ b/net/bridge/netfilter/ebt_arp.c @@ -125,16 +125,16 @@ static struct ebt_match filter_arp = .me = THIS_MODULE, }; -static int __init init(void) +static int __init ebt_arp_init(void) { return ebt_register_match(&filter_arp); } -static void __exit fini(void) +static void __exit ebt_arp_fini(void) { ebt_unregister_match(&filter_arp); } -module_init(init); -module_exit(fini); +module_init(ebt_arp_init); +module_exit(ebt_arp_fini); MODULE_LICENSE("GPL"); diff --git a/net/bridge/netfilter/ebt_arpreply.c b/net/bridge/netfilter/ebt_arpreply.c index b934de9..d19fc4b 100644 --- a/net/bridge/netfilter/ebt_arpreply.c +++ b/net/bridge/netfilter/ebt_arpreply.c @@ -82,16 +82,16 @@ static struct ebt_target reply_target = .me = THIS_MODULE, }; -static int __init init(void) +static int __init ebt_arpreply_init(void) { return ebt_register_target(&reply_target); } -static void __exit fini(void) +static void __exit ebt_arpreply_fini(void) { ebt_unregister_target(&reply_target); } -module_init(init); -module_exit(fini); +module_init(ebt_arpreply_init); +module_exit(ebt_arpreply_fini); MODULE_LICENSE("GPL"); diff --git a/net/bridge/netfilter/ebt_dnat.c b/net/bridge/netfilter/ebt_dnat.c index f546308..4582659 100644 --- a/net/bridge/netfilter/ebt_dnat.c +++ b/net/bridge/netfilter/ebt_dnat.c @@ -61,16 +61,16 @@ static struct ebt_target dnat = .me = THIS_MODULE, }; -static int __init init(void) +static int __init ebt_dnat_init(void) { return ebt_register_target(&dnat); } -static void __exit fini(void) +static void __exit ebt_dnat_fini(void) { ebt_unregister_target(&dnat); } -module_init(init); -module_exit(fini); +module_init(ebt_dnat_init); +module_exit(ebt_dnat_fini); MODULE_LICENSE("GPL"); diff --git a/net/bridge/netfilter/ebt_ip.c b/net/bridge/netfilter/ebt_ip.c index dc5d0b2..65b665c 100644 --- a/net/bridge/netfilter/ebt_ip.c +++ b/net/bridge/netfilter/ebt_ip.c @@ -112,16 +112,16 @@ static struct ebt_match filter_ip = .me = THIS_MODULE, }; -static int __init init(void) +static int __init ebt_ip_init(void) { return ebt_register_match(&filter_ip); } -static void __exit fini(void) +static void __exit ebt_ip_fini(void) { ebt_unregister_match(&filter_ip); } -module_init(init); -module_exit(fini); +module_init(ebt_ip_init); +module_exit(ebt_ip_fini); MODULE_LICENSE("GPL"); diff --git a/net/bridge/netfilter/ebt_limit.c b/net/bridge/netfilter/ebt_limit.c index 637c884..d48fa5c 100644 --- a/net/bridge/netfilter/ebt_limit.c +++ b/net/bridge/netfilter/ebt_limit.c @@ -98,16 +98,16 @@ static struct ebt_match ebt_limit_reg = .me = THIS_MODULE, }; -static int __init init(void) +static int __init ebt_limit_init(void) { return ebt_register_match(&ebt_limit_reg); } -static void __exit fini(void) +static void __exit ebt_limit_fini(void) { ebt_unregister_match(&ebt_limit_reg); } -module_init(init); -module_exit(fini); +module_init(ebt_limit_init); +module_exit(ebt_limit_fini); MODULE_LICENSE("GPL"); diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c index 288ff1d..d159c92 100644 --- a/net/bridge/netfilter/ebt_log.c +++ b/net/bridge/netfilter/ebt_log.c @@ -188,7 +188,7 @@ static struct nf_logger ebt_log_logger = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ebt_log_init(void) { int ret; @@ -205,12 +205,12 @@ static int __init init(void) return 0; } -static void __exit fini(void) +static void __exit ebt_log_fini(void) { nf_log_unregister_logger(&ebt_log_logger); ebt_unregister_watcher(&log); } -module_init(init); -module_exit(fini); +module_init(ebt_log_init); +module_exit(ebt_log_fini); MODULE_LICENSE("GPL"); diff --git a/net/bridge/netfilter/ebt_mark.c b/net/bridge/netfilter/ebt_mark.c index c93d35a..770c0df 100644 --- a/net/bridge/netfilter/ebt_mark.c +++ b/net/bridge/netfilter/ebt_mark.c @@ -52,16 +52,16 @@ static struct ebt_target mark_target = .me = THIS_MODULE, }; -static int __init init(void) +static int __init ebt_mark_init(void) { return ebt_register_target(&mark_target); } -static void __exit fini(void) +static void __exit ebt_mark_fini(void) { ebt_unregister_target(&mark_target); } -module_init(init); -module_exit(fini); +module_init(ebt_mark_init); +module_exit(ebt_mark_fini); MODULE_LICENSE("GPL"); diff --git a/net/bridge/netfilter/ebt_mark_m.c b/net/bridge/netfilter/ebt_mark_m.c index 625102d..a6413e4 100644 --- a/net/bridge/netfilter/ebt_mark_m.c +++ b/net/bridge/netfilter/ebt_mark_m.c @@ -47,16 +47,16 @@ static struct ebt_match filter_mark = .me = THIS_MODULE, }; -static int __init init(void) +static int __init ebt_mark_m_init(void) { return ebt_register_match(&filter_mark); } -static void __exit fini(void) +static void __exit ebt_mark_m_fini(void) { ebt_unregister_match(&filter_mark); } -module_init(init); -module_exit(fini); +module_init(ebt_mark_m_init); +module_exit(ebt_mark_m_fini); MODULE_LICENSE("GPL"); diff --git a/net/bridge/netfilter/ebt_pkttype.c b/net/bridge/netfilter/ebt_pkttype.c index ecd3b42..4fffd70 100644 --- a/net/bridge/netfilter/ebt_pkttype.c +++ b/net/bridge/netfilter/ebt_pkttype.c @@ -44,16 +44,16 @@ static struct ebt_match filter_pkttype = .me = THIS_MODULE, }; -static int __init init(void) +static int __init ebt_pkttype_init(void) { return ebt_register_match(&filter_pkttype); } -static void __exit fini(void) +static void __exit ebt_pkttype_fini(void) { ebt_unregister_match(&filter_pkttype); } -module_init(init); -module_exit(fini); +module_init(ebt_pkttype_init); +module_exit(ebt_pkttype_fini); MODULE_LICENSE("GPL"); diff --git a/net/bridge/netfilter/ebt_redirect.c b/net/bridge/netfilter/ebt_redirect.c index 1538b43..9f378ea 100644 --- a/net/bridge/netfilter/ebt_redirect.c +++ b/net/bridge/netfilter/ebt_redirect.c @@ -66,16 +66,16 @@ static struct ebt_target redirect_target = .me = THIS_MODULE, }; -static int __init init(void) +static int __init ebt_redirect_init(void) { return ebt_register_target(&redirect_target); } -static void __exit fini(void) +static void __exit ebt_redirect_fini(void) { ebt_unregister_target(&redirect_target); } -module_init(init); -module_exit(fini); +module_init(ebt_redirect_init); +module_exit(ebt_redirect_fini); MODULE_LICENSE("GPL"); diff --git a/net/bridge/netfilter/ebt_snat.c b/net/bridge/netfilter/ebt_snat.c index 1529bdc..cbb33e2 100644 --- a/net/bridge/netfilter/ebt_snat.c +++ b/net/bridge/netfilter/ebt_snat.c @@ -61,16 +61,16 @@ static struct ebt_target snat = .me = THIS_MODULE, }; -static int __init init(void) +static int __init ebt_snat_init(void) { return ebt_register_target(&snat); } -static void __exit fini(void) +static void __exit ebt_snat_fini(void) { ebt_unregister_target(&snat); } -module_init(init); -module_exit(fini); +module_init(ebt_snat_init); +module_exit(ebt_snat_fini); MODULE_LICENSE("GPL"); diff --git a/net/bridge/netfilter/ebt_stp.c b/net/bridge/netfilter/ebt_stp.c index 0248c67..a0bed82 100644 --- a/net/bridge/netfilter/ebt_stp.c +++ b/net/bridge/netfilter/ebt_stp.c @@ -180,16 +180,16 @@ static struct ebt_match filter_stp = .me = THIS_MODULE, }; -static int __init init(void) +static int __init ebt_stp_init(void) { return ebt_register_match(&filter_stp); } -static void __exit fini(void) +static void __exit ebt_stp_fini(void) { ebt_unregister_match(&filter_stp); } -module_init(init); -module_exit(fini); +module_init(ebt_stp_init); +module_exit(ebt_stp_fini); MODULE_LICENSE("GPL"); diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c index 802baf7..ee5a517 100644 --- a/net/bridge/netfilter/ebt_ulog.c +++ b/net/bridge/netfilter/ebt_ulog.c @@ -281,7 +281,7 @@ static struct nf_logger ebt_ulog_logger = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ebt_ulog_init(void) { int i, ret = 0; @@ -316,7 +316,7 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit ebt_ulog_fini(void) { ebt_ulog_buff_t *ub; int i; @@ -337,8 +337,8 @@ static void __exit fini(void) sock_release(ebtulognl->sk_socket); } -module_init(init); -module_exit(fini); +module_init(ebt_ulog_init); +module_exit(ebt_ulog_fini); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>"); MODULE_DESCRIPTION("ebtables userspace logging module for bridged Ethernet" diff --git a/net/bridge/netfilter/ebt_vlan.c b/net/bridge/netfilter/ebt_vlan.c index db60d73..a2b4528 100644 --- a/net/bridge/netfilter/ebt_vlan.c +++ b/net/bridge/netfilter/ebt_vlan.c @@ -178,7 +178,7 @@ static struct ebt_match filter_vlan = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ebt_vlan_init(void) { DEBUG_MSG("ebtables 802.1Q extension module v" MODULE_VERS "\n"); @@ -186,10 +186,10 @@ static int __init init(void) return ebt_register_match(&filter_vlan); } -static void __exit fini(void) +static void __exit ebt_vlan_fini(void) { ebt_unregister_match(&filter_vlan); } -module_init(init); -module_exit(fini); +module_init(ebt_vlan_init); +module_exit(ebt_vlan_fini); diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c index 1767c94..9a6e548 100644 --- a/net/bridge/netfilter/ebtable_broute.c +++ b/net/bridge/netfilter/ebtable_broute.c @@ -62,7 +62,7 @@ static int ebt_broute(struct sk_buff **pskb) return 0; /* bridge it */ } -static int __init init(void) +static int __init ebtable_broute_init(void) { int ret; @@ -74,13 +74,13 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit ebtable_broute_fini(void) { br_should_route_hook = NULL; synchronize_net(); ebt_unregister_table(&broute_table); } -module_init(init); -module_exit(fini); +module_init(ebtable_broute_init); +module_exit(ebtable_broute_fini); MODULE_LICENSE("GPL"); diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c index c18666e..3d5bd44 100644 --- a/net/bridge/netfilter/ebtable_filter.c +++ b/net/bridge/netfilter/ebtable_filter.c @@ -91,7 +91,7 @@ static struct nf_hook_ops ebt_ops_filter[] = { }, }; -static int __init init(void) +static int __init ebtable_filter_init(void) { int i, j, ret; @@ -109,7 +109,7 @@ cleanup: return ret; } -static void __exit fini(void) +static void __exit ebtable_filter_fini(void) { int i; @@ -118,6 +118,6 @@ static void __exit fini(void) ebt_unregister_table(&frame_filter); } -module_init(init); -module_exit(fini); +module_init(ebtable_filter_init); +module_exit(ebtable_filter_fini); MODULE_LICENSE("GPL"); diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c index 828cac2..04dd42e 100644 --- a/net/bridge/netfilter/ebtable_nat.c +++ b/net/bridge/netfilter/ebtable_nat.c @@ -98,7 +98,7 @@ static struct nf_hook_ops ebt_ops_nat[] = { }, }; -static int __init init(void) +static int __init ebtable_nat_init(void) { int i, ret, j; @@ -116,7 +116,7 @@ cleanup: return ret; } -static void __exit fini(void) +static void __exit ebtable_nat_fini(void) { int i; @@ -125,6 +125,6 @@ static void __exit fini(void) ebt_unregister_table(&frame_nat); } -module_init(init); -module_exit(fini); +module_init(ebtable_nat_init); +module_exit(ebtable_nat_fini); MODULE_LICENSE("GPL"); diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 9979533..01eae97 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -1487,7 +1487,7 @@ static struct nf_sockopt_ops ebt_sockopts = .get = do_ebt_get_ctl, }; -static int __init init(void) +static int __init ebtables_init(void) { int ret; @@ -1501,7 +1501,7 @@ static int __init init(void) return 0; } -static void __exit fini(void) +static void __exit ebtables_fini(void) { nf_unregister_sockopt(&ebt_sockopts); printk(KERN_NOTICE "Ebtables v2.0 unregistered\n"); @@ -1516,6 +1516,6 @@ EXPORT_SYMBOL(ebt_unregister_watcher); EXPORT_SYMBOL(ebt_register_target); EXPORT_SYMBOL(ebt_unregister_target); EXPORT_SYMBOL(ebt_do_table); -module_init(init); -module_exit(fini); +module_init(ebtables_init); +module_exit(ebtables_fini); MODULE_LICENSE("GPL"); diff --git a/net/core/datagram.c b/net/core/datagram.c index b8ce6bf..aecddcc 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -500,6 +500,8 @@ unsigned int datagram_poll(struct file *file, struct socket *sock, /* exceptional events? */ if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) mask |= POLLERR; + if (sk->sk_shutdown & RCV_SHUTDOWN) + mask |= POLLRDHUP; if (sk->sk_shutdown == SHUTDOWN_MASK) mask |= POLLHUP; diff --git a/net/core/dev.c b/net/core/dev.c index 08dec6e..a3ab11f 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -114,6 +114,7 @@ #include <linux/wireless.h> #include <net/iw_handler.h> #include <asm/current.h> +#include <linux/audit.h> /* * The list of packet types we will receive (as opposed to discard) @@ -192,7 +193,7 @@ static inline struct hlist_head *dev_index_hash(int ifindex) * Our notifier list */ -static struct notifier_block *netdev_chain; +static BLOCKING_NOTIFIER_HEAD(netdev_chain); /* * Device drivers call our routines to queue packets here. We empty the @@ -735,7 +736,8 @@ int dev_change_name(struct net_device *dev, char *newname) if (!err) { hlist_del(&dev->name_hlist); hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name)); - notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev); + blocking_notifier_call_chain(&netdev_chain, + NETDEV_CHANGENAME, dev); } return err; @@ -749,7 +751,7 @@ int dev_change_name(struct net_device *dev, char *newname) */ void netdev_features_change(struct net_device *dev) { - notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev); + blocking_notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev); } EXPORT_SYMBOL(netdev_features_change); @@ -764,7 +766,8 @@ EXPORT_SYMBOL(netdev_features_change); void netdev_state_change(struct net_device *dev) { if (dev->flags & IFF_UP) { - notifier_call_chain(&netdev_chain, NETDEV_CHANGE, dev); + blocking_notifier_call_chain(&netdev_chain, + NETDEV_CHANGE, dev); rtmsg_ifinfo(RTM_NEWLINK, dev, 0); } } @@ -861,7 +864,7 @@ int dev_open(struct net_device *dev) /* * ... and announce new interface. */ - notifier_call_chain(&netdev_chain, NETDEV_UP, dev); + blocking_notifier_call_chain(&netdev_chain, NETDEV_UP, dev); } return ret; } @@ -884,7 +887,7 @@ int dev_close(struct net_device *dev) * Tell people we are going down, so that they can * prepare to death, when device is still operating. */ - notifier_call_chain(&netdev_chain, NETDEV_GOING_DOWN, dev); + blocking_notifier_call_chain(&netdev_chain, NETDEV_GOING_DOWN, dev); dev_deactivate(dev); @@ -921,7 +924,7 @@ int dev_close(struct net_device *dev) /* * Tell people we are down */ - notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev); + blocking_notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev); return 0; } @@ -952,7 +955,7 @@ int register_netdevice_notifier(struct notifier_block *nb) int err; rtnl_lock(); - err = notifier_chain_register(&netdev_chain, nb); + err = blocking_notifier_chain_register(&netdev_chain, nb); if (!err) { for (dev = dev_base; dev; dev = dev->next) { nb->notifier_call(nb, NETDEV_REGISTER, dev); @@ -977,7 +980,12 @@ int register_netdevice_notifier(struct notifier_block *nb) int unregister_netdevice_notifier(struct notifier_block *nb) { - return notifier_chain_unregister(&netdev_chain, nb); + int err; + + rtnl_lock(); + err = blocking_notifier_chain_unregister(&netdev_chain, nb); + rtnl_unlock(); + return err; } /** @@ -986,12 +994,12 @@ int unregister_netdevice_notifier(struct notifier_block *nb) * @v: pointer passed unmodified to notifier function * * Call all network notifier blocks. Parameters and return value - * are as for notifier_call_chain(). + * are as for blocking_notifier_call_chain(). */ int call_netdevice_notifiers(unsigned long val, void *v) { - return notifier_call_chain(&netdev_chain, val, v); + return blocking_notifier_call_chain(&netdev_chain, val, v); } /* When > 0 there are consumers of rx skb time stamps */ @@ -2142,6 +2150,12 @@ void dev_set_promiscuity(struct net_device *dev, int inc) printk(KERN_INFO "device %s %s promiscuous mode\n", dev->name, (dev->flags & IFF_PROMISC) ? "entered" : "left"); + audit_log(current->audit_context, GFP_ATOMIC, + AUDIT_ANOM_PROMISCUOUS, + "dev=%s prom=%d old_prom=%d auid=%u", + dev->name, (dev->flags & IFF_PROMISC), + (old_flags & IFF_PROMISC), + audit_get_loginuid(current->audit_context)); } } @@ -2230,7 +2244,8 @@ int dev_change_flags(struct net_device *dev, unsigned flags) if (dev->flags & IFF_UP && ((old_flags ^ dev->flags) &~ (IFF_UP | IFF_PROMISC | IFF_ALLMULTI | IFF_VOLATILE))) - notifier_call_chain(&netdev_chain, NETDEV_CHANGE, dev); + blocking_notifier_call_chain(&netdev_chain, + NETDEV_CHANGE, dev); if ((flags ^ dev->gflags) & IFF_PROMISC) { int inc = (flags & IFF_PROMISC) ? +1 : -1; @@ -2274,8 +2289,8 @@ int dev_set_mtu(struct net_device *dev, int new_mtu) else dev->mtu = new_mtu; if (!err && dev->flags & IFF_UP) - notifier_call_chain(&netdev_chain, - NETDEV_CHANGEMTU, dev); + blocking_notifier_call_chain(&netdev_chain, + NETDEV_CHANGEMTU, dev); return err; } @@ -2291,7 +2306,8 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa) return -ENODEV; err = dev->set_mac_address(dev, sa); if (!err) - notifier_call_chain(&netdev_chain, NETDEV_CHANGEADDR, dev); + blocking_notifier_call_chain(&netdev_chain, + NETDEV_CHANGEADDR, dev); return err; } @@ -2347,7 +2363,7 @@ static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd) return -EINVAL; memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data, min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len)); - notifier_call_chain(&netdev_chain, + blocking_notifier_call_chain(&netdev_chain, NETDEV_CHANGEADDR, dev); return 0; @@ -2801,7 +2817,7 @@ int register_netdevice(struct net_device *dev) write_unlock_bh(&dev_base_lock); /* Notify protocols, that a new device appeared. */ - notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev); + blocking_notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev); /* Finish registration after unlock */ net_set_todo(dev); @@ -2880,7 +2896,7 @@ static void netdev_wait_allrefs(struct net_device *dev) rtnl_lock(); /* Rebroadcast unregister notification */ - notifier_call_chain(&netdev_chain, + blocking_notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev); if (test_bit(__LINK_STATE_LINKWATCH_PENDING, @@ -3136,7 +3152,7 @@ int unregister_netdevice(struct net_device *dev) /* Notify protocols, that we are about to destroy this device. They should clean all the things. */ - notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev); + blocking_notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev); /* * Flush the multicast chain diff --git a/net/core/request_sock.c b/net/core/request_sock.c index 98f0fc9..1e44eda 100644 --- a/net/core/request_sock.c +++ b/net/core/request_sock.c @@ -51,7 +51,7 @@ int reqsk_queue_alloc(struct request_sock_queue *queue, get_random_bytes(&lopt->hash_rnd, sizeof(lopt->hash_rnd)); rwlock_init(&queue->syn_wait_lock); - queue->rskq_accept_head = queue->rskq_accept_head = NULL; + queue->rskq_accept_head = NULL; lopt->nr_table_entries = nr_table_entries; write_lock_bh(&queue->syn_wait_lock); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index c9f8784..09464fa 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -149,7 +149,7 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, /* Get the DATA. Size must match skb_add_mtu(). */ size = SKB_DATA_ALIGN(size); - data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask); + data = ____kmalloc(size + sizeof(struct skb_shared_info), gfp_mask); if (!data) goto nodata; diff --git a/net/core/sock.c b/net/core/sock.c index 1a7e6ea..a96ea7d 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -187,6 +187,99 @@ static void sock_disable_timestamp(struct sock *sk) } +int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) +{ + int err = 0; + int skb_len; + + /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces + number of warnings when compiling with -W --ANK + */ + if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= + (unsigned)sk->sk_rcvbuf) { + err = -ENOMEM; + goto out; + } + + /* It would be deadlock, if sock_queue_rcv_skb is used + with socket lock! We assume that users of this + function are lock free. + */ + err = sk_filter(sk, skb, 1); + if (err) + goto out; + + skb->dev = NULL; + skb_set_owner_r(skb, sk); + + /* Cache the SKB length before we tack it onto the receive + * queue. Once it is added it no longer belongs to us and + * may be freed by other threads of control pulling packets + * from the queue. + */ + skb_len = skb->len; + + skb_queue_tail(&sk->sk_receive_queue, skb); + + if (!sock_flag(sk, SOCK_DEAD)) + sk->sk_data_ready(sk, skb_len); +out: + return err; +} +EXPORT_SYMBOL(sock_queue_rcv_skb); + +int sk_receive_skb(struct sock *sk, struct sk_buff *skb) +{ + int rc = NET_RX_SUCCESS; + + if (sk_filter(sk, skb, 0)) + goto discard_and_relse; + + skb->dev = NULL; + + bh_lock_sock(sk); + if (!sock_owned_by_user(sk)) + rc = sk->sk_backlog_rcv(sk, skb); + else + sk_add_backlog(sk, skb); + bh_unlock_sock(sk); +out: + sock_put(sk); + return rc; +discard_and_relse: + kfree_skb(skb); + goto out; +} +EXPORT_SYMBOL(sk_receive_skb); + +struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie) +{ + struct dst_entry *dst = sk->sk_dst_cache; + + if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) { + sk->sk_dst_cache = NULL; + dst_release(dst); + return NULL; + } + + return dst; +} +EXPORT_SYMBOL(__sk_dst_check); + +struct dst_entry *sk_dst_check(struct sock *sk, u32 cookie) +{ + struct dst_entry *dst = sk_dst_get(sk); + + if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) { + sk_dst_reset(sk); + dst_release(dst); + return NULL; + } + + return dst; +} +EXPORT_SYMBOL(sk_dst_check); + /* * This is meant for all protocols to use and covers goings on * at the socket level. Everything here is generic. @@ -404,8 +497,9 @@ set_rcvbuf: if (!valbool) { sk->sk_bound_dev_if = 0; } else { - if (optlen > IFNAMSIZ) - optlen = IFNAMSIZ; + if (optlen > IFNAMSIZ - 1) + optlen = IFNAMSIZ - 1; + memset(devname, 0, sizeof(devname)); if (copy_from_user(devname, optval, optlen)) { ret = -EFAULT; break; diff --git a/net/dccp/proto.c b/net/dccp/proto.c index d4b293e..1ff7328 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c @@ -350,7 +350,7 @@ unsigned int dccp_poll(struct file *file, struct socket *sock, if (sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == DCCP_CLOSED) mask |= POLLHUP; if (sk->sk_shutdown & RCV_SHUTDOWN) - mask |= POLLIN | POLLRDNORM; + mask |= POLLIN | POLLRDNORM | POLLRDHUP; /* Connected? */ if ((1 << sk->sk_state) & ~(DCCPF_REQUESTING | DCCPF_RESPOND)) { diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index cc7b9d9..d2ae989 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c @@ -68,7 +68,7 @@ __le16 decnet_address = 0; static DEFINE_RWLOCK(dndev_lock); static struct net_device *decnet_default_device; -static struct notifier_block *dnaddr_chain; +static BLOCKING_NOTIFIER_HEAD(dnaddr_chain); static struct dn_dev *dn_dev_create(struct net_device *dev, int *err); static void dn_dev_delete(struct net_device *dev); @@ -446,7 +446,7 @@ static void dn_dev_del_ifa(struct dn_dev *dn_db, struct dn_ifaddr **ifap, int de } rtmsg_ifa(RTM_DELADDR, ifa1); - notifier_call_chain(&dnaddr_chain, NETDEV_DOWN, ifa1); + blocking_notifier_call_chain(&dnaddr_chain, NETDEV_DOWN, ifa1); if (destroy) { dn_dev_free_ifa(ifa1); @@ -481,7 +481,7 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa) dn_db->ifa_list = ifa; rtmsg_ifa(RTM_NEWADDR, ifa); - notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa); + blocking_notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa); return 0; } @@ -1285,12 +1285,12 @@ void dn_dev_devices_on(void) int register_dnaddr_notifier(struct notifier_block *nb) { - return notifier_chain_register(&dnaddr_chain, nb); + return blocking_notifier_chain_register(&dnaddr_chain, nb); } int unregister_dnaddr_notifier(struct notifier_block *nb) { - return notifier_chain_unregister(&dnaddr_chain, nb); + return blocking_notifier_chain_unregister(&dnaddr_chain, nb); } #ifdef CONFIG_PROC_FS diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c index 16a5a31..74133ec 100644 --- a/net/decnet/netfilter/dn_rtmsg.c +++ b/net/decnet/netfilter/dn_rtmsg.c @@ -133,7 +133,7 @@ static struct nf_hook_ops dnrmg_ops = { .priority = NF_DN_PRI_DNRTMSG, }; -static int __init init(void) +static int __init dn_rtmsg_init(void) { int rv = 0; @@ -152,7 +152,7 @@ static int __init init(void) return rv; } -static void __exit fini(void) +static void __exit dn_rtmsg_fini(void) { nf_unregister_hook(&dnrmg_ops); sock_release(dnrmg->sk_socket); @@ -164,6 +164,6 @@ MODULE_AUTHOR("Steven Whitehouse <steve@chygwyn.com>"); MODULE_LICENSE("GPL"); MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_DNRTMSG); -module_init(init); -module_exit(fini); +module_init(dn_rtmsg_init); +module_exit(dn_rtmsg_fini); diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index c792994..8682656 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c @@ -42,6 +42,7 @@ #include <linux/spinlock.h> #include <linux/rcupdate.h> #include <linux/bitops.h> +#include <linux/mutex.h> #include <asm/uaccess.h> #include <asm/system.h> @@ -49,6 +50,7 @@ static const struct proto_ops econet_ops; static struct hlist_head econet_sklist; static DEFINE_RWLOCK(econet_lock); +static DEFINE_MUTEX(econet_mutex); /* Since there are only 256 possible network numbers (or fewer, depends how you count) it makes sense to use a simple lookup table. */ @@ -124,6 +126,8 @@ static int econet_recvmsg(struct kiocb *iocb, struct socket *sock, msg->msg_namelen = sizeof(struct sockaddr_ec); + mutex_lock(&econet_mutex); + /* * Call the generic datagram receiver. This handles all sorts * of horrible races and re-entrancy so we can forget about it @@ -174,6 +178,7 @@ static int econet_recvmsg(struct kiocb *iocb, struct socket *sock, out_free: skb_free_datagram(sk, skb); out: + mutex_unlock(&econet_mutex); return err; } @@ -184,8 +189,8 @@ out: static int econet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) { struct sockaddr_ec *sec = (struct sockaddr_ec *)uaddr; - struct sock *sk=sock->sk; - struct econet_sock *eo = ec_sk(sk); + struct sock *sk; + struct econet_sock *eo; /* * Check legality @@ -195,11 +200,18 @@ static int econet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len sec->sec_family != AF_ECONET) return -EINVAL; + mutex_lock(&econet_mutex); + + sk = sock->sk; + eo = ec_sk(sk); + eo->cb = sec->cb; eo->port = sec->port; eo->station = sec->addr.station; eo->net = sec->addr.net; + mutex_unlock(&econet_mutex); + return 0; } @@ -284,6 +296,8 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, * Get and verify the address. */ + mutex_lock(&econet_mutex); + if (saddr == NULL) { struct econet_sock *eo = ec_sk(sk); @@ -292,8 +306,10 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, port = eo->port; cb = eo->cb; } else { - if (msg->msg_namelen < sizeof(struct sockaddr_ec)) + if (msg->msg_namelen < sizeof(struct sockaddr_ec)) { + mutex_unlock(&econet_mutex); return -EINVAL; + } addr.station = saddr->addr.station; addr.net = saddr->addr.net; port = saddr->port; @@ -304,19 +320,21 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, dev = net2dev_map[addr.net]; /* If not directly reachable, use some default */ - if (dev == NULL) - { + if (dev == NULL) { dev = net2dev_map[0]; /* No interfaces at all? */ - if (dev == NULL) + if (dev == NULL) { + mutex_unlock(&econet_mutex); return -ENETDOWN; + } } - if (len + 15 > dev->mtu) + if (len + 15 > dev->mtu) { + mutex_unlock(&econet_mutex); return -EMSGSIZE; + } - if (dev->type == ARPHRD_ECONET) - { + if (dev->type == ARPHRD_ECONET) { /* Real hardware Econet. We're not worthy etc. */ #ifdef CONFIG_ECONET_NATIVE unsigned short proto = 0; @@ -374,6 +392,7 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, dev_queue_xmit(skb); dev_put(dev); + mutex_unlock(&econet_mutex); return(len); out_free: @@ -384,14 +403,18 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, #else err = -EPROTOTYPE; #endif + mutex_unlock(&econet_mutex); + return err; } #ifdef CONFIG_ECONET_AUNUDP /* AUN virtual Econet. */ - if (udpsock == NULL) + if (udpsock == NULL) { + mutex_unlock(&econet_mutex); return -ENETDOWN; /* No socket - can't send */ + } /* Make up a UDP datagram and hand it off to some higher intellect. */ @@ -438,8 +461,10 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, void __user *base = msg->msg_iov[i].iov_base; size_t len = msg->msg_iov[i].iov_len; /* Check it now since we switch to KERNEL_DS later. */ - if (!access_ok(VERIFY_READ, base, len)) + if (!access_ok(VERIFY_READ, base, len)) { + mutex_unlock(&econet_mutex); return -EFAULT; + } iov[i+1].iov_base = base; iov[i+1].iov_len = len; size += len; @@ -447,8 +472,11 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, /* Get a skbuff (no data, just holds our cb information) */ if ((skb = sock_alloc_send_skb(sk, 0, - msg->msg_flags & MSG_DONTWAIT, &err)) == NULL) + msg->msg_flags & MSG_DONTWAIT, + &err)) == NULL) { + mutex_unlock(&econet_mutex); return err; + } eb = (struct ec_cb *)&skb->cb; @@ -475,6 +503,8 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, #else err = -EPROTOTYPE; #endif + mutex_unlock(&econet_mutex); + return err; } @@ -485,18 +515,25 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, static int econet_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer) { - struct sock *sk = sock->sk; - struct econet_sock *eo = ec_sk(sk); + struct sock *sk; + struct econet_sock *eo; struct sockaddr_ec *sec = (struct sockaddr_ec *)uaddr; if (peer) return -EOPNOTSUPP; + mutex_lock(&econet_mutex); + + sk = sock->sk; + eo = ec_sk(sk); + sec->sec_family = AF_ECONET; sec->port = eo->port; sec->addr.station = eo->station; sec->addr.net = eo->net; + mutex_unlock(&econet_mutex); + *uaddr_len = sizeof(*sec); return 0; } @@ -522,10 +559,13 @@ static void econet_destroy_timer(unsigned long data) static int econet_release(struct socket *sock) { - struct sock *sk = sock->sk; + struct sock *sk; + mutex_lock(&econet_mutex); + + sk = sock->sk; if (!sk) - return 0; + goto out_unlock; econet_remove_socket(&econet_sklist, sk); @@ -549,10 +589,14 @@ static int econet_release(struct socket *sock) sk->sk_timer.expires = jiffies + HZ; sk->sk_timer.function = econet_destroy_timer; add_timer(&sk->sk_timer); - return 0; + + goto out_unlock; } sk_free(sk); + +out_unlock: + mutex_unlock(&econet_mutex); return 0; } @@ -608,6 +652,7 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg) struct ec_device *edev; struct net_device *dev; struct sockaddr_ec *sec; + int err; /* * Fetch the caller's info block into kernel space @@ -621,38 +666,35 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg) sec = (struct sockaddr_ec *)&ifr.ifr_addr; - switch (cmd) - { + mutex_lock(&econet_mutex); + + err = 0; + switch (cmd) { case SIOCSIFADDR: edev = dev->ec_ptr; - if (edev == NULL) - { + if (edev == NULL) { /* Magic up a new one. */ edev = kmalloc(sizeof(struct ec_device), GFP_KERNEL); if (edev == NULL) { - printk("af_ec: memory squeeze.\n"); - dev_put(dev); - return -ENOMEM; + err = -ENOMEM; + break; } memset(edev, 0, sizeof(struct ec_device)); dev->ec_ptr = edev; - } - else + } else net2dev_map[edev->net] = NULL; edev->station = sec->addr.station; edev->net = sec->addr.net; net2dev_map[sec->addr.net] = dev; if (!net2dev_map[0]) net2dev_map[0] = dev; - dev_put(dev); - return 0; + break; case SIOCGIFADDR: edev = dev->ec_ptr; - if (edev == NULL) - { - dev_put(dev); - return -ENODEV; + if (edev == NULL) { + err = -ENODEV; + break; } memset(sec, 0, sizeof(struct sockaddr_ec)); sec->addr.station = edev->station; @@ -660,12 +702,19 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg) sec->sec_family = AF_ECONET; dev_put(dev); if (copy_to_user(arg, &ifr, sizeof(struct ifreq))) - return -EFAULT; - return 0; + err = -EFAULT; + break; + + default: + err = -EINVAL; + break; } + mutex_unlock(&econet_mutex); + dev_put(dev); - return -EINVAL; + + return err; } /* @@ -699,7 +748,7 @@ static struct net_proto_family econet_family_ops = { .owner = THIS_MODULE, }; -static const struct proto_ops SOCKOPS_WRAPPED(econet_ops) = { +static const struct proto_ops econet_ops = { .family = PF_ECONET, .owner = THIS_MODULE, .release = econet_release, @@ -720,9 +769,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(econet_ops) = { .sendpage = sock_no_sendpage, }; -#include <linux/smp_lock.h> -SOCKOPS_WRAP(econet, PF_ECONET); - #if defined(CONFIG_ECONET_AUNUDP) || defined(CONFIG_ECONET_NATIVE) /* * Find the listening socket, if any, for the given data. diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 011cca7..e40f753 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig @@ -235,6 +235,7 @@ config IP_PNP_RARP # bool ' IP: ARP support' CONFIG_IP_PNP_ARP config NET_IPIP tristate "IP: tunneling" + select INET_TUNNEL ---help--- Tunneling means encapsulating data of one protocol type within another protocol and sending it over a channel that understands the @@ -395,7 +396,7 @@ config INET_ESP config INET_IPCOMP tristate "IP: IPComp transformation" select XFRM - select INET_TUNNEL + select INET_XFRM_TUNNEL select CRYPTO select CRYPTO_DEFLATE ---help--- @@ -404,14 +405,14 @@ config INET_IPCOMP If unsure, say Y. +config INET_XFRM_TUNNEL + tristate + select INET_TUNNEL + default n + config INET_TUNNEL - tristate "IP: tunnel transformation" - select XFRM - ---help--- - Support for generic IP tunnel transformation, which is required by - the IP tunneling module as well as tunnel mode IPComp. - - If unsure, say Y. + tristate + default n config INET_DIAG tristate "INET: socket monitoring interface" diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile index 35e5f59..9ef50a0 100644 --- a/net/ipv4/Makefile +++ b/net/ipv4/Makefile @@ -22,7 +22,8 @@ obj-$(CONFIG_SYN_COOKIES) += syncookies.o obj-$(CONFIG_INET_AH) += ah4.o obj-$(CONFIG_INET_ESP) += esp4.o obj-$(CONFIG_INET_IPCOMP) += ipcomp.o -obj-$(CONFIG_INET_TUNNEL) += xfrm4_tunnel.o +obj-$(CONFIG_INET_XFRM_TUNNEL) += xfrm4_tunnel.o +obj-$(CONFIG_INET_TUNNEL) += tunnel4.o obj-$(CONFIG_IP_PNP) += ipconfig.o obj-$(CONFIG_IP_ROUTE_MULTIPATH_RR) += multipath_rr.o obj-$(CONFIG_IP_ROUTE_MULTIPATH_RANDOM) += multipath_random.o diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 44fdf14..81c2f78 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -81,7 +81,7 @@ static struct ipv4_devconf ipv4_devconf_dflt = { static void rtmsg_ifa(int event, struct in_ifaddr *); -static struct notifier_block *inetaddr_chain; +static BLOCKING_NOTIFIER_HEAD(inetaddr_chain); static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, int destroy); #ifdef CONFIG_SYSCTL @@ -267,7 +267,8 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, *ifap1 = ifa->ifa_next; rtmsg_ifa(RTM_DELADDR, ifa); - notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa); + blocking_notifier_call_chain(&inetaddr_chain, + NETDEV_DOWN, ifa); inet_free_ifa(ifa); } else { promote = ifa; @@ -291,7 +292,7 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, So that, this order is correct. */ rtmsg_ifa(RTM_DELADDR, ifa1); - notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1); + blocking_notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1); if (promote) { @@ -303,7 +304,8 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, promote->ifa_flags &= ~IFA_F_SECONDARY; rtmsg_ifa(RTM_NEWADDR, promote); - notifier_call_chain(&inetaddr_chain, NETDEV_UP, promote); + blocking_notifier_call_chain(&inetaddr_chain, + NETDEV_UP, promote); for (ifa = promote->ifa_next; ifa; ifa = ifa->ifa_next) { if (ifa1->ifa_mask != ifa->ifa_mask || !inet_ifa_match(ifa1->ifa_address, ifa)) @@ -366,7 +368,7 @@ static int inet_insert_ifa(struct in_ifaddr *ifa) Notifier will trigger FIB update, so that listeners of netlink will know about new ifaddr */ rtmsg_ifa(RTM_NEWADDR, ifa); - notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa); + blocking_notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa); return 0; } @@ -938,12 +940,12 @@ u32 inet_confirm_addr(const struct net_device *dev, u32 dst, u32 local, int scop int register_inetaddr_notifier(struct notifier_block *nb) { - return notifier_chain_register(&inetaddr_chain, nb); + return blocking_notifier_chain_register(&inetaddr_chain, nb); } int unregister_inetaddr_notifier(struct notifier_block *nb) { - return notifier_chain_unregister(&inetaddr_chain, nb); + return blocking_notifier_chain_unregister(&inetaddr_chain, nb); } /* Rename ifa_labels for a device name change. Make some effort to preserve existing diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index e7bbff4..9831fd2 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -753,7 +753,7 @@ static void icmp_redirect(struct sk_buff *skb) case ICMP_REDIR_HOST: case ICMP_REDIR_HOSTTOS: ip_rt_redirect(skb->nh.iph->saddr, ip, skb->h.icmph->un.gateway, - iph->saddr, iph->tos, skb->dev); + iph->saddr, skb->dev); break; } out: diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 03d1374..eef07b0 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -114,7 +114,6 @@ #include <net/sock.h> #include <net/ip.h> #include <net/icmp.h> -#include <net/protocol.h> #include <net/ipip.h> #include <net/inet_ecn.h> #include <net/xfrm.h> @@ -274,7 +273,7 @@ static void ipip_tunnel_uninit(struct net_device *dev) dev_put(dev); } -static void ipip_err(struct sk_buff *skb, u32 info) +static int ipip_err(struct sk_buff *skb, u32 info) { #ifndef I_WISH_WORLD_WERE_PERFECT @@ -286,21 +285,22 @@ static void ipip_err(struct sk_buff *skb, u32 info) int type = skb->h.icmph->type; int code = skb->h.icmph->code; struct ip_tunnel *t; + int err; switch (type) { default: case ICMP_PARAMETERPROB: - return; + return 0; case ICMP_DEST_UNREACH: switch (code) { case ICMP_SR_FAILED: case ICMP_PORT_UNREACH: /* Impossible event. */ - return; + return 0; case ICMP_FRAG_NEEDED: /* Soft state for pmtu is maintained by IP core. */ - return; + return 0; default: /* All others are translated to HOST_UNREACH. rfc2003 contains "deep thoughts" about NET_UNREACH, @@ -311,14 +311,18 @@ static void ipip_err(struct sk_buff *skb, u32 info) break; case ICMP_TIME_EXCEEDED: if (code != ICMP_EXC_TTL) - return; + return 0; break; } + err = -ENOENT; + read_lock(&ipip_lock); t = ipip_tunnel_lookup(iph->daddr, iph->saddr); if (t == NULL || t->parms.iph.daddr == 0) goto out; + + err = 0; if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED) goto out; @@ -329,7 +333,7 @@ static void ipip_err(struct sk_buff *skb, u32 info) t->err_time = jiffies; out: read_unlock(&ipip_lock); - return; + return err; #else struct iphdr *iph = (struct iphdr*)dp; int hlen = iph->ihl<<2; @@ -344,15 +348,15 @@ out: struct rtable *rt; if (len < hlen + sizeof(struct iphdr)) - return; + return 0; eiph = (struct iphdr*)(dp + hlen); switch (type) { default: - return; + return 0; case ICMP_PARAMETERPROB: if (skb->h.icmph->un.gateway < hlen) - return; + return 0; /* So... This guy found something strange INSIDE encapsulated packet. Well, he is fool, but what can we do ? @@ -366,16 +370,16 @@ out: case ICMP_SR_FAILED: case ICMP_PORT_UNREACH: /* Impossible event. */ - return; + return 0; case ICMP_FRAG_NEEDED: /* And it is the only really necessary thing :-) */ rel_info = ntohs(skb->h.icmph->un.frag.mtu); if (rel_info < hlen+68) - return; + return 0; rel_info -= hlen; /* BSD 4.2 MORE DOES NOT EXIST IN NATURE. */ if (rel_info > ntohs(eiph->tot_len)) - return; + return 0; break; default: /* All others are translated to HOST_UNREACH. @@ -389,14 +393,14 @@ out: break; case ICMP_TIME_EXCEEDED: if (code != ICMP_EXC_TTL) - return; + return 0; break; } /* Prepare fake skb to feed it to icmp_send */ skb2 = skb_clone(skb, GFP_ATOMIC); if (skb2 == NULL) - return; + return 0; dst_release(skb2->dst); skb2->dst = NULL; skb_pull(skb2, skb->data - (u8*)eiph); @@ -409,7 +413,7 @@ out: fl.proto = IPPROTO_IPIP; if (ip_route_output_key(&rt, &key)) { kfree_skb(skb2); - return; + return 0; } skb2->dev = rt->u.dst.dev; @@ -424,14 +428,14 @@ out: rt->u.dst.dev->type != ARPHRD_TUNNEL) { ip_rt_put(rt); kfree_skb(skb2); - return; + return 0; } } else { ip_rt_put(rt); if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos, skb2->dev) || skb2->dst->dev->type != ARPHRD_TUNNEL) { kfree_skb(skb2); - return; + return 0; } } @@ -439,7 +443,7 @@ out: if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { if (rel_info > dst_mtu(skb2->dst)) { kfree_skb(skb2); - return; + return 0; } skb2->dst->ops->update_pmtu(skb2->dst, rel_info); rel_info = htonl(rel_info); @@ -453,7 +457,7 @@ out: icmp_send(skb2, rel_type, rel_code, rel_info); kfree_skb(skb2); - return; + return 0; #endif } @@ -855,39 +859,12 @@ static int __init ipip_fb_tunnel_init(struct net_device *dev) return 0; } -#ifdef CONFIG_INET_TUNNEL static struct xfrm_tunnel ipip_handler = { .handler = ipip_rcv, .err_handler = ipip_err, + .priority = 1, }; -static inline int ipip_register(void) -{ - return xfrm4_tunnel_register(&ipip_handler); -} - -static inline int ipip_unregister(void) -{ - return xfrm4_tunnel_deregister(&ipip_handler); -} -#else -static struct net_protocol ipip_protocol = { - .handler = ipip_rcv, - .err_handler = ipip_err, - .no_policy = 1, -}; - -static inline int ipip_register(void) -{ - return inet_add_protocol(&ipip_protocol, IPPROTO_IPIP); -} - -static inline int ipip_unregister(void) -{ - return inet_del_protocol(&ipip_protocol, IPPROTO_IPIP); -} -#endif - static char banner[] __initdata = KERN_INFO "IPv4 over IPv4 tunneling driver\n"; @@ -897,7 +874,7 @@ static int __init ipip_init(void) printk(banner); - if (ipip_register() < 0) { + if (xfrm4_tunnel_register(&ipip_handler)) { printk(KERN_INFO "ipip init: can't register tunnel\n"); return -EAGAIN; } @@ -919,7 +896,7 @@ static int __init ipip_init(void) err2: free_netdev(ipip_fb_tunnel_dev); err1: - ipip_unregister(); + xfrm4_tunnel_deregister(&ipip_handler); goto out; } @@ -939,7 +916,7 @@ static void __exit ipip_destroy_tunnels(void) static void __exit ipip_fini(void) { - if (ipip_unregister() < 0) + if (xfrm4_tunnel_deregister(&ipip_handler)) printk(KERN_INFO "ipip close: can't deregister tunnel\n"); rtnl_lock(); diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c index 7f0288b..f28ec68 100644 --- a/net/ipv4/ipvs/ip_vs_ctl.c +++ b/net/ipv4/ipvs/ip_vs_ctl.c @@ -34,6 +34,7 @@ #include <linux/netfilter.h> #include <linux/netfilter_ipv4.h> +#include <linux/mutex.h> #include <net/ip.h> #include <net/route.h> @@ -44,7 +45,7 @@ #include <net/ip_vs.h> /* semaphore for IPVS sockopts. And, [gs]etsockopt may sleep. */ -static DECLARE_MUTEX(__ip_vs_mutex); +static DEFINE_MUTEX(__ip_vs_mutex); /* lock for service table */ static DEFINE_RWLOCK(__ip_vs_svc_lock); @@ -1950,7 +1951,7 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) /* increase the module use count */ ip_vs_use_count_inc(); - if (down_interruptible(&__ip_vs_mutex)) { + if (mutex_lock_interruptible(&__ip_vs_mutex)) { ret = -ERESTARTSYS; goto out_dec; } @@ -2041,7 +2042,7 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) ip_vs_service_put(svc); out_unlock: - up(&__ip_vs_mutex); + mutex_unlock(&__ip_vs_mutex); out_dec: /* decrease the module use count */ ip_vs_use_count_dec(); @@ -2211,7 +2212,7 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) if (copy_from_user(arg, user, get_arglen[GET_CMDID(cmd)]) != 0) return -EFAULT; - if (down_interruptible(&__ip_vs_mutex)) + if (mutex_lock_interruptible(&__ip_vs_mutex)) return -ERESTARTSYS; switch (cmd) { @@ -2330,7 +2331,7 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) } out: - up(&__ip_vs_mutex); + mutex_unlock(&__ip_vs_mutex); return ret; } diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index ed42cdc..b5ad9ac 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c @@ -167,15 +167,15 @@ static struct nf_queue_rerouter ip_reroute = { .reroute = queue_reroute, }; -static int init(void) +static int ipv4_netfilter_init(void) { return nf_register_queue_rerouter(PF_INET, &ip_reroute); } -static void fini(void) +static void ipv4_netfilter_fini(void) { nf_unregister_queue_rerouter(PF_INET); } -module_init(init); -module_exit(fini); +module_init(ipv4_netfilter_init); +module_exit(ipv4_netfilter_fini); diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index ff0c594..a44a5d7 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -1166,7 +1166,7 @@ static struct nf_sockopt_ops arpt_sockopts = { .get = do_arpt_get_ctl, }; -static int __init init(void) +static int __init arp_tables_init(void) { int ret; @@ -1187,7 +1187,7 @@ static int __init init(void) return 0; } -static void __exit fini(void) +static void __exit arp_tables_fini(void) { nf_unregister_sockopt(&arpt_sockopts); xt_proto_fini(NF_ARP); @@ -1197,5 +1197,5 @@ EXPORT_SYMBOL(arpt_register_table); EXPORT_SYMBOL(arpt_unregister_table); EXPORT_SYMBOL(arpt_do_table); -module_init(init); -module_exit(fini); +module_init(arp_tables_init); +module_exit(arp_tables_fini); diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c index 0f2a953..a58325c 100644 --- a/net/ipv4/netfilter/arpt_mangle.c +++ b/net/ipv4/netfilter/arpt_mangle.c @@ -89,7 +89,7 @@ static struct arpt_target arpt_mangle_reg = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init arpt_mangle_init(void) { if (arpt_register_target(&arpt_mangle_reg)) return -EINVAL; @@ -97,10 +97,10 @@ static int __init init(void) return 0; } -static void __exit fini(void) +static void __exit arpt_mangle_fini(void) { arpt_unregister_target(&arpt_mangle_reg); } -module_init(init); -module_exit(fini); +module_init(arpt_mangle_init); +module_exit(arpt_mangle_fini); diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c index f6ab45f..d0d379c 100644 --- a/net/ipv4/netfilter/arptable_filter.c +++ b/net/ipv4/netfilter/arptable_filter.c @@ -179,7 +179,7 @@ static struct nf_hook_ops arpt_ops[] = { }, }; -static int __init init(void) +static int __init arptable_filter_init(void) { int ret, i; @@ -201,7 +201,7 @@ cleanup_hooks: return ret; } -static void __exit fini(void) +static void __exit arptable_filter_fini(void) { unsigned int i; @@ -211,5 +211,5 @@ static void __exit fini(void) arpt_unregister_table(&packet_filter); } -module_init(init); -module_exit(fini); +module_init(arptable_filter_init); +module_exit(arptable_filter_fini); diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c index 84e4f79..a604b1c 100644 --- a/net/ipv4/netfilter/ip_conntrack_amanda.c +++ b/net/ipv4/netfilter/ip_conntrack_amanda.c @@ -153,13 +153,13 @@ static struct ip_conntrack_helper amanda_helper = { }, }; -static void __exit fini(void) +static void __exit ip_conntrack_amanda_fini(void) { ip_conntrack_helper_unregister(&amanda_helper); kfree(amanda_buffer); } -static int __init init(void) +static int __init ip_conntrack_amanda_init(void) { int ret; @@ -177,5 +177,5 @@ static int __init init(void) } -module_init(init); -module_exit(fini); +module_init(ip_conntrack_amanda_init); +module_exit(ip_conntrack_amanda_fini); diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index 9e34034..ceaabc1 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c @@ -80,8 +80,8 @@ static int ip_conntrack_vmalloc; static unsigned int ip_conntrack_next_id; static unsigned int ip_conntrack_expect_next_id; #ifdef CONFIG_IP_NF_CONNTRACK_EVENTS -struct notifier_block *ip_conntrack_chain; -struct notifier_block *ip_conntrack_expect_chain; +ATOMIC_NOTIFIER_HEAD(ip_conntrack_chain); +ATOMIC_NOTIFIER_HEAD(ip_conntrack_expect_chain); DEFINE_PER_CPU(struct ip_conntrack_ecache, ip_conntrack_ecache); @@ -92,7 +92,7 @@ __ip_ct_deliver_cached_events(struct ip_conntrack_ecache *ecache) { DEBUGP("ecache: delivering events for %p\n", ecache->ct); if (is_confirmed(ecache->ct) && !is_dying(ecache->ct) && ecache->events) - notifier_call_chain(&ip_conntrack_chain, ecache->events, + atomic_notifier_call_chain(&ip_conntrack_chain, ecache->events, ecache->ct); ecache->events = 0; ip_conntrack_put(ecache->ct); diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c index e627e58..3e542bf 100644 --- a/net/ipv4/netfilter/ip_conntrack_ftp.c +++ b/net/ipv4/netfilter/ip_conntrack_ftp.c @@ -453,7 +453,7 @@ static struct ip_conntrack_helper ftp[MAX_PORTS]; static char ftp_names[MAX_PORTS][sizeof("ftp-65535")]; /* Not __exit: called from init() */ -static void fini(void) +static void ip_conntrack_ftp_fini(void) { int i; for (i = 0; i < ports_c; i++) { @@ -465,7 +465,7 @@ static void fini(void) kfree(ftp_buffer); } -static int __init init(void) +static int __init ip_conntrack_ftp_init(void) { int i, ret; char *tmpname; @@ -499,12 +499,12 @@ static int __init init(void) ret = ip_conntrack_helper_register(&ftp[i]); if (ret) { - fini(); + ip_conntrack_ftp_fini(); return ret; } } return 0; } -module_init(init); -module_exit(fini); +module_init(ip_conntrack_ftp_init); +module_exit(ip_conntrack_ftp_fini); diff --git a/net/ipv4/netfilter/ip_conntrack_helper_pptp.c b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c index d716bba..7d3ba43 100644 --- a/net/ipv4/netfilter/ip_conntrack_helper_pptp.c +++ b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c @@ -766,7 +766,7 @@ extern void ip_ct_proto_gre_fini(void); extern int __init ip_ct_proto_gre_init(void); /* ip_conntrack_pptp initialization */ -static int __init init(void) +static int __init ip_conntrack_helper_pptp_init(void) { int retcode; @@ -786,15 +786,15 @@ static int __init init(void) return 0; } -static void __exit fini(void) +static void __exit ip_conntrack_helper_pptp_fini(void) { ip_conntrack_helper_unregister(&pptp); ip_ct_proto_gre_fini(); printk("ip_conntrack_pptp version %s unloaded\n", IP_CT_PPTP_VERSION); } -module_init(init); -module_exit(fini); +module_init(ip_conntrack_helper_pptp_init); +module_exit(ip_conntrack_helper_pptp_fini); EXPORT_SYMBOL(ip_nat_pptp_hook_outbound); EXPORT_SYMBOL(ip_nat_pptp_hook_inbound); diff --git a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c index c51a2cf..a2ac5ce 100644 --- a/net/ipv4/netfilter/ip_conntrack_irc.c +++ b/net/ipv4/netfilter/ip_conntrack_irc.c @@ -242,9 +242,9 @@ static int help(struct sk_buff **pskb, static struct ip_conntrack_helper irc_helpers[MAX_PORTS]; static char irc_names[MAX_PORTS][sizeof("irc-65535")]; -static void fini(void); +static void ip_conntrack_irc_fini(void); -static int __init init(void) +static int __init ip_conntrack_irc_init(void) { int i, ret; struct ip_conntrack_helper *hlpr; @@ -288,7 +288,7 @@ static int __init init(void) if (ret) { printk("ip_conntrack_irc: ERROR registering port %d\n", ports[i]); - fini(); + ip_conntrack_irc_fini(); return -EBUSY; } } @@ -297,7 +297,7 @@ static int __init init(void) /* This function is intentionally _NOT_ defined as __exit, because * it is needed by the init function */ -static void fini(void) +static void ip_conntrack_irc_fini(void) { int i; for (i = 0; i < ports_c; i++) { @@ -308,5 +308,5 @@ static void fini(void) kfree(irc_buffer); } -module_init(init); -module_exit(fini); +module_init(ip_conntrack_irc_init); +module_exit(ip_conntrack_irc_fini); diff --git a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c index 4e68e16..a566a81 100644 --- a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c +++ b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c @@ -127,16 +127,16 @@ static struct ip_conntrack_helper helper = { .help = help, }; -static int __init init(void) +static int __init ip_conntrack_netbios_ns_init(void) { helper.timeout = timeout; return ip_conntrack_helper_register(&helper); } -static void __exit fini(void) +static void __exit ip_conntrack_netbios_ns_fini(void) { ip_conntrack_helper_unregister(&helper); } -module_init(init); -module_exit(fini); +module_init(ip_conntrack_netbios_ns_init); +module_exit(ip_conntrack_netbios_ns_fini); diff --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c index be602e8..5259abd 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c @@ -609,7 +609,7 @@ static ctl_table ip_ct_net_table[] = { static struct ctl_table_header *ip_ct_sysctl_header; #endif -static int __init init(void) +static int __init ip_conntrack_proto_sctp_init(void) { int ret; @@ -640,7 +640,7 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit ip_conntrack_proto_sctp_fini(void) { ip_conntrack_protocol_unregister(&ip_conntrack_protocol_sctp); #ifdef CONFIG_SYSCTL @@ -649,8 +649,8 @@ static void __exit fini(void) DEBUGP("SCTP conntrack module unloaded\n"); } -module_init(init); -module_exit(fini); +module_init(ip_conntrack_proto_sctp_init); +module_exit(ip_conntrack_proto_sctp_fini); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Kiran Kumar Immidi"); diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c index 833fcb4..5207602 100644 --- a/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c @@ -929,18 +929,18 @@ void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto) ip_ct_iterate_cleanup(kill_proto, &proto->proto); } -static int __init init(void) +static int __init ip_conntrack_standalone_init(void) { return init_or_cleanup(1); } -static void __exit fini(void) +static void __exit ip_conntrack_standalone_fini(void) { init_or_cleanup(0); } -module_init(init); -module_exit(fini); +module_init(ip_conntrack_standalone_init); +module_exit(ip_conntrack_standalone_fini); /* Some modules need us, but don't depend directly on any symbol. They should call this. */ diff --git a/net/ipv4/netfilter/ip_conntrack_tftp.c b/net/ipv4/netfilter/ip_conntrack_tftp.c index 4ba4463..7e33d3b 100644 --- a/net/ipv4/netfilter/ip_conntrack_tftp.c +++ b/net/ipv4/netfilter/ip_conntrack_tftp.c @@ -103,7 +103,7 @@ static int tftp_help(struct sk_buff **pskb, static struct ip_conntrack_helper tftp[MAX_PORTS]; static char tftp_names[MAX_PORTS][sizeof("tftp-65535")]; -static void fini(void) +static void ip_conntrack_tftp_fini(void) { int i; @@ -114,7 +114,7 @@ static void fini(void) } } -static int __init init(void) +static int __init ip_conntrack_tftp_init(void) { int i, ret; char *tmpname; @@ -148,12 +148,12 @@ static int __init init(void) if (ret) { printk("ERROR registering helper for port %d\n", ports[i]); - fini(); + ip_conntrack_tftp_fini(); return(ret); } } return(0); } -module_init(init); -module_exit(fini); +module_init(ip_conntrack_tftp_init); +module_exit(ip_conntrack_tftp_fini); diff --git a/net/ipv4/netfilter/ip_nat_amanda.c b/net/ipv4/netfilter/ip_nat_amanda.c index 706c807..3a88871 100644 --- a/net/ipv4/netfilter/ip_nat_amanda.c +++ b/net/ipv4/netfilter/ip_nat_amanda.c @@ -68,19 +68,19 @@ static unsigned int help(struct sk_buff **pskb, return ret; } -static void __exit fini(void) +static void __exit ip_nat_amanda_fini(void) { ip_nat_amanda_hook = NULL; /* Make sure noone calls it, meanwhile. */ synchronize_net(); } -static int __init init(void) +static int __init ip_nat_amanda_init(void) { BUG_ON(ip_nat_amanda_hook); ip_nat_amanda_hook = help; return 0; } -module_init(init); -module_exit(fini); +module_init(ip_nat_amanda_init); +module_exit(ip_nat_amanda_fini); diff --git a/net/ipv4/netfilter/ip_nat_ftp.c b/net/ipv4/netfilter/ip_nat_ftp.c index b8daab3..3328fc5 100644 --- a/net/ipv4/netfilter/ip_nat_ftp.c +++ b/net/ipv4/netfilter/ip_nat_ftp.c @@ -154,14 +154,14 @@ static unsigned int ip_nat_ftp(struct sk_buff **pskb, return NF_ACCEPT; } -static void __exit fini(void) +static void __exit ip_nat_ftp_fini(void) { ip_nat_ftp_hook = NULL; /* Make sure noone calls it, meanwhile. */ synchronize_net(); } -static int __init init(void) +static int __init ip_nat_ftp_init(void) { BUG_ON(ip_nat_ftp_hook); ip_nat_ftp_hook = ip_nat_ftp; @@ -177,5 +177,5 @@ static int warn_set(const char *val, struct kernel_param *kp) } module_param_call(ports, warn_set, NULL, NULL, 0); -module_init(init); -module_exit(fini); +module_init(ip_nat_ftp_init); +module_exit(ip_nat_ftp_fini); diff --git a/net/ipv4/netfilter/ip_nat_helper_pptp.c b/net/ipv4/netfilter/ip_nat_helper_pptp.c index b9c016c..f397772 100644 --- a/net/ipv4/netfilter/ip_nat_helper_pptp.c +++ b/net/ipv4/netfilter/ip_nat_helper_pptp.c @@ -370,7 +370,7 @@ pptp_inbound_pkt(struct sk_buff **pskb, extern int __init ip_nat_proto_gre_init(void); extern void __exit ip_nat_proto_gre_fini(void); -static int __init init(void) +static int __init ip_nat_helper_pptp_init(void) { int ret; @@ -396,7 +396,7 @@ static int __init init(void) return 0; } -static void __exit fini(void) +static void __exit ip_nat_helper_pptp_fini(void) { DEBUGP("cleanup_module\n" ); @@ -412,5 +412,5 @@ static void __exit fini(void) printk("ip_nat_pptp version %s unloaded\n", IP_NAT_PPTP_VERSION); } -module_init(init); -module_exit(fini); +module_init(ip_nat_helper_pptp_init); +module_exit(ip_nat_helper_pptp_fini); diff --git a/net/ipv4/netfilter/ip_nat_irc.c b/net/ipv4/netfilter/ip_nat_irc.c index 461c833..a767123 100644 --- a/net/ipv4/netfilter/ip_nat_irc.c +++ b/net/ipv4/netfilter/ip_nat_irc.c @@ -96,14 +96,14 @@ static unsigned int help(struct sk_buff **pskb, return ret; } -static void __exit fini(void) +static void __exit ip_nat_irc_fini(void) { ip_nat_irc_hook = NULL; /* Make sure noone calls it, meanwhile. */ synchronize_net(); } -static int __init init(void) +static int __init ip_nat_irc_init(void) { BUG_ON(ip_nat_irc_hook); ip_nat_irc_hook = help; @@ -119,5 +119,5 @@ static int warn_set(const char *val, struct kernel_param *kp) } module_param_call(ports, warn_set, NULL, NULL, 0); -module_init(init); -module_exit(fini); +module_init(ip_nat_irc_init); +module_exit(ip_nat_irc_fini); diff --git a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c index f029da2..c622538 100644 --- a/net/ipv4/netfilter/ip_nat_snmp_basic.c +++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c @@ -1324,7 +1324,7 @@ static struct ip_conntrack_helper snmp_trap_helper = { * *****************************************************************************/ -static int __init init(void) +static int __init ip_nat_snmp_basic_init(void) { int ret = 0; @@ -1339,13 +1339,13 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit ip_nat_snmp_basic_fini(void) { ip_conntrack_helper_unregister(&snmp_helper); ip_conntrack_helper_unregister(&snmp_trap_helper); } -module_init(init); -module_exit(fini); +module_init(ip_nat_snmp_basic_init); +module_exit(ip_nat_snmp_basic_fini); module_param(debug, bool, 0600); diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index 380aef3..3505b0d 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c @@ -425,17 +425,17 @@ static int init_or_cleanup(int init) return ret; } -static int __init init(void) +static int __init ip_nat_standalone_init(void) { return init_or_cleanup(1); } -static void __exit fini(void) +static void __exit ip_nat_standalone_fini(void) { init_or_cleanup(0); } -module_init(init); -module_exit(fini); +module_init(ip_nat_standalone_init); +module_exit(ip_nat_standalone_fini); MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ip_nat_tftp.c b/net/ipv4/netfilter/ip_nat_tftp.c index 43c3bd7..94a7801 100644 --- a/net/ipv4/netfilter/ip_nat_tftp.c +++ b/net/ipv4/netfilter/ip_nat_tftp.c @@ -53,19 +53,19 @@ static unsigned int help(struct sk_buff **pskb, return NF_ACCEPT; } -static void __exit fini(void) +static void __exit ip_nat_tftp_fini(void) { ip_nat_tftp_hook = NULL; /* Make sure noone calls it, meanwhile. */ synchronize_net(); } -static int __init init(void) +static int __init ip_nat_tftp_init(void) { BUG_ON(ip_nat_tftp_hook); ip_nat_tftp_hook = help; return 0; } -module_init(init); -module_exit(fini); +module_init(ip_nat_tftp_init); +module_exit(ip_nat_tftp_fini); diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 1655866..896a244 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c @@ -717,13 +717,13 @@ cleanup_netlink_notifier: return status; } -static int __init init(void) +static int __init ip_queue_init(void) { return init_or_cleanup(1); } -static void __exit fini(void) +static void __exit ip_queue_fini(void) { init_or_cleanup(0); } @@ -732,5 +732,5 @@ MODULE_DESCRIPTION("IPv4 packet queue handler"); MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); MODULE_LICENSE("GPL"); -module_init(init); -module_exit(fini); +module_init(ip_queue_init); +module_exit(ip_queue_fini); diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index a7b194c..460fd90 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -1364,7 +1364,7 @@ static struct ipt_match icmp_matchstruct = { .checkentry = icmp_checkentry, }; -static int __init init(void) +static int __init ip_tables_init(void) { int ret; @@ -1386,7 +1386,7 @@ static int __init init(void) return 0; } -static void __exit fini(void) +static void __exit ip_tables_fini(void) { nf_unregister_sockopt(&ipt_sockopts); @@ -1400,5 +1400,5 @@ static void __exit fini(void) EXPORT_SYMBOL(ipt_register_table); EXPORT_SYMBOL(ipt_unregister_table); EXPORT_SYMBOL(ipt_do_table); -module_init(init); -module_exit(fini); +module_init(ip_tables_init); +module_exit(ip_tables_fini); diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 61e11ed..e4768a3 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c @@ -770,15 +770,15 @@ cleanup_none: return -EINVAL; } -static int __init init(void) +static int __init ipt_clusterip_init(void) { return init_or_cleanup(0); } -static void __exit fini(void) +static void __exit ipt_clusterip_fini(void) { init_or_cleanup(1); } -module_init(init); -module_exit(fini); +module_init(ipt_clusterip_init); +module_exit(ipt_clusterip_fini); diff --git a/net/ipv4/netfilter/ipt_DSCP.c b/net/ipv4/netfilter/ipt_DSCP.c index cfb0b90..c8e9712 100644 --- a/net/ipv4/netfilter/ipt_DSCP.c +++ b/net/ipv4/netfilter/ipt_DSCP.c @@ -82,15 +82,15 @@ static struct ipt_target ipt_dscp_reg = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ipt_dscp_init(void) { return ipt_register_target(&ipt_dscp_reg); } -static void __exit fini(void) +static void __exit ipt_dscp_fini(void) { ipt_unregister_target(&ipt_dscp_reg); } -module_init(init); -module_exit(fini); +module_init(ipt_dscp_init); +module_exit(ipt_dscp_fini); diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c index b9b80f9..4adf5c9 100644 --- a/net/ipv4/netfilter/ipt_ECN.c +++ b/net/ipv4/netfilter/ipt_ECN.c @@ -151,15 +151,15 @@ static struct ipt_target ipt_ecn_reg = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ipt_ecn_init(void) { return ipt_register_target(&ipt_ecn_reg); } -static void __exit fini(void) +static void __exit ipt_ecn_fini(void) { ipt_unregister_target(&ipt_ecn_reg); } -module_init(init); -module_exit(fini); +module_init(ipt_ecn_init); +module_exit(ipt_ecn_fini); diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c index 750d322..39fd4c2 100644 --- a/net/ipv4/netfilter/ipt_LOG.c +++ b/net/ipv4/netfilter/ipt_LOG.c @@ -471,7 +471,7 @@ static struct nf_logger ipt_log_logger ={ .me = THIS_MODULE, }; -static int __init init(void) +static int __init ipt_log_init(void) { if (ipt_register_target(&ipt_log_reg)) return -EINVAL; @@ -485,11 +485,11 @@ static int __init init(void) return 0; } -static void __exit fini(void) +static void __exit ipt_log_fini(void) { nf_log_unregister_logger(&ipt_log_logger); ipt_unregister_target(&ipt_log_reg); } -module_init(init); -module_exit(fini); +module_init(ipt_log_init); +module_exit(ipt_log_fini); diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c index e0c321c..8b3e7f9 100644 --- a/net/ipv4/netfilter/ipt_MASQUERADE.c +++ b/net/ipv4/netfilter/ipt_MASQUERADE.c @@ -175,7 +175,7 @@ static struct ipt_target masquerade = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ipt_masquerade_init(void) { int ret; @@ -191,12 +191,12 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit ipt_masquerade_fini(void) { ipt_unregister_target(&masquerade); unregister_netdevice_notifier(&masq_dev_notifier); unregister_inetaddr_notifier(&masq_inet_notifier); } -module_init(init); -module_exit(fini); +module_init(ipt_masquerade_init); +module_exit(ipt_masquerade_fini); diff --git a/net/ipv4/netfilter/ipt_NETMAP.c b/net/ipv4/netfilter/ipt_NETMAP.c index fba181c..2fcf107 100644 --- a/net/ipv4/netfilter/ipt_NETMAP.c +++ b/net/ipv4/netfilter/ipt_NETMAP.c @@ -98,15 +98,15 @@ static struct ipt_target target_module = { .me = THIS_MODULE }; -static int __init init(void) +static int __init ipt_netmap_init(void) { return ipt_register_target(&target_module); } -static void __exit fini(void) +static void __exit ipt_netmap_fini(void) { ipt_unregister_target(&target_module); } -module_init(init); -module_exit(fini); +module_init(ipt_netmap_init); +module_exit(ipt_netmap_fini); diff --git a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c index be3da7c..f290463 100644 --- a/net/ipv4/netfilter/ipt_REDIRECT.c +++ b/net/ipv4/netfilter/ipt_REDIRECT.c @@ -112,15 +112,15 @@ static struct ipt_target redirect_reg = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ipt_redirect_init(void) { return ipt_register_target(&redirect_reg); } -static void __exit fini(void) +static void __exit ipt_redirect_fini(void) { ipt_unregister_target(&redirect_reg); } -module_init(init); -module_exit(fini); +module_init(ipt_redirect_init); +module_exit(ipt_redirect_fini); diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index 9d3b357..4269a54 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c @@ -313,15 +313,15 @@ static struct ipt_target ipt_reject_reg = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ipt_reject_init(void) { return ipt_register_target(&ipt_reject_reg); } -static void __exit fini(void) +static void __exit ipt_reject_fini(void) { ipt_unregister_target(&ipt_reject_reg); } -module_init(init); -module_exit(fini); +module_init(ipt_reject_init); +module_exit(ipt_reject_fini); diff --git a/net/ipv4/netfilter/ipt_SAME.c b/net/ipv4/netfilter/ipt_SAME.c index 7e2ebc9..7169b09 100644 --- a/net/ipv4/netfilter/ipt_SAME.c +++ b/net/ipv4/netfilter/ipt_SAME.c @@ -189,16 +189,16 @@ static struct ipt_target same_reg = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ipt_same_init(void) { return ipt_register_target(&same_reg); } -static void __exit fini(void) +static void __exit ipt_same_fini(void) { ipt_unregister_target(&same_reg); } -module_init(init); -module_exit(fini); +module_init(ipt_same_init); +module_exit(ipt_same_fini); diff --git a/net/ipv4/netfilter/ipt_TCPMSS.c b/net/ipv4/netfilter/ipt_TCPMSS.c index c4fc50e..ef2fe5b 100644 --- a/net/ipv4/netfilter/ipt_TCPMSS.c +++ b/net/ipv4/netfilter/ipt_TCPMSS.c @@ -243,15 +243,15 @@ static struct ipt_target ipt_tcpmss_reg = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ipt_tcpmss_init(void) { return ipt_register_target(&ipt_tcpmss_reg); } -static void __exit fini(void) +static void __exit ipt_tcpmss_fini(void) { ipt_unregister_target(&ipt_tcpmss_reg); } -module_init(init); -module_exit(fini); +module_init(ipt_tcpmss_init); +module_exit(ipt_tcpmss_fini); diff --git a/net/ipv4/netfilter/ipt_TOS.c b/net/ipv4/netfilter/ipt_TOS.c index 9aa7817..1c7a5ca 100644 --- a/net/ipv4/netfilter/ipt_TOS.c +++ b/net/ipv4/netfilter/ipt_TOS.c @@ -81,15 +81,15 @@ static struct ipt_target ipt_tos_reg = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ipt_tos_init(void) { return ipt_register_target(&ipt_tos_reg); } -static void __exit fini(void) +static void __exit ipt_tos_fini(void) { ipt_unregister_target(&ipt_tos_reg); } -module_init(init); -module_exit(fini); +module_init(ipt_tos_init); +module_exit(ipt_tos_fini); diff --git a/net/ipv4/netfilter/ipt_TTL.c b/net/ipv4/netfilter/ipt_TTL.c index 5009a00..f48892a 100644 --- a/net/ipv4/netfilter/ipt_TTL.c +++ b/net/ipv4/netfilter/ipt_TTL.c @@ -94,15 +94,15 @@ static struct ipt_target ipt_TTL = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ipt_ttl_init(void) { return ipt_register_target(&ipt_TTL); } -static void __exit fini(void) +static void __exit ipt_ttl_fini(void) { ipt_unregister_target(&ipt_TTL); } -module_init(init); -module_exit(fini); +module_init(ipt_ttl_init); +module_exit(ipt_ttl_fini); diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index a82a32e..c84cc03 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c @@ -374,7 +374,7 @@ static struct nf_logger ipt_ulog_logger = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ipt_ulog_init(void) { int i; @@ -407,7 +407,7 @@ static int __init init(void) return 0; } -static void __exit fini(void) +static void __exit ipt_ulog_fini(void) { ulog_buff_t *ub; int i; @@ -435,5 +435,5 @@ static void __exit fini(void) } -module_init(init); -module_exit(fini); +module_init(ipt_ulog_init); +module_exit(ipt_ulog_fini); diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c index 5fdf85d..893dae2 100644 --- a/net/ipv4/netfilter/ipt_addrtype.c +++ b/net/ipv4/netfilter/ipt_addrtype.c @@ -51,15 +51,15 @@ static struct ipt_match addrtype_match = { .me = THIS_MODULE }; -static int __init init(void) +static int __init ipt_addrtype_init(void) { return ipt_register_match(&addrtype_match); } -static void __exit fini(void) +static void __exit ipt_addrtype_fini(void) { ipt_unregister_match(&addrtype_match); } -module_init(init); -module_exit(fini); +module_init(ipt_addrtype_init); +module_exit(ipt_addrtype_fini); diff --git a/net/ipv4/netfilter/ipt_ah.c b/net/ipv4/netfilter/ipt_ah.c index 35a21fb..2927135 100644 --- a/net/ipv4/netfilter/ipt_ah.c +++ b/net/ipv4/netfilter/ipt_ah.c @@ -96,15 +96,15 @@ static struct ipt_match ah_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ipt_ah_init(void) { return ipt_register_match(&ah_match); } -static void __exit cleanup(void) +static void __exit ipt_ah_fini(void) { ipt_unregister_match(&ah_match); } -module_init(init); -module_exit(cleanup); +module_init(ipt_ah_init); +module_exit(ipt_ah_fini); diff --git a/net/ipv4/netfilter/ipt_dscp.c b/net/ipv4/netfilter/ipt_dscp.c index 11963c3..4717759 100644 --- a/net/ipv4/netfilter/ipt_dscp.c +++ b/net/ipv4/netfilter/ipt_dscp.c @@ -39,16 +39,16 @@ static struct ipt_match dscp_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ipt_dscp_init(void) { return ipt_register_match(&dscp_match); } -static void __exit fini(void) +static void __exit ipt_dscp_fini(void) { ipt_unregister_match(&dscp_match); } -module_init(init); -module_exit(fini); +module_init(ipt_dscp_init); +module_exit(ipt_dscp_fini); diff --git a/net/ipv4/netfilter/ipt_ecn.c b/net/ipv4/netfilter/ipt_ecn.c index d7e29f6..b282504 100644 --- a/net/ipv4/netfilter/ipt_ecn.c +++ b/net/ipv4/netfilter/ipt_ecn.c @@ -118,15 +118,15 @@ static struct ipt_match ecn_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ipt_ecn_init(void) { return ipt_register_match(&ecn_match); } -static void __exit fini(void) +static void __exit ipt_ecn_fini(void) { ipt_unregister_match(&ecn_match); } -module_init(init); -module_exit(fini); +module_init(ipt_ecn_init); +module_exit(ipt_ecn_fini); diff --git a/net/ipv4/netfilter/ipt_esp.c b/net/ipv4/netfilter/ipt_esp.c index af0d5ec..3840b41 100644 --- a/net/ipv4/netfilter/ipt_esp.c +++ b/net/ipv4/netfilter/ipt_esp.c @@ -97,15 +97,15 @@ static struct ipt_match esp_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ipt_esp_init(void) { return ipt_register_match(&esp_match); } -static void __exit cleanup(void) +static void __exit ipt_esp_fini(void) { ipt_unregister_match(&esp_match); } -module_init(init); -module_exit(cleanup); +module_init(ipt_esp_init); +module_exit(ipt_esp_fini); diff --git a/net/ipv4/netfilter/ipt_hashlimit.c b/net/ipv4/netfilter/ipt_hashlimit.c index dc1521c..7c6836c 100644 --- a/net/ipv4/netfilter/ipt_hashlimit.c +++ b/net/ipv4/netfilter/ipt_hashlimit.c @@ -40,6 +40,7 @@ /* FIXME: this is just for IP_NF_ASSERRT */ #include <linux/netfilter_ipv4/ip_conntrack.h> +#include <linux/mutex.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); @@ -92,7 +93,7 @@ struct ipt_hashlimit_htable { }; static DEFINE_SPINLOCK(hashlimit_lock); /* protects htables list */ -static DECLARE_MUTEX(hlimit_mutex); /* additional checkentry protection */ +static DEFINE_MUTEX(hlimit_mutex); /* additional checkentry protection */ static HLIST_HEAD(hashlimit_htables); static kmem_cache_t *hashlimit_cachep __read_mostly; @@ -542,13 +543,13 @@ hashlimit_checkentry(const char *tablename, * call vmalloc, and that can sleep. And we cannot just re-search * the list of htable's in htable_create(), since then we would * create duplicate proc files. -HW */ - down(&hlimit_mutex); + mutex_lock(&hlimit_mutex); r->hinfo = htable_find_get(r->name); if (!r->hinfo && (htable_create(r) != 0)) { - up(&hlimit_mutex); + mutex_unlock(&hlimit_mutex); return 0; } - up(&hlimit_mutex); + mutex_unlock(&hlimit_mutex); /* Ugly hack: For SMP, we only want to use one set */ r->u.master = r; @@ -718,15 +719,15 @@ cleanup_nothing: } -static int __init init(void) +static int __init ipt_hashlimit_init(void) { return init_or_fini(0); } -static void __exit fini(void) +static void __exit ipt_hashlimit_fini(void) { init_or_fini(1); } -module_init(init); -module_exit(fini); +module_init(ipt_hashlimit_init); +module_exit(ipt_hashlimit_fini); diff --git a/net/ipv4/netfilter/ipt_iprange.c b/net/ipv4/netfilter/ipt_iprange.c index ae70112..5202edd 100644 --- a/net/ipv4/netfilter/ipt_iprange.c +++ b/net/ipv4/netfilter/ipt_iprange.c @@ -71,15 +71,15 @@ static struct ipt_match iprange_match = { .me = THIS_MODULE }; -static int __init init(void) +static int __init ipt_iprange_init(void) { return ipt_register_match(&iprange_match); } -static void __exit fini(void) +static void __exit ipt_iprange_fini(void) { ipt_unregister_match(&iprange_match); } -module_init(init); -module_exit(fini); +module_init(ipt_iprange_init); +module_exit(ipt_iprange_fini); diff --git a/net/ipv4/netfilter/ipt_multiport.c b/net/ipv4/netfilter/ipt_multiport.c index bd07f7c..ac95d83 100644 --- a/net/ipv4/netfilter/ipt_multiport.c +++ b/net/ipv4/netfilter/ipt_multiport.c @@ -171,7 +171,7 @@ static struct ipt_match multiport_match_v1 = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ipt_multiport_init(void) { int err; @@ -185,11 +185,11 @@ static int __init init(void) return err; } -static void __exit fini(void) +static void __exit ipt_multiport_fini(void) { ipt_unregister_match(&multiport_match); ipt_unregister_match(&multiport_match_v1); } -module_init(init); -module_exit(fini); +module_init(ipt_multiport_init); +module_exit(ipt_multiport_fini); diff --git a/net/ipv4/netfilter/ipt_owner.c b/net/ipv4/netfilter/ipt_owner.c index 3900428..5ac6ac0 100644 --- a/net/ipv4/netfilter/ipt_owner.c +++ b/net/ipv4/netfilter/ipt_owner.c @@ -78,15 +78,15 @@ static struct ipt_match owner_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ipt_owner_init(void) { return ipt_register_match(&owner_match); } -static void __exit fini(void) +static void __exit ipt_owner_fini(void) { ipt_unregister_match(&owner_match); } -module_init(init); -module_exit(fini); +module_init(ipt_owner_init); +module_exit(ipt_owner_fini); diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c index 06792ea..1438432 100644 --- a/net/ipv4/netfilter/ipt_recent.c +++ b/net/ipv4/netfilter/ipt_recent.c @@ -962,7 +962,7 @@ static struct ipt_match recent_match = { }; /* Kernel module initialization. */ -static int __init init(void) +static int __init ipt_recent_init(void) { int err, count; @@ -995,7 +995,7 @@ static int __init init(void) } /* Kernel module destruction. */ -static void __exit fini(void) +static void __exit ipt_recent_fini(void) { ipt_unregister_match(&recent_match); @@ -1003,5 +1003,5 @@ static void __exit fini(void) } /* Register our module with the kernel. */ -module_init(init); -module_exit(fini); +module_init(ipt_recent_init); +module_exit(ipt_recent_fini); diff --git a/net/ipv4/netfilter/ipt_tos.c b/net/ipv4/netfilter/ipt_tos.c index e404e92d..5549c39 100644 --- a/net/ipv4/netfilter/ipt_tos.c +++ b/net/ipv4/netfilter/ipt_tos.c @@ -39,15 +39,15 @@ static struct ipt_match tos_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ipt_multiport_init(void) { return ipt_register_match(&tos_match); } -static void __exit fini(void) +static void __exit ipt_multiport_fini(void) { ipt_unregister_match(&tos_match); } -module_init(init); -module_exit(fini); +module_init(ipt_multiport_init); +module_exit(ipt_multiport_fini); diff --git a/net/ipv4/netfilter/ipt_ttl.c b/net/ipv4/netfilter/ipt_ttl.c index ae7ce4d..a5243bd 100644 --- a/net/ipv4/netfilter/ipt_ttl.c +++ b/net/ipv4/netfilter/ipt_ttl.c @@ -55,16 +55,16 @@ static struct ipt_match ttl_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ipt_ttl_init(void) { return ipt_register_match(&ttl_match); } -static void __exit fini(void) +static void __exit ipt_ttl_fini(void) { ipt_unregister_match(&ttl_match); } -module_init(init); -module_exit(fini); +module_init(ipt_ttl_init); +module_exit(ipt_ttl_fini); diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c index 212a307..3d80aefe 100644 --- a/net/ipv4/netfilter/iptable_filter.c +++ b/net/ipv4/netfilter/iptable_filter.c @@ -139,7 +139,7 @@ static struct nf_hook_ops ipt_ops[] = { static int forward = NF_ACCEPT; module_param(forward, bool, 0000); -static int __init init(void) +static int __init iptable_filter_init(void) { int ret; @@ -181,7 +181,7 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit iptable_filter_fini(void) { unsigned int i; @@ -191,5 +191,5 @@ static void __exit fini(void) ipt_unregister_table(&packet_filter); } -module_init(init); -module_exit(fini); +module_init(iptable_filter_init); +module_exit(iptable_filter_fini); diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c index 3212a5c..412fc96 100644 --- a/net/ipv4/netfilter/iptable_mangle.c +++ b/net/ipv4/netfilter/iptable_mangle.c @@ -201,7 +201,7 @@ static struct nf_hook_ops ipt_ops[] = { }, }; -static int __init init(void) +static int __init iptable_mangle_init(void) { int ret; @@ -247,7 +247,7 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit iptable_mangle_fini(void) { unsigned int i; @@ -257,5 +257,5 @@ static void __exit fini(void) ipt_unregister_table(&packet_mangler); } -module_init(init); -module_exit(fini); +module_init(iptable_mangle_init); +module_exit(iptable_mangle_fini); diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c index fdb9e9c..03cc79a 100644 --- a/net/ipv4/netfilter/iptable_raw.c +++ b/net/ipv4/netfilter/iptable_raw.c @@ -116,7 +116,7 @@ static struct nf_hook_ops ipt_ops[] = { }, }; -static int __init init(void) +static int __init iptable_raw_init(void) { int ret; @@ -144,7 +144,7 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit iptable_raw_fini(void) { unsigned int i; @@ -154,6 +154,6 @@ static void __exit fini(void) ipt_unregister_table(&packet_raw); } -module_init(init); -module_exit(fini); +module_init(iptable_raw_init); +module_exit(iptable_raw_fini); MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index c8abc9d..4afbc69 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c @@ -571,18 +571,18 @@ static int init_or_cleanup(int init) MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET)); MODULE_LICENSE("GPL"); -static int __init init(void) +static int __init nf_conntrack_l3proto_ipv4_init(void) { need_conntrack(); return init_or_cleanup(1); } -static void __exit fini(void) +static void __exit nf_conntrack_l3proto_ipv4_fini(void) { init_or_cleanup(0); } -module_init(init); -module_exit(fini); +module_init(nf_conntrack_l3proto_ipv4_init); +module_exit(nf_conntrack_l3proto_ipv4_fini); EXPORT_SYMBOL(nf_ct_ipv4_gather_frags); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index fca5fe0..94fcbc5 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -55,6 +55,8 @@ * Robert Olsson : Added rt_cache statistics * Arnaldo C. Melo : Convert proc stuff to seq_file * Eric Dumazet : hashed spinlocks and rt_check_expire() fixes. + * Ilia Sotnikov : Ignore TOS on PMTUD and Redirect + * Ilia Sotnikov : Removed TOS from hash calculations * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -247,9 +249,9 @@ static DEFINE_PER_CPU(struct rt_cache_stat, rt_cache_stat); static int rt_intern_hash(unsigned hash, struct rtable *rth, struct rtable **res); -static unsigned int rt_hash_code(u32 daddr, u32 saddr, u8 tos) +static unsigned int rt_hash_code(u32 daddr, u32 saddr) { - return (jhash_3words(daddr, saddr, (u32) tos, rt_hash_rnd) + return (jhash_2words(daddr, saddr, rt_hash_rnd) & rt_hash_mask); } @@ -1111,7 +1113,7 @@ static void rt_del(unsigned hash, struct rtable *rt) } void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw, - u32 saddr, u8 tos, struct net_device *dev) + u32 saddr, struct net_device *dev) { int i, k; struct in_device *in_dev = in_dev_get(dev); @@ -1119,8 +1121,6 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw, u32 skeys[2] = { saddr, 0 }; int ikeys[2] = { dev->ifindex, 0 }; - tos &= IPTOS_RT_MASK; - if (!in_dev) return; @@ -1141,8 +1141,7 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw, for (i = 0; i < 2; i++) { for (k = 0; k < 2; k++) { unsigned hash = rt_hash_code(daddr, - skeys[i] ^ (ikeys[k] << 5), - tos); + skeys[i] ^ (ikeys[k] << 5)); rthp=&rt_hash_table[hash].chain; @@ -1152,7 +1151,6 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw, if (rth->fl.fl4_dst != daddr || rth->fl.fl4_src != skeys[i] || - rth->fl.fl4_tos != tos || rth->fl.oif != ikeys[k] || rth->fl.iif != 0) { rthp = &rth->u.rt_next; @@ -1232,10 +1230,9 @@ reject_redirect: if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit()) printk(KERN_INFO "Redirect from %u.%u.%u.%u on %s about " "%u.%u.%u.%u ignored.\n" - " Advised path = %u.%u.%u.%u -> %u.%u.%u.%u, " - "tos %02x\n", + " Advised path = %u.%u.%u.%u -> %u.%u.%u.%u\n", NIPQUAD(old_gw), dev->name, NIPQUAD(new_gw), - NIPQUAD(saddr), NIPQUAD(daddr), tos); + NIPQUAD(saddr), NIPQUAD(daddr)); #endif in_dev_put(in_dev); } @@ -1253,8 +1250,7 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) rt->u.dst.expires) { unsigned hash = rt_hash_code(rt->fl.fl4_dst, rt->fl.fl4_src ^ - (rt->fl.oif << 5), - rt->fl.fl4_tos); + (rt->fl.oif << 5)); #if RT_CACHE_DEBUG >= 1 printk(KERN_DEBUG "ip_rt_advice: redirect to " "%u.%u.%u.%u/%02x dropped\n", @@ -1391,14 +1387,13 @@ unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu) struct rtable *rth; u32 skeys[2] = { iph->saddr, 0, }; u32 daddr = iph->daddr; - u8 tos = iph->tos & IPTOS_RT_MASK; unsigned short est_mtu = 0; if (ipv4_config.no_pmtu_disc) return 0; for (i = 0; i < 2; i++) { - unsigned hash = rt_hash_code(daddr, skeys[i], tos); + unsigned hash = rt_hash_code(daddr, skeys[i]); rcu_read_lock(); for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; @@ -1407,7 +1402,6 @@ unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu) rth->fl.fl4_src == skeys[i] && rth->rt_dst == daddr && rth->rt_src == iph->saddr && - rth->fl.fl4_tos == tos && rth->fl.iif == 0 && !(dst_metric_locked(&rth->u.dst, RTAX_MTU))) { unsigned short mtu = new_mtu; @@ -1658,7 +1652,7 @@ static int ip_route_input_mc(struct sk_buff *skb, u32 daddr, u32 saddr, RT_CACHE_STAT_INC(in_slow_mc); in_dev_put(in_dev); - hash = rt_hash_code(daddr, saddr ^ (dev->ifindex << 5), tos); + hash = rt_hash_code(daddr, saddr ^ (dev->ifindex << 5)); return rt_intern_hash(hash, rth, (struct rtable**) &skb->dst); e_nobufs: @@ -1823,7 +1817,7 @@ static inline int ip_mkroute_input_def(struct sk_buff *skb, return err; /* put it into the cache */ - hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos); + hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5)); return rt_intern_hash(hash, rth, (struct rtable**)&skb->dst); } @@ -1864,7 +1858,7 @@ static inline int ip_mkroute_input(struct sk_buff *skb, return err; /* put it into the cache */ - hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos); + hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5)); err = rt_intern_hash(hash, rth, &rtres); if (err) return err; @@ -2041,7 +2035,7 @@ local_input: rth->rt_flags &= ~RTCF_LOCAL; } rth->rt_type = res.type; - hash = rt_hash_code(daddr, saddr ^ (fl.iif << 5), tos); + hash = rt_hash_code(daddr, saddr ^ (fl.iif << 5)); err = rt_intern_hash(hash, rth, (struct rtable**)&skb->dst); goto done; @@ -2088,7 +2082,7 @@ int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr, int iif = dev->ifindex; tos &= IPTOS_RT_MASK; - hash = rt_hash_code(daddr, saddr ^ (iif << 5), tos); + hash = rt_hash_code(daddr, saddr ^ (iif << 5)); rcu_read_lock(); for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; @@ -2286,10 +2280,8 @@ static inline int ip_mkroute_output_def(struct rtable **rp, int err = __mkroute_output(&rth, res, fl, oldflp, dev_out, flags); unsigned hash; if (err == 0) { - u32 tos = RT_FL_TOS(oldflp); - hash = rt_hash_code(oldflp->fl4_dst, - oldflp->fl4_src ^ (oldflp->oif << 5), tos); + oldflp->fl4_src ^ (oldflp->oif << 5)); err = rt_intern_hash(hash, rth, rp); } @@ -2304,7 +2296,6 @@ static inline int ip_mkroute_output(struct rtable** rp, unsigned flags) { #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED - u32 tos = RT_FL_TOS(oldflp); unsigned char hop; unsigned hash; int err = -EINVAL; @@ -2334,7 +2325,7 @@ static inline int ip_mkroute_output(struct rtable** rp, hash = rt_hash_code(oldflp->fl4_dst, oldflp->fl4_src ^ - (oldflp->oif << 5), tos); + (oldflp->oif << 5)); err = rt_intern_hash(hash, rth, rp); /* forward hop information to multipath impl. */ @@ -2563,7 +2554,7 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp) unsigned hash; struct rtable *rth; - hash = rt_hash_code(flp->fl4_dst, flp->fl4_src ^ (flp->oif << 5), flp->fl4_tos); + hash = rt_hash_code(flp->fl4_dst, flp->fl4_src ^ (flp->oif << 5)); rcu_read_lock_bh(); for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 4b0272c..87f68e7 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -257,6 +257,7 @@ #include <linux/fs.h> #include <linux/random.h> #include <linux/bootmem.h> +#include <linux/cache.h> #include <net/icmp.h> #include <net/tcp.h> @@ -275,9 +276,9 @@ atomic_t tcp_orphan_count = ATOMIC_INIT(0); EXPORT_SYMBOL_GPL(tcp_orphan_count); -int sysctl_tcp_mem[3]; -int sysctl_tcp_wmem[3] = { 4 * 1024, 16 * 1024, 128 * 1024 }; -int sysctl_tcp_rmem[3] = { 4 * 1024, 87380, 87380 * 2 }; +int sysctl_tcp_mem[3] __read_mostly; +int sysctl_tcp_wmem[3] __read_mostly; +int sysctl_tcp_rmem[3] __read_mostly; EXPORT_SYMBOL(sysctl_tcp_mem); EXPORT_SYMBOL(sysctl_tcp_rmem); @@ -365,7 +366,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) if (sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == TCP_CLOSE) mask |= POLLHUP; if (sk->sk_shutdown & RCV_SHUTDOWN) - mask |= POLLIN | POLLRDNORM; + mask |= POLLIN | POLLRDNORM | POLLRDHUP; /* Connected? */ if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV)) { @@ -2081,7 +2082,8 @@ __setup("thash_entries=", set_thash_entries); void __init tcp_init(void) { struct sk_buff *skb = NULL; - int order, i; + unsigned long limit; + int order, i, max_share; if (sizeof(struct tcp_skb_cb) > sizeof(skb->cb)) __skb_cb_too_small_for_tcp(sizeof(struct tcp_skb_cb), @@ -2155,12 +2157,16 @@ void __init tcp_init(void) sysctl_tcp_mem[1] = 1024 << order; sysctl_tcp_mem[2] = 1536 << order; - if (order < 3) { - sysctl_tcp_wmem[2] = 64 * 1024; - sysctl_tcp_rmem[0] = PAGE_SIZE; - sysctl_tcp_rmem[1] = 43689; - sysctl_tcp_rmem[2] = 2 * 43689; - } + limit = ((unsigned long)sysctl_tcp_mem[1]) << (PAGE_SHIFT - 7); + max_share = min(4UL*1024*1024, limit); + + sysctl_tcp_wmem[0] = SK_STREAM_MEM_QUANTUM; + sysctl_tcp_wmem[1] = 16*1024; + sysctl_tcp_wmem[2] = max(64*1024, max_share); + + sysctl_tcp_rmem[0] = SK_STREAM_MEM_QUANTUM; + sysctl_tcp_rmem[1] = 87380; + sysctl_tcp_rmem[2] = max(87380, max_share); printk(KERN_INFO "TCP: Hash tables configured " "(established %d bind %d)\n", diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index e688c68..91c2f41 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c @@ -223,7 +223,7 @@ void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 rtt, u32 in_flight, /* In dangerous area, increase slowly. */ else if (sysctl_tcp_abc) { - /* RFC3465: Apppriate Byte Count + /* RFC3465: Appropriate Byte Count * increase once for each full cwnd acked */ if (tp->bytes_acked >= tp->snd_cwnd*tp->mss_cache) { diff --git a/net/ipv4/tunnel4.c b/net/ipv4/tunnel4.c new file mode 100644 index 0000000..0d7d386 --- /dev/null +++ b/net/ipv4/tunnel4.c @@ -0,0 +1,113 @@ +/* tunnel4.c: Generic IP tunnel transformer. + * + * Copyright (C) 2003 David S. Miller (davem@redhat.com) + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/netdevice.h> +#include <linux/skbuff.h> +#include <net/protocol.h> +#include <net/xfrm.h> + +static struct xfrm_tunnel *tunnel4_handlers; +static DEFINE_MUTEX(tunnel4_mutex); + +int xfrm4_tunnel_register(struct xfrm_tunnel *handler) +{ + struct xfrm_tunnel **pprev; + int ret = -EEXIST; + int priority = handler->priority; + + mutex_lock(&tunnel4_mutex); + + for (pprev = &tunnel4_handlers; *pprev; pprev = &(*pprev)->next) { + if ((*pprev)->priority > priority) + break; + if ((*pprev)->priority == priority) + goto err; + } + + handler->next = *pprev; + *pprev = handler; + + ret = 0; + +err: + mutex_unlock(&tunnel4_mutex); + + return ret; +} + +EXPORT_SYMBOL(xfrm4_tunnel_register); + +int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler) +{ + struct xfrm_tunnel **pprev; + int ret = -ENOENT; + + mutex_lock(&tunnel4_mutex); + + for (pprev = &tunnel4_handlers; *pprev; pprev = &(*pprev)->next) { + if (*pprev == handler) { + *pprev = handler->next; + ret = 0; + break; + } + } + + mutex_unlock(&tunnel4_mutex); + + synchronize_net(); + + return ret; +} + +EXPORT_SYMBOL(xfrm4_tunnel_deregister); + +static int tunnel4_rcv(struct sk_buff *skb) +{ + struct xfrm_tunnel *handler; + + for (handler = tunnel4_handlers; handler; handler = handler->next) + if (!handler->handler(skb)) + return 0; + + kfree_skb(skb); + return 0; +} + +static void tunnel4_err(struct sk_buff *skb, u32 info) +{ + struct xfrm_tunnel *handler; + + for (handler = tunnel4_handlers; handler; handler = handler->next) + if (!handler->err_handler(skb, info)) + break; +} + +static struct net_protocol tunnel4_protocol = { + .handler = tunnel4_rcv, + .err_handler = tunnel4_err, + .no_policy = 1, +}; + +static int __init tunnel4_init(void) +{ + if (inet_add_protocol(&tunnel4_protocol, IPPROTO_IPIP)) { + printk(KERN_ERR "tunnel4 init: can't add protocol\n"); + return -EAGAIN; + } + return 0; +} + +static void __exit tunnel4_fini(void) +{ + if (inet_del_protocol(&tunnel4_protocol, IPPROTO_IPIP)) + printk(KERN_ERR "tunnel4 close: can't remove protocol\n"); +} + +module_init(tunnel4_init); +module_exit(tunnel4_fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c index b08d56b..2d67093 100644 --- a/net/ipv4/xfrm4_tunnel.c +++ b/net/ipv4/xfrm4_tunnel.c @@ -26,64 +26,6 @@ static int ipip_xfrm_rcv(struct xfrm_state *x, struct xfrm_decap_state *decap, s return 0; } -static struct xfrm_tunnel *ipip_handler; -static DEFINE_MUTEX(xfrm4_tunnel_mutex); - -int xfrm4_tunnel_register(struct xfrm_tunnel *handler) -{ - int ret; - - mutex_lock(&xfrm4_tunnel_mutex); - ret = 0; - if (ipip_handler != NULL) - ret = -EINVAL; - if (!ret) - ipip_handler = handler; - mutex_unlock(&xfrm4_tunnel_mutex); - - return ret; -} - -EXPORT_SYMBOL(xfrm4_tunnel_register); - -int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler) -{ - int ret; - - mutex_lock(&xfrm4_tunnel_mutex); - ret = 0; - if (ipip_handler != handler) - ret = -EINVAL; - if (!ret) - ipip_handler = NULL; - mutex_unlock(&xfrm4_tunnel_mutex); - - synchronize_net(); - - return ret; -} - -EXPORT_SYMBOL(xfrm4_tunnel_deregister); - -static int ipip_rcv(struct sk_buff *skb) -{ - struct xfrm_tunnel *handler = ipip_handler; - - /* Tunnel devices take precedence. */ - if (handler && handler->handler(skb) == 0) - return 0; - - return xfrm4_rcv(skb); -} - -static void ipip_err(struct sk_buff *skb, u32 info) -{ - struct xfrm_tunnel *handler = ipip_handler; - - if (handler) - handler->err_handler(skb, info); -} - static int ipip_init_state(struct xfrm_state *x) { if (!x->props.mode) @@ -111,10 +53,15 @@ static struct xfrm_type ipip_type = { .output = ipip_output }; -static struct net_protocol ipip_protocol = { - .handler = ipip_rcv, - .err_handler = ipip_err, - .no_policy = 1, +static int xfrm_tunnel_err(struct sk_buff *skb, u32 info) +{ + return -ENOENT; +} + +static struct xfrm_tunnel xfrm_tunnel_handler = { + .handler = xfrm4_rcv, + .err_handler = xfrm_tunnel_err, + .priority = 2, }; static int __init ipip_init(void) @@ -123,8 +70,8 @@ static int __init ipip_init(void) printk(KERN_INFO "ipip init: can't add xfrm type\n"); return -EAGAIN; } - if (inet_add_protocol(&ipip_protocol, IPPROTO_IPIP) < 0) { - printk(KERN_INFO "ipip init: can't add protocol\n"); + if (xfrm4_tunnel_register(&xfrm_tunnel_handler)) { + printk(KERN_INFO "ipip init: can't add xfrm handler\n"); xfrm_unregister_type(&ipip_type, AF_INET); return -EAGAIN; } @@ -133,8 +80,8 @@ static int __init ipip_init(void) static void __exit ipip_fini(void) { - if (inet_del_protocol(&ipip_protocol, IPPROTO_IPIP) < 0) - printk(KERN_INFO "ipip close: can't remove protocol\n"); + if (xfrm4_tunnel_deregister(&xfrm_tunnel_handler)) + printk(KERN_INFO "ipip close: can't remove xfrm handler\n"); if (xfrm_unregister_type(&ipip_type, AF_INET) < 0) printk(KERN_INFO "ipip close: can't remove xfrm type\n"); } diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig index e6f83b6..f8a107a 100644 --- a/net/ipv6/Kconfig +++ b/net/ipv6/Kconfig @@ -88,7 +88,7 @@ config INET6_IPCOMP tristate "IPv6: IPComp transformation" depends on IPV6 select XFRM - select INET6_TUNNEL + select INET6_XFRM_TUNNEL select CRYPTO select CRYPTO_DEFLATE ---help--- @@ -97,19 +97,18 @@ config INET6_IPCOMP If unsure, say Y. +config INET6_XFRM_TUNNEL + tristate + select INET6_TUNNEL + default n + config INET6_TUNNEL - tristate "IPv6: tunnel transformation" - depends on IPV6 - select XFRM - ---help--- - Support for generic IPv6-in-IPv6 tunnel transformation, which is - required by the IPv6-in-IPv6 tunneling module as well as tunnel mode - IPComp. - - If unsure, say Y. + tristate + default n config IPV6_TUNNEL tristate "IPv6: IPv6-in-IPv6 tunnel" + select INET6_TUNNEL depends on IPV6 ---help--- Support for IPv6-in-IPv6 tunnels described in RFC 2473. diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile index 41877ab..a760b09 100644 --- a/net/ipv6/Makefile +++ b/net/ipv6/Makefile @@ -18,7 +18,8 @@ ipv6-objs += $(ipv6-y) obj-$(CONFIG_INET6_AH) += ah6.o obj-$(CONFIG_INET6_ESP) += esp6.o obj-$(CONFIG_INET6_IPCOMP) += ipcomp6.o -obj-$(CONFIG_INET6_TUNNEL) += xfrm6_tunnel.o +obj-$(CONFIG_INET6_XFRM_TUNNEL) += xfrm6_tunnel.o +obj-$(CONFIG_INET6_TUNNEL) += tunnel6.o obj-$(CONFIG_NETFILTER) += netfilter/ obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 01c62a0..445006e 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -143,7 +143,7 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev, struct prefix_info *pinfo); static int ipv6_chk_same_addr(const struct in6_addr *addr, struct net_device *dev); -static struct notifier_block *inet6addr_chain; +static ATOMIC_NOTIFIER_HEAD(inet6addr_chain); struct ipv6_devconf ipv6_devconf = { .forwarding = 0, @@ -593,7 +593,7 @@ out2: read_unlock_bh(&addrconf_lock); if (likely(err == 0)) - notifier_call_chain(&inet6addr_chain, NETDEV_UP, ifa); + atomic_notifier_call_chain(&inet6addr_chain, NETDEV_UP, ifa); else { kfree(ifa); ifa = ERR_PTR(err); @@ -688,7 +688,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) ipv6_ifa_notify(RTM_DELADDR, ifp); - notifier_call_chain(&inet6addr_chain,NETDEV_DOWN,ifp); + atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifp); addrconf_del_timer(ifp); @@ -3767,12 +3767,12 @@ static void addrconf_sysctl_unregister(struct ipv6_devconf *p) int register_inet6addr_notifier(struct notifier_block *nb) { - return notifier_chain_register(&inet6addr_chain, nb); + return atomic_notifier_chain_register(&inet6addr_chain, nb); } int unregister_inet6addr_notifier(struct notifier_block *nb) { - return notifier_chain_unregister(&inet6addr_chain,nb); + return atomic_notifier_chain_unregister(&inet6addr_chain,nb); } /* diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 4859753..ff9040c 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -44,7 +44,6 @@ #include <net/ip.h> #include <net/ipv6.h> -#include <net/protocol.h> #include <net/ip6_route.h> #include <net/addrconf.h> #include <net/ip6_tunnel.h> @@ -391,7 +390,7 @@ parse_tlv_tnl_enc_lim(struct sk_buff *skb, __u8 * raw) * to the specifications in RFC 2473. **/ -static void +static int ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, int type, int code, int offset, __u32 info) { @@ -402,6 +401,7 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, int rel_code = ICMPV6_ADDR_UNREACH; __u32 rel_info = 0; __u16 len; + int err = -ENOENT; /* If the packet doesn't contain the original IPv6 header we are in trouble since we might need the source address for further @@ -411,6 +411,8 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, if ((t = ip6ip6_tnl_lookup(&ipv6h->daddr, &ipv6h->saddr)) == NULL) goto out; + err = 0; + switch (type) { __u32 teli; struct ipv6_tlv_tnl_enc_lim *tel; @@ -492,6 +494,7 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, } out: read_unlock(&ip6ip6_lock); + return err; } static inline void ip6ip6_ecn_decapsulate(struct ipv6hdr *outer_iph, @@ -511,9 +514,8 @@ static inline void ip6ip6_ecn_decapsulate(struct ipv6hdr *outer_iph, **/ static int -ip6ip6_rcv(struct sk_buff **pskb) +ip6ip6_rcv(struct sk_buff *skb) { - struct sk_buff *skb = *pskb; struct ipv6hdr *ipv6h; struct ip6_tnl *t; @@ -1112,39 +1114,12 @@ ip6ip6_fb_tnl_dev_init(struct net_device *dev) return 0; } -#ifdef CONFIG_INET6_TUNNEL static struct xfrm6_tunnel ip6ip6_handler = { .handler = ip6ip6_rcv, .err_handler = ip6ip6_err, + .priority = 1, }; -static inline int ip6ip6_register(void) -{ - return xfrm6_tunnel_register(&ip6ip6_handler); -} - -static inline int ip6ip6_unregister(void) -{ - return xfrm6_tunnel_deregister(&ip6ip6_handler); -} -#else -static struct inet6_protocol xfrm6_tunnel_protocol = { - .handler = ip6ip6_rcv, - .err_handler = ip6ip6_err, - .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, -}; - -static inline int ip6ip6_register(void) -{ - return inet6_add_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6); -} - -static inline int ip6ip6_unregister(void) -{ - return inet6_del_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6); -} -#endif - /** * ip6_tunnel_init - register protocol and reserve needed resources * @@ -1155,7 +1130,7 @@ static int __init ip6_tunnel_init(void) { int err; - if (ip6ip6_register() < 0) { + if (xfrm6_tunnel_register(&ip6ip6_handler)) { printk(KERN_ERR "ip6ip6 init: can't register tunnel\n"); return -EAGAIN; } @@ -1174,7 +1149,7 @@ static int __init ip6_tunnel_init(void) } return 0; fail: - ip6ip6_unregister(); + xfrm6_tunnel_deregister(&ip6ip6_handler); return err; } @@ -1184,7 +1159,7 @@ fail: static void __exit ip6_tunnel_cleanup(void) { - if (ip6ip6_unregister() < 0) + if (xfrm6_tunnel_deregister(&ip6ip6_handler)) printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n"); unregister_netdev(ip6ip6_fb_tnl_dev); diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index 028b636..d4cfec3 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c @@ -228,6 +228,9 @@ static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x) t->id.proto = IPPROTO_IPV6; t->id.spi = xfrm6_tunnel_alloc_spi((xfrm_address_t *)&x->props.saddr); + if (!t->id.spi) + goto error; + memcpy(t->id.daddr.a6, x->id.daddr.a6, sizeof(struct in6_addr)); memcpy(&t->sel, &x->sel, sizeof(t->sel)); t->props.family = AF_INET6; @@ -243,7 +246,9 @@ out: return t; error: + t->km.state = XFRM_STATE_DEAD; xfrm_state_put(t); + t = NULL; goto out; } diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index 344eab3..e81c6a9 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c @@ -713,13 +713,13 @@ cleanup_netlink_notifier: return status; } -static int __init init(void) +static int __init ip6_queue_init(void) { return init_or_cleanup(1); } -static void __exit fini(void) +static void __exit ip6_queue_fini(void) { init_or_cleanup(0); } @@ -727,5 +727,5 @@ static void __exit fini(void) MODULE_DESCRIPTION("IPv6 packet queue handler"); MODULE_LICENSE("GPL"); -module_init(init); -module_exit(fini); +module_init(ip6_queue_init); +module_exit(ip6_queue_fini); diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index db3c9ae..3ecf2db 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -1406,7 +1406,7 @@ static struct ip6t_match icmp6_matchstruct = { .family = AF_INET6, }; -static int __init init(void) +static int __init ip6_tables_init(void) { int ret; @@ -1429,7 +1429,7 @@ static int __init init(void) return 0; } -static void __exit fini(void) +static void __exit ip6_tables_fini(void) { nf_unregister_sockopt(&ip6t_sockopts); xt_unregister_match(&icmp6_matchstruct); @@ -1517,5 +1517,5 @@ EXPORT_SYMBOL(ip6t_do_table); EXPORT_SYMBOL(ip6t_ext_hdr); EXPORT_SYMBOL(ipv6_find_hdr); -module_init(init); -module_exit(fini); +module_init(ip6_tables_init); +module_exit(ip6_tables_fini); diff --git a/net/ipv6/netfilter/ip6t_HL.c b/net/ipv6/netfilter/ip6t_HL.c index da14c6d..b8eff8e 100644 --- a/net/ipv6/netfilter/ip6t_HL.c +++ b/net/ipv6/netfilter/ip6t_HL.c @@ -93,15 +93,15 @@ static struct ip6t_target ip6t_HL = { .me = THIS_MODULE }; -static int __init init(void) +static int __init ip6t_hl_init(void) { return ip6t_register_target(&ip6t_HL); } -static void __exit fini(void) +static void __exit ip6t_hl_fini(void) { ip6t_unregister_target(&ip6t_HL); } -module_init(init); -module_exit(fini); +module_init(ip6t_hl_init); +module_exit(ip6t_hl_fini); diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c index 07c6bcb..a96c0de 100644 --- a/net/ipv6/netfilter/ip6t_LOG.c +++ b/net/ipv6/netfilter/ip6t_LOG.c @@ -483,7 +483,7 @@ static struct nf_logger ip6t_logger = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ip6t_log_init(void) { if (ip6t_register_target(&ip6t_log_reg)) return -EINVAL; @@ -497,11 +497,11 @@ static int __init init(void) return 0; } -static void __exit fini(void) +static void __exit ip6t_log_fini(void) { nf_log_unregister_logger(&ip6t_logger); ip6t_unregister_target(&ip6t_log_reg); } -module_init(init); -module_exit(fini); +module_init(ip6t_log_init); +module_exit(ip6t_log_fini); diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index ddfa385..de1175c 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c @@ -255,17 +255,17 @@ static struct ip6t_target ip6t_reject_reg = { .me = THIS_MODULE }; -static int __init init(void) +static int __init ip6t_reject_init(void) { if (ip6t_register_target(&ip6t_reject_reg)) return -EINVAL; return 0; } -static void __exit fini(void) +static void __exit ip6t_reject_fini(void) { ip6t_unregister_target(&ip6t_reject_reg); } -module_init(init); -module_exit(fini); +module_init(ip6t_reject_init); +module_exit(ip6t_reject_fini); diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c index 178f6fb..2f7bb20 100644 --- a/net/ipv6/netfilter/ip6t_ah.c +++ b/net/ipv6/netfilter/ip6t_ah.c @@ -122,15 +122,15 @@ static struct ip6t_match ah_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ip6t_ah_init(void) { return ip6t_register_match(&ah_match); } -static void __exit cleanup(void) +static void __exit ip6t_ah_fini(void) { ip6t_unregister_match(&ah_match); } -module_init(init); -module_exit(cleanup); +module_init(ip6t_ah_init); +module_exit(ip6t_ah_fini); diff --git a/net/ipv6/netfilter/ip6t_dst.c b/net/ipv6/netfilter/ip6t_dst.c index e97a702..9422413 100644 --- a/net/ipv6/netfilter/ip6t_dst.c +++ b/net/ipv6/netfilter/ip6t_dst.c @@ -206,15 +206,15 @@ static struct ip6t_match opts_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ip6t_dst_init(void) { return ip6t_register_match(&opts_match); } -static void __exit cleanup(void) +static void __exit ip6t_dst_fini(void) { ip6t_unregister_match(&opts_match); } -module_init(init); -module_exit(cleanup); +module_init(ip6t_dst_init); +module_exit(ip6t_dst_fini); diff --git a/net/ipv6/netfilter/ip6t_esp.c b/net/ipv6/netfilter/ip6t_esp.c index 540b8bf..36bedad 100644 --- a/net/ipv6/netfilter/ip6t_esp.c +++ b/net/ipv6/netfilter/ip6t_esp.c @@ -101,15 +101,15 @@ static struct ip6t_match esp_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ip6t_esp_init(void) { return ip6t_register_match(&esp_match); } -static void __exit cleanup(void) +static void __exit ip6t_esp_fini(void) { ip6t_unregister_match(&esp_match); } -module_init(init); -module_exit(cleanup); +module_init(ip6t_esp_init); +module_exit(ip6t_esp_fini); diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c index d4b0bad..94dbdb8 100644 --- a/net/ipv6/netfilter/ip6t_eui64.c +++ b/net/ipv6/netfilter/ip6t_eui64.c @@ -70,15 +70,15 @@ static struct ip6t_match eui64_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ip6t_eui64_init(void) { return ip6t_register_match(&eui64_match); } -static void __exit fini(void) +static void __exit ip6t_eui64_fini(void) { ip6t_unregister_match(&eui64_match); } -module_init(init); -module_exit(fini); +module_init(ip6t_eui64_init); +module_exit(ip6t_eui64_fini); diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c index 4c41e14..06768c8 100644 --- a/net/ipv6/netfilter/ip6t_frag.c +++ b/net/ipv6/netfilter/ip6t_frag.c @@ -139,15 +139,15 @@ static struct ip6t_match frag_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ip6t_frag_init(void) { return ip6t_register_match(&frag_match); } -static void __exit cleanup(void) +static void __exit ip6t_frag_fini(void) { ip6t_unregister_match(&frag_match); } -module_init(init); -module_exit(cleanup); +module_init(ip6t_frag_init); +module_exit(ip6t_frag_fini); diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c index b4a1fdf..374f1be 100644 --- a/net/ipv6/netfilter/ip6t_hbh.c +++ b/net/ipv6/netfilter/ip6t_hbh.c @@ -206,15 +206,15 @@ static struct ip6t_match opts_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ip6t_hbh_init(void) { return ip6t_register_match(&opts_match); } -static void __exit cleanup(void) +static void __exit ip6t_hbh_fini(void) { ip6t_unregister_match(&opts_match); } -module_init(init); -module_exit(cleanup); +module_init(ip6t_hbh_init); +module_exit(ip6t_hbh_fini); diff --git a/net/ipv6/netfilter/ip6t_hl.c b/net/ipv6/netfilter/ip6t_hl.c index 3740557..44a729e 100644 --- a/net/ipv6/netfilter/ip6t_hl.c +++ b/net/ipv6/netfilter/ip6t_hl.c @@ -55,16 +55,16 @@ static struct ip6t_match hl_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ip6t_hl_init(void) { return ip6t_register_match(&hl_match); } -static void __exit fini(void) +static void __exit ip6t_hl_fini(void) { ip6t_unregister_match(&hl_match); } -module_init(init); -module_exit(fini); +module_init(ip6t_hl_init); +module_exit(ip6t_hl_fini); diff --git a/net/ipv6/netfilter/ip6t_multiport.c b/net/ipv6/netfilter/ip6t_multiport.c index 752b65d..10c48ba 100644 --- a/net/ipv6/netfilter/ip6t_multiport.c +++ b/net/ipv6/netfilter/ip6t_multiport.c @@ -111,15 +111,15 @@ static struct ip6t_match multiport_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ip6t_multiport_init(void) { return ip6t_register_match(&multiport_match); } -static void __exit fini(void) +static void __exit ip6t_multiport_fini(void) { ip6t_unregister_match(&multiport_match); } -module_init(init); -module_exit(fini); +module_init(ip6t_multiport_init); +module_exit(ip6t_multiport_fini); diff --git a/net/ipv6/netfilter/ip6t_owner.c b/net/ipv6/netfilter/ip6t_owner.c index e2cee3b..5d04799 100644 --- a/net/ipv6/netfilter/ip6t_owner.c +++ b/net/ipv6/netfilter/ip6t_owner.c @@ -79,15 +79,15 @@ static struct ip6t_match owner_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ip6t_owner_init(void) { return ip6t_register_match(&owner_match); } -static void __exit fini(void) +static void __exit ip6t_owner_fini(void) { ip6t_unregister_match(&owner_match); } -module_init(init); -module_exit(fini); +module_init(ip6t_owner_init); +module_exit(ip6t_owner_fini); diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c index 4c6b55b..fbb0184 100644 --- a/net/ipv6/netfilter/ip6t_rt.c +++ b/net/ipv6/netfilter/ip6t_rt.c @@ -225,15 +225,15 @@ static struct ip6t_match rt_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init ip6t_rt_init(void) { return ip6t_register_match(&rt_match); } -static void __exit cleanup(void) +static void __exit ip6t_rt_fini(void) { ip6t_unregister_match(&rt_match); } -module_init(init); -module_exit(cleanup); +module_init(ip6t_rt_init); +module_exit(ip6t_rt_fini); diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c index ce4a968..e5e724d 100644 --- a/net/ipv6/netfilter/ip6table_filter.c +++ b/net/ipv6/netfilter/ip6table_filter.c @@ -159,7 +159,7 @@ static struct nf_hook_ops ip6t_ops[] = { static int forward = NF_ACCEPT; module_param(forward, bool, 0000); -static int __init init(void) +static int __init ip6table_filter_init(void) { int ret; @@ -201,7 +201,7 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit ip6table_filter_fini(void) { unsigned int i; @@ -211,5 +211,5 @@ static void __exit fini(void) ip6t_unregister_table(&packet_filter); } -module_init(init); -module_exit(fini); +module_init(ip6table_filter_init); +module_exit(ip6table_filter_fini); diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c index 30a4627..e1f0f6a 100644 --- a/net/ipv6/netfilter/ip6table_mangle.c +++ b/net/ipv6/netfilter/ip6table_mangle.c @@ -228,7 +228,7 @@ static struct nf_hook_ops ip6t_ops[] = { }, }; -static int __init init(void) +static int __init ip6table_mangle_init(void) { int ret; @@ -274,7 +274,7 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit ip6table_mangle_fini(void) { unsigned int i; @@ -284,5 +284,5 @@ static void __exit fini(void) ip6t_unregister_table(&packet_mangler); } -module_init(init); -module_exit(fini); +module_init(ip6table_mangle_init); +module_exit(ip6table_mangle_fini); diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c index db28ba3..54d1fff 100644 --- a/net/ipv6/netfilter/ip6table_raw.c +++ b/net/ipv6/netfilter/ip6table_raw.c @@ -142,7 +142,7 @@ static struct nf_hook_ops ip6t_ops[] = { }, }; -static int __init init(void) +static int __init ip6table_raw_init(void) { int ret; @@ -170,7 +170,7 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit ip6table_raw_fini(void) { unsigned int i; @@ -180,6 +180,6 @@ static void __exit fini(void) ip6t_unregister_table(&packet_raw); } -module_init(init); -module_exit(fini); +module_init(ip6table_raw_init); +module_exit(ip6table_raw_fini); MODULE_LICENSE("GPL"); diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index c16f629..c8b5a96 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c @@ -588,16 +588,16 @@ MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET6)); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>"); -static int __init init(void) +static int __init nf_conntrack_l3proto_ipv6_init(void) { need_conntrack(); return init_or_cleanup(1); } -static void __exit fini(void) +static void __exit nf_conntrack_l3proto_ipv6_fini(void) { init_or_cleanup(0); } -module_init(init); -module_exit(fini); +module_init(nf_conntrack_l3proto_ipv6_init); +module_exit(nf_conntrack_l3proto_ipv6_fini); diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c new file mode 100644 index 0000000..5659b52 --- /dev/null +++ b/net/ipv6/tunnel6.c @@ -0,0 +1,131 @@ +/* + * Copyright (C)2003,2004 USAGI/WIDE Project + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors Mitsuru KANDA <mk@linux-ipv6.org> + * YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/netdevice.h> +#include <linux/skbuff.h> +#include <net/protocol.h> +#include <net/xfrm.h> + +static struct xfrm6_tunnel *tunnel6_handlers; +static DEFINE_MUTEX(tunnel6_mutex); + +int xfrm6_tunnel_register(struct xfrm6_tunnel *handler) +{ + struct xfrm6_tunnel **pprev; + int ret = -EEXIST; + int priority = handler->priority; + + mutex_lock(&tunnel6_mutex); + + for (pprev = &tunnel6_handlers; *pprev; pprev = &(*pprev)->next) { + if ((*pprev)->priority > priority) + break; + if ((*pprev)->priority == priority) + goto err; + } + + handler->next = *pprev; + *pprev = handler; + + ret = 0; + +err: + mutex_unlock(&tunnel6_mutex); + + return ret; +} + +EXPORT_SYMBOL(xfrm6_tunnel_register); + +int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler) +{ + struct xfrm6_tunnel **pprev; + int ret = -ENOENT; + + mutex_lock(&tunnel6_mutex); + + for (pprev = &tunnel6_handlers; *pprev; pprev = &(*pprev)->next) { + if (*pprev == handler) { + *pprev = handler->next; + ret = 0; + break; + } + } + + mutex_unlock(&tunnel6_mutex); + + synchronize_net(); + + return ret; +} + +EXPORT_SYMBOL(xfrm6_tunnel_deregister); + +static int tunnel6_rcv(struct sk_buff **pskb) +{ + struct sk_buff *skb = *pskb; + struct xfrm6_tunnel *handler; + + for (handler = tunnel6_handlers; handler; handler = handler->next) + if (!handler->handler(skb)) + return 0; + + kfree_skb(skb); + return 0; +} + +static void tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, + int type, int code, int offset, __u32 info) +{ + struct xfrm6_tunnel *handler; + + for (handler = tunnel6_handlers; handler; handler = handler->next) + if (!handler->err_handler(skb, opt, type, code, offset, info)) + break; +} + +static struct inet6_protocol tunnel6_protocol = { + .handler = tunnel6_rcv, + .err_handler = tunnel6_err, + .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, +}; + +static int __init tunnel6_init(void) +{ + if (inet6_add_protocol(&tunnel6_protocol, IPPROTO_IPV6)) { + printk(KERN_ERR "tunnel6 init(): can't add protocol\n"); + return -EAGAIN; + } + return 0; +} + +static void __exit tunnel6_fini(void) +{ + if (inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6)) + printk(KERN_ERR "tunnel6 close: can't remove protocol\n"); +} + +module_init(tunnel6_init); +module_exit(tunnel6_fini); +MODULE_LICENSE("GPL"); diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c index 1ca2da6..cccf8b7 100644 --- a/net/ipv6/xfrm6_input.c +++ b/net/ipv6/xfrm6_input.c @@ -28,9 +28,8 @@ static inline void ipip6_ecn_decapsulate(struct sk_buff *skb) IP6_ECN_set_ce(inner_iph); } -int xfrm6_rcv_spi(struct sk_buff **pskb, u32 spi) +int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi) { - struct sk_buff *skb = *pskb; int err; u32 seq; struct sec_decap_state xfrm_vec[XFRM_MAX_DEPTH]; @@ -159,5 +158,5 @@ EXPORT_SYMBOL(xfrm6_rcv_spi); int xfrm6_rcv(struct sk_buff **pskb) { - return xfrm6_rcv_spi(pskb, 0); + return xfrm6_rcv_spi(*pskb, 0); } diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c index 08f9abb..a8f6776 100644 --- a/net/ipv6/xfrm6_tunnel.c +++ b/net/ipv6/xfrm6_tunnel.c @@ -28,7 +28,6 @@ #include <net/ip.h> #include <net/xfrm.h> #include <net/ipv6.h> -#include <net/protocol.h> #include <linux/ipv6.h> #include <linux/icmpv6.h> #include <linux/mutex.h> @@ -357,71 +356,18 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct xfrm_decap_state *dec return 0; } -static struct xfrm6_tunnel *xfrm6_tunnel_handler; -static DEFINE_MUTEX(xfrm6_tunnel_mutex); - -int xfrm6_tunnel_register(struct xfrm6_tunnel *handler) +static int xfrm6_tunnel_rcv(struct sk_buff *skb) { - int ret; - - mutex_lock(&xfrm6_tunnel_mutex); - ret = 0; - if (xfrm6_tunnel_handler != NULL) - ret = -EINVAL; - if (!ret) - xfrm6_tunnel_handler = handler; - mutex_unlock(&xfrm6_tunnel_mutex); - - return ret; -} - -EXPORT_SYMBOL(xfrm6_tunnel_register); - -int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler) -{ - int ret; - - mutex_lock(&xfrm6_tunnel_mutex); - ret = 0; - if (xfrm6_tunnel_handler != handler) - ret = -EINVAL; - if (!ret) - xfrm6_tunnel_handler = NULL; - mutex_unlock(&xfrm6_tunnel_mutex); - - synchronize_net(); - - return ret; -} - -EXPORT_SYMBOL(xfrm6_tunnel_deregister); - -static int xfrm6_tunnel_rcv(struct sk_buff **pskb) -{ - struct sk_buff *skb = *pskb; - struct xfrm6_tunnel *handler = xfrm6_tunnel_handler; struct ipv6hdr *iph = skb->nh.ipv6h; u32 spi; - /* device-like_ip6ip6_handler() */ - if (handler && handler->handler(pskb) == 0) - return 0; - spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr); - return xfrm6_rcv_spi(pskb, spi); + return xfrm6_rcv_spi(skb, spi); } -static void xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt, - int type, int code, int offset, __u32 info) +static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt, + int type, int code, int offset, __u32 info) { - struct xfrm6_tunnel *handler = xfrm6_tunnel_handler; - - /* call here first for device-like ip6ip6 err handling */ - if (handler) { - handler->err_handler(skb, opt, type, code, offset, info); - return; - } - /* xfrm6_tunnel native err handling */ switch (type) { case ICMPV6_DEST_UNREACH: @@ -462,7 +408,8 @@ static void xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt, default: break; } - return; + + return 0; } static int xfrm6_tunnel_init_state(struct xfrm_state *x) @@ -493,10 +440,10 @@ static struct xfrm_type xfrm6_tunnel_type = { .output = xfrm6_tunnel_output, }; -static struct inet6_protocol xfrm6_tunnel_protocol = { +static struct xfrm6_tunnel xfrm6_tunnel_handler = { .handler = xfrm6_tunnel_rcv, - .err_handler = xfrm6_tunnel_err, - .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, + .err_handler = xfrm6_tunnel_err, + .priority = 2, }; static int __init xfrm6_tunnel_init(void) @@ -508,16 +455,16 @@ static int __init xfrm6_tunnel_init(void) "xfrm6_tunnel init: can't add xfrm type\n"); return -EAGAIN; } - if (inet6_add_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6) < 0) { + if (xfrm6_tunnel_register(&xfrm6_tunnel_handler)) { X6TPRINTK1(KERN_ERR - "xfrm6_tunnel init(): can't add protocol\n"); + "xfrm6_tunnel init(): can't add handler\n"); xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); return -EAGAIN; } if (xfrm6_tunnel_spi_init() < 0) { X6TPRINTK1(KERN_ERR "xfrm6_tunnel init: failed to initialize spi\n"); - inet6_del_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6); + xfrm6_tunnel_deregister(&xfrm6_tunnel_handler); xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); return -EAGAIN; } @@ -529,9 +476,9 @@ static void __exit xfrm6_tunnel_fini(void) X6TPRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__); xfrm6_tunnel_spi_fini(); - if (inet6_del_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6) < 0) + if (xfrm6_tunnel_deregister(&xfrm6_tunnel_handler)) X6TPRINTK1(KERN_ERR - "xfrm6_tunnel close: can't remove protocol\n"); + "xfrm6_tunnel close: can't remove handler\n"); if (xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6) < 0) X6TPRINTK1(KERN_ERR "xfrm6_tunnel close: can't remove xfrm type\n"); diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 0fb513a..2dbf134 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c @@ -1892,6 +1892,29 @@ static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) return rc; } + +#ifdef CONFIG_COMPAT +static int ipx_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) +{ + /* + * These 4 commands use same structure on 32bit and 64bit. Rest of IPX + * commands is handled by generic ioctl code. As these commands are + * SIOCPROTOPRIVATE..SIOCPROTOPRIVATE+3, they cannot be handled by generic + * code. + */ + switch (cmd) { + case SIOCAIPXITFCRT: + case SIOCAIPXPRISLT: + case SIOCIPXCFGDATA: + case SIOCIPXNCPCONN: + return ipx_ioctl(sock, cmd, arg); + default: + return -ENOIOCTLCMD; + } +} +#endif + + /* * Socket family declarations */ @@ -1913,6 +1936,9 @@ static const struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = { .getname = ipx_getname, .poll = datagram_poll, .ioctl = ipx_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ipx_compat_ioctl, +#endif .listen = sock_no_listen, .shutdown = sock_no_shutdown, /* FIXME: support shutdown */ .setsockopt = ipx_setsockopt, diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 7594456..2f37c9f 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c @@ -1302,7 +1302,7 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock, if (sk->sk_state != TCP_ESTABLISHED) return -ENOTCONN; - /* Check that we don't send out to big frames */ + /* Check that we don't send out too big frames */ if (len > self->max_data_size) { IRDA_DEBUG(2, "%s(), Chopping frame from %zd to %d bytes!\n", __FUNCTION__, len, self->max_data_size); @@ -1546,7 +1546,7 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock, IRDA_ASSERT(self != NULL, return -1;); /* - * Check that we don't send out to big frames. This is an unreliable + * Check that we don't send out too big frames. This is an unreliable * service, so we have no fragmentation and no coalescence */ if (len > self->max_data_size) { @@ -1642,7 +1642,7 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock, } /* - * Check that we don't send out to big frames. This is an unreliable + * Check that we don't send out too big frames. This is an unreliable * service, so we have no fragmentation and no coalescence */ if (len > self->max_data_size) { @@ -1830,6 +1830,19 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) return 0; } +#ifdef CONFIG_COMPAT +/* + * Function irda_ioctl (sock, cmd, arg) + */ +static int irda_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) +{ + /* + * All IRDA's ioctl are standard ones. + */ + return -ENOIOCTLCMD; +} +#endif + /* * Function irda_setsockopt (sock, level, optname, optval, optlen) * @@ -2476,6 +2489,9 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = { .getname = irda_getname, .poll = irda_poll, .ioctl = irda_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = irda_compat_ioctl, +#endif .listen = irda_listen, .shutdown = irda_shutdown, .setsockopt = irda_setsockopt, @@ -2497,6 +2513,9 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = { .getname = irda_getname, .poll = datagram_poll, .ioctl = irda_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = irda_compat_ioctl, +#endif .listen = irda_listen, .shutdown = irda_shutdown, .setsockopt = irda_setsockopt, @@ -2518,6 +2537,9 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = { .getname = irda_getname, .poll = datagram_poll, .ioctl = irda_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = irda_compat_ioctl, +#endif .listen = irda_listen, .shutdown = irda_shutdown, .setsockopt = irda_setsockopt, @@ -2540,6 +2562,9 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = { .getname = irda_getname, .poll = datagram_poll, .ioctl = irda_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = irda_compat_ioctl, +#endif .listen = sock_no_listen, .shutdown = irda_shutdown, .setsockopt = irda_setsockopt, diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 0ae281d..56389c8 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -90,8 +90,8 @@ static int nf_conntrack_vmalloc; static unsigned int nf_conntrack_next_id; static unsigned int nf_conntrack_expect_next_id; #ifdef CONFIG_NF_CONNTRACK_EVENTS -struct notifier_block *nf_conntrack_chain; -struct notifier_block *nf_conntrack_expect_chain; +ATOMIC_NOTIFIER_HEAD(nf_conntrack_chain); +ATOMIC_NOTIFIER_HEAD(nf_conntrack_expect_chain); DEFINE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache); @@ -103,7 +103,7 @@ __nf_ct_deliver_cached_events(struct nf_conntrack_ecache *ecache) DEBUGP("ecache: delivering events for %p\n", ecache->ct); if (nf_ct_is_confirmed(ecache->ct) && !nf_ct_is_dying(ecache->ct) && ecache->events) - notifier_call_chain(&nf_conntrack_chain, ecache->events, + atomic_notifier_call_chain(&nf_conntrack_chain, ecache->events, ecache->ct); ecache->events = 0; diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c index cd191b0..e38a4b5 100644 --- a/net/netfilter/nf_conntrack_ftp.c +++ b/net/netfilter/nf_conntrack_ftp.c @@ -624,7 +624,7 @@ static struct nf_conntrack_helper ftp[MAX_PORTS][2]; static char ftp_names[MAX_PORTS][2][sizeof("ftp-65535")]; /* don't make this __exit, since it's called from __init ! */ -static void fini(void) +static void nf_conntrack_ftp_fini(void) { int i, j; for (i = 0; i < ports_c; i++) { @@ -642,7 +642,7 @@ static void fini(void) kfree(ftp_buffer); } -static int __init init(void) +static int __init nf_conntrack_ftp_init(void) { int i, j = -1, ret = 0; char *tmpname; @@ -683,7 +683,7 @@ static int __init init(void) printk("nf_ct_ftp: failed to register helper " " for pf: %d port: %d\n", ftp[i][j].tuple.src.l3num, ports[i]); - fini(); + nf_conntrack_ftp_fini(); return ret; } } @@ -692,5 +692,5 @@ static int __init init(void) return 0; } -module_init(init); -module_exit(fini); +module_init(nf_conntrack_ftp_init); +module_exit(nf_conntrack_ftp_fini); diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c index cf798e6..9cccc32 100644 --- a/net/netfilter/nf_conntrack_proto_sctp.c +++ b/net/netfilter/nf_conntrack_proto_sctp.c @@ -615,7 +615,7 @@ static ctl_table nf_ct_net_table[] = { static struct ctl_table_header *nf_ct_sysctl_header; #endif -int __init init(void) +int __init nf_conntrack_proto_sctp_init(void) { int ret; @@ -652,7 +652,7 @@ int __init init(void) return ret; } -void __exit fini(void) +void __exit nf_conntrack_proto_sctp_fini(void) { nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp6); nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp4); @@ -662,8 +662,8 @@ void __exit fini(void) DEBUGP("SCTP conntrack module unloaded\n"); } -module_init(init); -module_exit(fini); +module_init(nf_conntrack_proto_sctp_init); +module_exit(nf_conntrack_proto_sctp_fini); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Kiran Kumar Immidi"); diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 75577e1..c72aa3c 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -806,18 +806,18 @@ void nf_conntrack_protocol_unregister(struct nf_conntrack_protocol *proto) nf_ct_iterate_cleanup(kill_proto, proto); } -static int __init init(void) +static int __init nf_conntrack_standalone_init(void) { return init_or_cleanup(1); } -static void __exit fini(void) +static void __exit nf_conntrack_standalone_fini(void) { init_or_cleanup(0); } -module_init(init); -module_exit(fini); +module_init(nf_conntrack_standalone_init); +module_exit(nf_conntrack_standalone_fini); /* Some modules need us, but don't depend directly on any symbol. They should call this. */ diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 54cbbaa..3e3f544 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -1081,13 +1081,13 @@ cleanup_netlink_notifier: return status; } -static int __init init(void) +static int __init nfnetlink_log_init(void) { return init_or_cleanup(1); } -static void __exit fini(void) +static void __exit nfnetlink_log_fini(void) { init_or_cleanup(0); } @@ -1097,5 +1097,5 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); MODULE_LICENSE("GPL"); MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_ULOG); -module_init(init); -module_exit(fini); +module_init(nfnetlink_log_init); +module_exit(nfnetlink_log_fini); diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index b570166..d0e62f6 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -1117,13 +1117,13 @@ cleanup_netlink_notifier: return status; } -static int __init init(void) +static int __init nfnetlink_queue_init(void) { return init_or_cleanup(1); } -static void __exit fini(void) +static void __exit nfnetlink_queue_fini(void) { init_or_cleanup(0); } @@ -1133,5 +1133,5 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); MODULE_LICENSE("GPL"); MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_QUEUE); -module_init(init); -module_exit(fini); +module_init(nfnetlink_queue_init); +module_exit(nfnetlink_queue_fini); diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index 0a29a24..a657ab5 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -21,10 +21,12 @@ #include <linux/seq_file.h> #include <linux/string.h> #include <linux/vmalloc.h> +#include <linux/mutex.h> #include <linux/netfilter/x_tables.h> #include <linux/netfilter_arp.h> + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); MODULE_DESCRIPTION("[ip,ip6,arp]_tables backend module"); @@ -32,7 +34,7 @@ MODULE_DESCRIPTION("[ip,ip6,arp]_tables backend module"); #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) struct xt_af { - struct semaphore mutex; + struct mutex mutex; struct list_head match; struct list_head target; struct list_head tables; @@ -64,11 +66,11 @@ xt_register_target(struct xt_target *target) { int ret, af = target->family; - ret = down_interruptible(&xt[af].mutex); + ret = mutex_lock_interruptible(&xt[af].mutex); if (ret != 0) return ret; list_add(&target->list, &xt[af].target); - up(&xt[af].mutex); + mutex_unlock(&xt[af].mutex); return ret; } EXPORT_SYMBOL(xt_register_target); @@ -78,9 +80,9 @@ xt_unregister_target(struct xt_target *target) { int af = target->family; - down(&xt[af].mutex); + mutex_lock(&xt[af].mutex); LIST_DELETE(&xt[af].target, target); - up(&xt[af].mutex); + mutex_unlock(&xt[af].mutex); } EXPORT_SYMBOL(xt_unregister_target); @@ -89,12 +91,12 @@ xt_register_match(struct xt_match *match) { int ret, af = match->family; - ret = down_interruptible(&xt[af].mutex); + ret = mutex_lock_interruptible(&xt[af].mutex); if (ret != 0) return ret; list_add(&match->list, &xt[af].match); - up(&xt[af].mutex); + mutex_unlock(&xt[af].mutex); return ret; } @@ -105,9 +107,9 @@ xt_unregister_match(struct xt_match *match) { int af = match->family; - down(&xt[af].mutex); + mutex_lock(&xt[af].mutex); LIST_DELETE(&xt[af].match, match); - up(&xt[af].mutex); + mutex_unlock(&xt[af].mutex); } EXPORT_SYMBOL(xt_unregister_match); @@ -124,21 +126,21 @@ struct xt_match *xt_find_match(int af, const char *name, u8 revision) struct xt_match *m; int err = 0; - if (down_interruptible(&xt[af].mutex) != 0) + if (mutex_lock_interruptible(&xt[af].mutex) != 0) return ERR_PTR(-EINTR); list_for_each_entry(m, &xt[af].match, list) { if (strcmp(m->name, name) == 0) { if (m->revision == revision) { if (try_module_get(m->me)) { - up(&xt[af].mutex); + mutex_unlock(&xt[af].mutex); return m; } } else err = -EPROTOTYPE; /* Found something. */ } } - up(&xt[af].mutex); + mutex_unlock(&xt[af].mutex); return ERR_PTR(err); } EXPORT_SYMBOL(xt_find_match); @@ -149,21 +151,21 @@ struct xt_target *xt_find_target(int af, const char *name, u8 revision) struct xt_target *t; int err = 0; - if (down_interruptible(&xt[af].mutex) != 0) + if (mutex_lock_interruptible(&xt[af].mutex) != 0) return ERR_PTR(-EINTR); list_for_each_entry(t, &xt[af].target, list) { if (strcmp(t->name, name) == 0) { if (t->revision == revision) { if (try_module_get(t->me)) { - up(&xt[af].mutex); + mutex_unlock(&xt[af].mutex); return t; } } else err = -EPROTOTYPE; /* Found something. */ } } - up(&xt[af].mutex); + mutex_unlock(&xt[af].mutex); return ERR_PTR(err); } EXPORT_SYMBOL(xt_find_target); @@ -218,7 +220,7 @@ int xt_find_revision(int af, const char *name, u8 revision, int target, { int have_rev, best = -1; - if (down_interruptible(&xt[af].mutex) != 0) { + if (mutex_lock_interruptible(&xt[af].mutex) != 0) { *err = -EINTR; return 1; } @@ -226,7 +228,7 @@ int xt_find_revision(int af, const char *name, u8 revision, int target, have_rev = target_revfn(af, name, revision, &best); else have_rev = match_revfn(af, name, revision, &best); - up(&xt[af].mutex); + mutex_unlock(&xt[af].mutex); /* Nothing at all? Return 0 to try loading module. */ if (best == -1) { @@ -352,20 +354,20 @@ struct xt_table *xt_find_table_lock(int af, const char *name) { struct xt_table *t; - if (down_interruptible(&xt[af].mutex) != 0) + if (mutex_lock_interruptible(&xt[af].mutex) != 0) return ERR_PTR(-EINTR); list_for_each_entry(t, &xt[af].tables, list) if (strcmp(t->name, name) == 0 && try_module_get(t->me)) return t; - up(&xt[af].mutex); + mutex_unlock(&xt[af].mutex); return NULL; } EXPORT_SYMBOL_GPL(xt_find_table_lock); void xt_table_unlock(struct xt_table *table) { - up(&xt[table->af].mutex); + mutex_unlock(&xt[table->af].mutex); } EXPORT_SYMBOL_GPL(xt_table_unlock); @@ -405,7 +407,7 @@ int xt_register_table(struct xt_table *table, int ret; struct xt_table_info *private; - ret = down_interruptible(&xt[table->af].mutex); + ret = mutex_lock_interruptible(&xt[table->af].mutex); if (ret != 0) return ret; @@ -431,7 +433,7 @@ int xt_register_table(struct xt_table *table, ret = 0; unlock: - up(&xt[table->af].mutex); + mutex_unlock(&xt[table->af].mutex); return ret; } EXPORT_SYMBOL_GPL(xt_register_table); @@ -440,10 +442,10 @@ void *xt_unregister_table(struct xt_table *table) { struct xt_table_info *private; - down(&xt[table->af].mutex); + mutex_lock(&xt[table->af].mutex); private = table->private; LIST_DELETE(&xt[table->af].tables, table); - up(&xt[table->af].mutex); + mutex_unlock(&xt[table->af].mutex); return private; } @@ -507,7 +509,7 @@ static void *xt_tgt_seq_start(struct seq_file *seq, loff_t *pos) if (!list) return NULL; - if (down_interruptible(&xt[af].mutex) != 0) + if (mutex_lock_interruptible(&xt[af].mutex) != 0) return NULL; return xt_get_idx(list, seq, *pos); @@ -536,7 +538,7 @@ static void xt_tgt_seq_stop(struct seq_file *seq, void *v) struct proc_dir_entry *pde = seq->private; u_int16_t af = (unsigned long)pde->data & 0xffff; - up(&xt[af].mutex); + mutex_unlock(&xt[af].mutex); } static int xt_name_seq_show(struct seq_file *seq, void *v) @@ -668,7 +670,7 @@ static int __init xt_init(void) return -ENOMEM; for (i = 0; i < NPROTO; i++) { - init_MUTEX(&xt[i].mutex); + mutex_init(&xt[i].mutex); INIT_LIST_HEAD(&xt[i].target); INIT_LIST_HEAD(&xt[i].match); INIT_LIST_HEAD(&xt[i].tables); diff --git a/net/netfilter/xt_CLASSIFY.c b/net/netfilter/xt_CLASSIFY.c index 3cd2ac9..e54e577 100644 --- a/net/netfilter/xt_CLASSIFY.c +++ b/net/netfilter/xt_CLASSIFY.c @@ -62,7 +62,7 @@ static struct xt_target classify6_reg = { }; -static int __init init(void) +static int __init xt_classify_init(void) { int ret; @@ -77,11 +77,11 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit xt_classify_fini(void) { xt_unregister_target(&classify_reg); xt_unregister_target(&classify6_reg); } -module_init(init); -module_exit(fini); +module_init(xt_classify_init); +module_exit(xt_classify_fini); diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c index 35448b8..60c375d 100644 --- a/net/netfilter/xt_CONNMARK.c +++ b/net/netfilter/xt_CONNMARK.c @@ -115,7 +115,7 @@ static struct xt_target connmark6_reg = { .me = THIS_MODULE }; -static int __init init(void) +static int __init xt_connmark_init(void) { int ret; @@ -132,11 +132,11 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit xt_connmark_fini(void) { xt_unregister_target(&connmark_reg); xt_unregister_target(&connmark6_reg); } -module_init(init); -module_exit(fini); +module_init(xt_connmark_init); +module_exit(xt_connmark_fini); diff --git a/net/netfilter/xt_MARK.c b/net/netfilter/xt_MARK.c index 73bdd5c..ee9c34e 100644 --- a/net/netfilter/xt_MARK.c +++ b/net/netfilter/xt_MARK.c @@ -145,7 +145,7 @@ static struct xt_target ip6t_mark_reg_v0 = { .revision = 0, }; -static int __init init(void) +static int __init xt_mark_init(void) { int err; @@ -166,12 +166,12 @@ static int __init init(void) return err; } -static void __exit fini(void) +static void __exit xt_mark_fini(void) { xt_unregister_target(&ipt_mark_reg_v0); xt_unregister_target(&ipt_mark_reg_v1); xt_unregister_target(&ip6t_mark_reg_v0); } -module_init(init); -module_exit(fini); +module_init(xt_mark_init); +module_exit(xt_mark_fini); diff --git a/net/netfilter/xt_NFQUEUE.c b/net/netfilter/xt_NFQUEUE.c index 2873e1c..86ccceb 100644 --- a/net/netfilter/xt_NFQUEUE.c +++ b/net/netfilter/xt_NFQUEUE.c @@ -61,7 +61,7 @@ static struct xt_target arpt_NFQ_reg = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init xt_nfqueue_init(void) { int ret; ret = xt_register_target(&ipt_NFQ_reg); @@ -83,12 +83,12 @@ out_ip: return ret; } -static void __exit fini(void) +static void __exit xt_nfqueue_fini(void) { xt_unregister_target(&arpt_NFQ_reg); xt_unregister_target(&ip6t_NFQ_reg); xt_unregister_target(&ipt_NFQ_reg); } -module_init(init); -module_exit(fini); +module_init(xt_nfqueue_init); +module_exit(xt_nfqueue_fini); diff --git a/net/netfilter/xt_NOTRACK.c b/net/netfilter/xt_NOTRACK.c index cf2ebd7..98f4b53 100644 --- a/net/netfilter/xt_NOTRACK.c +++ b/net/netfilter/xt_NOTRACK.c @@ -52,7 +52,7 @@ static struct xt_target notrack6_reg = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init xt_notrack_init(void) { int ret; @@ -67,11 +67,11 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit xt_notrack_fini(void) { xt_unregister_target(¬rack6_reg); xt_unregister_target(¬rack_reg); } -module_init(init); -module_exit(fini); +module_init(xt_notrack_init); +module_exit(xt_notrack_fini); diff --git a/net/netfilter/xt_comment.c b/net/netfilter/xt_comment.c index 2637724..197609c 100644 --- a/net/netfilter/xt_comment.c +++ b/net/netfilter/xt_comment.c @@ -45,7 +45,7 @@ static struct xt_match comment6_match = { .me = THIS_MODULE }; -static int __init init(void) +static int __init xt_comment_init(void) { int ret; @@ -60,11 +60,11 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit xt_comment_fini(void) { xt_unregister_match(&comment_match); xt_unregister_match(&comment6_match); } -module_init(init); -module_exit(fini); +module_init(xt_comment_init); +module_exit(xt_comment_fini); diff --git a/net/netfilter/xt_connbytes.c b/net/netfilter/xt_connbytes.c index 4985f5e..1396fe2 100644 --- a/net/netfilter/xt_connbytes.c +++ b/net/netfilter/xt_connbytes.c @@ -160,7 +160,7 @@ static struct xt_match connbytes6_match = { .me = THIS_MODULE }; -static int __init init(void) +static int __init xt_connbytes_init(void) { int ret; ret = xt_register_match(&connbytes_match); @@ -173,11 +173,11 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit xt_connbytes_fini(void) { xt_unregister_match(&connbytes_match); xt_unregister_match(&connbytes6_match); } -module_init(init); -module_exit(fini); +module_init(xt_connbytes_init); +module_exit(xt_connbytes_fini); diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c index 7b16f1e..dc26a27 100644 --- a/net/netfilter/xt_connmark.c +++ b/net/netfilter/xt_connmark.c @@ -102,7 +102,7 @@ static struct xt_match connmark6_match = { .me = THIS_MODULE }; -static int __init init(void) +static int __init xt_connmark_init(void) { int ret; @@ -118,11 +118,11 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit xt_connmark_fini(void) { xt_unregister_match(&connmark6_match); xt_unregister_match(&connmark_match); } -module_init(init); -module_exit(fini); +module_init(xt_connmark_init); +module_exit(xt_connmark_fini); diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c index 65a8480..145489a 100644 --- a/net/netfilter/xt_conntrack.c +++ b/net/netfilter/xt_conntrack.c @@ -239,7 +239,7 @@ static struct xt_match conntrack_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init xt_conntrack_init(void) { int ret; need_conntrack(); @@ -248,10 +248,10 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit xt_conntrack_fini(void) { xt_unregister_match(&conntrack_match); } -module_init(init); -module_exit(fini); +module_init(xt_conntrack_init); +module_exit(xt_conntrack_fini); diff --git a/net/netfilter/xt_dccp.c b/net/netfilter/xt_dccp.c index 2f331de..dfb10b6 100644 --- a/net/netfilter/xt_dccp.c +++ b/net/netfilter/xt_dccp.c @@ -164,7 +164,7 @@ static struct xt_match dccp6_match = }; -static int __init init(void) +static int __init xt_dccp_init(void) { int ret; @@ -191,12 +191,12 @@ out_kfree: return ret; } -static void __exit fini(void) +static void __exit xt_dccp_fini(void) { xt_unregister_match(&dccp6_match); xt_unregister_match(&dccp_match); kfree(dccp_optbuf); } -module_init(init); -module_exit(fini); +module_init(xt_dccp_init); +module_exit(xt_dccp_fini); diff --git a/net/netfilter/xt_helper.c b/net/netfilter/xt_helper.c index 101f000..799c2a4 100644 --- a/net/netfilter/xt_helper.c +++ b/net/netfilter/xt_helper.c @@ -182,7 +182,7 @@ static struct xt_match helper6_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init xt_helper_init(void) { int ret; need_conntrack(); @@ -198,12 +198,12 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit xt_helper_fini(void) { xt_unregister_match(&helper_match); xt_unregister_match(&helper6_match); } -module_init(init); -module_exit(fini); +module_init(xt_helper_init); +module_exit(xt_helper_fini); diff --git a/net/netfilter/xt_length.c b/net/netfilter/xt_length.c index 38560ca..109132c 100644 --- a/net/netfilter/xt_length.c +++ b/net/netfilter/xt_length.c @@ -68,7 +68,7 @@ static struct xt_match length6_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init xt_length_init(void) { int ret; ret = xt_register_match(&length_match); @@ -81,11 +81,11 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit xt_length_fini(void) { xt_unregister_match(&length_match); xt_unregister_match(&length6_match); } -module_init(init); -module_exit(fini); +module_init(xt_length_init); +module_exit(xt_length_fini); diff --git a/net/netfilter/xt_limit.c b/net/netfilter/xt_limit.c index e91c1a4..ce7fdb7 100644 --- a/net/netfilter/xt_limit.c +++ b/net/netfilter/xt_limit.c @@ -153,7 +153,7 @@ static struct xt_match limit6_reg = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init xt_limit_init(void) { int ret; @@ -168,11 +168,11 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit xt_limit_fini(void) { xt_unregister_match(&ipt_limit_reg); xt_unregister_match(&limit6_reg); } -module_init(init); -module_exit(fini); +module_init(xt_limit_init); +module_exit(xt_limit_fini); diff --git a/net/netfilter/xt_mac.c b/net/netfilter/xt_mac.c index f4defa2..356290f 100644 --- a/net/netfilter/xt_mac.c +++ b/net/netfilter/xt_mac.c @@ -62,7 +62,7 @@ static struct xt_match mac6_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init xt_mac_init(void) { int ret; ret = xt_register_match(&mac_match); @@ -76,11 +76,11 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit xt_mac_fini(void) { xt_unregister_match(&mac_match); xt_unregister_match(&mac6_match); } -module_init(init); -module_exit(fini); +module_init(xt_mac_init); +module_exit(xt_mac_fini); diff --git a/net/netfilter/xt_mark.c b/net/netfilter/xt_mark.c index ce0badf..8b385a3 100644 --- a/net/netfilter/xt_mark.c +++ b/net/netfilter/xt_mark.c @@ -69,7 +69,7 @@ static struct xt_match mark6_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init xt_mark_init(void) { int ret; ret = xt_register_match(&mark_match); @@ -83,11 +83,11 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit xt_mark_fini(void) { xt_unregister_match(&mark_match); xt_unregister_match(&mark6_match); } -module_init(init); -module_exit(fini); +module_init(xt_mark_init); +module_exit(xt_mark_fini); diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c index 089f4f7..5fe4c9d 100644 --- a/net/netfilter/xt_physdev.c +++ b/net/netfilter/xt_physdev.c @@ -134,7 +134,7 @@ static struct xt_match physdev6_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init xt_physdev_init(void) { int ret; @@ -149,11 +149,11 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit xt_physdev_fini(void) { xt_unregister_match(&physdev_match); xt_unregister_match(&physdev6_match); } -module_init(init); -module_exit(fini); +module_init(xt_physdev_init); +module_exit(xt_physdev_fini); diff --git a/net/netfilter/xt_pkttype.c b/net/netfilter/xt_pkttype.c index 8b8bca9..3ac703b 100644 --- a/net/netfilter/xt_pkttype.c +++ b/net/netfilter/xt_pkttype.c @@ -49,7 +49,7 @@ static struct xt_match pkttype6_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init xt_pkttype_init(void) { int ret; ret = xt_register_match(&pkttype_match); @@ -63,11 +63,11 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit xt_pkttype_fini(void) { xt_unregister_match(&pkttype_match); xt_unregister_match(&pkttype6_match); } -module_init(init); -module_exit(fini); +module_init(xt_pkttype_init); +module_exit(xt_pkttype_fini); diff --git a/net/netfilter/xt_realm.c b/net/netfilter/xt_realm.c index 5e31a4a..a80b7d13 100644 --- a/net/netfilter/xt_realm.c +++ b/net/netfilter/xt_realm.c @@ -49,15 +49,15 @@ static struct xt_match realm_match = { .me = THIS_MODULE }; -static int __init init(void) +static int __init xt_realm_init(void) { return xt_register_match(&realm_match); } -static void __exit fini(void) +static void __exit xt_realm_fini(void) { xt_unregister_match(&realm_match); } -module_init(init); -module_exit(fini); +module_init(xt_realm_init); +module_exit(xt_realm_fini); diff --git a/net/netfilter/xt_sctp.c b/net/netfilter/xt_sctp.c index c6eb24a..34bd872 100644 --- a/net/netfilter/xt_sctp.c +++ b/net/netfilter/xt_sctp.c @@ -200,7 +200,7 @@ static struct xt_match sctp6_match = { .me = THIS_MODULE }; -static int __init init(void) +static int __init xt_sctp_init(void) { int ret; ret = xt_register_match(&sctp_match); @@ -214,11 +214,11 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit xt_sctp_fini(void) { xt_unregister_match(&sctp6_match); xt_unregister_match(&sctp_match); } -module_init(init); -module_exit(fini); +module_init(xt_sctp_init); +module_exit(xt_sctp_fini); diff --git a/net/netfilter/xt_state.c b/net/netfilter/xt_state.c index e6c0be9..f9e304d 100644 --- a/net/netfilter/xt_state.c +++ b/net/netfilter/xt_state.c @@ -89,7 +89,7 @@ static struct xt_match state6_match = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init xt_state_init(void) { int ret; @@ -106,11 +106,11 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit xt_state_fini(void) { xt_unregister_match(&state_match); xt_unregister_match(&state6_match); } -module_init(init); -module_exit(fini); +module_init(xt_state_init); +module_exit(xt_state_fini); diff --git a/net/netfilter/xt_string.c b/net/netfilter/xt_string.c index 703d80f..79d9ea6 100644 --- a/net/netfilter/xt_string.c +++ b/net/netfilter/xt_string.c @@ -91,7 +91,7 @@ static struct xt_match string6_match = { .me = THIS_MODULE }; -static int __init init(void) +static int __init xt_string_init(void) { int ret; @@ -105,11 +105,11 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit xt_string_fini(void) { xt_unregister_match(&string_match); xt_unregister_match(&string6_match); } -module_init(init); -module_exit(fini); +module_init(xt_string_init); +module_exit(xt_string_fini); diff --git a/net/netfilter/xt_tcpmss.c b/net/netfilter/xt_tcpmss.c index 70a8858..cf7d335c 100644 --- a/net/netfilter/xt_tcpmss.c +++ b/net/netfilter/xt_tcpmss.c @@ -112,7 +112,7 @@ static struct xt_match tcpmss6_match = { }; -static int __init init(void) +static int __init xt_tcpmss_init(void) { int ret; ret = xt_register_match(&tcpmss_match); @@ -126,11 +126,11 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit xt_tcpmss_fini(void) { xt_unregister_match(&tcpmss6_match); xt_unregister_match(&tcpmss_match); } -module_init(init); -module_exit(fini); +module_init(xt_tcpmss_init); +module_exit(xt_tcpmss_fini); diff --git a/net/netfilter/xt_tcpudp.c b/net/netfilter/xt_tcpudp.c index 14a990e..1b61dac 100644 --- a/net/netfilter/xt_tcpudp.c +++ b/net/netfilter/xt_tcpudp.c @@ -238,7 +238,7 @@ static struct xt_match udp6_matchstruct = { .me = THIS_MODULE, }; -static int __init init(void) +static int __init xt_tcpudp_init(void) { int ret; ret = xt_register_match(&tcp_matchstruct); @@ -268,7 +268,7 @@ out_unreg_tcp: return ret; } -static void __exit fini(void) +static void __exit xt_tcpudp_fini(void) { xt_unregister_match(&udp6_matchstruct); xt_unregister_match(&udp_matchstruct); @@ -276,5 +276,5 @@ static void __exit fini(void) xt_unregister_match(&tcp_matchstruct); } -module_init(init); -module_exit(fini); +module_init(xt_tcpudp_init); +module_exit(xt_tcpudp_fini); diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index d00a903..2a233ff 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -123,7 +123,7 @@ static void netlink_destroy_callback(struct netlink_callback *cb); static DEFINE_RWLOCK(nl_table_lock); static atomic_t nl_table_users = ATOMIC_INIT(0); -static struct notifier_block *netlink_chain; +static ATOMIC_NOTIFIER_HEAD(netlink_chain); static u32 netlink_group_mask(u32 group) { @@ -469,7 +469,8 @@ static int netlink_release(struct socket *sock) .protocol = sk->sk_protocol, .pid = nlk->pid, }; - notifier_call_chain(&netlink_chain, NETLINK_URELEASE, &n); + atomic_notifier_call_chain(&netlink_chain, + NETLINK_URELEASE, &n); } if (nlk->module) @@ -1695,12 +1696,12 @@ static struct file_operations netlink_seq_fops = { int netlink_register_notifier(struct notifier_block *nb) { - return notifier_chain_register(&netlink_chain, nb); + return atomic_notifier_chain_register(&netlink_chain, nb); } int netlink_unregister_notifier(struct notifier_block *nb) { - return notifier_chain_unregister(&netlink_chain, nb); + return atomic_notifier_chain_unregister(&netlink_chain, nb); } static const struct proto_ops netlink_ops = { diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 43e7241..f329b72 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -13,26 +13,27 @@ #include <linux/socket.h> #include <linux/string.h> #include <linux/skbuff.h> +#include <linux/mutex.h> #include <net/sock.h> #include <net/genetlink.h> struct sock *genl_sock = NULL; -static DECLARE_MUTEX(genl_sem); /* serialization of message processing */ +static DEFINE_MUTEX(genl_mutex); /* serialization of message processing */ static void genl_lock(void) { - down(&genl_sem); + mutex_lock(&genl_mutex); } static int genl_trylock(void) { - return down_trylock(&genl_sem); + return !mutex_trylock(&genl_mutex); } static void genl_unlock(void) { - up(&genl_sem); + mutex_unlock(&genl_mutex); if (genl_sock && genl_sock->sk_receive_queue.qlen) genl_sock->sk_data_ready(genl_sock, 0); diff --git a/net/nonet.c b/net/nonet.c index 1230f0a..92e7664 100644 --- a/net/nonet.c +++ b/net/nonet.c @@ -19,7 +19,7 @@ static int sock_no_open(struct inode *irrelevant, struct file *dontcare) return -ENXIO; } -struct file_operations bad_sock_fops = { +const struct file_operations bad_sock_fops = { .owner = THIS_MODULE, .open = sock_no_open, }; diff --git a/net/rxrpc/main.c b/net/rxrpc/main.c index 36fdcbc..48cbd06 100644 --- a/net/rxrpc/main.c +++ b/net/rxrpc/main.c @@ -79,8 +79,8 @@ static int __init rxrpc_initialise(void) error_sysctl: #ifdef CONFIG_SYSCTL rxrpc_sysctl_cleanup(); -#endif error_proc: +#endif #ifdef CONFIG_PROC_FS rxrpc_proc_cleanup(); #endif diff --git a/net/sctp/input.c b/net/sctp/input.c index cb78b50..d117ebc 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -127,7 +127,6 @@ int sctp_rcv(struct sk_buff *skb) union sctp_addr dest; int family; struct sctp_af *af; - int ret = 0; if (skb->pkt_type!=PACKET_HOST) goto discard_it; @@ -227,16 +226,13 @@ int sctp_rcv(struct sk_buff *skb) goto discard_release; nf_reset(skb); - ret = sk_filter(sk, skb, 1); - if (ret) + if (sk_filter(sk, skb, 1)) goto discard_release; /* Create an SCTP packet structure. */ chunk = sctp_chunkify(skb, asoc, sk); - if (!chunk) { - ret = -ENOMEM; + if (!chunk) goto discard_release; - } SCTP_INPUT_CB(skb)->chunk = chunk; /* Remember what endpoint is to handle this packet. */ @@ -277,11 +273,11 @@ int sctp_rcv(struct sk_buff *skb) sctp_bh_unlock_sock(sk); sock_put(sk); - return ret; + return 0; discard_it: kfree_skb(skb); - return ret; + return 0; discard_release: /* Release any structures we may be holding. */ diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 0ea947e..b6e4b89 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -4894,6 +4894,8 @@ unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait) /* Is there any exceptional events? */ if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) mask |= POLLERR; + if (sk->sk_shutdown & RCV_SHUTDOWN) + mask |= POLLRDHUP; if (sk->sk_shutdown == SHUTDOWN_MASK) mask |= POLLHUP; diff --git a/net/socket.c b/net/socket.c index 5211ba2..fcd77ea 100644 --- a/net/socket.c +++ b/net/socket.c @@ -539,7 +539,7 @@ static int sock_no_open(struct inode *irrelevant, struct file *dontcare) return -ENXIO; } -struct file_operations bad_sock_fops = { +const struct file_operations bad_sock_fops = { .owner = THIS_MODULE, .open = sock_no_open, }; diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 8d6f1a1..55163af 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c @@ -64,14 +64,26 @@ rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt) struct rpc_authops *ops; u32 flavor = pseudoflavor_to_flavor(pseudoflavor); - if (flavor >= RPC_AUTH_MAXFLAVOR || !(ops = auth_flavors[flavor])) - return ERR_PTR(-EINVAL); + auth = ERR_PTR(-EINVAL); + if (flavor >= RPC_AUTH_MAXFLAVOR) + goto out; + + /* FIXME - auth_flavors[] really needs an rw lock, + * and module refcounting. */ +#ifdef CONFIG_KMOD + if ((ops = auth_flavors[flavor]) == NULL) + request_module("rpc-auth-%u", flavor); +#endif + if ((ops = auth_flavors[flavor]) == NULL) + goto out; auth = ops->create(clnt, pseudoflavor); if (IS_ERR(auth)) return auth; if (clnt->cl_auth) rpcauth_destroy(clnt->cl_auth); clnt->cl_auth = auth; + +out: return auth; } diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index bb46efd..900ef31 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -721,6 +721,8 @@ gss_destroy(struct rpc_auth *auth) gss_auth = container_of(auth, struct gss_auth, rpc_auth); rpc_unlink(gss_auth->path); + dput(gss_auth->dentry); + gss_auth->dentry = NULL; gss_mech_put(gss_auth->mech); rpcauth_free_credcache(auth); diff --git a/net/sunrpc/auth_gss/gss_krb5_seal.c b/net/sunrpc/auth_gss/gss_krb5_seal.c index d0dfdfd..f433112 100644 --- a/net/sunrpc/auth_gss/gss_krb5_seal.c +++ b/net/sunrpc/auth_gss/gss_krb5_seal.c @@ -70,15 +70,19 @@ # define RPCDBG_FACILITY RPCDBG_AUTH #endif +spinlock_t krb5_seq_lock = SPIN_LOCK_UNLOCKED; + u32 gss_get_mic_kerberos(struct gss_ctx *gss_ctx, struct xdr_buf *text, struct xdr_netobj *token) { struct krb5_ctx *ctx = gss_ctx->internal_ctx_id; s32 checksum_type; - struct xdr_netobj md5cksum = {.len = 0, .data = NULL}; + char cksumdata[16]; + struct xdr_netobj md5cksum = {.len = 0, .data = cksumdata}; unsigned char *ptr, *krb5_hdr, *msg_start; s32 now; + u32 seq_send; dprintk("RPC: gss_krb5_seal\n"); @@ -133,16 +137,15 @@ gss_get_mic_kerberos(struct gss_ctx *gss_ctx, struct xdr_buf *text, BUG(); } - kfree(md5cksum.data); + spin_lock(&krb5_seq_lock); + seq_send = ctx->seq_send++; + spin_unlock(&krb5_seq_lock); if ((krb5_make_seq_num(ctx->seq, ctx->initiate ? 0 : 0xff, - ctx->seq_send, krb5_hdr + 16, krb5_hdr + 8))) + seq_send, krb5_hdr + 16, krb5_hdr + 8))) goto out_err; - ctx->seq_send++; - return ((ctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE); out_err: - kfree(md5cksum.data); return GSS_S_FAILURE; } diff --git a/net/sunrpc/auth_gss/gss_krb5_unseal.c b/net/sunrpc/auth_gss/gss_krb5_unseal.c index db055fd..0828cf6 100644 --- a/net/sunrpc/auth_gss/gss_krb5_unseal.c +++ b/net/sunrpc/auth_gss/gss_krb5_unseal.c @@ -79,7 +79,8 @@ gss_verify_mic_kerberos(struct gss_ctx *gss_ctx, int signalg; int sealalg; s32 checksum_type; - struct xdr_netobj md5cksum = {.len = 0, .data = NULL}; + char cksumdata[16]; + struct xdr_netobj md5cksum = {.len = 0, .data = cksumdata}; s32 now; int direction; s32 seqnum; @@ -176,6 +177,5 @@ gss_verify_mic_kerberos(struct gss_ctx *gss_ctx, ret = GSS_S_COMPLETE; out: - kfree(md5cksum.data); return ret; } diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c index af777cf..89d1f3e 100644 --- a/net/sunrpc/auth_gss/gss_krb5_wrap.c +++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c @@ -121,12 +121,14 @@ gss_wrap_kerberos(struct gss_ctx *ctx, int offset, { struct krb5_ctx *kctx = ctx->internal_ctx_id; s32 checksum_type; - struct xdr_netobj md5cksum = {.len = 0, .data = NULL}; + char cksumdata[16]; + struct xdr_netobj md5cksum = {.len = 0, .data = cksumdata}; int blocksize = 0, plainlen; unsigned char *ptr, *krb5_hdr, *msg_start; s32 now; int headlen; struct page **tmp_pages; + u32 seq_send; dprintk("RPC: gss_wrap_kerberos\n"); @@ -205,23 +207,22 @@ gss_wrap_kerberos(struct gss_ctx *ctx, int offset, BUG(); } - kfree(md5cksum.data); + spin_lock(&krb5_seq_lock); + seq_send = kctx->seq_send++; + spin_unlock(&krb5_seq_lock); /* XXX would probably be more efficient to compute checksum * and encrypt at the same time: */ if ((krb5_make_seq_num(kctx->seq, kctx->initiate ? 0 : 0xff, - kctx->seq_send, krb5_hdr + 16, krb5_hdr + 8))) + seq_send, krb5_hdr + 16, krb5_hdr + 8))) goto out_err; if (gss_encrypt_xdr_buf(kctx->enc, buf, offset + headlen - blocksize, pages)) goto out_err; - kctx->seq_send++; - return ((kctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE); out_err: - if (md5cksum.data) kfree(md5cksum.data); return GSS_S_FAILURE; } @@ -232,7 +233,8 @@ gss_unwrap_kerberos(struct gss_ctx *ctx, int offset, struct xdr_buf *buf) int signalg; int sealalg; s32 checksum_type; - struct xdr_netobj md5cksum = {.len = 0, .data = NULL}; + char cksumdata[16]; + struct xdr_netobj md5cksum = {.len = 0, .data = cksumdata}; s32 now; int direction; s32 seqnum; @@ -358,6 +360,5 @@ gss_unwrap_kerberos(struct gss_ctx *ctx, int offset, struct xdr_buf *buf) ret = GSS_S_COMPLETE; out: - if (md5cksum.data) kfree(md5cksum.data); return ret; } diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c index 5840080..5bf11cc 100644 --- a/net/sunrpc/auth_gss/gss_spkm3_mech.c +++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c @@ -102,6 +102,12 @@ get_key(const void *p, const void *end, struct crypto_tfm **res, int *resalg) alg_mode = CRYPTO_TFM_MODE_CBC; setkey = 1; break; + case NID_cast5_cbc: + /* XXXX here in name only, not used */ + alg_name = "cast5"; + alg_mode = CRYPTO_TFM_MODE_CBC; + setkey = 0; /* XXX will need to set to 1 */ + break; case NID_md5: if (key.len == 0) { dprintk("RPC: SPKM3 get_key: NID_md5 zero Key length\n"); diff --git a/net/sunrpc/auth_gss/gss_spkm3_seal.c b/net/sunrpc/auth_gss/gss_spkm3_seal.c index 86fbf7c..18c7862 100644 --- a/net/sunrpc/auth_gss/gss_spkm3_seal.c +++ b/net/sunrpc/auth_gss/gss_spkm3_seal.c @@ -57,7 +57,8 @@ spkm3_make_token(struct spkm3_ctx *ctx, { s32 checksum_type; char tokhdrbuf[25]; - struct xdr_netobj md5cksum = {.len = 0, .data = NULL}; + char cksumdata[16]; + struct xdr_netobj md5cksum = {.len = 0, .data = cksumdata}; struct xdr_netobj mic_hdr = {.len = 0, .data = tokhdrbuf}; int tokenlen = 0; unsigned char *ptr; @@ -115,13 +116,11 @@ spkm3_make_token(struct spkm3_ctx *ctx, dprintk("RPC: gss_spkm3_seal: SPKM_WRAP_TOK not supported\n"); goto out_err; } - kfree(md5cksum.data); /* XXX need to implement sequence numbers, and ctx->expired */ return GSS_S_COMPLETE; out_err: - kfree(md5cksum.data); token->data = NULL; token->len = 0; return GSS_S_FAILURE; diff --git a/net/sunrpc/auth_gss/gss_spkm3_unseal.c b/net/sunrpc/auth_gss/gss_spkm3_unseal.c index 96851b0..8537f58 100644 --- a/net/sunrpc/auth_gss/gss_spkm3_unseal.c +++ b/net/sunrpc/auth_gss/gss_spkm3_unseal.c @@ -56,7 +56,8 @@ spkm3_read_token(struct spkm3_ctx *ctx, { s32 code; struct xdr_netobj wire_cksum = {.len =0, .data = NULL}; - struct xdr_netobj md5cksum = {.len = 0, .data = NULL}; + char cksumdata[16]; + struct xdr_netobj md5cksum = {.len = 0, .data = cksumdata}; unsigned char *ptr = (unsigned char *)read_token->data; unsigned char *cksum; int bodysize, md5elen; @@ -120,7 +121,6 @@ spkm3_read_token(struct spkm3_ctx *ctx, /* XXX: need to add expiration and sequencing */ ret = GSS_S_COMPLETE; out: - kfree(md5cksum.data); kfree(wire_cksum.data); return ret; } diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 23632d8..4d7eb9e 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c @@ -78,7 +78,8 @@ struct rsi { static struct cache_head *rsi_table[RSI_HASHMAX]; static struct cache_detail rsi_cache; -static struct rsi *rsi_lookup(struct rsi *item, int set); +static struct rsi *rsi_update(struct rsi *new, struct rsi *old); +static struct rsi *rsi_lookup(struct rsi *item); static void rsi_free(struct rsi *rsii) { @@ -88,13 +89,11 @@ static void rsi_free(struct rsi *rsii) kfree(rsii->out_token.data); } -static void rsi_put(struct cache_head *item, struct cache_detail *cd) +static void rsi_put(struct kref *ref) { - struct rsi *rsii = container_of(item, struct rsi, h); - if (cache_put(item, cd)) { - rsi_free(rsii); - kfree(rsii); - } + struct rsi *rsii = container_of(ref, struct rsi, h.ref); + rsi_free(rsii); + kfree(rsii); } static inline int rsi_hash(struct rsi *item) @@ -103,8 +102,10 @@ static inline int rsi_hash(struct rsi *item) ^ hash_mem(item->in_token.data, item->in_token.len, RSI_HASHBITS); } -static inline int rsi_match(struct rsi *item, struct rsi *tmp) +static int rsi_match(struct cache_head *a, struct cache_head *b) { + struct rsi *item = container_of(a, struct rsi, h); + struct rsi *tmp = container_of(b, struct rsi, h); return netobj_equal(&item->in_handle, &tmp->in_handle) && netobj_equal(&item->in_token, &tmp->in_token); } @@ -125,8 +126,11 @@ static inline int dup_netobj(struct xdr_netobj *dst, struct xdr_netobj *src) return dup_to_netobj(dst, src->data, src->len); } -static inline void rsi_init(struct rsi *new, struct rsi *item) +static void rsi_init(struct cache_head *cnew, struct cache_head *citem) { + struct rsi *new = container_of(cnew, struct rsi, h); + struct rsi *item = container_of(citem, struct rsi, h); + new->out_handle.data = NULL; new->out_handle.len = 0; new->out_token.data = NULL; @@ -141,8 +145,11 @@ static inline void rsi_init(struct rsi *new, struct rsi *item) item->in_token.data = NULL; } -static inline void rsi_update(struct rsi *new, struct rsi *item) +static void update_rsi(struct cache_head *cnew, struct cache_head *citem) { + struct rsi *new = container_of(cnew, struct rsi, h); + struct rsi *item = container_of(citem, struct rsi, h); + BUG_ON(new->out_handle.data || new->out_token.data); new->out_handle.len = item->out_handle.len; item->out_handle.len = 0; @@ -157,6 +164,15 @@ static inline void rsi_update(struct rsi *new, struct rsi *item) new->minor_status = item->minor_status; } +static struct cache_head *rsi_alloc(void) +{ + struct rsi *rsii = kmalloc(sizeof(*rsii), GFP_KERNEL); + if (rsii) + return &rsii->h; + else + return NULL; +} + static void rsi_request(struct cache_detail *cd, struct cache_head *h, char **bpp, int *blen) @@ -198,6 +214,10 @@ static int rsi_parse(struct cache_detail *cd, if (dup_to_netobj(&rsii.in_token, buf, len)) goto out; + rsip = rsi_lookup(&rsii); + if (!rsip) + goto out; + rsii.h.flags = 0; /* expiry */ expiry = get_expiry(&mesg); @@ -240,12 +260,14 @@ static int rsi_parse(struct cache_detail *cd, goto out; } rsii.h.expiry_time = expiry; - rsip = rsi_lookup(&rsii, 1); + rsip = rsi_update(&rsii, rsip); status = 0; out: rsi_free(&rsii); if (rsip) - rsi_put(&rsip->h, &rsi_cache); + cache_put(&rsip->h, &rsi_cache); + else + status = -ENOMEM; return status; } @@ -257,9 +279,37 @@ static struct cache_detail rsi_cache = { .cache_put = rsi_put, .cache_request = rsi_request, .cache_parse = rsi_parse, + .match = rsi_match, + .init = rsi_init, + .update = update_rsi, + .alloc = rsi_alloc, }; -static DefineSimpleCacheLookup(rsi, 0) +static struct rsi *rsi_lookup(struct rsi *item) +{ + struct cache_head *ch; + int hash = rsi_hash(item); + + ch = sunrpc_cache_lookup(&rsi_cache, &item->h, hash); + if (ch) + return container_of(ch, struct rsi, h); + else + return NULL; +} + +static struct rsi *rsi_update(struct rsi *new, struct rsi *old) +{ + struct cache_head *ch; + int hash = rsi_hash(new); + + ch = sunrpc_cache_update(&rsi_cache, &new->h, + &old->h, hash); + if (ch) + return container_of(ch, struct rsi, h); + else + return NULL; +} + /* * The rpcsec_context cache is used to store a context that is @@ -293,7 +343,8 @@ struct rsc { static struct cache_head *rsc_table[RSC_HASHMAX]; static struct cache_detail rsc_cache; -static struct rsc *rsc_lookup(struct rsc *item, int set); +static struct rsc *rsc_update(struct rsc *new, struct rsc *old); +static struct rsc *rsc_lookup(struct rsc *item); static void rsc_free(struct rsc *rsci) { @@ -304,14 +355,12 @@ static void rsc_free(struct rsc *rsci) put_group_info(rsci->cred.cr_group_info); } -static void rsc_put(struct cache_head *item, struct cache_detail *cd) +static void rsc_put(struct kref *ref) { - struct rsc *rsci = container_of(item, struct rsc, h); + struct rsc *rsci = container_of(ref, struct rsc, h.ref); - if (cache_put(item, cd)) { - rsc_free(rsci); - kfree(rsci); - } + rsc_free(rsci); + kfree(rsci); } static inline int @@ -320,15 +369,21 @@ rsc_hash(struct rsc *rsci) return hash_mem(rsci->handle.data, rsci->handle.len, RSC_HASHBITS); } -static inline int -rsc_match(struct rsc *new, struct rsc *tmp) +static int +rsc_match(struct cache_head *a, struct cache_head *b) { + struct rsc *new = container_of(a, struct rsc, h); + struct rsc *tmp = container_of(b, struct rsc, h); + return netobj_equal(&new->handle, &tmp->handle); } -static inline void -rsc_init(struct rsc *new, struct rsc *tmp) +static void +rsc_init(struct cache_head *cnew, struct cache_head *ctmp) { + struct rsc *new = container_of(cnew, struct rsc, h); + struct rsc *tmp = container_of(ctmp, struct rsc, h); + new->handle.len = tmp->handle.len; tmp->handle.len = 0; new->handle.data = tmp->handle.data; @@ -337,9 +392,12 @@ rsc_init(struct rsc *new, struct rsc *tmp) new->cred.cr_group_info = NULL; } -static inline void -rsc_update(struct rsc *new, struct rsc *tmp) +static void +update_rsc(struct cache_head *cnew, struct cache_head *ctmp) { + struct rsc *new = container_of(cnew, struct rsc, h); + struct rsc *tmp = container_of(ctmp, struct rsc, h); + new->mechctx = tmp->mechctx; tmp->mechctx = NULL; memset(&new->seqdata, 0, sizeof(new->seqdata)); @@ -348,6 +406,16 @@ rsc_update(struct rsc *new, struct rsc *tmp) tmp->cred.cr_group_info = NULL; } +static struct cache_head * +rsc_alloc(void) +{ + struct rsc *rsci = kmalloc(sizeof(*rsci), GFP_KERNEL); + if (rsci) + return &rsci->h; + else + return NULL; +} + static int rsc_parse(struct cache_detail *cd, char *mesg, int mlen) { @@ -373,6 +441,10 @@ static int rsc_parse(struct cache_detail *cd, if (expiry == 0) goto out; + rscp = rsc_lookup(&rsci); + if (!rscp) + goto out; + /* uid, or NEGATIVE */ rv = get_int(&mesg, &rsci.cred.cr_uid); if (rv == -EINVAL) @@ -428,12 +500,14 @@ static int rsc_parse(struct cache_detail *cd, gss_mech_put(gm); } rsci.h.expiry_time = expiry; - rscp = rsc_lookup(&rsci, 1); + rscp = rsc_update(&rsci, rscp); status = 0; out: rsc_free(&rsci); if (rscp) - rsc_put(&rscp->h, &rsc_cache); + cache_put(&rscp->h, &rsc_cache); + else + status = -ENOMEM; return status; } @@ -444,9 +518,37 @@ static struct cache_detail rsc_cache = { .name = "auth.rpcsec.context", .cache_put = rsc_put, .cache_parse = rsc_parse, + .match = rsc_match, + .init = rsc_init, + .update = update_rsc, + .alloc = rsc_alloc, }; -static DefineSimpleCacheLookup(rsc, 0); +static struct rsc *rsc_lookup(struct rsc *item) +{ + struct cache_head *ch; + int hash = rsc_hash(item); + + ch = sunrpc_cache_lookup(&rsc_cache, &item->h, hash); + if (ch) + return container_of(ch, struct rsc, h); + else + return NULL; +} + +static struct rsc *rsc_update(struct rsc *new, struct rsc *old) +{ + struct cache_head *ch; + int hash = rsc_hash(new); + + ch = sunrpc_cache_update(&rsc_cache, &new->h, + &old->h, hash); + if (ch) + return container_of(ch, struct rsc, h); + else + return NULL; +} + static struct rsc * gss_svc_searchbyctx(struct xdr_netobj *handle) @@ -457,7 +559,7 @@ gss_svc_searchbyctx(struct xdr_netobj *handle) memset(&rsci, 0, sizeof(rsci)); if (dup_to_netobj(&rsci.handle, handle->data, handle->len)) return NULL; - found = rsc_lookup(&rsci, 0); + found = rsc_lookup(&rsci); rsc_free(&rsci); if (!found) return NULL; @@ -645,6 +747,8 @@ find_gss_auth_domain(struct gss_ctx *ctx, u32 svc) return auth_domain_find(name); } +static struct auth_ops svcauthops_gss; + int svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name) { @@ -655,20 +759,18 @@ svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name) new = kmalloc(sizeof(*new), GFP_KERNEL); if (!new) goto out; - cache_init(&new->h.h); + kref_init(&new->h.ref); new->h.name = kmalloc(strlen(name) + 1, GFP_KERNEL); if (!new->h.name) goto out_free_dom; strcpy(new->h.name, name); - new->h.flavour = RPC_AUTH_GSS; + new->h.flavour = &svcauthops_gss; new->pseudoflavor = pseudoflavor; - new->h.h.expiry_time = NEVER; - test = auth_domain_lookup(&new->h, 1); - if (test == &new->h) { - BUG_ON(atomic_dec_and_test(&new->h.h.refcnt)); - } else { /* XXX Duplicate registration? */ + test = auth_domain_lookup(name, &new->h); + if (test != &new->h) { /* XXX Duplicate registration? */ auth_domain_put(&new->h); + /* dangling ref-count... */ goto out; } return 0; @@ -895,7 +997,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, u32 *authp) goto drop; } - rsip = rsi_lookup(&rsikey, 0); + rsip = rsi_lookup(&rsikey); rsi_free(&rsikey); if (!rsip) { goto drop; @@ -970,7 +1072,7 @@ drop: ret = SVC_DROP; out: if (rsci) - rsc_put(&rsci->h, &rsc_cache); + cache_put(&rsci->h, &rsc_cache); return ret; } @@ -1062,7 +1164,7 @@ out_err: put_group_info(rqstp->rq_cred.cr_group_info); rqstp->rq_cred.cr_group_info = NULL; if (gsd->rsci) - rsc_put(&gsd->rsci->h, &rsc_cache); + cache_put(&gsd->rsci->h, &rsc_cache); gsd->rsci = NULL; return stat; diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 0acccfe..3ac4193 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -37,16 +37,138 @@ static void cache_defer_req(struct cache_req *req, struct cache_head *item); static void cache_revisit_request(struct cache_head *item); -void cache_init(struct cache_head *h) +static void cache_init(struct cache_head *h) { time_t now = get_seconds(); h->next = NULL; h->flags = 0; - atomic_set(&h->refcnt, 1); + kref_init(&h->ref); h->expiry_time = now + CACHE_NEW_EXPIRY; h->last_refresh = now; } +struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail, + struct cache_head *key, int hash) +{ + struct cache_head **head, **hp; + struct cache_head *new = NULL; + + head = &detail->hash_table[hash]; + + read_lock(&detail->hash_lock); + + for (hp=head; *hp != NULL ; hp = &(*hp)->next) { + struct cache_head *tmp = *hp; + if (detail->match(tmp, key)) { + cache_get(tmp); + read_unlock(&detail->hash_lock); + return tmp; + } + } + read_unlock(&detail->hash_lock); + /* Didn't find anything, insert an empty entry */ + + new = detail->alloc(); + if (!new) + return NULL; + cache_init(new); + + write_lock(&detail->hash_lock); + + /* check if entry appeared while we slept */ + for (hp=head; *hp != NULL ; hp = &(*hp)->next) { + struct cache_head *tmp = *hp; + if (detail->match(tmp, key)) { + cache_get(tmp); + write_unlock(&detail->hash_lock); + cache_put(new, detail); + return tmp; + } + } + detail->init(new, key); + new->next = *head; + *head = new; + detail->entries++; + cache_get(new); + write_unlock(&detail->hash_lock); + + return new; +} +EXPORT_SYMBOL(sunrpc_cache_lookup); + + +static void queue_loose(struct cache_detail *detail, struct cache_head *ch); + +static int cache_fresh_locked(struct cache_head *head, time_t expiry) +{ + head->expiry_time = expiry; + head->last_refresh = get_seconds(); + return !test_and_set_bit(CACHE_VALID, &head->flags); +} + +static void cache_fresh_unlocked(struct cache_head *head, + struct cache_detail *detail, int new) +{ + if (new) + cache_revisit_request(head); + if (test_and_clear_bit(CACHE_PENDING, &head->flags)) { + cache_revisit_request(head); + queue_loose(detail, head); + } +} + +struct cache_head *sunrpc_cache_update(struct cache_detail *detail, + struct cache_head *new, struct cache_head *old, int hash) +{ + /* The 'old' entry is to be replaced by 'new'. + * If 'old' is not VALID, we update it directly, + * otherwise we need to replace it + */ + struct cache_head **head; + struct cache_head *tmp; + int is_new; + + if (!test_bit(CACHE_VALID, &old->flags)) { + write_lock(&detail->hash_lock); + if (!test_bit(CACHE_VALID, &old->flags)) { + if (test_bit(CACHE_NEGATIVE, &new->flags)) + set_bit(CACHE_NEGATIVE, &old->flags); + else + detail->update(old, new); + is_new = cache_fresh_locked(old, new->expiry_time); + write_unlock(&detail->hash_lock); + cache_fresh_unlocked(old, detail, is_new); + return old; + } + write_unlock(&detail->hash_lock); + } + /* We need to insert a new entry */ + tmp = detail->alloc(); + if (!tmp) { + cache_put(old, detail); + return NULL; + } + cache_init(tmp); + detail->init(tmp, old); + head = &detail->hash_table[hash]; + + write_lock(&detail->hash_lock); + if (test_bit(CACHE_NEGATIVE, &new->flags)) + set_bit(CACHE_NEGATIVE, &tmp->flags); + else + detail->update(tmp, new); + tmp->next = *head; + *head = tmp; + cache_get(tmp); + is_new = cache_fresh_locked(tmp, new->expiry_time); + cache_fresh_locked(old, 0); + write_unlock(&detail->hash_lock); + cache_fresh_unlocked(tmp, detail, is_new); + cache_fresh_unlocked(old, detail, 0); + cache_put(old, detail); + return tmp; +} +EXPORT_SYMBOL(sunrpc_cache_update); static int cache_make_upcall(struct cache_detail *detail, struct cache_head *h); /* @@ -94,7 +216,8 @@ int cache_check(struct cache_detail *detail, clear_bit(CACHE_PENDING, &h->flags); if (rv == -EAGAIN) { set_bit(CACHE_NEGATIVE, &h->flags); - cache_fresh(detail, h, get_seconds()+CACHE_NEW_EXPIRY); + cache_fresh_unlocked(h, detail, + cache_fresh_locked(h, get_seconds()+CACHE_NEW_EXPIRY)); rv = -ENOENT; } break; @@ -110,25 +233,11 @@ int cache_check(struct cache_detail *detail, if (rv == -EAGAIN) cache_defer_req(rqstp, h); - if (rv && h) - detail->cache_put(h, detail); + if (rv) + cache_put(h, detail); return rv; } -static void queue_loose(struct cache_detail *detail, struct cache_head *ch); - -void cache_fresh(struct cache_detail *detail, - struct cache_head *head, time_t expiry) -{ - - head->expiry_time = expiry; - head->last_refresh = get_seconds(); - if (!test_and_set_bit(CACHE_VALID, &head->flags)) - cache_revisit_request(head); - if (test_and_clear_bit(CACHE_PENDING, &head->flags)) - queue_loose(detail, head); -} - /* * caches need to be periodically cleaned. * For this we maintain a list of cache_detail and @@ -322,7 +431,7 @@ static int cache_clean(void) if (test_and_clear_bit(CACHE_PENDING, &ch->flags)) queue_loose(current_detail, ch); - if (atomic_read(&ch->refcnt) == 1) + if (atomic_read(&ch->ref.refcount) == 1) break; } if (ch) { @@ -337,7 +446,7 @@ static int cache_clean(void) current_index ++; spin_unlock(&cache_list_lock); if (ch) - d->cache_put(ch, d); + cache_put(ch, d); } else spin_unlock(&cache_list_lock); @@ -453,7 +562,7 @@ static void cache_defer_req(struct cache_req *req, struct cache_head *item) /* there was one too many */ dreq->revisit(dreq, 1); } - if (test_bit(CACHE_VALID, &item->flags)) { + if (!test_bit(CACHE_PENDING, &item->flags)) { /* must have just been validated... */ cache_revisit_request(item); } @@ -614,7 +723,7 @@ cache_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) !test_bit(CACHE_PENDING, &rq->item->flags)) { list_del(&rq->q.list); spin_unlock(&queue_lock); - cd->cache_put(rq->item, cd); + cache_put(rq->item, cd); kfree(rq->buf); kfree(rq); } else @@ -794,10 +903,10 @@ static void queue_loose(struct cache_detail *detail, struct cache_head *ch) if (cr->item != ch) continue; if (cr->readers != 0) - break; + continue; list_del(&cr->q.list); spin_unlock(&queue_lock); - detail->cache_put(cr->item, detail); + cache_put(cr->item, detail); kfree(cr->buf); kfree(cr); return; @@ -1082,8 +1191,8 @@ static int c_show(struct seq_file *m, void *p) return cd->cache_show(m, cd, NULL); ifdebug(CACHE) - seq_printf(m, "# expiry=%ld refcnt=%d\n", - cp->expiry_time, atomic_read(&cp->refcnt)); + seq_printf(m, "# expiry=%ld refcnt=%d flags=%lx\n", + cp->expiry_time, atomic_read(&cp->ref.refcount), cp->flags); cache_get(cp); if (cache_check(cd, cp, NULL)) /* cache_check does a cache_put on failure */ diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index d784797..aa8965e 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -28,12 +28,11 @@ #include <linux/mm.h> #include <linux/slab.h> #include <linux/utsname.h> +#include <linux/workqueue.h> #include <linux/sunrpc/clnt.h> -#include <linux/workqueue.h> #include <linux/sunrpc/rpc_pipe_fs.h> - -#include <linux/nfs.h> +#include <linux/sunrpc/metrics.h> #define RPC_SLACK_SPACE (1024) /* total overkill */ @@ -71,8 +70,15 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name) static uint32_t clntid; int error; + clnt->cl_vfsmnt = ERR_PTR(-ENOENT); + clnt->cl_dentry = ERR_PTR(-ENOENT); if (dir_name == NULL) return 0; + + clnt->cl_vfsmnt = rpc_get_mount(); + if (IS_ERR(clnt->cl_vfsmnt)) + return PTR_ERR(clnt->cl_vfsmnt); + for (;;) { snprintf(clnt->cl_pathname, sizeof(clnt->cl_pathname), "%s/clnt%x", dir_name, @@ -85,6 +91,7 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name) if (error != -EEXIST) { printk(KERN_INFO "RPC: Couldn't create pipefs entry %s, error %d\n", clnt->cl_pathname, error); + rpc_put_mount(); return error; } } @@ -147,6 +154,7 @@ rpc_new_client(struct rpc_xprt *xprt, char *servname, clnt->cl_vers = version->number; clnt->cl_prot = xprt->prot; clnt->cl_stats = program->stats; + clnt->cl_metrics = rpc_alloc_iostats(clnt); rpc_init_wait_queue(&clnt->cl_pmap_default.pm_bindwait, "bindwait"); if (!clnt->cl_port) @@ -175,7 +183,11 @@ rpc_new_client(struct rpc_xprt *xprt, char *servname, return clnt; out_no_auth: - rpc_rmdir(clnt->cl_pathname); + if (!IS_ERR(clnt->cl_dentry)) { + rpc_rmdir(clnt->cl_pathname); + dput(clnt->cl_dentry); + rpc_put_mount(); + } out_no_path: if (clnt->cl_server != clnt->cl_inline_name) kfree(clnt->cl_server); @@ -240,11 +252,15 @@ rpc_clone_client(struct rpc_clnt *clnt) new->cl_autobind = 0; new->cl_oneshot = 0; new->cl_dead = 0; + if (!IS_ERR(new->cl_dentry)) { + dget(new->cl_dentry); + rpc_get_mount(); + } rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval); if (new->cl_auth) atomic_inc(&new->cl_auth->au_count); new->cl_pmap = &new->cl_pmap_default; - rpc_init_wait_queue(&new->cl_pmap_default.pm_bindwait, "bindwait"); + new->cl_metrics = rpc_alloc_iostats(clnt); return new; out_no_clnt: printk(KERN_INFO "RPC: out of memory in %s\n", __FUNCTION__); @@ -314,6 +330,12 @@ rpc_destroy_client(struct rpc_clnt *clnt) if (clnt->cl_server != clnt->cl_inline_name) kfree(clnt->cl_server); out_free: + rpc_free_iostats(clnt->cl_metrics); + clnt->cl_metrics = NULL; + if (!IS_ERR(clnt->cl_dentry)) { + dput(clnt->cl_dentry); + rpc_put_mount(); + } kfree(clnt); return 0; } @@ -473,15 +495,16 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags, int status; /* If this client is slain all further I/O fails */ + status = -EIO; if (clnt->cl_dead) - return -EIO; + goto out_release; flags |= RPC_TASK_ASYNC; /* Create/initialize a new RPC task */ status = -ENOMEM; if (!(task = rpc_new_task(clnt, flags, tk_ops, data))) - goto out; + goto out_release; /* Mask signals on GSS_AUTH upcalls */ rpc_task_sigmask(task, &oldset); @@ -496,7 +519,10 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags, rpc_release_task(task); rpc_restore_sigmask(&oldset); -out: + return status; +out_release: + if (tk_ops->rpc_release != NULL) + tk_ops->rpc_release(data); return status; } @@ -993,6 +1019,8 @@ call_timeout(struct rpc_task *task) } dprintk("RPC: %4d call_timeout (major)\n", task->tk_pid); + task->tk_timeouts++; + if (RPC_IS_SOFT(task)) { printk(KERN_NOTICE "%s: server %s not responding, timed out\n", clnt->cl_protname, clnt->cl_server); @@ -1045,6 +1073,11 @@ call_decode(struct rpc_task *task) return; } + /* + * Ensure that we see all writes made by xprt_complete_rqst() + * before it changed req->rq_received. + */ + smp_rmb(); req->rq_rcv_buf.len = req->rq_private_buf.len; /* Check that the softirq receive buffer is valid */ @@ -1194,8 +1227,8 @@ call_verify(struct rpc_task *task) task->tk_action = call_bind; goto out_retry; case RPC_AUTH_TOOWEAK: - printk(KERN_NOTICE "call_verify: server requires stronger " - "authentication.\n"); + printk(KERN_NOTICE "call_verify: server %s requires stronger " + "authentication.\n", task->tk_client->cl_server); break; default: printk(KERN_WARNING "call_verify: unknown auth error: %x\n", n); diff --git a/net/sunrpc/pmap_clnt.c b/net/sunrpc/pmap_clnt.c index 8139ce6..d25b054 100644 --- a/net/sunrpc/pmap_clnt.c +++ b/net/sunrpc/pmap_clnt.c @@ -82,6 +82,7 @@ rpc_getport(struct rpc_task *task, struct rpc_clnt *clnt) rpc_call_setup(child, &msg, 0); /* ... and run the child task */ + task->tk_xprt->stat.bind_count++; rpc_run_child(task, child, pmap_getport_done); return; @@ -103,6 +104,11 @@ rpc_getport_external(struct sockaddr_in *sin, __u32 prog, __u32 vers, int prot) .pm_prot = prot, .pm_port = 0 }; + struct rpc_message msg = { + .rpc_proc = &pmap_procedures[PMAP_GETPORT], + .rpc_argp = &map, + .rpc_resp = &map.pm_port, + }; struct rpc_clnt *pmap_clnt; char hostname[32]; int status; @@ -116,7 +122,7 @@ rpc_getport_external(struct sockaddr_in *sin, __u32 prog, __u32 vers, int prot) return PTR_ERR(pmap_clnt); /* Setup the call info struct */ - status = rpc_call(pmap_clnt, PMAP_GETPORT, &map, &map.pm_port, 0); + status = rpc_call_sync(pmap_clnt, &msg, 0); if (status >= 0) { if (map.pm_port != 0) @@ -161,16 +167,27 @@ pmap_getport_done(struct rpc_task *task) int rpc_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay) { - struct sockaddr_in sin; - struct rpc_portmap map; + struct sockaddr_in sin = { + .sin_family = AF_INET, + .sin_addr.s_addr = htonl(INADDR_LOOPBACK), + }; + struct rpc_portmap map = { + .pm_prog = prog, + .pm_vers = vers, + .pm_prot = prot, + .pm_port = port, + }; + struct rpc_message msg = { + .rpc_proc = &pmap_procedures[port ? PMAP_SET : PMAP_UNSET], + .rpc_argp = &map, + .rpc_resp = okay, + }; struct rpc_clnt *pmap_clnt; int error = 0; dprintk("RPC: registering (%d, %d, %d, %d) with portmapper.\n", prog, vers, prot, port); - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); pmap_clnt = pmap_create("localhost", &sin, IPPROTO_UDP, 1); if (IS_ERR(pmap_clnt)) { error = PTR_ERR(pmap_clnt); @@ -178,13 +195,7 @@ rpc_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay) return error; } - map.pm_prog = prog; - map.pm_vers = vers; - map.pm_prot = prot; - map.pm_port = port; - - error = rpc_call(pmap_clnt, port? PMAP_SET : PMAP_UNSET, - &map, okay, 0); + error = rpc_call_sync(pmap_clnt, &msg, 0); if (error < 0) { printk(KERN_WARNING @@ -260,6 +271,8 @@ static struct rpc_procinfo pmap_procedures[] = { .p_decode = (kxdrproc_t) xdr_decode_bool, .p_bufsiz = 4, .p_count = 1, + .p_statidx = PMAP_SET, + .p_name = "SET", }, [PMAP_UNSET] = { .p_proc = PMAP_UNSET, @@ -267,6 +280,8 @@ static struct rpc_procinfo pmap_procedures[] = { .p_decode = (kxdrproc_t) xdr_decode_bool, .p_bufsiz = 4, .p_count = 1, + .p_statidx = PMAP_UNSET, + .p_name = "UNSET", }, [PMAP_GETPORT] = { .p_proc = PMAP_GETPORT, @@ -274,6 +289,8 @@ static struct rpc_procinfo pmap_procedures[] = { .p_decode = (kxdrproc_t) xdr_decode_port, .p_bufsiz = 4, .p_count = 1, + .p_statidx = PMAP_GETPORT, + .p_name = "GETPORT", }, }; diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index ad9d9fc..cc673dd 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -91,7 +91,8 @@ rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg) res = 0; } else if (rpci->flags & RPC_PIPE_WAIT_FOR_OPEN) { if (list_empty(&rpci->pipe)) - schedule_delayed_work(&rpci->queue_timeout, + queue_delayed_work(rpciod_workqueue, + &rpci->queue_timeout, RPC_UPCALL_TIMEOUT); list_add_tail(&msg->list, &rpci->pipe); rpci->pipelen += msg->len; @@ -132,7 +133,7 @@ rpc_close_pipes(struct inode *inode) if (ops->release_pipe) ops->release_pipe(inode); cancel_delayed_work(&rpci->queue_timeout); - flush_scheduled_work(); + flush_workqueue(rpciod_workqueue); } rpc_inode_setowner(inode, NULL); mutex_unlock(&inode->i_mutex); @@ -394,7 +395,7 @@ enum { */ struct rpc_filelist { char *name; - struct file_operations *i_fop; + const struct file_operations *i_fop; int mode; }; @@ -434,14 +435,17 @@ static struct rpc_filelist authfiles[] = { }, }; -static int -rpc_get_mount(void) +struct vfsmount *rpc_get_mount(void) { - return simple_pin_fs("rpc_pipefs", &rpc_mount, &rpc_mount_count); + int err; + + err = simple_pin_fs("rpc_pipefs", &rpc_mount, &rpc_mount_count); + if (err != 0) + return ERR_PTR(err); + return rpc_mount; } -static void -rpc_put_mount(void) +void rpc_put_mount(void) { simple_release_fs(&rpc_mount, &rpc_mount_count); } @@ -451,12 +455,13 @@ rpc_lookup_parent(char *path, struct nameidata *nd) { if (path[0] == '\0') return -ENOENT; - if (rpc_get_mount()) { + nd->mnt = rpc_get_mount(); + if (IS_ERR(nd->mnt)) { printk(KERN_WARNING "%s: %s failed to mount " "pseudofilesystem \n", __FILE__, __FUNCTION__); - return -ENODEV; + return PTR_ERR(nd->mnt); } - nd->mnt = mntget(rpc_mount); + mntget(nd->mnt); nd->dentry = dget(rpc_mount->mnt_root); nd->last_type = LAST_ROOT; nd->flags = LOOKUP_PARENT; @@ -593,7 +598,6 @@ __rpc_mkdir(struct inode *dir, struct dentry *dentry) d_instantiate(dentry, inode); dir->i_nlink++; inode_dir_notify(dir, DN_CREATE); - rpc_get_mount(); return 0; out_err: printk(KERN_WARNING "%s: %s failed to allocate inode for dentry %s\n", @@ -614,7 +618,6 @@ __rpc_rmdir(struct inode *dir, struct dentry *dentry) if (!error) { inode_dir_notify(dir, DN_DELETE); d_drop(dentry); - rpc_put_mount(); } return 0; } @@ -668,7 +671,7 @@ rpc_mkdir(char *path, struct rpc_clnt *rpc_client) out: mutex_unlock(&dir->i_mutex); rpc_release_path(&nd); - return dentry; + return dget(dentry); err_depopulate: rpc_depopulate(dentry); __rpc_rmdir(dir, dentry); @@ -732,7 +735,7 @@ rpc_mkpipe(char *path, void *private, struct rpc_pipe_ops *ops, int flags) out: mutex_unlock(&dir->i_mutex); rpc_release_path(&nd); - return dentry; + return dget(dentry); err_dput: dput(dentry); dentry = ERR_PTR(-ENOMEM); diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index dff0779..5c3eee76 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -65,7 +65,7 @@ static LIST_HEAD(all_tasks); */ static DEFINE_MUTEX(rpciod_mutex); static unsigned int rpciod_users; -static struct workqueue_struct *rpciod_workqueue; +struct workqueue_struct *rpciod_workqueue; /* * Spinlock for other critical sections of code. @@ -182,6 +182,7 @@ static void __rpc_add_wait_queue(struct rpc_wait_queue *queue, struct rpc_task * else list_add_tail(&task->u.tk_wait.list, &queue->tasks[0]); task->u.tk_wait.rpc_waitq = queue; + queue->qlen++; rpc_set_queued(task); dprintk("RPC: %4d added to queue %p \"%s\"\n", @@ -216,6 +217,7 @@ static void __rpc_remove_wait_queue(struct rpc_task *task) __rpc_remove_wait_queue_priority(task); else list_del(&task->u.tk_wait.list); + queue->qlen--; dprintk("RPC: %4d removed from queue %p \"%s\"\n", task->tk_pid, queue, rpc_qname(queue)); } @@ -816,6 +818,9 @@ void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, int flags, cons BUG_ON(task->tk_ops == NULL); + /* starting timestamp */ + task->tk_start = jiffies; + dprintk("RPC: %4d new task procpid %d\n", task->tk_pid, current->pid); } @@ -917,8 +922,11 @@ struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags, { struct rpc_task *task; task = rpc_new_task(clnt, flags, ops, data); - if (task == NULL) + if (task == NULL) { + if (ops->rpc_release != NULL) + ops->rpc_release(data); return ERR_PTR(-ENOMEM); + } atomic_inc(&task->tk_count); rpc_execute(task); return task; @@ -1159,16 +1167,12 @@ rpc_init_mempool(void) NULL, NULL); if (!rpc_buffer_slabp) goto err_nomem; - rpc_task_mempool = mempool_create(RPC_TASK_POOLSIZE, - mempool_alloc_slab, - mempool_free_slab, - rpc_task_slabp); + rpc_task_mempool = mempool_create_slab_pool(RPC_TASK_POOLSIZE, + rpc_task_slabp); if (!rpc_task_mempool) goto err_nomem; - rpc_buffer_mempool = mempool_create(RPC_BUFFER_POOLSIZE, - mempool_alloc_slab, - mempool_free_slab, - rpc_buffer_slabp); + rpc_buffer_mempool = mempool_create_slab_pool(RPC_BUFFER_POOLSIZE, + rpc_buffer_slabp); if (!rpc_buffer_mempool) goto err_nomem; return 0; diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c index 4979f22..dea5296 100644 --- a/net/sunrpc/stats.c +++ b/net/sunrpc/stats.c @@ -21,6 +21,7 @@ #include <linux/seq_file.h> #include <linux/sunrpc/clnt.h> #include <linux/sunrpc/svcsock.h> +#include <linux/sunrpc/metrics.h> #define RPCDBG_FACILITY RPCDBG_MISC @@ -106,11 +107,125 @@ void svc_seq_show(struct seq_file *seq, const struct svc_stat *statp) { } } +/** + * rpc_alloc_iostats - allocate an rpc_iostats structure + * @clnt: RPC program, version, and xprt + * + */ +struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) +{ + unsigned int ops = clnt->cl_maxproc; + size_t size = ops * sizeof(struct rpc_iostats); + struct rpc_iostats *new; + + new = kmalloc(size, GFP_KERNEL); + if (new) + memset(new, 0 , size); + return new; +} +EXPORT_SYMBOL(rpc_alloc_iostats); + +/** + * rpc_free_iostats - release an rpc_iostats structure + * @stats: doomed rpc_iostats structure + * + */ +void rpc_free_iostats(struct rpc_iostats *stats) +{ + kfree(stats); +} +EXPORT_SYMBOL(rpc_free_iostats); + +/** + * rpc_count_iostats - tally up per-task stats + * @task: completed rpc_task + * + * Relies on the caller for serialization. + */ +void rpc_count_iostats(struct rpc_task *task) +{ + struct rpc_rqst *req = task->tk_rqstp; + struct rpc_iostats *stats = task->tk_client->cl_metrics; + struct rpc_iostats *op_metrics; + long rtt, execute, queue; + + if (!stats || !req) + return; + op_metrics = &stats[task->tk_msg.rpc_proc->p_statidx]; + + op_metrics->om_ops++; + op_metrics->om_ntrans += req->rq_ntrans; + op_metrics->om_timeouts += task->tk_timeouts; + + op_metrics->om_bytes_sent += task->tk_bytes_sent; + op_metrics->om_bytes_recv += req->rq_received; + + queue = (long)req->rq_xtime - task->tk_start; + if (queue < 0) + queue = -queue; + op_metrics->om_queue += queue; + + rtt = task->tk_rtt; + if (rtt < 0) + rtt = -rtt; + op_metrics->om_rtt += rtt; + + execute = (long)jiffies - task->tk_start; + if (execute < 0) + execute = -execute; + op_metrics->om_execute += execute; +} + +void _print_name(struct seq_file *seq, unsigned int op, struct rpc_procinfo *procs) +{ + if (procs[op].p_name) + seq_printf(seq, "\t%12s: ", procs[op].p_name); + else if (op == 0) + seq_printf(seq, "\t NULL: "); + else + seq_printf(seq, "\t%12u: ", op); +} + +#define MILLISECS_PER_JIFFY (1000 / HZ) + +void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt) +{ + struct rpc_iostats *stats = clnt->cl_metrics; + struct rpc_xprt *xprt = clnt->cl_xprt; + unsigned int op, maxproc = clnt->cl_maxproc; + + if (!stats) + return; + + seq_printf(seq, "\tRPC iostats version: %s ", RPC_IOSTATS_VERS); + seq_printf(seq, "p/v: %u/%u (%s)\n", + clnt->cl_prog, clnt->cl_vers, clnt->cl_protname); + + if (xprt) + xprt->ops->print_stats(xprt, seq); + + seq_printf(seq, "\tper-op statistics\n"); + for (op = 0; op < maxproc; op++) { + struct rpc_iostats *metrics = &stats[op]; + _print_name(seq, op, clnt->cl_procinfo); + seq_printf(seq, "%lu %lu %lu %Lu %Lu %Lu %Lu %Lu\n", + metrics->om_ops, + metrics->om_ntrans, + metrics->om_timeouts, + metrics->om_bytes_sent, + metrics->om_bytes_recv, + metrics->om_queue * MILLISECS_PER_JIFFY, + metrics->om_rtt * MILLISECS_PER_JIFFY, + metrics->om_execute * MILLISECS_PER_JIFFY); + } +} +EXPORT_SYMBOL(rpc_print_iostats); + /* * Register/unregister RPC proc files */ static inline struct proc_dir_entry * -do_register(const char *name, void *data, struct file_operations *fops) +do_register(const char *name, void *data, const struct file_operations *fops) { struct proc_dir_entry *ent; @@ -138,7 +253,7 @@ rpc_proc_unregister(const char *name) } struct proc_dir_entry * -svc_proc_register(struct svc_stat *statp, struct file_operations *fops) +svc_proc_register(struct svc_stat *statp, const struct file_operations *fops) { return do_register(statp->program->pg_name, statp, fops); } diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c index 9f73732..769114f 100644 --- a/net/sunrpc/sunrpc_syms.c +++ b/net/sunrpc/sunrpc_syms.c @@ -105,8 +105,6 @@ EXPORT_SYMBOL(auth_unix_lookup); EXPORT_SYMBOL(cache_check); EXPORT_SYMBOL(cache_flush); EXPORT_SYMBOL(cache_purge); -EXPORT_SYMBOL(cache_fresh); -EXPORT_SYMBOL(cache_init); EXPORT_SYMBOL(cache_register); EXPORT_SYMBOL(cache_unregister); EXPORT_SYMBOL(qword_add); @@ -142,6 +140,7 @@ EXPORT_SYMBOL(nlm_debug); extern int register_rpc_pipefs(void); extern void unregister_rpc_pipefs(void); +extern struct cache_detail ip_map_cache; static int __init init_sunrpc(void) @@ -158,7 +157,6 @@ init_sunrpc(void) #ifdef CONFIG_PROC_FS rpc_proc_init(); #endif - cache_register(&auth_domain_cache); cache_register(&ip_map_cache); out: return err; @@ -169,8 +167,6 @@ cleanup_sunrpc(void) { unregister_rpc_pipefs(); rpc_destroy_mempool(); - if (cache_unregister(&auth_domain_cache)) - printk(KERN_ERR "sunrpc: failed to unregister auth_domain cache\n"); if (cache_unregister(&ip_map_cache)) printk(KERN_ERR "sunrpc: failed to unregister ip_map cache\n"); #ifdef RPC_DEBUG diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c index dda4f0c..5b28c61 100644 --- a/net/sunrpc/svcauth.c +++ b/net/sunrpc/svcauth.c @@ -106,112 +106,56 @@ svc_auth_unregister(rpc_authflavor_t flavor) EXPORT_SYMBOL(svc_auth_unregister); /************************************************** - * cache for domain name to auth_domain - * Entries are only added by flavours which will normally - * have a structure that 'inherits' from auth_domain. - * e.g. when an IP -> domainname is given to auth_unix, - * and the domain name doesn't exist, it will create a - * auth_unix_domain and add it to this hash table. - * If it finds the name does exist, but isn't AUTH_UNIX, - * it will complain. + * 'auth_domains' are stored in a hash table indexed by name. + * When the last reference to an 'auth_domain' is dropped, + * the object is unhashed and freed. + * If auth_domain_lookup fails to find an entry, it will return + * it's second argument 'new'. If this is non-null, it will + * have been atomically linked into the table. */ -/* - * Auth auth_domain cache is somewhat different to other caches, - * largely because the entries are possibly of different types: - * each auth flavour has it's own type. - * One consequence of this that DefineCacheLookup cannot - * allocate a new structure as it cannot know the size. - * Notice that the "INIT" code fragment is quite different - * from other caches. When auth_domain_lookup might be - * creating a new domain, the new domain is passed in - * complete and it is used as-is rather than being copied into - * another structure. - */ #define DN_HASHBITS 6 #define DN_HASHMAX (1<<DN_HASHBITS) #define DN_HASHMASK (DN_HASHMAX-1) -static struct cache_head *auth_domain_table[DN_HASHMAX]; - -static void auth_domain_drop(struct cache_head *item, struct cache_detail *cd) -{ - struct auth_domain *dom = container_of(item, struct auth_domain, h); - if (cache_put(item,cd)) - authtab[dom->flavour]->domain_release(dom); -} - - -struct cache_detail auth_domain_cache = { - .owner = THIS_MODULE, - .hash_size = DN_HASHMAX, - .hash_table = auth_domain_table, - .name = "auth.domain", - .cache_put = auth_domain_drop, -}; +static struct hlist_head auth_domain_table[DN_HASHMAX]; +static spinlock_t auth_domain_lock = SPIN_LOCK_UNLOCKED; void auth_domain_put(struct auth_domain *dom) { - auth_domain_drop(&dom->h, &auth_domain_cache); -} - -static inline int auth_domain_hash(struct auth_domain *item) -{ - return hash_str(item->name, DN_HASHBITS); -} -static inline int auth_domain_match(struct auth_domain *tmp, struct auth_domain *item) -{ - return strcmp(tmp->name, item->name) == 0; + if (atomic_dec_and_lock(&dom->ref.refcount, &auth_domain_lock)) { + hlist_del(&dom->hash); + dom->flavour->domain_release(dom); + } } struct auth_domain * -auth_domain_lookup(struct auth_domain *item, int set) +auth_domain_lookup(char *name, struct auth_domain *new) { - struct auth_domain *tmp = NULL; - struct cache_head **hp, **head; - head = &auth_domain_cache.hash_table[auth_domain_hash(item)]; - - if (set) - write_lock(&auth_domain_cache.hash_lock); - else - read_lock(&auth_domain_cache.hash_lock); - for (hp=head; *hp != NULL; hp = &tmp->h.next) { - tmp = container_of(*hp, struct auth_domain, h); - if (!auth_domain_match(tmp, item)) - continue; - if (!set) { - cache_get(&tmp->h); - goto out_noset; + struct auth_domain *hp; + struct hlist_head *head; + struct hlist_node *np; + + head = &auth_domain_table[hash_str(name, DN_HASHBITS)]; + + spin_lock(&auth_domain_lock); + + hlist_for_each_entry(hp, np, head, hash) { + if (strcmp(hp->name, name)==0) { + kref_get(&hp->ref); + spin_unlock(&auth_domain_lock); + return hp; } - *hp = tmp->h.next; - tmp->h.next = NULL; - auth_domain_drop(&tmp->h, &auth_domain_cache); - goto out_set; } - /* Didn't find anything */ - if (!set) - goto out_nada; - auth_domain_cache.entries++; -out_set: - item->h.next = *head; - *head = &item->h; - cache_get(&item->h); - write_unlock(&auth_domain_cache.hash_lock); - cache_fresh(&auth_domain_cache, &item->h, item->h.expiry_time); - cache_get(&item->h); - return item; -out_nada: - tmp = NULL; -out_noset: - read_unlock(&auth_domain_cache.hash_lock); - return tmp; + if (new) { + hlist_add_head(&new->hash, head); + kref_get(&new->ref); + } + spin_unlock(&auth_domain_lock); + return new; } struct auth_domain *auth_domain_find(char *name) { - struct auth_domain *rv, ad; - - ad.name = name; - rv = auth_domain_lookup(&ad, 0); - return rv; + return auth_domain_lookup(name, NULL); } diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index 3e6c694..7e5707e 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c @@ -27,41 +27,35 @@ struct unix_domain { /* other stuff later */ }; +extern struct auth_ops svcauth_unix; + struct auth_domain *unix_domain_find(char *name) { - struct auth_domain *rv, ud; - struct unix_domain *new; - - ud.name = name; - - rv = auth_domain_lookup(&ud, 0); - - foundit: - if (rv && rv->flavour != RPC_AUTH_UNIX) { - auth_domain_put(rv); - return NULL; - } - if (rv) - return rv; - - new = kmalloc(sizeof(*new), GFP_KERNEL); - if (new == NULL) - return NULL; - cache_init(&new->h.h); - new->h.name = kstrdup(name, GFP_KERNEL); - new->h.flavour = RPC_AUTH_UNIX; - new->addr_changes = 0; - new->h.h.expiry_time = NEVER; - - rv = auth_domain_lookup(&new->h, 2); - if (rv == &new->h) { - if (atomic_dec_and_test(&new->h.h.refcnt)) BUG(); - } else { - auth_domain_put(&new->h); - goto foundit; + struct auth_domain *rv; + struct unix_domain *new = NULL; + + rv = auth_domain_lookup(name, NULL); + while(1) { + if (rv) { + if (new && rv != &new->h) + auth_domain_put(&new->h); + + if (rv->flavour != &svcauth_unix) { + auth_domain_put(rv); + return NULL; + } + return rv; + } + + new = kmalloc(sizeof(*new), GFP_KERNEL); + if (new == NULL) + return NULL; + kref_init(&new->h.ref); + new->h.name = kstrdup(name, GFP_KERNEL); + new->h.flavour = &svcauth_unix; + new->addr_changes = 0; + rv = auth_domain_lookup(name, &new->h); } - - return rv; } static void svcauth_unix_domain_release(struct auth_domain *dom) @@ -90,15 +84,15 @@ struct ip_map { }; static struct cache_head *ip_table[IP_HASHMAX]; -static void ip_map_put(struct cache_head *item, struct cache_detail *cd) +static void ip_map_put(struct kref *kref) { + struct cache_head *item = container_of(kref, struct cache_head, ref); struct ip_map *im = container_of(item, struct ip_map,h); - if (cache_put(item, cd)) { - if (test_bit(CACHE_VALID, &item->flags) && - !test_bit(CACHE_NEGATIVE, &item->flags)) - auth_domain_put(&im->m_client->h); - kfree(im); - } + + if (test_bit(CACHE_VALID, &item->flags) && + !test_bit(CACHE_NEGATIVE, &item->flags)) + auth_domain_put(&im->m_client->h); + kfree(im); } #if IP_HASHBITS == 8 @@ -112,28 +106,38 @@ static inline int hash_ip(unsigned long ip) return (hash ^ (hash>>8)) & 0xff; } #endif - -static inline int ip_map_hash(struct ip_map *item) -{ - return hash_str(item->m_class, IP_HASHBITS) ^ - hash_ip((unsigned long)item->m_addr.s_addr); -} -static inline int ip_map_match(struct ip_map *item, struct ip_map *tmp) +static int ip_map_match(struct cache_head *corig, struct cache_head *cnew) { - return strcmp(tmp->m_class, item->m_class) == 0 - && tmp->m_addr.s_addr == item->m_addr.s_addr; + struct ip_map *orig = container_of(corig, struct ip_map, h); + struct ip_map *new = container_of(cnew, struct ip_map, h); + return strcmp(orig->m_class, new->m_class) == 0 + && orig->m_addr.s_addr == new->m_addr.s_addr; } -static inline void ip_map_init(struct ip_map *new, struct ip_map *item) +static void ip_map_init(struct cache_head *cnew, struct cache_head *citem) { + struct ip_map *new = container_of(cnew, struct ip_map, h); + struct ip_map *item = container_of(citem, struct ip_map, h); + strcpy(new->m_class, item->m_class); new->m_addr.s_addr = item->m_addr.s_addr; } -static inline void ip_map_update(struct ip_map *new, struct ip_map *item) +static void update(struct cache_head *cnew, struct cache_head *citem) { - cache_get(&item->m_client->h.h); + struct ip_map *new = container_of(cnew, struct ip_map, h); + struct ip_map *item = container_of(citem, struct ip_map, h); + + kref_get(&item->m_client->h.ref); new->m_client = item->m_client; new->m_add_change = item->m_add_change; } +static struct cache_head *ip_map_alloc(void) +{ + struct ip_map *i = kmalloc(sizeof(*i), GFP_KERNEL); + if (i) + return &i->h; + else + return NULL; +} static void ip_map_request(struct cache_detail *cd, struct cache_head *h, @@ -154,7 +158,8 @@ static void ip_map_request(struct cache_detail *cd, (*bpp)[-1] = '\n'; } -static struct ip_map *ip_map_lookup(struct ip_map *, int); +static struct ip_map *ip_map_lookup(char *class, struct in_addr addr); +static int ip_map_update(struct ip_map *ipm, struct unix_domain *udom, time_t expiry); static int ip_map_parse(struct cache_detail *cd, char *mesg, int mlen) @@ -166,7 +171,11 @@ static int ip_map_parse(struct cache_detail *cd, int len; int b1,b2,b3,b4; char c; - struct ip_map ipm, *ipmp; + char class[8]; + struct in_addr addr; + int err; + + struct ip_map *ipmp; struct auth_domain *dom; time_t expiry; @@ -175,7 +184,7 @@ static int ip_map_parse(struct cache_detail *cd, mesg[mlen-1] = 0; /* class */ - len = qword_get(&mesg, ipm.m_class, sizeof(ipm.m_class)); + len = qword_get(&mesg, class, sizeof(class)); if (len <= 0) return -EINVAL; /* ip address */ @@ -200,25 +209,22 @@ static int ip_map_parse(struct cache_detail *cd, } else dom = NULL; - ipm.m_addr.s_addr = + addr.s_addr = htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4); - ipm.h.flags = 0; - if (dom) { - ipm.m_client = container_of(dom, struct unix_domain, h); - ipm.m_add_change = ipm.m_client->addr_changes; + + ipmp = ip_map_lookup(class,addr); + if (ipmp) { + err = ip_map_update(ipmp, + container_of(dom, struct unix_domain, h), + expiry); } else - set_bit(CACHE_NEGATIVE, &ipm.h.flags); - ipm.h.expiry_time = expiry; + err = -ENOMEM; - ipmp = ip_map_lookup(&ipm, 1); - if (ipmp) - ip_map_put(&ipmp->h, &ip_map_cache); if (dom) auth_domain_put(dom); - if (!ipmp) - return -ENOMEM; + cache_flush(); - return 0; + return err; } static int ip_map_show(struct seq_file *m, @@ -262,32 +268,70 @@ struct cache_detail ip_map_cache = { .cache_request = ip_map_request, .cache_parse = ip_map_parse, .cache_show = ip_map_show, + .match = ip_map_match, + .init = ip_map_init, + .update = update, + .alloc = ip_map_alloc, }; -static DefineSimpleCacheLookup(ip_map, 0) +static struct ip_map *ip_map_lookup(char *class, struct in_addr addr) +{ + struct ip_map ip; + struct cache_head *ch; + + strcpy(ip.m_class, class); + ip.m_addr = addr; + ch = sunrpc_cache_lookup(&ip_map_cache, &ip.h, + hash_str(class, IP_HASHBITS) ^ + hash_ip((unsigned long)addr.s_addr)); + + if (ch) + return container_of(ch, struct ip_map, h); + else + return NULL; +} +static int ip_map_update(struct ip_map *ipm, struct unix_domain *udom, time_t expiry) +{ + struct ip_map ip; + struct cache_head *ch; + + ip.m_client = udom; + ip.h.flags = 0; + if (!udom) + set_bit(CACHE_NEGATIVE, &ip.h.flags); + else { + ip.m_add_change = udom->addr_changes; + /* if this is from the legacy set_client system call, + * we need m_add_change to be one higher + */ + if (expiry == NEVER) + ip.m_add_change++; + } + ip.h.expiry_time = expiry; + ch = sunrpc_cache_update(&ip_map_cache, + &ip.h, &ipm->h, + hash_str(ipm->m_class, IP_HASHBITS) ^ + hash_ip((unsigned long)ipm->m_addr.s_addr)); + if (!ch) + return -ENOMEM; + cache_put(ch, &ip_map_cache); + return 0; +} int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom) { struct unix_domain *udom; - struct ip_map ip, *ipmp; + struct ip_map *ipmp; - if (dom->flavour != RPC_AUTH_UNIX) + if (dom->flavour != &svcauth_unix) return -EINVAL; udom = container_of(dom, struct unix_domain, h); - strcpy(ip.m_class, "nfsd"); - ip.m_addr = addr; - ip.m_client = udom; - ip.m_add_change = udom->addr_changes+1; - ip.h.flags = 0; - ip.h.expiry_time = NEVER; - - ipmp = ip_map_lookup(&ip, 1); + ipmp = ip_map_lookup("nfsd", addr); - if (ipmp) { - ip_map_put(&ipmp->h, &ip_map_cache); - return 0; - } else + if (ipmp) + return ip_map_update(ipmp, udom, NEVER); + else return -ENOMEM; } @@ -295,7 +339,7 @@ int auth_unix_forget_old(struct auth_domain *dom) { struct unix_domain *udom; - if (dom->flavour != RPC_AUTH_UNIX) + if (dom->flavour != &svcauth_unix) return -EINVAL; udom = container_of(dom, struct unix_domain, h); udom->addr_changes++; @@ -310,7 +354,7 @@ struct auth_domain *auth_unix_lookup(struct in_addr addr) strcpy(key.m_class, "nfsd"); key.m_addr = addr; - ipm = ip_map_lookup(&key, 0); + ipm = ip_map_lookup("nfsd", addr); if (!ipm) return NULL; @@ -323,31 +367,28 @@ struct auth_domain *auth_unix_lookup(struct in_addr addr) rv = NULL; } else { rv = &ipm->m_client->h; - cache_get(&rv->h); + kref_get(&rv->ref); } - ip_map_put(&ipm->h, &ip_map_cache); + cache_put(&ipm->h, &ip_map_cache); return rv; } void svcauth_unix_purge(void) { cache_purge(&ip_map_cache); - cache_purge(&auth_domain_cache); } static int svcauth_unix_set_client(struct svc_rqst *rqstp) { - struct ip_map key, *ipm; + struct ip_map *ipm; rqstp->rq_client = NULL; if (rqstp->rq_proc == 0) return SVC_OK; - strcpy(key.m_class, rqstp->rq_server->sv_program->pg_class); - key.m_addr = rqstp->rq_addr.sin_addr; - - ipm = ip_map_lookup(&key, 0); + ipm = ip_map_lookup(rqstp->rq_server->sv_program->pg_class, + rqstp->rq_addr.sin_addr); if (ipm == NULL) return SVC_DENIED; @@ -361,8 +402,8 @@ svcauth_unix_set_client(struct svc_rqst *rqstp) return SVC_DENIED; case 0: rqstp->rq_client = &ipm->m_client->h; - cache_get(&rqstp->rq_client->h); - ip_map_put(&ipm->h, &ip_map_cache); + kref_get(&rqstp->rq_client->ref); + cache_put(&ipm->h, &ip_map_cache); break; } return SVC_OK; diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 8ff2c8a..4dd5b3c 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -44,13 +44,13 @@ #include <linux/random.h> #include <linux/sunrpc/clnt.h> +#include <linux/sunrpc/metrics.h> /* * Local variables */ #ifdef RPC_DEBUG -# undef RPC_DEBUG_DATA # define RPCDBG_FACILITY RPCDBG_XPRT #endif @@ -548,6 +548,7 @@ void xprt_connect(struct rpc_task *task) task->tk_timeout = xprt->connect_timeout; rpc_sleep_on(&xprt->pending, task, xprt_connect_status, NULL); + xprt->stat.connect_start = jiffies; xprt->ops->connect(task); } return; @@ -558,6 +559,8 @@ static void xprt_connect_status(struct rpc_task *task) struct rpc_xprt *xprt = task->tk_xprt; if (task->tk_status >= 0) { + xprt->stat.connect_count++; + xprt->stat.connect_time += (long)jiffies - xprt->stat.connect_start; dprintk("RPC: %4d xprt_connect_status: connection established\n", task->tk_pid); return; @@ -601,16 +604,14 @@ static void xprt_connect_status(struct rpc_task *task) struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid) { struct list_head *pos; - struct rpc_rqst *req = NULL; list_for_each(pos, &xprt->recv) { struct rpc_rqst *entry = list_entry(pos, struct rpc_rqst, rq_list); - if (entry->rq_xid == xid) { - req = entry; - break; - } + if (entry->rq_xid == xid) + return entry; } - return req; + xprt->stat.bad_xids++; + return NULL; } /** @@ -646,7 +647,12 @@ void xprt_complete_rqst(struct rpc_task *task, int copied) dprintk("RPC: %5u xid %08x complete (%d bytes received)\n", task->tk_pid, ntohl(req->rq_xid), copied); + task->tk_xprt->stat.recvs++; + task->tk_rtt = (long)jiffies - req->rq_xtime; + list_del_init(&req->rq_list); + /* Ensure all writes are done before we update req->rq_received */ + smp_wmb(); req->rq_received = req->rq_private_buf.len = copied; rpc_wake_up_task(task); } @@ -723,7 +729,6 @@ void xprt_transmit(struct rpc_task *task) dprintk("RPC: %4d xprt_transmit(%u)\n", task->tk_pid, req->rq_slen); - smp_rmb(); if (!req->rq_received) { if (list_empty(&req->rq_list)) { spin_lock_bh(&xprt->transport_lock); @@ -744,12 +749,19 @@ void xprt_transmit(struct rpc_task *task) if (status == 0) { dprintk("RPC: %4d xmit complete\n", task->tk_pid); spin_lock_bh(&xprt->transport_lock); + xprt->ops->set_retrans_timeout(task); + + xprt->stat.sends++; + xprt->stat.req_u += xprt->stat.sends - xprt->stat.recvs; + xprt->stat.bklog_u += xprt->backlog.qlen; + /* Don't race with disconnect */ if (!xprt_connected(xprt)) task->tk_status = -ENOTCONN; else if (!req->rq_received) rpc_sleep_on(&xprt->pending, task, NULL, xprt_timer); + xprt->ops->release_xprt(xprt, task); spin_unlock_bh(&xprt->transport_lock); return; @@ -848,6 +860,7 @@ void xprt_release(struct rpc_task *task) if (!(req = task->tk_rqstp)) return; + rpc_count_iostats(task); spin_lock_bh(&xprt->transport_lock); xprt->ops->release_xprt(xprt, task); if (xprt->ops->release_request) diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index c458f8d..4b4e7df 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -382,6 +382,7 @@ static int xs_tcp_send_request(struct rpc_task *task) /* If we've sent the entire packet, immediately * reset the count of bytes sent. */ req->rq_bytes_sent += status; + task->tk_bytes_sent += status; if (likely(req->rq_bytes_sent >= req->rq_slen)) { req->rq_bytes_sent = 0; return 0; @@ -1114,6 +1115,8 @@ static void xs_tcp_connect_worker(void *args) } /* Tell the socket layer to start connecting... */ + xprt->stat.connect_count++; + xprt->stat.connect_start = jiffies; status = sock->ops->connect(sock, (struct sockaddr *) &xprt->addr, sizeof(xprt->addr), O_NONBLOCK); dprintk("RPC: %p connect status %d connected %d sock state %d\n", @@ -1177,6 +1180,50 @@ static void xs_connect(struct rpc_task *task) } } +/** + * xs_udp_print_stats - display UDP socket-specifc stats + * @xprt: rpc_xprt struct containing statistics + * @seq: output file + * + */ +static void xs_udp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) +{ + seq_printf(seq, "\txprt:\tudp %u %lu %lu %lu %lu %Lu %Lu\n", + xprt->port, + xprt->stat.bind_count, + xprt->stat.sends, + xprt->stat.recvs, + xprt->stat.bad_xids, + xprt->stat.req_u, + xprt->stat.bklog_u); +} + +/** + * xs_tcp_print_stats - display TCP socket-specifc stats + * @xprt: rpc_xprt struct containing statistics + * @seq: output file + * + */ +static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) +{ + long idle_time = 0; + + if (xprt_connected(xprt)) + idle_time = (long)(jiffies - xprt->last_used) / HZ; + + seq_printf(seq, "\txprt:\ttcp %u %lu %lu %lu %ld %lu %lu %lu %Lu %Lu\n", + xprt->port, + xprt->stat.bind_count, + xprt->stat.connect_count, + xprt->stat.connect_time, + idle_time, + xprt->stat.sends, + xprt->stat.recvs, + xprt->stat.bad_xids, + xprt->stat.req_u, + xprt->stat.bklog_u); +} + static struct rpc_xprt_ops xs_udp_ops = { .set_buffer_size = xs_udp_set_buffer_size, .reserve_xprt = xprt_reserve_xprt_cong, @@ -1191,6 +1238,7 @@ static struct rpc_xprt_ops xs_udp_ops = { .release_request = xprt_release_rqst_cong, .close = xs_close, .destroy = xs_destroy, + .print_stats = xs_udp_print_stats, }; static struct rpc_xprt_ops xs_tcp_ops = { @@ -1204,6 +1252,7 @@ static struct rpc_xprt_ops xs_tcp_ops = { .set_retrans_timeout = xprt_set_retrans_timeout_def, .close = xs_close, .destroy = xs_destroy, + .print_stats = xs_tcp_print_stats, }; /** diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 2b4cc2e..d901465 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1878,6 +1878,8 @@ static unsigned int unix_poll(struct file * file, struct socket *sock, poll_tabl mask |= POLLERR; if (sk->sk_shutdown == SHUTDOWN_MASK) mask |= POLLHUP; + if (sk->sk_shutdown & RCV_SHUTDOWN) + mask |= POLLRDHUP; /* readable? */ if (!skb_queue_empty(&sk->sk_receive_queue) || |