aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/802/tr.c2
-rw-r--r--net/8021q/Makefile2
-rw-r--r--net/8021q/vlan.c495
-rw-r--r--net/8021q/vlan.h24
-rw-r--r--net/8021q/vlan_dev.c217
-rw-r--r--net/8021q/vlan_netlink.c243
-rw-r--r--net/8021q/vlanproc.c6
-rw-r--r--net/Makefile1
-rw-r--r--net/appletalk/aarp.c2
-rw-r--r--net/appletalk/atalk_proc.c6
-rw-r--r--net/atm/br2684.c24
-rw-r--r--net/atm/clip.c2
-rw-r--r--net/atm/lec.c2
-rw-r--r--net/atm/mpoa_proc.c2
-rw-r--r--net/atm/proc.c10
-rw-r--r--net/ax25/af_ax25.c2
-rw-r--r--net/ax25/ax25_route.c2
-rw-r--r--net/ax25/ax25_uid.c2
-rw-r--r--net/bluetooth/hci_conn.c51
-rw-r--r--net/bluetooth/hci_core.c100
-rw-r--r--net/bluetooth/hci_event.c29
-rw-r--r--net/bluetooth/rfcomm/tty.c34
-rw-r--r--net/bridge/br_if.c10
-rw-r--r--net/bridge/br_sysfs_br.c8
-rw-r--r--net/bridge/br_sysfs_if.c3
-rw-r--r--net/core/dev.c382
-rw-r--r--net/core/dev_mcast.c129
-rw-r--r--net/core/gen_estimator.c3
-rw-r--r--net/core/netpoll.c18
-rw-r--r--net/core/pktgen.c249
-rw-r--r--net/core/rtnetlink.c470
-rw-r--r--net/core/skbuff.c13
-rw-r--r--net/core/sock.c42
-rw-r--r--net/dccp/ccids/ccid3.c212
-rw-r--r--net/dccp/ccids/ccid3.h5
-rw-r--r--net/dccp/ccids/lib/loss_interval.c246
-rw-r--r--net/dccp/ccids/lib/loss_interval.h46
-rw-r--r--net/dccp/dccp.h4
-rw-r--r--net/dccp/ipv6.c20
-rw-r--r--net/decnet/af_decnet.c2
-rw-r--r--net/decnet/dn_dev.c5
-rw-r--r--net/decnet/dn_neigh.c2
-rw-r--r--net/decnet/dn_route.c2
-rw-r--r--net/ethernet/eth.c12
-rw-r--r--net/ipv4/Kconfig42
-rw-r--r--net/ipv4/Makefile5
-rw-r--r--net/ipv4/af_inet.c3
-rw-r--r--net/ipv4/ah4.c1
-rw-r--r--net/ipv4/esp4.c1
-rw-r--r--net/ipv4/fib_frontend.c4
-rw-r--r--net/ipv4/fib_semantics.c16
-rw-r--r--net/ipv4/ip_gre.c3
-rw-r--r--net/ipv4/ip_output.c6
-rw-r--r--net/ipv4/ipcomp.c1
-rw-r--r--net/ipv4/ipip.c3
-rw-r--r--net/ipv4/ipvs/ip_vs_app.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_conn.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_ctl.c2
-rw-r--r--net/ipv4/multipath.c55
-rw-r--r--net/ipv4/multipath_drr.c249
-rw-r--r--net/ipv4/multipath_random.c114
-rw-r--r--net/ipv4/multipath_rr.c95
-rw-r--r--net/ipv4/multipath_wrandom.c329
-rw-r--r--net/ipv4/netfilter/Kconfig2
-rw-r--r--net/ipv4/netfilter/arp_tables.c6
-rw-r--r--net/ipv4/netfilter/arpt_mangle.c10
-rw-r--r--net/ipv4/netfilter/ip_tables.c177
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c118
-rw-r--r--net/ipv4/netfilter/ipt_ECN.c36
-rw-r--r--net/ipv4/netfilter/ipt_LOG.c56
-rw-r--r--net/ipv4/netfilter/ipt_MASQUERADE.c30
-rw-r--r--net/ipv4/netfilter/ipt_NETMAP.c23
-rw-r--r--net/ipv4/netfilter/ipt_REDIRECT.c20
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c30
-rw-r--r--net/ipv4/netfilter/ipt_SAME.c69
-rw-r--r--net/ipv4/netfilter/ipt_TOS.c8
-rw-r--r--net/ipv4/netfilter/ipt_TTL.c14
-rw-r--r--net/ipv4/netfilter/ipt_ULOG.c68
-rw-r--r--net/ipv4/netfilter/ipt_addrtype.c14
-rw-r--r--net/ipv4/netfilter/ipt_ah.c25
-rw-r--r--net/ipv4/netfilter/ipt_ecn.c59
-rw-r--r--net/ipv4/netfilter/ipt_iprange.c50
-rw-r--r--net/ipv4/netfilter/ipt_owner.c20
-rw-r--r--net/ipv4/netfilter/ipt_recent.c45
-rw-r--r--net/ipv4/netfilter/ipt_tos.c6
-rw-r--r--net/ipv4/netfilter/ipt_ttl.c26
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c36
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c112
-rw-r--r--net/ipv4/netfilter/nf_conntrack_proto_icmp.c26
-rw-r--r--net/ipv4/netfilter/nf_nat_amanda.c4
-rw-r--r--net/ipv4/netfilter/nf_nat_core.c127
-rw-r--r--net/ipv4/netfilter/nf_nat_ftp.c18
-rw-r--r--net/ipv4/netfilter/nf_nat_h323.c121
-rw-r--r--net/ipv4/netfilter/nf_nat_helper.c59
-rw-r--r--net/ipv4/netfilter/nf_nat_irc.c17
-rw-r--r--net/ipv4/netfilter/nf_nat_pptp.c43
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_gre.c17
-rw-r--r--net/ipv4/netfilter/nf_nat_rule.c48
-rw-r--r--net/ipv4/netfilter/nf_nat_sip.c18
-rw-r--r--net/ipv4/netfilter/nf_nat_snmp_basic.c6
-rw-r--r--net/ipv4/netfilter/nf_nat_standalone.c47
-rw-r--r--net/ipv4/netfilter/nf_nat_tftp.c2
-rw-r--r--net/ipv4/route.c261
-rw-r--r--net/ipv4/tcp.c26
-rw-r--r--net/ipv4/tcp_ipv4.c19
-rw-r--r--net/ipv4/tcp_output.c8
-rw-r--r--net/ipv4/tcp_probe.c194
-rw-r--r--net/ipv4/udp.c140
-rw-r--r--net/ipv4/xfrm4_input.c114
-rw-r--r--net/ipv4/xfrm4_tunnel.c1
-rw-r--r--net/ipv6/Kconfig2
-rw-r--r--net/ipv6/Makefile2
-rw-r--r--net/ipv6/addrconf.c9
-rw-r--r--net/ipv6/af_inet6.c10
-rw-r--r--net/ipv6/ah6.c13
-rw-r--r--net/ipv6/anycast.c2
-rw-r--r--net/ipv6/datagram.c5
-rw-r--r--net/ipv6/esp6.c1
-rw-r--r--net/ipv6/exthdrs.c140
-rw-r--r--net/ipv6/icmp.c2
-rw-r--r--net/ipv6/ip6_flowlabel.c2
-rw-r--r--net/ipv6/ip6_output.c6
-rw-r--r--net/ipv6/ip6_tunnel.c4
-rw-r--r--net/ipv6/ipcomp6.c2
-rw-r--r--net/ipv6/ipv6_sockglue.c15
-rw-r--r--net/ipv6/mcast.c4
-rw-r--r--net/ipv6/mip6.c24
-rw-r--r--net/ipv6/netfilter/ip6_tables.c200
-rw-r--r--net/ipv6/netfilter/ip6t_HL.c14
-rw-r--r--net/ipv6/netfilter/ip6t_LOG.c57
-rw-r--r--net/ipv6/netfilter/ip6t_REJECT.c45
-rw-r--r--net/ipv6/netfilter/ip6t_ah.c82
-rw-r--r--net/ipv6/netfilter/ip6t_eui64.c20
-rw-r--r--net/ipv6/netfilter/ip6t_frag.c111
-rw-r--r--net/ipv6/netfilter/ip6t_hbh.c88
-rw-r--r--net/ipv6/netfilter/ip6t_hl.c22
-rw-r--r--net/ipv6/netfilter/ip6t_ipv6header.c22
-rw-r--r--net/ipv6/netfilter/ip6t_mh.c30
-rw-r--r--net/ipv6/netfilter/ip6t_owner.c26
-rw-r--r--net/ipv6/netfilter/ip6t_rt.c134
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c6
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c6
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c16
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c26
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c52
-rw-r--r--net/ipv6/raw.c40
-rw-r--r--net/ipv6/sit.c3
-rw-r--r--net/ipv6/tcp_ipv6.c20
-rw-r--r--net/ipv6/xfrm6_policy.c4
-rw-r--r--net/ipv6/xfrm6_state.c4
-rw-r--r--net/ipv6/xfrm6_tunnel.c1
-rw-r--r--net/ipx/ipx_proc.c6
-rw-r--r--net/irda/Makefile2
-rw-r--r--net/irda/discovery.c2
-rw-r--r--net/irda/ircomm/ircomm_core.c2
-rw-r--r--net/irda/iriap.c2
-rw-r--r--net/irda/irlan/irlan_common.c2
-rw-r--r--net/irda/irlap.c2
-rw-r--r--net/irda/irlap_frame.c7
-rw-r--r--net/irda/irlmp.c2
-rw-r--r--net/irda/irmod.c48
-rw-r--r--net/irda/irnetlink.c170
-rw-r--r--net/irda/irttp.c31
-rw-r--r--net/llc/llc_proc.c4
-rw-r--r--net/mac80211/ieee80211_ioctl.c25
-rw-r--r--net/mac80211/rc80211_simple.c12
-rw-r--r--net/netfilter/Kconfig25
-rw-r--r--net/netfilter/Makefile4
-rw-r--r--net/netfilter/core.c10
-rw-r--r--net/netfilter/nf_conntrack_amanda.c17
-rw-r--r--net/netfilter/nf_conntrack_core.c513
-rw-r--r--net/netfilter/nf_conntrack_ecache.c16
-rw-r--r--net/netfilter/nf_conntrack_expect.c367
-rw-r--r--net/netfilter/nf_conntrack_extend.c195
-rw-r--r--net/netfilter/nf_conntrack_ftp.c143
-rw-r--r--net/netfilter/nf_conntrack_h323_asn1.c18
-rw-r--r--net/netfilter/nf_conntrack_h323_main.c307
-rw-r--r--net/netfilter/nf_conntrack_helper.c131
-rw-r--r--net/netfilter/nf_conntrack_irc.c39
-rw-r--r--net/netfilter/nf_conntrack_l3proto_generic.c13
-rw-r--r--net/netfilter/nf_conntrack_netbios_ns.c12
-rw-r--r--net/netfilter/nf_conntrack_netlink.c182
-rw-r--r--net/netfilter/nf_conntrack_pptp.c120
-rw-r--r--net/netfilter/nf_conntrack_proto_gre.c28
-rw-r--r--net/netfilter/nf_conntrack_proto_sctp.c95
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c129
-rw-r--r--net/netfilter/nf_conntrack_sane.c45
-rw-r--r--net/netfilter/nf_conntrack_sip.c37
-rw-r--r--net/netfilter/nf_conntrack_standalone.c47
-rw-r--r--net/netfilter/nf_conntrack_tftp.c32
-rw-r--r--net/netfilter/nf_log.c2
-rw-r--r--net/netfilter/nf_queue.c59
-rw-r--r--net/netfilter/nfnetlink_log.c2
-rw-r--r--net/netfilter/nfnetlink_queue.c6
-rw-r--r--net/netfilter/x_tables.c11
-rw-r--r--net/netfilter/xt_CLASSIFY.c2
-rw-r--r--net/netfilter/xt_CONNMARK.c18
-rw-r--r--net/netfilter/xt_CONNSECMARK.c18
-rw-r--r--net/netfilter/xt_DSCP.c18
-rw-r--r--net/netfilter/xt_MARK.c24
-rw-r--r--net/netfilter/xt_NFLOG.c12
-rw-r--r--net/netfilter/xt_NFQUEUE.c2
-rw-r--r--net/netfilter/xt_NOTRACK.c2
-rw-r--r--net/netfilter/xt_SECMARK.c26
-rw-r--r--net/netfilter/xt_TCPMSS.c28
-rw-r--r--net/netfilter/xt_TRACE.c53
-rw-r--r--net/netfilter/xt_comment.c8
-rw-r--r--net/netfilter/xt_connbytes.c32
-rw-r--r--net/netfilter/xt_connmark.c26
-rw-r--r--net/netfilter/xt_conntrack.c42
-rw-r--r--net/netfilter/xt_dccp.c50
-rw-r--r--net/netfilter/xt_dscp.c48
-rw-r--r--net/netfilter/xt_esp.c24
-rw-r--r--net/netfilter/xt_hashlimit.c65
-rw-r--r--net/netfilter/xt_helper.c61
-rw-r--r--net/netfilter/xt_length.c14
-rw-r--r--net/netfilter/xt_limit.c23
-rw-r--r--net/netfilter/xt_mac.c16
-rw-r--r--net/netfilter/xt_mark.c16
-rw-r--r--net/netfilter/xt_multiport.c54
-rw-r--r--net/netfilter/xt_physdev.c48
-rw-r--r--net/netfilter/xt_pkttype.c10
-rw-r--r--net/netfilter/xt_policy.c50
-rw-r--r--net/netfilter/xt_quota.c21
-rw-r--r--net/netfilter/xt_realm.c8
-rw-r--r--net/netfilter/xt_sctp.c61
-rw-r--r--net/netfilter/xt_state.c20
-rw-r--r--net/netfilter/xt_statistic.c20
-rw-r--r--net/netfilter/xt_string.c38
-rw-r--r--net/netfilter/xt_tcpmss.c10
-rw-r--r--net/netfilter/xt_tcpudp.c63
-rw-r--r--net/netfilter/xt_u32.c135
-rw-r--r--net/netlink/af_netlink.c2
-rw-r--r--net/netlink/attr.c11
-rw-r--r--net/netrom/af_netrom.c2
-rw-r--r--net/netrom/nr_route.c4
-rw-r--r--net/packet/af_packet.c2
-rw-r--r--net/rose/af_rose.c2
-rw-r--r--net/rose/rose_route.c6
-rw-r--r--net/rxrpc/ar-proc.c52
-rw-r--r--net/sched/Kconfig23
-rw-r--r--net/sched/act_api.c23
-rw-r--r--net/sched/act_gact.c11
-rw-r--r--net/sched/act_ipt.c12
-rw-r--r--net/sched/act_mirred.c12
-rw-r--r--net/sched/act_pedit.c11
-rw-r--r--net/sched/act_police.c36
-rw-r--r--net/sched/act_simple.c1
-rw-r--r--net/sched/cls_api.c10
-rw-r--r--net/sched/cls_basic.c1
-rw-r--r--net/sched/cls_fw.c19
-rw-r--r--net/sched/cls_route.c20
-rw-r--r--net/sched/cls_rsvp.c17
-rw-r--r--net/sched/cls_rsvp6.c16
-rw-r--r--net/sched/cls_tcindex.c3
-rw-r--r--net/sched/cls_u32.c18
-rw-r--r--net/sched/em_cmp.c1
-rw-r--r--net/sched/em_meta.c2
-rw-r--r--net/sched/em_nbyte.c2
-rw-r--r--net/sched/em_text.c2
-rw-r--r--net/sched/em_u32.c2
-rw-r--r--net/sched/ematch.c15
-rw-r--r--net/sched/sch_api.c18
-rw-r--r--net/sched/sch_atm.c4
-rw-r--r--net/sched/sch_blackhole.c1
-rw-r--r--net/sched/sch_cbq.c34
-rw-r--r--net/sched/sch_dsmark.c1
-rw-r--r--net/sched/sch_fifo.c1
-rw-r--r--net/sched/sch_generic.c219
-rw-r--r--net/sched/sch_gred.c1
-rw-r--r--net/sched/sch_hfsc.c21
-rw-r--r--net/sched/sch_htb.c123
-rw-r--r--net/sched/sch_ingress.c9
-rw-r--r--net/sched/sch_netem.c2
-rw-r--r--net/sched/sch_prio.c145
-rw-r--r--net/sched/sch_red.c1
-rw-r--r--net/sched/sch_sfq.c18
-rw-r--r--net/sched/sch_tbf.c19
-rw-r--r--net/sched/sch_teql.c24
-rw-r--r--net/sctp/proc.c4
-rw-r--r--net/sunrpc/auth.c370
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c349
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_mech.c2
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_mech.c2
-rw-r--r--net/sunrpc/auth_null.c10
-rw-r--r--net/sunrpc/auth_unix.c54
-rw-r--r--net/sunrpc/cache.c2
-rw-r--r--net/sunrpc/clnt.c371
-rw-r--r--net/sunrpc/rpc_pipe.c80
-rw-r--r--net/sunrpc/rpcb_clnt.c65
-rw-r--r--net/sunrpc/sched.c209
-rw-r--r--net/sunrpc/sunrpc_syms.c8
-rw-r--r--net/sunrpc/svcsock.c20
-rw-r--r--net/sunrpc/xprt.c19
-rw-r--r--net/sunrpc/xprtsock.c81
-rw-r--r--net/tipc/eth_media.c11
-rw-r--r--net/tipc/link.c16
-rw-r--r--net/tipc/port.c10
-rw-r--r--net/tipc/port.h6
-rw-r--r--net/tipc/socket.c80
-rw-r--r--net/unix/af_unix.c8
-rw-r--r--net/unix/garbage.c325
-rw-r--r--net/wanrouter/wanproc.c4
-rw-r--r--net/x25/x25_proc.c6
-rw-r--r--net/xfrm/xfrm_state.c31
305 files changed, 7735 insertions, 7197 deletions
diff --git a/net/802/tr.c b/net/802/tr.c
index 0ba1946211c9..e56e61a7f545 100644
--- a/net/802/tr.c
+++ b/net/802/tr.c
@@ -567,7 +567,7 @@ static int rif_seq_show(struct seq_file *seq, void *v)
567} 567}
568 568
569 569
570static struct seq_operations rif_seq_ops = { 570static const struct seq_operations rif_seq_ops = {
571 .start = rif_seq_start, 571 .start = rif_seq_start,
572 .next = rif_seq_next, 572 .next = rif_seq_next,
573 .stop = rif_seq_stop, 573 .stop = rif_seq_stop,
diff --git a/net/8021q/Makefile b/net/8021q/Makefile
index 97feb44dbdce..10ca7f486c3a 100644
--- a/net/8021q/Makefile
+++ b/net/8021q/Makefile
@@ -4,7 +4,7 @@
4 4
5obj-$(CONFIG_VLAN_8021Q) += 8021q.o 5obj-$(CONFIG_VLAN_8021Q) += 8021q.o
6 6
78021q-objs := vlan.o vlan_dev.o 78021q-objs := vlan.o vlan_dev.o vlan_netlink.o
8 8
9ifeq ($(CONFIG_PROC_FS),y) 9ifeq ($(CONFIG_PROC_FS),y)
108021q-objs += vlanproc.o 108021q-objs += vlanproc.o
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index de78c9dd713b..abb9900edb3f 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -97,35 +97,22 @@ static int __init vlan_proto_init(void)
97 97
98 /* Register us to receive netdevice events */ 98 /* Register us to receive netdevice events */
99 err = register_netdevice_notifier(&vlan_notifier_block); 99 err = register_netdevice_notifier(&vlan_notifier_block);
100 if (err < 0) { 100 if (err < 0)
101 dev_remove_pack(&vlan_packet_type); 101 goto err1;
102 vlan_proc_cleanup();
103 return err;
104 }
105 102
106 vlan_ioctl_set(vlan_ioctl_handler); 103 err = vlan_netlink_init();
104 if (err < 0)
105 goto err2;
107 106
107 vlan_ioctl_set(vlan_ioctl_handler);
108 return 0; 108 return 0;
109}
110
111/* Cleanup all vlan devices
112 * Note: devices that have been registered that but not
113 * brought up will exist but have no module ref count.
114 */
115static void __exit vlan_cleanup_devices(void)
116{
117 struct net_device *dev, *nxt;
118
119 rtnl_lock();
120 for_each_netdev_safe(dev, nxt) {
121 if (dev->priv_flags & IFF_802_1Q_VLAN) {
122 unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev,
123 VLAN_DEV_INFO(dev)->vlan_id);
124 109
125 unregister_netdevice(dev); 110err2:
126 } 111 unregister_netdevice_notifier(&vlan_notifier_block);
127 } 112err1:
128 rtnl_unlock(); 113 vlan_proc_cleanup();
114 dev_remove_pack(&vlan_packet_type);
115 return err;
129} 116}
130 117
131/* 118/*
@@ -136,13 +123,13 @@ static void __exit vlan_cleanup_module(void)
136{ 123{
137 int i; 124 int i;
138 125
126 vlan_netlink_fini();
139 vlan_ioctl_set(NULL); 127 vlan_ioctl_set(NULL);
140 128
141 /* Un-register us from receiving netdevice events */ 129 /* Un-register us from receiving netdevice events */
142 unregister_netdevice_notifier(&vlan_notifier_block); 130 unregister_netdevice_notifier(&vlan_notifier_block);
143 131
144 dev_remove_pack(&vlan_packet_type); 132 dev_remove_pack(&vlan_packet_type);
145 vlan_cleanup_devices();
146 133
147 /* This table must be empty if there are no module 134 /* This table must be empty if there are no module
148 * references left. 135 * references left.
@@ -197,6 +184,34 @@ static void vlan_group_free(struct vlan_group *grp)
197 kfree(grp); 184 kfree(grp);
198} 185}
199 186
187static struct vlan_group *vlan_group_alloc(int ifindex)
188{
189 struct vlan_group *grp;
190 unsigned int size;
191 unsigned int i;
192
193 grp = kzalloc(sizeof(struct vlan_group), GFP_KERNEL);
194 if (!grp)
195 return NULL;
196
197 size = sizeof(struct net_device *) * VLAN_GROUP_ARRAY_PART_LEN;
198
199 for (i = 0; i < VLAN_GROUP_ARRAY_SPLIT_PARTS; i++) {
200 grp->vlan_devices_arrays[i] = kzalloc(size, GFP_KERNEL);
201 if (!grp->vlan_devices_arrays[i])
202 goto err;
203 }
204
205 grp->real_dev_ifindex = ifindex;
206 hlist_add_head_rcu(&grp->hlist,
207 &vlan_group_hash[vlan_grp_hashfn(ifindex)]);
208 return grp;
209
210err:
211 vlan_group_free(grp);
212 return NULL;
213}
214
200static void vlan_rcu_free(struct rcu_head *rcu) 215static void vlan_rcu_free(struct rcu_head *rcu)
201{ 216{
202 vlan_group_free(container_of(rcu, struct vlan_group, rcu)); 217 vlan_group_free(container_of(rcu, struct vlan_group, rcu));
@@ -278,50 +293,66 @@ static int unregister_vlan_dev(struct net_device *real_dev,
278 return ret; 293 return ret;
279} 294}
280 295
281static int unregister_vlan_device(const char *vlan_IF_name) 296int unregister_vlan_device(struct net_device *dev)
282{ 297{
283 struct net_device *dev = NULL;
284 int ret; 298 int ret;
285 299
300 ret = unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev,
301 VLAN_DEV_INFO(dev)->vlan_id);
302 unregister_netdevice(dev);
286 303
287 dev = dev_get_by_name(vlan_IF_name); 304 if (ret == 1)
288 ret = -EINVAL; 305 ret = 0;
289 if (dev) { 306 return ret;
290 if (dev->priv_flags & IFF_802_1Q_VLAN) { 307}
291 rtnl_lock();
292 308
293 ret = unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev, 309/*
294 VLAN_DEV_INFO(dev)->vlan_id); 310 * vlan network devices have devices nesting below it, and are a special
311 * "super class" of normal network devices; split their locks off into a
312 * separate class since they always nest.
313 */
314static struct lock_class_key vlan_netdev_xmit_lock_key;
295 315
296 dev_put(dev); 316static int vlan_dev_init(struct net_device *dev)
297 unregister_netdevice(dev); 317{
318 struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev;
298 319
299 rtnl_unlock(); 320 /* IFF_BROADCAST|IFF_MULTICAST; ??? */
321 dev->flags = real_dev->flags & ~IFF_UP;
322 dev->iflink = real_dev->ifindex;
323 dev->state = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) |
324 (1<<__LINK_STATE_DORMANT))) |
325 (1<<__LINK_STATE_PRESENT);
300 326
301 if (ret == 1) 327 if (is_zero_ether_addr(dev->dev_addr))
302 ret = 0; 328 memcpy(dev->dev_addr, real_dev->dev_addr, dev->addr_len);
303 } else { 329 if (is_zero_ether_addr(dev->broadcast))
304 printk(VLAN_ERR 330 memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len);
305 "%s: ERROR: Tried to remove a non-vlan device " 331
306 "with VLAN code, name: %s priv_flags: %hX\n", 332 if (real_dev->features & NETIF_F_HW_VLAN_TX) {
307 __FUNCTION__, dev->name, dev->priv_flags); 333 dev->hard_header = real_dev->hard_header;
308 dev_put(dev); 334 dev->hard_header_len = real_dev->hard_header_len;
309 ret = -EPERM; 335 dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit;
310 } 336 dev->rebuild_header = real_dev->rebuild_header;
311 } else { 337 } else {
312#ifdef VLAN_DEBUG 338 dev->hard_header = vlan_dev_hard_header;
313 printk(VLAN_DBG "%s: WARNING: Could not find dev.\n", __FUNCTION__); 339 dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN;
314#endif 340 dev->hard_start_xmit = vlan_dev_hard_start_xmit;
315 ret = -EINVAL; 341 dev->rebuild_header = vlan_dev_rebuild_header;
316 } 342 }
343 dev->hard_header_parse = real_dev->hard_header_parse;
344 dev->hard_header_cache = NULL;
317 345
318 return ret; 346 lockdep_set_class(&dev->_xmit_lock, &vlan_netdev_xmit_lock_key);
347 return 0;
319} 348}
320 349
321static void vlan_setup(struct net_device *new_dev) 350void vlan_setup(struct net_device *new_dev)
322{ 351{
323 SET_MODULE_OWNER(new_dev); 352 SET_MODULE_OWNER(new_dev);
324 353
354 ether_setup(new_dev);
355
325 /* new_dev->ifindex = 0; it will be set when added to 356 /* new_dev->ifindex = 0; it will be set when added to
326 * the global list. 357 * the global list.
327 * iflink is set as well. 358 * iflink is set as well.
@@ -338,12 +369,14 @@ static void vlan_setup(struct net_device *new_dev)
338 369
339 /* set up method calls */ 370 /* set up method calls */
340 new_dev->change_mtu = vlan_dev_change_mtu; 371 new_dev->change_mtu = vlan_dev_change_mtu;
372 new_dev->init = vlan_dev_init;
341 new_dev->open = vlan_dev_open; 373 new_dev->open = vlan_dev_open;
342 new_dev->stop = vlan_dev_stop; 374 new_dev->stop = vlan_dev_stop;
343 new_dev->set_mac_address = vlan_dev_set_mac_address;
344 new_dev->set_multicast_list = vlan_dev_set_multicast_list; 375 new_dev->set_multicast_list = vlan_dev_set_multicast_list;
345 new_dev->destructor = free_netdev; 376 new_dev->destructor = free_netdev;
346 new_dev->do_ioctl = vlan_dev_ioctl; 377 new_dev->do_ioctl = vlan_dev_ioctl;
378
379 memset(new_dev->broadcast, 0, sizeof(ETH_ALEN));
347} 380}
348 381
349static void vlan_transfer_operstate(const struct net_device *dev, struct net_device *vlandev) 382static void vlan_transfer_operstate(const struct net_device *dev, struct net_device *vlandev)
@@ -366,77 +399,110 @@ static void vlan_transfer_operstate(const struct net_device *dev, struct net_dev
366 } 399 }
367} 400}
368 401
369/* 402int vlan_check_real_dev(struct net_device *real_dev, unsigned short vlan_id)
370 * vlan network devices have devices nesting below it, and are a special
371 * "super class" of normal network devices; split their locks off into a
372 * separate class since they always nest.
373 */
374static struct lock_class_key vlan_netdev_xmit_lock_key;
375
376
377/* Attach a VLAN device to a mac address (ie Ethernet Card).
378 * Returns the device that was created, or NULL if there was
379 * an error of some kind.
380 */
381static struct net_device *register_vlan_device(const char *eth_IF_name,
382 unsigned short VLAN_ID)
383{ 403{
384 struct vlan_group *grp;
385 struct net_device *new_dev;
386 struct net_device *real_dev; /* the ethernet device */
387 char name[IFNAMSIZ];
388 int i;
389
390#ifdef VLAN_DEBUG
391 printk(VLAN_DBG "%s: if_name -:%s:- vid: %i\n",
392 __FUNCTION__, eth_IF_name, VLAN_ID);
393#endif
394
395 if (VLAN_ID >= VLAN_VID_MASK)
396 goto out_ret_null;
397
398 /* find the device relating to eth_IF_name. */
399 real_dev = dev_get_by_name(eth_IF_name);
400 if (!real_dev)
401 goto out_ret_null;
402
403 if (real_dev->features & NETIF_F_VLAN_CHALLENGED) { 404 if (real_dev->features & NETIF_F_VLAN_CHALLENGED) {
404 printk(VLAN_DBG "%s: VLANs not supported on %s.\n", 405 printk(VLAN_DBG "%s: VLANs not supported on %s.\n",
405 __FUNCTION__, real_dev->name); 406 __FUNCTION__, real_dev->name);
406 goto out_put_dev; 407 return -EOPNOTSUPP;
407 } 408 }
408 409
409 if ((real_dev->features & NETIF_F_HW_VLAN_RX) && 410 if ((real_dev->features & NETIF_F_HW_VLAN_RX) &&
410 !real_dev->vlan_rx_register) { 411 !real_dev->vlan_rx_register) {
411 printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n", 412 printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n",
412 __FUNCTION__, real_dev->name); 413 __FUNCTION__, real_dev->name);
413 goto out_put_dev; 414 return -EOPNOTSUPP;
414 } 415 }
415 416
416 if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) && 417 if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) &&
417 (!real_dev->vlan_rx_add_vid || !real_dev->vlan_rx_kill_vid)) { 418 (!real_dev->vlan_rx_add_vid || !real_dev->vlan_rx_kill_vid)) {
418 printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n", 419 printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n",
419 __FUNCTION__, real_dev->name); 420 __FUNCTION__, real_dev->name);
420 goto out_put_dev; 421 return -EOPNOTSUPP;
421 } 422 }
422 423
423 /* From this point on, all the data structures must remain
424 * consistent.
425 */
426 rtnl_lock();
427
428 /* The real device must be up and operating in order to 424 /* The real device must be up and operating in order to
429 * assosciate a VLAN device with it. 425 * assosciate a VLAN device with it.
430 */ 426 */
431 if (!(real_dev->flags & IFF_UP)) 427 if (!(real_dev->flags & IFF_UP))
432 goto out_unlock; 428 return -ENETDOWN;
433 429
434 if (__find_vlan_dev(real_dev, VLAN_ID) != NULL) { 430 if (__find_vlan_dev(real_dev, vlan_id) != NULL) {
435 /* was already registered. */ 431 /* was already registered. */
436 printk(VLAN_DBG "%s: ALREADY had VLAN registered\n", __FUNCTION__); 432 printk(VLAN_DBG "%s: ALREADY had VLAN registered\n", __FUNCTION__);
437 goto out_unlock; 433 return -EEXIST;
434 }
435
436 return 0;
437}
438
439int register_vlan_dev(struct net_device *dev)
440{
441 struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
442 struct net_device *real_dev = vlan->real_dev;
443 unsigned short vlan_id = vlan->vlan_id;
444 struct vlan_group *grp, *ngrp = NULL;
445 int err;
446
447 grp = __vlan_find_group(real_dev->ifindex);
448 if (!grp) {
449 ngrp = grp = vlan_group_alloc(real_dev->ifindex);
450 if (!grp)
451 return -ENOBUFS;
438 } 452 }
439 453
454 err = register_netdevice(dev);
455 if (err < 0)
456 goto out_free_group;
457
458 /* Account for reference in struct vlan_dev_info */
459 dev_hold(real_dev);
460
461 vlan_transfer_operstate(real_dev, dev);
462 linkwatch_fire_event(dev); /* _MUST_ call rfc2863_policy() */
463
464 /* So, got the sucker initialized, now lets place
465 * it into our local structure.
466 */
467 vlan_group_set_device(grp, vlan_id, dev);
468 if (ngrp && real_dev->features & NETIF_F_HW_VLAN_RX)
469 real_dev->vlan_rx_register(real_dev, ngrp);
470 if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
471 real_dev->vlan_rx_add_vid(real_dev, vlan_id);
472
473 if (vlan_proc_add_dev(dev) < 0)
474 printk(KERN_WARNING "VLAN: failed to add proc entry for %s\n",
475 dev->name);
476 return 0;
477
478out_free_group:
479 if (ngrp)
480 vlan_group_free(ngrp);
481 return err;
482}
483
484/* Attach a VLAN device to a mac address (ie Ethernet Card).
485 * Returns 0 if the device was created or a negative error code otherwise.
486 */
487static int register_vlan_device(struct net_device *real_dev,
488 unsigned short VLAN_ID)
489{
490 struct net_device *new_dev;
491 char name[IFNAMSIZ];
492 int err;
493
494#ifdef VLAN_DEBUG
495 printk(VLAN_DBG "%s: if_name -:%s:- vid: %i\n",
496 __FUNCTION__, eth_IF_name, VLAN_ID);
497#endif
498
499 if (VLAN_ID >= VLAN_VID_MASK)
500 return -ERANGE;
501
502 err = vlan_check_real_dev(real_dev, VLAN_ID);
503 if (err < 0)
504 return err;
505
440 /* Gotta set up the fields for the device. */ 506 /* Gotta set up the fields for the device. */
441#ifdef VLAN_DEBUG 507#ifdef VLAN_DEBUG
442 printk(VLAN_DBG "About to allocate name, vlan_name_type: %i\n", 508 printk(VLAN_DBG "About to allocate name, vlan_name_type: %i\n",
@@ -471,138 +537,64 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
471 vlan_setup); 537 vlan_setup);
472 538
473 if (new_dev == NULL) 539 if (new_dev == NULL)
474 goto out_unlock; 540 return -ENOBUFS;
475
476#ifdef VLAN_DEBUG
477 printk(VLAN_DBG "Allocated new name -:%s:-\n", new_dev->name);
478#endif
479 /* IFF_BROADCAST|IFF_MULTICAST; ??? */
480 new_dev->flags = real_dev->flags;
481 new_dev->flags &= ~IFF_UP;
482
483 new_dev->state = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) |
484 (1<<__LINK_STATE_DORMANT))) |
485 (1<<__LINK_STATE_PRESENT);
486 541
487 /* need 4 bytes for extra VLAN header info, 542 /* need 4 bytes for extra VLAN header info,
488 * hope the underlying device can handle it. 543 * hope the underlying device can handle it.
489 */ 544 */
490 new_dev->mtu = real_dev->mtu; 545 new_dev->mtu = real_dev->mtu;
491 546
492 /* TODO: maybe just assign it to be ETHERNET? */ 547#ifdef VLAN_DEBUG
493 new_dev->type = real_dev->type; 548 printk(VLAN_DBG "Allocated new name -:%s:-\n", new_dev->name);
494
495 new_dev->hard_header_len = real_dev->hard_header_len;
496 if (!(real_dev->features & NETIF_F_HW_VLAN_TX)) {
497 /* Regular ethernet + 4 bytes (18 total). */
498 new_dev->hard_header_len += VLAN_HLEN;
499 }
500
501 VLAN_MEM_DBG("new_dev->priv malloc, addr: %p size: %i\n", 549 VLAN_MEM_DBG("new_dev->priv malloc, addr: %p size: %i\n",
502 new_dev->priv, 550 new_dev->priv,
503 sizeof(struct vlan_dev_info)); 551 sizeof(struct vlan_dev_info));
504 552#endif
505 memcpy(new_dev->broadcast, real_dev->broadcast, real_dev->addr_len);
506 memcpy(new_dev->dev_addr, real_dev->dev_addr, real_dev->addr_len);
507 new_dev->addr_len = real_dev->addr_len;
508
509 if (real_dev->features & NETIF_F_HW_VLAN_TX) {
510 new_dev->hard_header = real_dev->hard_header;
511 new_dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit;
512 new_dev->rebuild_header = real_dev->rebuild_header;
513 } else {
514 new_dev->hard_header = vlan_dev_hard_header;
515 new_dev->hard_start_xmit = vlan_dev_hard_start_xmit;
516 new_dev->rebuild_header = vlan_dev_rebuild_header;
517 }
518 new_dev->hard_header_parse = real_dev->hard_header_parse;
519 553
520 VLAN_DEV_INFO(new_dev)->vlan_id = VLAN_ID; /* 1 through VLAN_VID_MASK */ 554 VLAN_DEV_INFO(new_dev)->vlan_id = VLAN_ID; /* 1 through VLAN_VID_MASK */
521 VLAN_DEV_INFO(new_dev)->real_dev = real_dev; 555 VLAN_DEV_INFO(new_dev)->real_dev = real_dev;
522 VLAN_DEV_INFO(new_dev)->dent = NULL; 556 VLAN_DEV_INFO(new_dev)->dent = NULL;
523 VLAN_DEV_INFO(new_dev)->flags = 1; 557 VLAN_DEV_INFO(new_dev)->flags = VLAN_FLAG_REORDER_HDR;
524 558
525#ifdef VLAN_DEBUG 559 new_dev->rtnl_link_ops = &vlan_link_ops;
526 printk(VLAN_DBG "About to go find the group for idx: %i\n", 560 err = register_vlan_dev(new_dev);
527 real_dev->ifindex); 561 if (err < 0)
528#endif
529
530 if (register_netdevice(new_dev))
531 goto out_free_newdev; 562 goto out_free_newdev;
532 563
533 lockdep_set_class(&new_dev->_xmit_lock, &vlan_netdev_xmit_lock_key); 564 /* Account for reference in struct vlan_dev_info */
534 565 dev_hold(real_dev);
535 new_dev->iflink = real_dev->ifindex;
536 vlan_transfer_operstate(real_dev, new_dev);
537 linkwatch_fire_event(new_dev); /* _MUST_ call rfc2863_policy() */
538
539 /* So, got the sucker initialized, now lets place
540 * it into our local structure.
541 */
542 grp = __vlan_find_group(real_dev->ifindex);
543
544 /* Note, we are running under the RTNL semaphore
545 * so it cannot "appear" on us.
546 */
547 if (!grp) { /* need to add a new group */
548 grp = kzalloc(sizeof(struct vlan_group), GFP_KERNEL);
549 if (!grp)
550 goto out_free_unregister;
551
552 for (i=0; i < VLAN_GROUP_ARRAY_SPLIT_PARTS; i++) {
553 grp->vlan_devices_arrays[i] = kzalloc(
554 sizeof(struct net_device *)*VLAN_GROUP_ARRAY_PART_LEN,
555 GFP_KERNEL);
556
557 if (!grp->vlan_devices_arrays[i])
558 goto out_free_arrays;
559 }
560
561 /* printk(KERN_ALERT "VLAN REGISTER: Allocated new group.\n"); */
562 grp->real_dev_ifindex = real_dev->ifindex;
563
564 hlist_add_head_rcu(&grp->hlist,
565 &vlan_group_hash[vlan_grp_hashfn(real_dev->ifindex)]);
566
567 if (real_dev->features & NETIF_F_HW_VLAN_RX)
568 real_dev->vlan_rx_register(real_dev, grp);
569 }
570
571 vlan_group_set_device(grp, VLAN_ID, new_dev);
572
573 if (vlan_proc_add_dev(new_dev)<0)/* create it's proc entry */
574 printk(KERN_WARNING "VLAN: failed to add proc entry for %s\n",
575 new_dev->name);
576
577 if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
578 real_dev->vlan_rx_add_vid(real_dev, VLAN_ID);
579
580 rtnl_unlock();
581
582
583#ifdef VLAN_DEBUG 566#ifdef VLAN_DEBUG
584 printk(VLAN_DBG "Allocated new device successfully, returning.\n"); 567 printk(VLAN_DBG "Allocated new device successfully, returning.\n");
585#endif 568#endif
586 return new_dev; 569 return 0;
587
588out_free_arrays:
589 vlan_group_free(grp);
590
591out_free_unregister:
592 unregister_netdev(new_dev);
593 goto out_unlock;
594 570
595out_free_newdev: 571out_free_newdev:
596 free_netdev(new_dev); 572 free_netdev(new_dev);
573 return err;
574}
597 575
598out_unlock: 576static void vlan_sync_address(struct net_device *dev,
599 rtnl_unlock(); 577 struct net_device *vlandev)
578{
579 struct vlan_dev_info *vlan = VLAN_DEV_INFO(vlandev);
600 580
601out_put_dev: 581 /* May be called without an actual change */
602 dev_put(real_dev); 582 if (!compare_ether_addr(vlan->real_dev_addr, dev->dev_addr))
583 return;
603 584
604out_ret_null: 585 /* vlan address was different from the old address and is equal to
605 return NULL; 586 * the new address */
587 if (compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) &&
588 !compare_ether_addr(vlandev->dev_addr, dev->dev_addr))
589 dev_unicast_delete(dev, vlandev->dev_addr, ETH_ALEN);
590
591 /* vlan address was equal to the old address and is different from
592 * the new address */
593 if (!compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) &&
594 compare_ether_addr(vlandev->dev_addr, dev->dev_addr))
595 dev_unicast_add(dev, vlandev->dev_addr, ETH_ALEN);
596
597 memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN);
606} 598}
607 599
608static int vlan_device_event(struct notifier_block *unused, unsigned long event, void *ptr) 600static int vlan_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
@@ -631,6 +623,17 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
631 } 623 }
632 break; 624 break;
633 625
626 case NETDEV_CHANGEADDR:
627 /* Adjust unicast filters on underlying device */
628 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
629 vlandev = vlan_group_get_device(grp, i);
630 if (!vlandev)
631 continue;
632
633 vlan_sync_address(dev, vlandev);
634 }
635 break;
636
634 case NETDEV_DOWN: 637 case NETDEV_DOWN:
635 /* Put all VLANs for this dev in the down state too. */ 638 /* Put all VLANs for this dev in the down state too. */
636 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { 639 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
@@ -693,9 +696,10 @@ out:
693 */ 696 */
694static int vlan_ioctl_handler(void __user *arg) 697static int vlan_ioctl_handler(void __user *arg)
695{ 698{
696 int err = 0; 699 int err;
697 unsigned short vid = 0; 700 unsigned short vid = 0;
698 struct vlan_ioctl_args args; 701 struct vlan_ioctl_args args;
702 struct net_device *dev = NULL;
699 703
700 if (copy_from_user(&args, arg, sizeof(struct vlan_ioctl_args))) 704 if (copy_from_user(&args, arg, sizeof(struct vlan_ioctl_args)))
701 return -EFAULT; 705 return -EFAULT;
@@ -708,35 +712,61 @@ static int vlan_ioctl_handler(void __user *arg)
708 printk(VLAN_DBG "%s: args.cmd: %x\n", __FUNCTION__, args.cmd); 712 printk(VLAN_DBG "%s: args.cmd: %x\n", __FUNCTION__, args.cmd);
709#endif 713#endif
710 714
715 rtnl_lock();
716
717 switch (args.cmd) {
718 case SET_VLAN_INGRESS_PRIORITY_CMD:
719 case SET_VLAN_EGRESS_PRIORITY_CMD:
720 case SET_VLAN_FLAG_CMD:
721 case ADD_VLAN_CMD:
722 case DEL_VLAN_CMD:
723 case GET_VLAN_REALDEV_NAME_CMD:
724 case GET_VLAN_VID_CMD:
725 err = -ENODEV;
726 dev = __dev_get_by_name(args.device1);
727 if (!dev)
728 goto out;
729
730 err = -EINVAL;
731 if (args.cmd != ADD_VLAN_CMD &&
732 !(dev->priv_flags & IFF_802_1Q_VLAN))
733 goto out;
734 }
735
711 switch (args.cmd) { 736 switch (args.cmd) {
712 case SET_VLAN_INGRESS_PRIORITY_CMD: 737 case SET_VLAN_INGRESS_PRIORITY_CMD:
738 err = -EPERM;
713 if (!capable(CAP_NET_ADMIN)) 739 if (!capable(CAP_NET_ADMIN))
714 return -EPERM; 740 break;
715 err = vlan_dev_set_ingress_priority(args.device1, 741 vlan_dev_set_ingress_priority(dev,
716 args.u.skb_priority, 742 args.u.skb_priority,
717 args.vlan_qos); 743 args.vlan_qos);
718 break; 744 break;
719 745
720 case SET_VLAN_EGRESS_PRIORITY_CMD: 746 case SET_VLAN_EGRESS_PRIORITY_CMD:
747 err = -EPERM;
721 if (!capable(CAP_NET_ADMIN)) 748 if (!capable(CAP_NET_ADMIN))
722 return -EPERM; 749 break;
723 err = vlan_dev_set_egress_priority(args.device1, 750 err = vlan_dev_set_egress_priority(dev,
724 args.u.skb_priority, 751 args.u.skb_priority,
725 args.vlan_qos); 752 args.vlan_qos);
726 break; 753 break;
727 754
728 case SET_VLAN_FLAG_CMD: 755 case SET_VLAN_FLAG_CMD:
756 err = -EPERM;
729 if (!capable(CAP_NET_ADMIN)) 757 if (!capable(CAP_NET_ADMIN))
730 return -EPERM; 758 break;
731 err = vlan_dev_set_vlan_flag(args.device1, 759 err = vlan_dev_set_vlan_flag(dev,
732 args.u.flag, 760 args.u.flag,
733 args.vlan_qos); 761 args.vlan_qos);
734 break; 762 break;
735 763
736 case SET_VLAN_NAME_TYPE_CMD: 764 case SET_VLAN_NAME_TYPE_CMD:
765 err = -EPERM;
737 if (!capable(CAP_NET_ADMIN)) 766 if (!capable(CAP_NET_ADMIN))
738 return -EPERM; 767 return -EPERM;
739 if (args.u.name_type < VLAN_NAME_TYPE_HIGHEST) { 768 if ((args.u.name_type >= 0) &&
769 (args.u.name_type < VLAN_NAME_TYPE_HIGHEST)) {
740 vlan_name_type = args.u.name_type; 770 vlan_name_type = args.u.name_type;
741 err = 0; 771 err = 0;
742 } else { 772 } else {
@@ -745,26 +775,17 @@ static int vlan_ioctl_handler(void __user *arg)
745 break; 775 break;
746 776
747 case ADD_VLAN_CMD: 777 case ADD_VLAN_CMD:
778 err = -EPERM;
748 if (!capable(CAP_NET_ADMIN)) 779 if (!capable(CAP_NET_ADMIN))
749 return -EPERM; 780 break;
750 /* we have been given the name of the Ethernet Device we want to 781 err = register_vlan_device(dev, args.u.VID);
751 * talk to: args.dev1 We also have the
752 * VLAN ID: args.u.VID
753 */
754 if (register_vlan_device(args.device1, args.u.VID)) {
755 err = 0;
756 } else {
757 err = -EINVAL;
758 }
759 break; 782 break;
760 783
761 case DEL_VLAN_CMD: 784 case DEL_VLAN_CMD:
785 err = -EPERM;
762 if (!capable(CAP_NET_ADMIN)) 786 if (!capable(CAP_NET_ADMIN))
763 return -EPERM; 787 break;
764 /* Here, the args.dev1 is the actual VLAN we want 788 err = unregister_vlan_device(dev);
765 * to get rid of.
766 */
767 err = unregister_vlan_device(args.device1);
768 break; 789 break;
769 790
770 case GET_VLAN_INGRESS_PRIORITY_CMD: 791 case GET_VLAN_INGRESS_PRIORITY_CMD:
@@ -788,9 +809,7 @@ static int vlan_ioctl_handler(void __user *arg)
788 err = -EINVAL; 809 err = -EINVAL;
789 break; 810 break;
790 case GET_VLAN_REALDEV_NAME_CMD: 811 case GET_VLAN_REALDEV_NAME_CMD:
791 err = vlan_dev_get_realdev_name(args.device1, args.u.device2); 812 vlan_dev_get_realdev_name(dev, args.u.device2);
792 if (err)
793 goto out;
794 if (copy_to_user(arg, &args, 813 if (copy_to_user(arg, &args,
795 sizeof(struct vlan_ioctl_args))) { 814 sizeof(struct vlan_ioctl_args))) {
796 err = -EFAULT; 815 err = -EFAULT;
@@ -798,9 +817,7 @@ static int vlan_ioctl_handler(void __user *arg)
798 break; 817 break;
799 818
800 case GET_VLAN_VID_CMD: 819 case GET_VLAN_VID_CMD:
801 err = vlan_dev_get_vid(args.device1, &vid); 820 vlan_dev_get_vid(dev, &vid);
802 if (err)
803 goto out;
804 args.u.VID = vid; 821 args.u.VID = vid;
805 if (copy_to_user(arg, &args, 822 if (copy_to_user(arg, &args,
806 sizeof(struct vlan_ioctl_args))) { 823 sizeof(struct vlan_ioctl_args))) {
@@ -812,9 +829,11 @@ static int vlan_ioctl_handler(void __user *arg)
812 /* pass on to underlying device instead?? */ 829 /* pass on to underlying device instead?? */
813 printk(VLAN_DBG "%s: Unknown VLAN CMD: %x \n", 830 printk(VLAN_DBG "%s: Unknown VLAN CMD: %x \n",
814 __FUNCTION__, args.cmd); 831 __FUNCTION__, args.cmd);
815 return -EINVAL; 832 err = -EINVAL;
833 break;
816 } 834 }
817out: 835out:
836 rtnl_unlock();
818 return err; 837 return err;
819} 838}
820 839
diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h
index 1976cdba8f72..62ce1c519aab 100644
--- a/net/8021q/vlan.h
+++ b/net/8021q/vlan.h
@@ -58,15 +58,27 @@ int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
58int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev); 58int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev);
59int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev); 59int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev);
60int vlan_dev_change_mtu(struct net_device *dev, int new_mtu); 60int vlan_dev_change_mtu(struct net_device *dev, int new_mtu);
61int vlan_dev_set_mac_address(struct net_device *dev, void* addr);
62int vlan_dev_open(struct net_device* dev); 61int vlan_dev_open(struct net_device* dev);
63int vlan_dev_stop(struct net_device* dev); 62int vlan_dev_stop(struct net_device* dev);
64int vlan_dev_ioctl(struct net_device* dev, struct ifreq *ifr, int cmd); 63int vlan_dev_ioctl(struct net_device* dev, struct ifreq *ifr, int cmd);
65int vlan_dev_set_ingress_priority(char* dev_name, __u32 skb_prio, short vlan_prio); 64void vlan_dev_set_ingress_priority(const struct net_device *dev,
66int vlan_dev_set_egress_priority(char* dev_name, __u32 skb_prio, short vlan_prio); 65 u32 skb_prio, short vlan_prio);
67int vlan_dev_set_vlan_flag(char* dev_name, __u32 flag, short flag_val); 66int vlan_dev_set_egress_priority(const struct net_device *dev,
68int vlan_dev_get_realdev_name(const char* dev_name, char* result); 67 u32 skb_prio, short vlan_prio);
69int vlan_dev_get_vid(const char* dev_name, unsigned short* result); 68int vlan_dev_set_vlan_flag(const struct net_device *dev,
69 u32 flag, short flag_val);
70void vlan_dev_get_realdev_name(const struct net_device *dev, char *result);
71void vlan_dev_get_vid(const struct net_device *dev, unsigned short *result);
70void vlan_dev_set_multicast_list(struct net_device *vlan_dev); 72void vlan_dev_set_multicast_list(struct net_device *vlan_dev);
71 73
74int vlan_check_real_dev(struct net_device *real_dev, unsigned short vlan_id);
75void vlan_setup(struct net_device *dev);
76int register_vlan_dev(struct net_device *dev);
77int unregister_vlan_device(struct net_device *dev);
78
79int vlan_netlink_init(void);
80void vlan_netlink_fini(void);
81
82extern struct rtnl_link_ops vlan_link_ops;
83
72#endif /* !(__BEN_VLAN_802_1Q_INC__) */ 84#endif /* !(__BEN_VLAN_802_1Q_INC__) */
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index ec46084f44b4..d4a62d1b52b4 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -73,7 +73,7 @@ int vlan_dev_rebuild_header(struct sk_buff *skb)
73 73
74static inline struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb) 74static inline struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb)
75{ 75{
76 if (VLAN_DEV_INFO(skb->dev)->flags & 1) { 76 if (VLAN_DEV_INFO(skb->dev)->flags & VLAN_FLAG_REORDER_HDR) {
77 if (skb_shared(skb) || skb_cloned(skb)) { 77 if (skb_shared(skb) || skb_cloned(skb)) {
78 struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC); 78 struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
79 kfree_skb(skb); 79 kfree_skb(skb);
@@ -350,7 +350,8 @@ int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
350 * header shuffling in the hard_start_xmit. Users can turn off this 350 * header shuffling in the hard_start_xmit. Users can turn off this
351 * REORDER behaviour with the vconfig tool. 351 * REORDER behaviour with the vconfig tool.
352 */ 352 */
353 build_vlan_header = ((VLAN_DEV_INFO(dev)->flags & 1) == 0); 353 if (!(VLAN_DEV_INFO(dev)->flags & VLAN_FLAG_REORDER_HDR))
354 build_vlan_header = 1;
354 355
355 if (build_vlan_header) { 356 if (build_vlan_header) {
356 vhdr = (struct vlan_hdr *) skb_push(skb, VLAN_HLEN); 357 vhdr = (struct vlan_hdr *) skb_push(skb, VLAN_HLEN);
@@ -534,172 +535,81 @@ int vlan_dev_change_mtu(struct net_device *dev, int new_mtu)
534 return 0; 535 return 0;
535} 536}
536 537
537int vlan_dev_set_ingress_priority(char *dev_name, __u32 skb_prio, short vlan_prio) 538void vlan_dev_set_ingress_priority(const struct net_device *dev,
539 u32 skb_prio, short vlan_prio)
538{ 540{
539 struct net_device *dev = dev_get_by_name(dev_name); 541 struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
540 542
541 if (dev) { 543 if (vlan->ingress_priority_map[vlan_prio & 0x7] && !skb_prio)
542 if (dev->priv_flags & IFF_802_1Q_VLAN) { 544 vlan->nr_ingress_mappings--;
543 /* see if a priority mapping exists.. */ 545 else if (!vlan->ingress_priority_map[vlan_prio & 0x7] && skb_prio)
544 VLAN_DEV_INFO(dev)->ingress_priority_map[vlan_prio & 0x7] = skb_prio; 546 vlan->nr_ingress_mappings++;
545 dev_put(dev);
546 return 0;
547 }
548 547
549 dev_put(dev); 548 vlan->ingress_priority_map[vlan_prio & 0x7] = skb_prio;
550 }
551 return -EINVAL;
552} 549}
553 550
554int vlan_dev_set_egress_priority(char *dev_name, __u32 skb_prio, short vlan_prio) 551int vlan_dev_set_egress_priority(const struct net_device *dev,
552 u32 skb_prio, short vlan_prio)
555{ 553{
556 struct net_device *dev = dev_get_by_name(dev_name); 554 struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
557 struct vlan_priority_tci_mapping *mp = NULL; 555 struct vlan_priority_tci_mapping *mp = NULL;
558 struct vlan_priority_tci_mapping *np; 556 struct vlan_priority_tci_mapping *np;
557 u32 vlan_qos = (vlan_prio << 13) & 0xE000;
559 558
560 if (dev) { 559 /* See if a priority mapping exists.. */
561 if (dev->priv_flags & IFF_802_1Q_VLAN) { 560 mp = vlan->egress_priority_map[skb_prio & 0xF];
562 /* See if a priority mapping exists.. */ 561 while (mp) {
563 mp = VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF]; 562 if (mp->priority == skb_prio) {
564 while (mp) { 563 if (mp->vlan_qos && !vlan_qos)
565 if (mp->priority == skb_prio) { 564 vlan->nr_egress_mappings--;
566 mp->vlan_qos = ((vlan_prio << 13) & 0xE000); 565 else if (!mp->vlan_qos && vlan_qos)
567 dev_put(dev); 566 vlan->nr_egress_mappings++;
568 return 0; 567 mp->vlan_qos = vlan_qos;
569 } 568 return 0;
570 mp = mp->next;
571 }
572
573 /* Create a new mapping then. */
574 mp = VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF];
575 np = kmalloc(sizeof(struct vlan_priority_tci_mapping), GFP_KERNEL);
576 if (np) {
577 np->next = mp;
578 np->priority = skb_prio;
579 np->vlan_qos = ((vlan_prio << 13) & 0xE000);
580 VLAN_DEV_INFO(dev)->egress_priority_map[skb_prio & 0xF] = np;
581 dev_put(dev);
582 return 0;
583 } else {
584 dev_put(dev);
585 return -ENOBUFS;
586 }
587 }
588 dev_put(dev);
589 }
590 return -EINVAL;
591}
592
593/* Flags are defined in the vlan_dev_info class in include/linux/if_vlan.h file. */
594int vlan_dev_set_vlan_flag(char *dev_name, __u32 flag, short flag_val)
595{
596 struct net_device *dev = dev_get_by_name(dev_name);
597
598 if (dev) {
599 if (dev->priv_flags & IFF_802_1Q_VLAN) {
600 /* verify flag is supported */
601 if (flag == 1) {
602 if (flag_val) {
603 VLAN_DEV_INFO(dev)->flags |= 1;
604 } else {
605 VLAN_DEV_INFO(dev)->flags &= ~1;
606 }
607 dev_put(dev);
608 return 0;
609 } else {
610 printk(KERN_ERR "%s: flag %i is not valid.\n",
611 __FUNCTION__, (int)(flag));
612 dev_put(dev);
613 return -EINVAL;
614 }
615 } else {
616 printk(KERN_ERR
617 "%s: %s is not a vlan device, priv_flags: %hX.\n",
618 __FUNCTION__, dev->name, dev->priv_flags);
619 dev_put(dev);
620 } 569 }
621 } else { 570 mp = mp->next;
622 printk(KERN_ERR "%s: Could not find device: %s\n",
623 __FUNCTION__, dev_name);
624 } 571 }
625 572
626 return -EINVAL; 573 /* Create a new mapping then. */
574 mp = vlan->egress_priority_map[skb_prio & 0xF];
575 np = kmalloc(sizeof(struct vlan_priority_tci_mapping), GFP_KERNEL);
576 if (!np)
577 return -ENOBUFS;
578
579 np->next = mp;
580 np->priority = skb_prio;
581 np->vlan_qos = vlan_qos;
582 vlan->egress_priority_map[skb_prio & 0xF] = np;
583 if (vlan_qos)
584 vlan->nr_egress_mappings++;
585 return 0;
627} 586}
628 587
629 588/* Flags are defined in the vlan_flags enum in include/linux/if_vlan.h file. */
630int vlan_dev_get_realdev_name(const char *dev_name, char* result) 589int vlan_dev_set_vlan_flag(const struct net_device *dev,
590 u32 flag, short flag_val)
631{ 591{
632 struct net_device *dev = dev_get_by_name(dev_name); 592 /* verify flag is supported */
633 int rv = 0; 593 if (flag == VLAN_FLAG_REORDER_HDR) {
634 if (dev) { 594 if (flag_val) {
635 if (dev->priv_flags & IFF_802_1Q_VLAN) { 595 VLAN_DEV_INFO(dev)->flags |= VLAN_FLAG_REORDER_HDR;
636 strncpy(result, VLAN_DEV_INFO(dev)->real_dev->name, 23);
637 rv = 0;
638 } else { 596 } else {
639 rv = -EINVAL; 597 VLAN_DEV_INFO(dev)->flags &= ~VLAN_FLAG_REORDER_HDR;
640 } 598 }
641 dev_put(dev); 599 return 0;
642 } else {
643 rv = -ENODEV;
644 } 600 }
645 return rv; 601 printk(KERN_ERR "%s: flag %i is not valid.\n", __FUNCTION__, flag);
602 return -EINVAL;
646} 603}
647 604
648int vlan_dev_get_vid(const char *dev_name, unsigned short* result) 605void vlan_dev_get_realdev_name(const struct net_device *dev, char *result)
649{ 606{
650 struct net_device *dev = dev_get_by_name(dev_name); 607 strncpy(result, VLAN_DEV_INFO(dev)->real_dev->name, 23);
651 int rv = 0;
652 if (dev) {
653 if (dev->priv_flags & IFF_802_1Q_VLAN) {
654 *result = VLAN_DEV_INFO(dev)->vlan_id;
655 rv = 0;
656 } else {
657 rv = -EINVAL;
658 }
659 dev_put(dev);
660 } else {
661 rv = -ENODEV;
662 }
663 return rv;
664} 608}
665 609
666 610void vlan_dev_get_vid(const struct net_device *dev, unsigned short *result)
667int vlan_dev_set_mac_address(struct net_device *dev, void *addr_struct_p)
668{ 611{
669 struct sockaddr *addr = (struct sockaddr *)(addr_struct_p); 612 *result = VLAN_DEV_INFO(dev)->vlan_id;
670 int i;
671
672 if (netif_running(dev))
673 return -EBUSY;
674
675 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
676
677 printk("%s: Setting MAC address to ", dev->name);
678 for (i = 0; i < 6; i++)
679 printk(" %2.2x", dev->dev_addr[i]);
680 printk(".\n");
681
682 if (memcmp(VLAN_DEV_INFO(dev)->real_dev->dev_addr,
683 dev->dev_addr,
684 dev->addr_len) != 0) {
685 if (!(VLAN_DEV_INFO(dev)->real_dev->flags & IFF_PROMISC)) {
686 int flgs = VLAN_DEV_INFO(dev)->real_dev->flags;
687
688 /* Increment our in-use promiscuity counter */
689 dev_set_promiscuity(VLAN_DEV_INFO(dev)->real_dev, 1);
690
691 /* Make PROMISC visible to the user. */
692 flgs |= IFF_PROMISC;
693 printk("VLAN (%s): Setting underlying device (%s) to promiscious mode.\n",
694 dev->name, VLAN_DEV_INFO(dev)->real_dev->name);
695 dev_change_flags(VLAN_DEV_INFO(dev)->real_dev, flgs);
696 }
697 } else {
698 printk("VLAN (%s): Underlying device (%s) has same MAC, not checking promiscious mode.\n",
699 dev->name, VLAN_DEV_INFO(dev)->real_dev->name);
700 }
701
702 return 0;
703} 613}
704 614
705static inline int vlan_dmi_equals(struct dev_mc_list *dmi1, 615static inline int vlan_dmi_equals(struct dev_mc_list *dmi1,
@@ -788,15 +698,32 @@ static void vlan_flush_mc_list(struct net_device *dev)
788 698
789int vlan_dev_open(struct net_device *dev) 699int vlan_dev_open(struct net_device *dev)
790{ 700{
791 if (!(VLAN_DEV_INFO(dev)->real_dev->flags & IFF_UP)) 701 struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
702 struct net_device *real_dev = vlan->real_dev;
703 int err;
704
705 if (!(real_dev->flags & IFF_UP))
792 return -ENETDOWN; 706 return -ENETDOWN;
793 707
708 if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) {
709 err = dev_unicast_add(real_dev, dev->dev_addr, ETH_ALEN);
710 if (err < 0)
711 return err;
712 }
713 memcpy(vlan->real_dev_addr, real_dev->dev_addr, ETH_ALEN);
714
794 return 0; 715 return 0;
795} 716}
796 717
797int vlan_dev_stop(struct net_device *dev) 718int vlan_dev_stop(struct net_device *dev)
798{ 719{
720 struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev;
721
799 vlan_flush_mc_list(dev); 722 vlan_flush_mc_list(dev);
723
724 if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr))
725 dev_unicast_delete(real_dev, dev->dev_addr, dev->addr_len);
726
800 return 0; 727 return 0;
801} 728}
802 729
diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c
new file mode 100644
index 000000000000..6cdd1e015e2d
--- /dev/null
+++ b/net/8021q/vlan_netlink.c
@@ -0,0 +1,243 @@
1/*
2 * VLAN netlink control interface
3 *
4 * Copyright (c) 2007 Patrick McHardy <kaber@trash.net>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 */
10
11#include <linux/kernel.h>
12#include <linux/netdevice.h>
13#include <linux/if_vlan.h>
14#include <net/netlink.h>
15#include <net/rtnetlink.h>
16#include "vlan.h"
17
18
19static const struct nla_policy vlan_policy[IFLA_VLAN_MAX + 1] = {
20 [IFLA_VLAN_ID] = { .type = NLA_U16 },
21 [IFLA_VLAN_FLAGS] = { .len = sizeof(struct ifla_vlan_flags) },
22 [IFLA_VLAN_EGRESS_QOS] = { .type = NLA_NESTED },
23 [IFLA_VLAN_INGRESS_QOS] = { .type = NLA_NESTED },
24};
25
26static const struct nla_policy vlan_map_policy[IFLA_VLAN_QOS_MAX + 1] = {
27 [IFLA_VLAN_QOS_MAPPING] = { .len = sizeof(struct ifla_vlan_qos_mapping) },
28};
29
30
31static inline int vlan_validate_qos_map(struct nlattr *attr)
32{
33 if (!attr)
34 return 0;
35 return nla_validate_nested(attr, IFLA_VLAN_QOS_MAX, vlan_map_policy);
36}
37
38static int vlan_validate(struct nlattr *tb[], struct nlattr *data[])
39{
40 struct ifla_vlan_flags *flags;
41 u16 id;
42 int err;
43
44 if (tb[IFLA_ADDRESS]) {
45 if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
46 return -EINVAL;
47 if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
48 return -EADDRNOTAVAIL;
49 }
50
51 if (!data)
52 return -EINVAL;
53
54 if (data[IFLA_VLAN_ID]) {
55 id = nla_get_u16(data[IFLA_VLAN_ID]);
56 if (id >= VLAN_VID_MASK)
57 return -ERANGE;
58 }
59 if (data[IFLA_VLAN_FLAGS]) {
60 flags = nla_data(data[IFLA_VLAN_FLAGS]);
61 if ((flags->flags & flags->mask) & ~VLAN_FLAG_REORDER_HDR)
62 return -EINVAL;
63 }
64
65 err = vlan_validate_qos_map(data[IFLA_VLAN_INGRESS_QOS]);
66 if (err < 0)
67 return err;
68 err = vlan_validate_qos_map(data[IFLA_VLAN_EGRESS_QOS]);
69 if (err < 0)
70 return err;
71 return 0;
72}
73
74static int vlan_changelink(struct net_device *dev,
75 struct nlattr *tb[], struct nlattr *data[])
76{
77 struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
78 struct ifla_vlan_flags *flags;
79 struct ifla_vlan_qos_mapping *m;
80 struct nlattr *attr;
81 int rem;
82
83 if (data[IFLA_VLAN_FLAGS]) {
84 flags = nla_data(data[IFLA_VLAN_FLAGS]);
85 vlan->flags = (vlan->flags & ~flags->mask) |
86 (flags->flags & flags->mask);
87 }
88 if (data[IFLA_VLAN_INGRESS_QOS]) {
89 nla_for_each_nested(attr, data[IFLA_VLAN_INGRESS_QOS], rem) {
90 m = nla_data(attr);
91 vlan_dev_set_ingress_priority(dev, m->to, m->from);
92 }
93 }
94 if (data[IFLA_VLAN_EGRESS_QOS]) {
95 nla_for_each_nested(attr, data[IFLA_VLAN_EGRESS_QOS], rem) {
96 m = nla_data(attr);
97 vlan_dev_set_egress_priority(dev, m->from, m->to);
98 }
99 }
100 return 0;
101}
102
103static int vlan_newlink(struct net_device *dev,
104 struct nlattr *tb[], struct nlattr *data[])
105{
106 struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
107 struct net_device *real_dev;
108 int err;
109
110 if (!data[IFLA_VLAN_ID])
111 return -EINVAL;
112
113 if (!tb[IFLA_LINK])
114 return -EINVAL;
115 real_dev = __dev_get_by_index(nla_get_u32(tb[IFLA_LINK]));
116 if (!real_dev)
117 return -ENODEV;
118
119 vlan->vlan_id = nla_get_u16(data[IFLA_VLAN_ID]);
120 vlan->real_dev = real_dev;
121 vlan->flags = VLAN_FLAG_REORDER_HDR;
122
123 err = vlan_check_real_dev(real_dev, vlan->vlan_id);
124 if (err < 0)
125 return err;
126
127 if (!tb[IFLA_MTU])
128 dev->mtu = real_dev->mtu;
129 else if (dev->mtu > real_dev->mtu)
130 return -EINVAL;
131
132 err = vlan_changelink(dev, tb, data);
133 if (err < 0)
134 return err;
135
136 return register_vlan_dev(dev);
137}
138
139static void vlan_dellink(struct net_device *dev)
140{
141 unregister_vlan_device(dev);
142}
143
144static inline size_t vlan_qos_map_size(unsigned int n)
145{
146 if (n == 0)
147 return 0;
148 /* IFLA_VLAN_{EGRESS,INGRESS}_QOS + n * IFLA_VLAN_QOS_MAPPING */
149 return nla_total_size(sizeof(struct nlattr)) +
150 nla_total_size(sizeof(struct ifla_vlan_qos_mapping)) * n;
151}
152
153static size_t vlan_get_size(const struct net_device *dev)
154{
155 struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
156
157 return nla_total_size(2) + /* IFLA_VLAN_ID */
158 vlan_qos_map_size(vlan->nr_ingress_mappings) +
159 vlan_qos_map_size(vlan->nr_egress_mappings);
160}
161
162static int vlan_fill_info(struct sk_buff *skb, const struct net_device *dev)
163{
164 struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
165 struct vlan_priority_tci_mapping *pm;
166 struct ifla_vlan_flags f;
167 struct ifla_vlan_qos_mapping m;
168 struct nlattr *nest;
169 unsigned int i;
170
171 NLA_PUT_U16(skb, IFLA_VLAN_ID, VLAN_DEV_INFO(dev)->vlan_id);
172 if (vlan->flags) {
173 f.flags = vlan->flags;
174 f.mask = ~0;
175 NLA_PUT(skb, IFLA_VLAN_FLAGS, sizeof(f), &f);
176 }
177 if (vlan->nr_ingress_mappings) {
178 nest = nla_nest_start(skb, IFLA_VLAN_INGRESS_QOS);
179 if (nest == NULL)
180 goto nla_put_failure;
181
182 for (i = 0; i < ARRAY_SIZE(vlan->ingress_priority_map); i++) {
183 if (!vlan->ingress_priority_map[i])
184 continue;
185
186 m.from = i;
187 m.to = vlan->ingress_priority_map[i];
188 NLA_PUT(skb, IFLA_VLAN_QOS_MAPPING,
189 sizeof(m), &m);
190 }
191 nla_nest_end(skb, nest);
192 }
193
194 if (vlan->nr_egress_mappings) {
195 nest = nla_nest_start(skb, IFLA_VLAN_EGRESS_QOS);
196 if (nest == NULL)
197 goto nla_put_failure;
198
199 for (i = 0; i < ARRAY_SIZE(vlan->egress_priority_map); i++) {
200 for (pm = vlan->egress_priority_map[i]; pm;
201 pm = pm->next) {
202 if (!pm->vlan_qos)
203 continue;
204
205 m.from = pm->priority;
206 m.to = (pm->vlan_qos >> 13) & 0x7;
207 NLA_PUT(skb, IFLA_VLAN_QOS_MAPPING,
208 sizeof(m), &m);
209 }
210 }
211 nla_nest_end(skb, nest);
212 }
213 return 0;
214
215nla_put_failure:
216 return -EMSGSIZE;
217}
218
219struct rtnl_link_ops vlan_link_ops __read_mostly = {
220 .kind = "vlan",
221 .maxtype = IFLA_VLAN_MAX,
222 .policy = vlan_policy,
223 .priv_size = sizeof(struct vlan_dev_info),
224 .setup = vlan_setup,
225 .validate = vlan_validate,
226 .newlink = vlan_newlink,
227 .changelink = vlan_changelink,
228 .dellink = vlan_dellink,
229 .get_size = vlan_get_size,
230 .fill_info = vlan_fill_info,
231};
232
233int __init vlan_netlink_init(void)
234{
235 return rtnl_link_register(&vlan_link_ops);
236}
237
238void __exit vlan_netlink_fini(void)
239{
240 rtnl_link_unregister(&vlan_link_ops);
241}
242
243MODULE_ALIAS_RTNL_LINK("vlan");
diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c
index d216a64421cd..c0040c9064a1 100644
--- a/net/8021q/vlanproc.c
+++ b/net/8021q/vlanproc.c
@@ -69,7 +69,7 @@ static const char name_conf[] = "config";
69 * Generic /proc/net/vlan/<file> file and inode operations 69 * Generic /proc/net/vlan/<file> file and inode operations
70 */ 70 */
71 71
72static struct seq_operations vlan_seq_ops = { 72static const struct seq_operations vlan_seq_ops = {
73 .start = vlan_seq_start, 73 .start = vlan_seq_start,
74 .next = vlan_seq_next, 74 .next = vlan_seq_next,
75 .stop = vlan_seq_stop, 75 .stop = vlan_seq_stop,
@@ -342,7 +342,7 @@ static int vlandev_seq_show(struct seq_file *seq, void *offset)
342 seq_printf(seq, "Device: %s", dev_info->real_dev->name); 342 seq_printf(seq, "Device: %s", dev_info->real_dev->name);
343 /* now show all PRIORITY mappings relating to this VLAN */ 343 /* now show all PRIORITY mappings relating to this VLAN */
344 seq_printf(seq, 344 seq_printf(seq,
345 "\nINGRESS priority mappings: 0:%lu 1:%lu 2:%lu 3:%lu 4:%lu 5:%lu 6:%lu 7:%lu\n", 345 "\nINGRESS priority mappings: 0:%u 1:%u 2:%u 3:%u 4:%u 5:%u 6:%u 7:%u\n",
346 dev_info->ingress_priority_map[0], 346 dev_info->ingress_priority_map[0],
347 dev_info->ingress_priority_map[1], 347 dev_info->ingress_priority_map[1],
348 dev_info->ingress_priority_map[2], 348 dev_info->ingress_priority_map[2],
@@ -357,7 +357,7 @@ static int vlandev_seq_show(struct seq_file *seq, void *offset)
357 const struct vlan_priority_tci_mapping *mp 357 const struct vlan_priority_tci_mapping *mp
358 = dev_info->egress_priority_map[i]; 358 = dev_info->egress_priority_map[i];
359 while (mp) { 359 while (mp) {
360 seq_printf(seq, "%lu:%hu ", 360 seq_printf(seq, "%u:%hu ",
361 mp->priority, ((mp->vlan_qos >> 13) & 0x7)); 361 mp->priority, ((mp->vlan_qos >> 13) & 0x7));
362 mp = mp->next; 362 mp = mp->next;
363 } 363 }
diff --git a/net/Makefile b/net/Makefile
index 34e5b2d7f877..a87a88963432 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -37,7 +37,6 @@ obj-$(CONFIG_AX25) += ax25/
37obj-$(CONFIG_IRDA) += irda/ 37obj-$(CONFIG_IRDA) += irda/
38obj-$(CONFIG_BT) += bluetooth/ 38obj-$(CONFIG_BT) += bluetooth/
39obj-$(CONFIG_SUNRPC) += sunrpc/ 39obj-$(CONFIG_SUNRPC) += sunrpc/
40obj-$(CONFIG_RXRPC) += rxrpc/
41obj-$(CONFIG_AF_RXRPC) += rxrpc/ 40obj-$(CONFIG_AF_RXRPC) += rxrpc/
42obj-$(CONFIG_ATM) += atm/ 41obj-$(CONFIG_ATM) += atm/
43obj-$(CONFIG_DECNET) += decnet/ 42obj-$(CONFIG_DECNET) += decnet/
diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c
index 5ef6a238bdbc..3d1655f98388 100644
--- a/net/appletalk/aarp.c
+++ b/net/appletalk/aarp.c
@@ -1024,7 +1024,7 @@ static int aarp_seq_show(struct seq_file *seq, void *v)
1024 return 0; 1024 return 0;
1025} 1025}
1026 1026
1027static struct seq_operations aarp_seq_ops = { 1027static const struct seq_operations aarp_seq_ops = {
1028 .start = aarp_seq_start, 1028 .start = aarp_seq_start,
1029 .next = aarp_seq_next, 1029 .next = aarp_seq_next,
1030 .stop = aarp_seq_stop, 1030 .stop = aarp_seq_stop,
diff --git a/net/appletalk/atalk_proc.c b/net/appletalk/atalk_proc.c
index 57ff8122b5c5..87a582cc8111 100644
--- a/net/appletalk/atalk_proc.c
+++ b/net/appletalk/atalk_proc.c
@@ -204,21 +204,21 @@ out:
204 return 0; 204 return 0;
205} 205}
206 206
207static struct seq_operations atalk_seq_interface_ops = { 207static const struct seq_operations atalk_seq_interface_ops = {
208 .start = atalk_seq_interface_start, 208 .start = atalk_seq_interface_start,
209 .next = atalk_seq_interface_next, 209 .next = atalk_seq_interface_next,
210 .stop = atalk_seq_interface_stop, 210 .stop = atalk_seq_interface_stop,
211 .show = atalk_seq_interface_show, 211 .show = atalk_seq_interface_show,
212}; 212};
213 213
214static struct seq_operations atalk_seq_route_ops = { 214static const struct seq_operations atalk_seq_route_ops = {
215 .start = atalk_seq_route_start, 215 .start = atalk_seq_route_start,
216 .next = atalk_seq_route_next, 216 .next = atalk_seq_route_next,
217 .stop = atalk_seq_route_stop, 217 .stop = atalk_seq_route_stop,
218 .show = atalk_seq_route_show, 218 .show = atalk_seq_route_show,
219}; 219};
220 220
221static struct seq_operations atalk_seq_socket_ops = { 221static const struct seq_operations atalk_seq_socket_ops = {
222 .start = atalk_seq_socket_start, 222 .start = atalk_seq_socket_start,
223 .next = atalk_seq_socket_next, 223 .next = atalk_seq_socket_next,
224 .stop = atalk_seq_socket_stop, 224 .stop = atalk_seq_socket_stop,
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index 0e9f00c5c899..faa6aaf67563 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -699,28 +699,13 @@ static struct atm_ioctl br2684_ioctl_ops = {
699#ifdef CONFIG_PROC_FS 699#ifdef CONFIG_PROC_FS
700static void *br2684_seq_start(struct seq_file *seq, loff_t *pos) 700static void *br2684_seq_start(struct seq_file *seq, loff_t *pos)
701{ 701{
702 loff_t offs = 0;
703 struct br2684_dev *brd;
704
705 read_lock(&devs_lock); 702 read_lock(&devs_lock);
706 703 return seq_list_start(&br2684_devs, *pos);
707 list_for_each_entry(brd, &br2684_devs, br2684_devs) {
708 if (offs == *pos)
709 return brd;
710 ++offs;
711 }
712 return NULL;
713} 704}
714 705
715static void *br2684_seq_next(struct seq_file *seq, void *v, loff_t *pos) 706static void *br2684_seq_next(struct seq_file *seq, void *v, loff_t *pos)
716{ 707{
717 struct br2684_dev *brd = v; 708 return seq_list_next(v, &br2684_devs, pos);
718
719 ++*pos;
720
721 brd = list_entry(brd->br2684_devs.next,
722 struct br2684_dev, br2684_devs);
723 return (&brd->br2684_devs != &br2684_devs) ? brd : NULL;
724} 709}
725 710
726static void br2684_seq_stop(struct seq_file *seq, void *v) 711static void br2684_seq_stop(struct seq_file *seq, void *v)
@@ -730,7 +715,8 @@ static void br2684_seq_stop(struct seq_file *seq, void *v)
730 715
731static int br2684_seq_show(struct seq_file *seq, void *v) 716static int br2684_seq_show(struct seq_file *seq, void *v)
732{ 717{
733 const struct br2684_dev *brdev = v; 718 const struct br2684_dev *brdev = list_entry(v, struct br2684_dev,
719 br2684_devs);
734 const struct net_device *net_dev = brdev->net_dev; 720 const struct net_device *net_dev = brdev->net_dev;
735 const struct br2684_vcc *brvcc; 721 const struct br2684_vcc *brvcc;
736 722
@@ -772,7 +758,7 @@ static int br2684_seq_show(struct seq_file *seq, void *v)
772 return 0; 758 return 0;
773} 759}
774 760
775static struct seq_operations br2684_seq_ops = { 761static const struct seq_operations br2684_seq_ops = {
776 .start = br2684_seq_start, 762 .start = br2684_seq_start,
777 .next = br2684_seq_next, 763 .next = br2684_seq_next,
778 .stop = br2684_seq_stop, 764 .stop = br2684_seq_stop,
diff --git a/net/atm/clip.c b/net/atm/clip.c
index 876b77f14745..ecf0f79b94ae 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -928,7 +928,7 @@ static int clip_seq_show(struct seq_file *seq, void *v)
928 return 0; 928 return 0;
929} 929}
930 930
931static struct seq_operations arp_seq_ops = { 931static const struct seq_operations arp_seq_ops = {
932 .start = clip_seq_start, 932 .start = clip_seq_start,
933 .next = neigh_seq_next, 933 .next = neigh_seq_next,
934 .stop = neigh_seq_stop, 934 .stop = neigh_seq_stop,
diff --git a/net/atm/lec.c b/net/atm/lec.c
index 4dc5f2b8c43c..2770fb451ae8 100644
--- a/net/atm/lec.c
+++ b/net/atm/lec.c
@@ -1174,7 +1174,7 @@ static int lec_seq_show(struct seq_file *seq, void *v)
1174 return 0; 1174 return 0;
1175} 1175}
1176 1176
1177static struct seq_operations lec_seq_ops = { 1177static const struct seq_operations lec_seq_ops = {
1178 .start = lec_seq_start, 1178 .start = lec_seq_start,
1179 .next = lec_seq_next, 1179 .next = lec_seq_next,
1180 .stop = lec_seq_stop, 1180 .stop = lec_seq_stop,
diff --git a/net/atm/mpoa_proc.c b/net/atm/mpoa_proc.c
index 4b05cbec7a58..91f3ffc90dbd 100644
--- a/net/atm/mpoa_proc.c
+++ b/net/atm/mpoa_proc.c
@@ -177,7 +177,7 @@ static int mpc_show(struct seq_file *m, void *v)
177 return 0; 177 return 0;
178} 178}
179 179
180static struct seq_operations mpc_op = { 180static const struct seq_operations mpc_op = {
181 .start = mpc_start, 181 .start = mpc_start,
182 .next = mpc_next, 182 .next = mpc_next,
183 .stop = mpc_stop, 183 .stop = mpc_stop,
diff --git a/net/atm/proc.c b/net/atm/proc.c
index 9e61e512f667..99fc1fe950ee 100644
--- a/net/atm/proc.c
+++ b/net/atm/proc.c
@@ -110,7 +110,7 @@ static inline void *vcc_walk(struct vcc_state *state, loff_t l)
110} 110}
111 111
112static int __vcc_seq_open(struct inode *inode, struct file *file, 112static int __vcc_seq_open(struct inode *inode, struct file *file,
113 int family, struct seq_operations *ops) 113 int family, const struct seq_operations *ops)
114{ 114{
115 struct vcc_state *state; 115 struct vcc_state *state;
116 struct seq_file *seq; 116 struct seq_file *seq;
@@ -260,7 +260,7 @@ static int atm_dev_seq_show(struct seq_file *seq, void *v)
260 return 0; 260 return 0;
261} 261}
262 262
263static struct seq_operations atm_dev_seq_ops = { 263static const struct seq_operations atm_dev_seq_ops = {
264 .start = atm_dev_seq_start, 264 .start = atm_dev_seq_start,
265 .next = atm_dev_seq_next, 265 .next = atm_dev_seq_next,
266 .stop = atm_dev_seq_stop, 266 .stop = atm_dev_seq_stop,
@@ -295,7 +295,7 @@ static int pvc_seq_show(struct seq_file *seq, void *v)
295 return 0; 295 return 0;
296} 296}
297 297
298static struct seq_operations pvc_seq_ops = { 298static const struct seq_operations pvc_seq_ops = {
299 .start = vcc_seq_start, 299 .start = vcc_seq_start,
300 .next = vcc_seq_next, 300 .next = vcc_seq_next,
301 .stop = vcc_seq_stop, 301 .stop = vcc_seq_stop,
@@ -329,7 +329,7 @@ static int vcc_seq_show(struct seq_file *seq, void *v)
329 return 0; 329 return 0;
330} 330}
331 331
332static struct seq_operations vcc_seq_ops = { 332static const struct seq_operations vcc_seq_ops = {
333 .start = vcc_seq_start, 333 .start = vcc_seq_start,
334 .next = vcc_seq_next, 334 .next = vcc_seq_next,
335 .stop = vcc_seq_stop, 335 .stop = vcc_seq_stop,
@@ -364,7 +364,7 @@ static int svc_seq_show(struct seq_file *seq, void *v)
364 return 0; 364 return 0;
365} 365}
366 366
367static struct seq_operations svc_seq_ops = { 367static const struct seq_operations svc_seq_ops = {
368 .start = vcc_seq_start, 368 .start = vcc_seq_start,
369 .next = vcc_seq_next, 369 .next = vcc_seq_next,
370 .stop = vcc_seq_stop, 370 .stop = vcc_seq_stop,
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 429e13a6c6ad..c83cf8432970 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1924,7 +1924,7 @@ static int ax25_info_show(struct seq_file *seq, void *v)
1924 return 0; 1924 return 0;
1925} 1925}
1926 1926
1927static struct seq_operations ax25_info_seqops = { 1927static const struct seq_operations ax25_info_seqops = {
1928 .start = ax25_info_start, 1928 .start = ax25_info_start,
1929 .next = ax25_info_next, 1929 .next = ax25_info_next,
1930 .stop = ax25_info_stop, 1930 .stop = ax25_info_stop,
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
index d65b8e22868d..9ecf6f1df863 100644
--- a/net/ax25/ax25_route.c
+++ b/net/ax25/ax25_route.c
@@ -320,7 +320,7 @@ static int ax25_rt_seq_show(struct seq_file *seq, void *v)
320 return 0; 320 return 0;
321} 321}
322 322
323static struct seq_operations ax25_rt_seqops = { 323static const struct seq_operations ax25_rt_seqops = {
324 .start = ax25_rt_seq_start, 324 .start = ax25_rt_seq_start,
325 .next = ax25_rt_seq_next, 325 .next = ax25_rt_seq_next,
326 .stop = ax25_rt_seq_stop, 326 .stop = ax25_rt_seq_stop,
diff --git a/net/ax25/ax25_uid.c b/net/ax25/ax25_uid.c
index 75c76647b2cb..ce0b13d44385 100644
--- a/net/ax25/ax25_uid.c
+++ b/net/ax25/ax25_uid.c
@@ -185,7 +185,7 @@ static int ax25_uid_seq_show(struct seq_file *seq, void *v)
185 return 0; 185 return 0;
186} 186}
187 187
188static struct seq_operations ax25_uid_seqops = { 188static const struct seq_operations ax25_uid_seqops = {
189 .start = ax25_uid_seq_start, 189 .start = ax25_uid_seq_start,
190 .next = ax25_uid_seq_next, 190 .next = ax25_uid_seq_next,
191 .stop = ax25_uid_seq_stop, 191 .stop = ax25_uid_seq_stop,
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 63980bd6b5f2..5fdfc9a67d39 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -123,8 +123,8 @@ void hci_add_sco(struct hci_conn *conn, __u16 handle)
123 conn->state = BT_CONNECT; 123 conn->state = BT_CONNECT;
124 conn->out = 1; 124 conn->out = 1;
125 125
126 cp.pkt_type = cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
127 cp.handle = cpu_to_le16(handle); 126 cp.handle = cpu_to_le16(handle);
127 cp.pkt_type = cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
128 128
129 hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ADD_SCO, sizeof(cp), &cp); 129 hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ADD_SCO, sizeof(cp), &cp);
130} 130}
@@ -220,19 +220,19 @@ int hci_conn_del(struct hci_conn *conn)
220 220
221 del_timer(&conn->disc_timer); 221 del_timer(&conn->disc_timer);
222 222
223 if (conn->type == SCO_LINK) { 223 if (conn->type == ACL_LINK) {
224 struct hci_conn *acl = conn->link;
225 if (acl) {
226 acl->link = NULL;
227 hci_conn_put(acl);
228 }
229 } else {
230 struct hci_conn *sco = conn->link; 224 struct hci_conn *sco = conn->link;
231 if (sco) 225 if (sco)
232 sco->link = NULL; 226 sco->link = NULL;
233 227
234 /* Unacked frames */ 228 /* Unacked frames */
235 hdev->acl_cnt += conn->sent; 229 hdev->acl_cnt += conn->sent;
230 } else {
231 struct hci_conn *acl = conn->link;
232 if (acl) {
233 acl->link = NULL;
234 hci_conn_put(acl);
235 }
236 } 236 }
237 237
238 tasklet_disable(&hdev->tx_task); 238 tasklet_disable(&hdev->tx_task);
@@ -297,9 +297,10 @@ EXPORT_SYMBOL(hci_get_route);
297 297
298/* Create SCO or ACL connection. 298/* Create SCO or ACL connection.
299 * Device _must_ be locked */ 299 * Device _must_ be locked */
300struct hci_conn * hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst) 300struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
301{ 301{
302 struct hci_conn *acl; 302 struct hci_conn *acl;
303 struct hci_conn *sco;
303 304
304 BT_DBG("%s dst %s", hdev->name, batostr(dst)); 305 BT_DBG("%s dst %s", hdev->name, batostr(dst));
305 306
@@ -313,28 +314,26 @@ struct hci_conn * hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
313 if (acl->state == BT_OPEN || acl->state == BT_CLOSED) 314 if (acl->state == BT_OPEN || acl->state == BT_CLOSED)
314 hci_acl_connect(acl); 315 hci_acl_connect(acl);
315 316
316 if (type == SCO_LINK) { 317 if (type == ACL_LINK)
317 struct hci_conn *sco; 318 return acl;
318 319
319 if (!(sco = hci_conn_hash_lookup_ba(hdev, SCO_LINK, dst))) { 320 if (!(sco = hci_conn_hash_lookup_ba(hdev, type, dst))) {
320 if (!(sco = hci_conn_add(hdev, SCO_LINK, dst))) { 321 if (!(sco = hci_conn_add(hdev, type, dst))) {
321 hci_conn_put(acl); 322 hci_conn_put(acl);
322 return NULL; 323 return NULL;
323 }
324 } 324 }
325 acl->link = sco; 325 }
326 sco->link = acl;
327 326
328 hci_conn_hold(sco); 327 acl->link = sco;
328 sco->link = acl;
329 329
330 if (acl->state == BT_CONNECTED && 330 hci_conn_hold(sco);
331 (sco->state == BT_OPEN || sco->state == BT_CLOSED))
332 hci_add_sco(sco, acl->handle);
333 331
334 return sco; 332 if (acl->state == BT_CONNECTED &&
335 } else { 333 (sco->state == BT_OPEN || sco->state == BT_CLOSED))
336 return acl; 334 hci_add_sco(sco, acl->handle);
337 } 335
336 return sco;
338} 337}
339EXPORT_SYMBOL(hci_connect); 338EXPORT_SYMBOL(hci_connect);
340 339
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index aa4b56a8c3ea..f6d867e0179f 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -826,7 +826,7 @@ EXPORT_SYMBOL(hci_free_dev);
826int hci_register_dev(struct hci_dev *hdev) 826int hci_register_dev(struct hci_dev *hdev)
827{ 827{
828 struct list_head *head = &hci_dev_list, *p; 828 struct list_head *head = &hci_dev_list, *p;
829 int id = 0; 829 int i, id = 0;
830 830
831 BT_DBG("%p name %s type %d owner %p", hdev, hdev->name, hdev->type, hdev->owner); 831 BT_DBG("%p name %s type %d owner %p", hdev, hdev->name, hdev->type, hdev->owner);
832 832
@@ -851,6 +851,7 @@ int hci_register_dev(struct hci_dev *hdev)
851 851
852 hdev->flags = 0; 852 hdev->flags = 0;
853 hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); 853 hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1);
854 hdev->esco_type = (ESCO_HV1);
854 hdev->link_mode = (HCI_LM_ACCEPT); 855 hdev->link_mode = (HCI_LM_ACCEPT);
855 856
856 hdev->idle_timeout = 0; 857 hdev->idle_timeout = 0;
@@ -865,6 +866,9 @@ int hci_register_dev(struct hci_dev *hdev)
865 skb_queue_head_init(&hdev->cmd_q); 866 skb_queue_head_init(&hdev->cmd_q);
866 skb_queue_head_init(&hdev->raw_q); 867 skb_queue_head_init(&hdev->raw_q);
867 868
869 for (i = 0; i < 3; i++)
870 hdev->reassembly[i] = NULL;
871
868 init_waitqueue_head(&hdev->req_wait_q); 872 init_waitqueue_head(&hdev->req_wait_q);
869 init_MUTEX(&hdev->req_lock); 873 init_MUTEX(&hdev->req_lock);
870 874
@@ -889,6 +893,8 @@ EXPORT_SYMBOL(hci_register_dev);
889/* Unregister HCI device */ 893/* Unregister HCI device */
890int hci_unregister_dev(struct hci_dev *hdev) 894int hci_unregister_dev(struct hci_dev *hdev)
891{ 895{
896 int i;
897
892 BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); 898 BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
893 899
894 hci_unregister_sysfs(hdev); 900 hci_unregister_sysfs(hdev);
@@ -899,9 +905,13 @@ int hci_unregister_dev(struct hci_dev *hdev)
899 905
900 hci_dev_do_close(hdev); 906 hci_dev_do_close(hdev);
901 907
908 for (i = 0; i < 3; i++)
909 kfree_skb(hdev->reassembly[i]);
910
902 hci_notify(hdev, HCI_DEV_UNREG); 911 hci_notify(hdev, HCI_DEV_UNREG);
903 912
904 __hci_dev_put(hdev); 913 __hci_dev_put(hdev);
914
905 return 0; 915 return 0;
906} 916}
907EXPORT_SYMBOL(hci_unregister_dev); 917EXPORT_SYMBOL(hci_unregister_dev);
@@ -922,6 +932,90 @@ int hci_resume_dev(struct hci_dev *hdev)
922} 932}
923EXPORT_SYMBOL(hci_resume_dev); 933EXPORT_SYMBOL(hci_resume_dev);
924 934
935/* Receive packet type fragment */
936#define __reassembly(hdev, type) ((hdev)->reassembly[(type) - 2])
937
938int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
939{
940 if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
941 return -EILSEQ;
942
943 while (count) {
944 struct sk_buff *skb = __reassembly(hdev, type);
945 struct { int expect; } *scb;
946 int len = 0;
947
948 if (!skb) {
949 /* Start of the frame */
950
951 switch (type) {
952 case HCI_EVENT_PKT:
953 if (count >= HCI_EVENT_HDR_SIZE) {
954 struct hci_event_hdr *h = data;
955 len = HCI_EVENT_HDR_SIZE + h->plen;
956 } else
957 return -EILSEQ;
958 break;
959
960 case HCI_ACLDATA_PKT:
961 if (count >= HCI_ACL_HDR_SIZE) {
962 struct hci_acl_hdr *h = data;
963 len = HCI_ACL_HDR_SIZE + __le16_to_cpu(h->dlen);
964 } else
965 return -EILSEQ;
966 break;
967
968 case HCI_SCODATA_PKT:
969 if (count >= HCI_SCO_HDR_SIZE) {
970 struct hci_sco_hdr *h = data;
971 len = HCI_SCO_HDR_SIZE + h->dlen;
972 } else
973 return -EILSEQ;
974 break;
975 }
976
977 skb = bt_skb_alloc(len, GFP_ATOMIC);
978 if (!skb) {
979 BT_ERR("%s no memory for packet", hdev->name);
980 return -ENOMEM;
981 }
982
983 skb->dev = (void *) hdev;
984 bt_cb(skb)->pkt_type = type;
985
986 __reassembly(hdev, type) = skb;
987
988 scb = (void *) skb->cb;
989 scb->expect = len;
990 } else {
991 /* Continuation */
992
993 scb = (void *) skb->cb;
994 len = scb->expect;
995 }
996
997 len = min(len, count);
998
999 memcpy(skb_put(skb, len), data, len);
1000
1001 scb->expect -= len;
1002
1003 if (scb->expect == 0) {
1004 /* Complete frame */
1005
1006 __reassembly(hdev, type) = NULL;
1007
1008 bt_cb(skb)->pkt_type = type;
1009 hci_recv_frame(skb);
1010 }
1011
1012 count -= len; data += len;
1013 }
1014
1015 return 0;
1016}
1017EXPORT_SYMBOL(hci_recv_fragment);
1018
925/* ---- Interface to upper protocols ---- */ 1019/* ---- Interface to upper protocols ---- */
926 1020
927/* Register/Unregister protocols. 1021/* Register/Unregister protocols.
@@ -1029,7 +1123,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *p
1029 1123
1030 skb = bt_skb_alloc(len, GFP_ATOMIC); 1124 skb = bt_skb_alloc(len, GFP_ATOMIC);
1031 if (!skb) { 1125 if (!skb) {
1032 BT_ERR("%s Can't allocate memory for HCI command", hdev->name); 1126 BT_ERR("%s no memory for command", hdev->name);
1033 return -ENOMEM; 1127 return -ENOMEM;
1034 } 1128 }
1035 1129
@@ -1161,7 +1255,7 @@ EXPORT_SYMBOL(hci_send_sco);
1161static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote) 1255static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
1162{ 1256{
1163 struct hci_conn_hash *h = &hdev->conn_hash; 1257 struct hci_conn_hash *h = &hdev->conn_hash;
1164 struct hci_conn *conn = NULL; 1258 struct hci_conn *conn = NULL;
1165 int num = 0, min = ~0; 1259 int num = 0, min = ~0;
1166 struct list_head *p; 1260 struct list_head *p;
1167 1261
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 447ba7131220..4baea1e38652 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -350,11 +350,24 @@ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *s
350 if (hdev->features[0] & LMP_5SLOT) 350 if (hdev->features[0] & LMP_5SLOT)
351 hdev->pkt_type |= (HCI_DM5 | HCI_DH5); 351 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
352 352
353 if (hdev->features[1] & LMP_HV2) 353 if (hdev->features[1] & LMP_HV2) {
354 hdev->pkt_type |= (HCI_HV2); 354 hdev->pkt_type |= (HCI_HV2);
355 hdev->esco_type |= (ESCO_HV2);
356 }
357
358 if (hdev->features[1] & LMP_HV3) {
359 hdev->pkt_type |= (HCI_HV3);
360 hdev->esco_type |= (ESCO_HV3);
361 }
355 362
356 if (hdev->features[1] & LMP_HV3) 363 if (hdev->features[3] & LMP_ESCO)
357 hdev->pkt_type |= (HCI_HV3); 364 hdev->esco_type |= (ESCO_EV3);
365
366 if (hdev->features[4] & LMP_EV4)
367 hdev->esco_type |= (ESCO_EV4);
368
369 if (hdev->features[4] & LMP_EV5)
370 hdev->esco_type |= (ESCO_EV5);
358 371
359 BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, 372 BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name,
360 lf->features[0], lf->features[1], lf->features[2]); 373 lf->features[0], lf->features[1], lf->features[2]);
@@ -881,12 +894,12 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s
881 if (conn) { 894 if (conn) {
882 conn->sent -= count; 895 conn->sent -= count;
883 896
884 if (conn->type == SCO_LINK) { 897 if (conn->type == ACL_LINK) {
885 if ((hdev->sco_cnt += count) > hdev->sco_pkts)
886 hdev->sco_cnt = hdev->sco_pkts;
887 } else {
888 if ((hdev->acl_cnt += count) > hdev->acl_pkts) 898 if ((hdev->acl_cnt += count) > hdev->acl_pkts)
889 hdev->acl_cnt = hdev->acl_pkts; 899 hdev->acl_cnt = hdev->acl_pkts;
900 } else {
901 if ((hdev->sco_cnt += count) > hdev->sco_pkts)
902 hdev->sco_cnt = hdev->sco_pkts;
890 } 903 }
891 } 904 }
892 } 905 }
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index b2b1cceb102a..23ba61a13bdd 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -95,6 +95,10 @@ static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
95 95
96 BT_DBG("dev %p dlc %p", dev, dlc); 96 BT_DBG("dev %p dlc %p", dev, dlc);
97 97
98 write_lock_bh(&rfcomm_dev_lock);
99 list_del_init(&dev->list);
100 write_unlock_bh(&rfcomm_dev_lock);
101
98 rfcomm_dlc_lock(dlc); 102 rfcomm_dlc_lock(dlc);
99 /* Detach DLC if it's owned by this dev */ 103 /* Detach DLC if it's owned by this dev */
100 if (dlc->owner == dev) 104 if (dlc->owner == dev)
@@ -156,8 +160,13 @@ static inline struct rfcomm_dev *rfcomm_dev_get(int id)
156 read_lock(&rfcomm_dev_lock); 160 read_lock(&rfcomm_dev_lock);
157 161
158 dev = __rfcomm_dev_get(id); 162 dev = __rfcomm_dev_get(id);
159 if (dev) 163
160 rfcomm_dev_hold(dev); 164 if (dev) {
165 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
166 dev = NULL;
167 else
168 rfcomm_dev_hold(dev);
169 }
161 170
162 read_unlock(&rfcomm_dev_lock); 171 read_unlock(&rfcomm_dev_lock);
163 172
@@ -265,6 +274,12 @@ out:
265 274
266 dev->tty_dev = tty_register_device(rfcomm_tty_driver, dev->id, NULL); 275 dev->tty_dev = tty_register_device(rfcomm_tty_driver, dev->id, NULL);
267 276
277 if (IS_ERR(dev->tty_dev)) {
278 list_del(&dev->list);
279 kfree(dev);
280 return PTR_ERR(dev->tty_dev);
281 }
282
268 return dev->id; 283 return dev->id;
269} 284}
270 285
@@ -272,10 +287,7 @@ static void rfcomm_dev_del(struct rfcomm_dev *dev)
272{ 287{
273 BT_DBG("dev %p", dev); 288 BT_DBG("dev %p", dev);
274 289
275 write_lock_bh(&rfcomm_dev_lock); 290 set_bit(RFCOMM_TTY_RELEASED, &dev->flags);
276 list_del_init(&dev->list);
277 write_unlock_bh(&rfcomm_dev_lock);
278
279 rfcomm_dev_put(dev); 291 rfcomm_dev_put(dev);
280} 292}
281 293
@@ -329,7 +341,7 @@ static int rfcomm_create_dev(struct sock *sk, void __user *arg)
329 if (copy_from_user(&req, arg, sizeof(req))) 341 if (copy_from_user(&req, arg, sizeof(req)))
330 return -EFAULT; 342 return -EFAULT;
331 343
332 BT_DBG("sk %p dev_id %id flags 0x%x", sk, req.dev_id, req.flags); 344 BT_DBG("sk %p dev_id %d flags 0x%x", sk, req.dev_id, req.flags);
333 345
334 if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) 346 if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN))
335 return -EPERM; 347 return -EPERM;
@@ -370,7 +382,7 @@ static int rfcomm_release_dev(void __user *arg)
370 if (copy_from_user(&req, arg, sizeof(req))) 382 if (copy_from_user(&req, arg, sizeof(req)))
371 return -EFAULT; 383 return -EFAULT;
372 384
373 BT_DBG("dev_id %id flags 0x%x", req.dev_id, req.flags); 385 BT_DBG("dev_id %d flags 0x%x", req.dev_id, req.flags);
374 386
375 if (!(dev = rfcomm_dev_get(req.dev_id))) 387 if (!(dev = rfcomm_dev_get(req.dev_id)))
376 return -ENODEV; 388 return -ENODEV;
@@ -383,6 +395,10 @@ static int rfcomm_release_dev(void __user *arg)
383 if (req.flags & (1 << RFCOMM_HANGUP_NOW)) 395 if (req.flags & (1 << RFCOMM_HANGUP_NOW))
384 rfcomm_dlc_close(dev->dlc, 0); 396 rfcomm_dlc_close(dev->dlc, 0);
385 397
398 /* Shut down TTY synchronously before freeing rfcomm_dev */
399 if (dev->tty)
400 tty_vhangup(dev->tty);
401
386 rfcomm_dev_del(dev); 402 rfcomm_dev_del(dev);
387 rfcomm_dev_put(dev); 403 rfcomm_dev_put(dev);
388 return 0; 404 return 0;
@@ -415,6 +431,8 @@ static int rfcomm_get_dev_list(void __user *arg)
415 431
416 list_for_each(p, &rfcomm_dev_list) { 432 list_for_each(p, &rfcomm_dev_list) {
417 struct rfcomm_dev *dev = list_entry(p, struct rfcomm_dev, list); 433 struct rfcomm_dev *dev = list_entry(p, struct rfcomm_dev, list);
434 if (test_bit(RFCOMM_TTY_RELEASED, &dev->flags))
435 continue;
418 (di + n)->id = dev->id; 436 (di + n)->id = dev->id;
419 (di + n)->flags = dev->flags; 437 (di + n)->flags = dev->flags;
420 (di + n)->state = dev->dlc->state; 438 (di + n)->state = dev->dlc->state;
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 849deaf14108..7b4ce9113be2 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -368,10 +368,18 @@ void br_features_recompute(struct net_bridge *br)
368 list_for_each_entry(p, &br->port_list, list) { 368 list_for_each_entry(p, &br->port_list, list) {
369 unsigned long feature = p->dev->features; 369 unsigned long feature = p->dev->features;
370 370
371 /* if device needs checksumming, downgrade to hw checksumming */
371 if (checksum & NETIF_F_NO_CSUM && !(feature & NETIF_F_NO_CSUM)) 372 if (checksum & NETIF_F_NO_CSUM && !(feature & NETIF_F_NO_CSUM))
372 checksum ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM; 373 checksum ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM;
374
375 /* if device can't do all checksum, downgrade to ipv4/ipv6 */
373 if (checksum & NETIF_F_HW_CSUM && !(feature & NETIF_F_HW_CSUM)) 376 if (checksum & NETIF_F_HW_CSUM && !(feature & NETIF_F_HW_CSUM))
374 checksum ^= NETIF_F_HW_CSUM | NETIF_F_IP_CSUM; 377 checksum ^= NETIF_F_HW_CSUM
378 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
379
380 if (checksum & NETIF_F_IPV6_CSUM && !(feature & NETIF_F_IPV6_CSUM))
381 checksum &= ~NETIF_F_IPV6_CSUM;
382
375 if (!(feature & NETIF_F_IP_CSUM)) 383 if (!(feature & NETIF_F_IP_CSUM))
376 checksum = 0; 384 checksum = 0;
377 385
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
index 33c6c4a7c689..4f42263e0a8a 100644
--- a/net/bridge/br_sysfs_br.c
+++ b/net/bridge/br_sysfs_br.c
@@ -360,8 +360,9 @@ static struct attribute_group bridge_group = {
360 * 360 *
361 * Returns the number of bytes read. 361 * Returns the number of bytes read.
362 */ 362 */
363static ssize_t brforward_read(struct kobject *kobj, char *buf, 363static ssize_t brforward_read(struct kobject *kobj,
364 loff_t off, size_t count) 364 struct bin_attribute *bin_attr,
365 char *buf, loff_t off, size_t count)
365{ 366{
366 struct device *dev = to_dev(kobj); 367 struct device *dev = to_dev(kobj);
367 struct net_bridge *br = to_bridge(dev); 368 struct net_bridge *br = to_bridge(dev);
@@ -383,8 +384,7 @@ static ssize_t brforward_read(struct kobject *kobj, char *buf,
383 384
384static struct bin_attribute bridge_forward = { 385static struct bin_attribute bridge_forward = {
385 .attr = { .name = SYSFS_BRIDGE_FDB, 386 .attr = { .name = SYSFS_BRIDGE_FDB,
386 .mode = S_IRUGO, 387 .mode = S_IRUGO, },
387 .owner = THIS_MODULE, },
388 .read = brforward_read, 388 .read = brforward_read,
389}; 389};
390 390
diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c
index 2da22927d8dd..79db51fcb476 100644
--- a/net/bridge/br_sysfs_if.c
+++ b/net/bridge/br_sysfs_if.c
@@ -29,8 +29,7 @@ struct brport_attribute {
29#define BRPORT_ATTR(_name,_mode,_show,_store) \ 29#define BRPORT_ATTR(_name,_mode,_show,_store) \
30struct brport_attribute brport_attr_##_name = { \ 30struct brport_attribute brport_attr_##_name = { \
31 .attr = {.name = __stringify(_name), \ 31 .attr = {.name = __stringify(_name), \
32 .mode = _mode, \ 32 .mode = _mode }, \
33 .owner = THIS_MODULE, }, \
34 .show = _show, \ 33 .show = _show, \
35 .store = _store, \ 34 .store = _store, \
36}; 35};
diff --git a/net/core/dev.c b/net/core/dev.c
index ee051bb398a0..96443055324e 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -151,9 +151,22 @@ static struct list_head ptype_base[16] __read_mostly; /* 16 way hashed list */
151static struct list_head ptype_all __read_mostly; /* Taps */ 151static struct list_head ptype_all __read_mostly; /* Taps */
152 152
153#ifdef CONFIG_NET_DMA 153#ifdef CONFIG_NET_DMA
154static struct dma_client *net_dma_client; 154struct net_dma {
155static unsigned int net_dma_count; 155 struct dma_client client;
156static spinlock_t net_dma_event_lock; 156 spinlock_t lock;
157 cpumask_t channel_mask;
158 struct dma_chan *channels[NR_CPUS];
159};
160
161static enum dma_state_client
162netdev_dma_event(struct dma_client *client, struct dma_chan *chan,
163 enum dma_state state);
164
165static struct net_dma net_dma = {
166 .client = {
167 .event_callback = netdev_dma_event,
168 },
169};
157#endif 170#endif
158 171
159/* 172/*
@@ -942,7 +955,7 @@ int dev_open(struct net_device *dev)
942 /* 955 /*
943 * Initialize multicasting status 956 * Initialize multicasting status
944 */ 957 */
945 dev_mc_upload(dev); 958 dev_set_rx_mode(dev);
946 959
947 /* 960 /*
948 * Wakeup transmit queue engine 961 * Wakeup transmit queue engine
@@ -1429,7 +1442,9 @@ gso:
1429 skb->next = nskb; 1442 skb->next = nskb;
1430 return rc; 1443 return rc;
1431 } 1444 }
1432 if (unlikely(netif_queue_stopped(dev) && skb->next)) 1445 if (unlikely((netif_queue_stopped(dev) ||
1446 netif_subqueue_stopped(dev, skb->queue_mapping)) &&
1447 skb->next))
1433 return NETDEV_TX_BUSY; 1448 return NETDEV_TX_BUSY;
1434 } while (skb->next); 1449 } while (skb->next);
1435 1450
@@ -1510,8 +1525,10 @@ int dev_queue_xmit(struct sk_buff *skb)
1510 skb_headroom(skb)); 1525 skb_headroom(skb));
1511 1526
1512 if (!(dev->features & NETIF_F_GEN_CSUM) && 1527 if (!(dev->features & NETIF_F_GEN_CSUM) &&
1513 (!(dev->features & NETIF_F_IP_CSUM) || 1528 !((dev->features & NETIF_F_IP_CSUM) &&
1514 skb->protocol != htons(ETH_P_IP))) 1529 skb->protocol == htons(ETH_P_IP)) &&
1530 !((dev->features & NETIF_F_IPV6_CSUM) &&
1531 skb->protocol == htons(ETH_P_IPV6)))
1515 if (skb_checksum_help(skb)) 1532 if (skb_checksum_help(skb))
1516 goto out_kfree_skb; 1533 goto out_kfree_skb;
1517 } 1534 }
@@ -1545,6 +1562,8 @@ gso:
1545 spin_lock(&dev->queue_lock); 1562 spin_lock(&dev->queue_lock);
1546 q = dev->qdisc; 1563 q = dev->qdisc;
1547 if (q->enqueue) { 1564 if (q->enqueue) {
1565 /* reset queue_mapping to zero */
1566 skb->queue_mapping = 0;
1548 rc = q->enqueue(skb, q); 1567 rc = q->enqueue(skb, q);
1549 qdisc_run(dev); 1568 qdisc_run(dev);
1550 spin_unlock(&dev->queue_lock); 1569 spin_unlock(&dev->queue_lock);
@@ -1574,7 +1593,8 @@ gso:
1574 1593
1575 HARD_TX_LOCK(dev, cpu); 1594 HARD_TX_LOCK(dev, cpu);
1576 1595
1577 if (!netif_queue_stopped(dev)) { 1596 if (!netif_queue_stopped(dev) &&
1597 !netif_subqueue_stopped(dev, skb->queue_mapping)) {
1578 rc = 0; 1598 rc = 0;
1579 if (!dev_hard_start_xmit(skb, dev)) { 1599 if (!dev_hard_start_xmit(skb, dev)) {
1580 HARD_TX_UNLOCK(dev); 1600 HARD_TX_UNLOCK(dev);
@@ -2015,12 +2035,13 @@ out:
2015 * There may not be any more sk_buffs coming right now, so push 2035 * There may not be any more sk_buffs coming right now, so push
2016 * any pending DMA copies to hardware 2036 * any pending DMA copies to hardware
2017 */ 2037 */
2018 if (net_dma_client) { 2038 if (!cpus_empty(net_dma.channel_mask)) {
2019 struct dma_chan *chan; 2039 int chan_idx;
2020 rcu_read_lock(); 2040 for_each_cpu_mask(chan_idx, net_dma.channel_mask) {
2021 list_for_each_entry_rcu(chan, &net_dma_client->channels, client_node) 2041 struct dma_chan *chan = net_dma.channels[chan_idx];
2022 dma_async_memcpy_issue_pending(chan); 2042 if (chan)
2023 rcu_read_unlock(); 2043 dma_async_memcpy_issue_pending(chan);
2044 }
2024 } 2045 }
2025#endif 2046#endif
2026 return; 2047 return;
@@ -2496,17 +2517,7 @@ int netdev_set_master(struct net_device *slave, struct net_device *master)
2496 return 0; 2517 return 0;
2497} 2518}
2498 2519
2499/** 2520static void __dev_set_promiscuity(struct net_device *dev, int inc)
2500 * dev_set_promiscuity - update promiscuity count on a device
2501 * @dev: device
2502 * @inc: modifier
2503 *
2504 * Add or remove promiscuity from a device. While the count in the device
2505 * remains above zero the interface remains promiscuous. Once it hits zero
2506 * the device reverts back to normal filtering operation. A negative inc
2507 * value is used to drop promiscuity on the device.
2508 */
2509void dev_set_promiscuity(struct net_device *dev, int inc)
2510{ 2521{
2511 unsigned short old_flags = dev->flags; 2522 unsigned short old_flags = dev->flags;
2512 2523
@@ -2515,7 +2526,6 @@ void dev_set_promiscuity(struct net_device *dev, int inc)
2515 else 2526 else
2516 dev->flags |= IFF_PROMISC; 2527 dev->flags |= IFF_PROMISC;
2517 if (dev->flags != old_flags) { 2528 if (dev->flags != old_flags) {
2518 dev_mc_upload(dev);
2519 printk(KERN_INFO "device %s %s promiscuous mode\n", 2529 printk(KERN_INFO "device %s %s promiscuous mode\n",
2520 dev->name, (dev->flags & IFF_PROMISC) ? "entered" : 2530 dev->name, (dev->flags & IFF_PROMISC) ? "entered" :
2521 "left"); 2531 "left");
@@ -2529,6 +2539,25 @@ void dev_set_promiscuity(struct net_device *dev, int inc)
2529} 2539}
2530 2540
2531/** 2541/**
2542 * dev_set_promiscuity - update promiscuity count on a device
2543 * @dev: device
2544 * @inc: modifier
2545 *
2546 * Add or remove promiscuity from a device. While the count in the device
2547 * remains above zero the interface remains promiscuous. Once it hits zero
2548 * the device reverts back to normal filtering operation. A negative inc
2549 * value is used to drop promiscuity on the device.
2550 */
2551void dev_set_promiscuity(struct net_device *dev, int inc)
2552{
2553 unsigned short old_flags = dev->flags;
2554
2555 __dev_set_promiscuity(dev, inc);
2556 if (dev->flags != old_flags)
2557 dev_set_rx_mode(dev);
2558}
2559
2560/**
2532 * dev_set_allmulti - update allmulti count on a device 2561 * dev_set_allmulti - update allmulti count on a device
2533 * @dev: device 2562 * @dev: device
2534 * @inc: modifier 2563 * @inc: modifier
@@ -2548,7 +2577,176 @@ void dev_set_allmulti(struct net_device *dev, int inc)
2548 if ((dev->allmulti += inc) == 0) 2577 if ((dev->allmulti += inc) == 0)
2549 dev->flags &= ~IFF_ALLMULTI; 2578 dev->flags &= ~IFF_ALLMULTI;
2550 if (dev->flags ^ old_flags) 2579 if (dev->flags ^ old_flags)
2551 dev_mc_upload(dev); 2580 dev_set_rx_mode(dev);
2581}
2582
2583/*
2584 * Upload unicast and multicast address lists to device and
2585 * configure RX filtering. When the device doesn't support unicast
2586 * filtering it is put in promiscous mode while unicast addresses
2587 * are present.
2588 */
2589void __dev_set_rx_mode(struct net_device *dev)
2590{
2591 /* dev_open will call this function so the list will stay sane. */
2592 if (!(dev->flags&IFF_UP))
2593 return;
2594
2595 if (!netif_device_present(dev))
2596 return;
2597
2598 if (dev->set_rx_mode)
2599 dev->set_rx_mode(dev);
2600 else {
2601 /* Unicast addresses changes may only happen under the rtnl,
2602 * therefore calling __dev_set_promiscuity here is safe.
2603 */
2604 if (dev->uc_count > 0 && !dev->uc_promisc) {
2605 __dev_set_promiscuity(dev, 1);
2606 dev->uc_promisc = 1;
2607 } else if (dev->uc_count == 0 && dev->uc_promisc) {
2608 __dev_set_promiscuity(dev, -1);
2609 dev->uc_promisc = 0;
2610 }
2611
2612 if (dev->set_multicast_list)
2613 dev->set_multicast_list(dev);
2614 }
2615}
2616
2617void dev_set_rx_mode(struct net_device *dev)
2618{
2619 netif_tx_lock_bh(dev);
2620 __dev_set_rx_mode(dev);
2621 netif_tx_unlock_bh(dev);
2622}
2623
2624int __dev_addr_delete(struct dev_addr_list **list, int *count,
2625 void *addr, int alen, int glbl)
2626{
2627 struct dev_addr_list *da;
2628
2629 for (; (da = *list) != NULL; list = &da->next) {
2630 if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 &&
2631 alen == da->da_addrlen) {
2632 if (glbl) {
2633 int old_glbl = da->da_gusers;
2634 da->da_gusers = 0;
2635 if (old_glbl == 0)
2636 break;
2637 }
2638 if (--da->da_users)
2639 return 0;
2640
2641 *list = da->next;
2642 kfree(da);
2643 (*count)--;
2644 return 0;
2645 }
2646 }
2647 return -ENOENT;
2648}
2649
2650int __dev_addr_add(struct dev_addr_list **list, int *count,
2651 void *addr, int alen, int glbl)
2652{
2653 struct dev_addr_list *da;
2654
2655 for (da = *list; da != NULL; da = da->next) {
2656 if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 &&
2657 da->da_addrlen == alen) {
2658 if (glbl) {
2659 int old_glbl = da->da_gusers;
2660 da->da_gusers = 1;
2661 if (old_glbl)
2662 return 0;
2663 }
2664 da->da_users++;
2665 return 0;
2666 }
2667 }
2668
2669 da = kmalloc(sizeof(*da), GFP_ATOMIC);
2670 if (da == NULL)
2671 return -ENOMEM;
2672 memcpy(da->da_addr, addr, alen);
2673 da->da_addrlen = alen;
2674 da->da_users = 1;
2675 da->da_gusers = glbl ? 1 : 0;
2676 da->next = *list;
2677 *list = da;
2678 (*count)++;
2679 return 0;
2680}
2681
2682void __dev_addr_discard(struct dev_addr_list **list)
2683{
2684 struct dev_addr_list *tmp;
2685
2686 while (*list != NULL) {
2687 tmp = *list;
2688 *list = tmp->next;
2689 if (tmp->da_users > tmp->da_gusers)
2690 printk("__dev_addr_discard: address leakage! "
2691 "da_users=%d\n", tmp->da_users);
2692 kfree(tmp);
2693 }
2694}
2695
2696/**
2697 * dev_unicast_delete - Release secondary unicast address.
2698 * @dev: device
2699 *
2700 * Release reference to a secondary unicast address and remove it
2701 * from the device if the reference count drop to zero.
2702 *
2703 * The caller must hold the rtnl_mutex.
2704 */
2705int dev_unicast_delete(struct net_device *dev, void *addr, int alen)
2706{
2707 int err;
2708
2709 ASSERT_RTNL();
2710
2711 netif_tx_lock_bh(dev);
2712 err = __dev_addr_delete(&dev->uc_list, &dev->uc_count, addr, alen, 0);
2713 if (!err)
2714 __dev_set_rx_mode(dev);
2715 netif_tx_unlock_bh(dev);
2716 return err;
2717}
2718EXPORT_SYMBOL(dev_unicast_delete);
2719
2720/**
2721 * dev_unicast_add - add a secondary unicast address
2722 * @dev: device
2723 *
2724 * Add a secondary unicast address to the device or increase
2725 * the reference count if it already exists.
2726 *
2727 * The caller must hold the rtnl_mutex.
2728 */
2729int dev_unicast_add(struct net_device *dev, void *addr, int alen)
2730{
2731 int err;
2732
2733 ASSERT_RTNL();
2734
2735 netif_tx_lock_bh(dev);
2736 err = __dev_addr_add(&dev->uc_list, &dev->uc_count, addr, alen, 0);
2737 if (!err)
2738 __dev_set_rx_mode(dev);
2739 netif_tx_unlock_bh(dev);
2740 return err;
2741}
2742EXPORT_SYMBOL(dev_unicast_add);
2743
2744static void dev_unicast_discard(struct net_device *dev)
2745{
2746 netif_tx_lock_bh(dev);
2747 __dev_addr_discard(&dev->uc_list);
2748 dev->uc_count = 0;
2749 netif_tx_unlock_bh(dev);
2552} 2750}
2553 2751
2554unsigned dev_get_flags(const struct net_device *dev) 2752unsigned dev_get_flags(const struct net_device *dev)
@@ -2594,7 +2792,7 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
2594 * Load in the correct multicast list now the flags have changed. 2792 * Load in the correct multicast list now the flags have changed.
2595 */ 2793 */
2596 2794
2597 dev_mc_upload(dev); 2795 dev_set_rx_mode(dev);
2598 2796
2599 /* 2797 /*
2600 * Have we downed the interface. We handle IFF_UP ourselves 2798 * Have we downed the interface. We handle IFF_UP ourselves
@@ -2607,7 +2805,7 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
2607 ret = ((old_flags & IFF_UP) ? dev_close : dev_open)(dev); 2805 ret = ((old_flags & IFF_UP) ? dev_close : dev_open)(dev);
2608 2806
2609 if (!ret) 2807 if (!ret)
2610 dev_mc_upload(dev); 2808 dev_set_rx_mode(dev);
2611 } 2809 }
2612 2810
2613 if (dev->flags & IFF_UP && 2811 if (dev->flags & IFF_UP &&
@@ -3107,6 +3305,22 @@ int register_netdevice(struct net_device *dev)
3107 } 3305 }
3108 } 3306 }
3109 3307
3308 /* Fix illegal checksum combinations */
3309 if ((dev->features & NETIF_F_HW_CSUM) &&
3310 (dev->features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) {
3311 printk(KERN_NOTICE "%s: mixed HW and IP checksum settings.\n",
3312 dev->name);
3313 dev->features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM);
3314 }
3315
3316 if ((dev->features & NETIF_F_NO_CSUM) &&
3317 (dev->features & (NETIF_F_HW_CSUM|NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) {
3318 printk(KERN_NOTICE "%s: mixed no checksumming and other settings.\n",
3319 dev->name);
3320 dev->features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM|NETIF_F_HW_CSUM);
3321 }
3322
3323
3110 /* Fix illegal SG+CSUM combinations. */ 3324 /* Fix illegal SG+CSUM combinations. */
3111 if ((dev->features & NETIF_F_SG) && 3325 if ((dev->features & NETIF_F_SG) &&
3112 !(dev->features & NETIF_F_ALL_CSUM)) { 3326 !(dev->features & NETIF_F_ALL_CSUM)) {
@@ -3343,16 +3557,18 @@ static struct net_device_stats *internal_stats(struct net_device *dev)
3343} 3557}
3344 3558
3345/** 3559/**
3346 * alloc_netdev - allocate network device 3560 * alloc_netdev_mq - allocate network device
3347 * @sizeof_priv: size of private data to allocate space for 3561 * @sizeof_priv: size of private data to allocate space for
3348 * @name: device name format string 3562 * @name: device name format string
3349 * @setup: callback to initialize device 3563 * @setup: callback to initialize device
3564 * @queue_count: the number of subqueues to allocate
3350 * 3565 *
3351 * Allocates a struct net_device with private data area for driver use 3566 * Allocates a struct net_device with private data area for driver use
3352 * and performs basic initialization. 3567 * and performs basic initialization. Also allocates subquue structs
3568 * for each queue on the device at the end of the netdevice.
3353 */ 3569 */
3354struct net_device *alloc_netdev(int sizeof_priv, const char *name, 3570struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
3355 void (*setup)(struct net_device *)) 3571 void (*setup)(struct net_device *), unsigned int queue_count)
3356{ 3572{
3357 void *p; 3573 void *p;
3358 struct net_device *dev; 3574 struct net_device *dev;
@@ -3361,7 +3577,9 @@ struct net_device *alloc_netdev(int sizeof_priv, const char *name,
3361 BUG_ON(strlen(name) >= sizeof(dev->name)); 3577 BUG_ON(strlen(name) >= sizeof(dev->name));
3362 3578
3363 /* ensure 32-byte alignment of both the device and private area */ 3579 /* ensure 32-byte alignment of both the device and private area */
3364 alloc_size = (sizeof(*dev) + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST; 3580 alloc_size = (sizeof(*dev) + NETDEV_ALIGN_CONST +
3581 (sizeof(struct net_device_subqueue) * queue_count)) &
3582 ~NETDEV_ALIGN_CONST;
3365 alloc_size += sizeof_priv + NETDEV_ALIGN_CONST; 3583 alloc_size += sizeof_priv + NETDEV_ALIGN_CONST;
3366 3584
3367 p = kzalloc(alloc_size, GFP_KERNEL); 3585 p = kzalloc(alloc_size, GFP_KERNEL);
@@ -3374,15 +3592,22 @@ struct net_device *alloc_netdev(int sizeof_priv, const char *name,
3374 (((long)p + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST); 3592 (((long)p + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
3375 dev->padded = (char *)dev - (char *)p; 3593 dev->padded = (char *)dev - (char *)p;
3376 3594
3377 if (sizeof_priv) 3595 if (sizeof_priv) {
3378 dev->priv = netdev_priv(dev); 3596 dev->priv = ((char *)dev +
3597 ((sizeof(struct net_device) +
3598 (sizeof(struct net_device_subqueue) *
3599 queue_count) + NETDEV_ALIGN_CONST)
3600 & ~NETDEV_ALIGN_CONST));
3601 }
3602
3603 dev->egress_subqueue_count = queue_count;
3379 3604
3380 dev->get_stats = internal_stats; 3605 dev->get_stats = internal_stats;
3381 setup(dev); 3606 setup(dev);
3382 strcpy(dev->name, name); 3607 strcpy(dev->name, name);
3383 return dev; 3608 return dev;
3384} 3609}
3385EXPORT_SYMBOL(alloc_netdev); 3610EXPORT_SYMBOL(alloc_netdev_mq);
3386 3611
3387/** 3612/**
3388 * free_netdev - free network device 3613 * free_netdev - free network device
@@ -3471,8 +3696,9 @@ void unregister_netdevice(struct net_device *dev)
3471 raw_notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev); 3696 raw_notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev);
3472 3697
3473 /* 3698 /*
3474 * Flush the multicast chain 3699 * Flush the unicast and multicast chains
3475 */ 3700 */
3701 dev_unicast_discard(dev);
3476 dev_mc_discard(dev); 3702 dev_mc_discard(dev);
3477 3703
3478 if (dev->uninit) 3704 if (dev->uninit)
@@ -3563,12 +3789,13 @@ static int dev_cpu_callback(struct notifier_block *nfb,
3563 * This is called when the number of channels allocated to the net_dma_client 3789 * This is called when the number of channels allocated to the net_dma_client
3564 * changes. The net_dma_client tries to have one DMA channel per CPU. 3790 * changes. The net_dma_client tries to have one DMA channel per CPU.
3565 */ 3791 */
3566static void net_dma_rebalance(void) 3792
3793static void net_dma_rebalance(struct net_dma *net_dma)
3567{ 3794{
3568 unsigned int cpu, i, n; 3795 unsigned int cpu, i, n, chan_idx;
3569 struct dma_chan *chan; 3796 struct dma_chan *chan;
3570 3797
3571 if (net_dma_count == 0) { 3798 if (cpus_empty(net_dma->channel_mask)) {
3572 for_each_online_cpu(cpu) 3799 for_each_online_cpu(cpu)
3573 rcu_assign_pointer(per_cpu(softnet_data, cpu).net_dma, NULL); 3800 rcu_assign_pointer(per_cpu(softnet_data, cpu).net_dma, NULL);
3574 return; 3801 return;
@@ -3577,10 +3804,12 @@ static void net_dma_rebalance(void)
3577 i = 0; 3804 i = 0;
3578 cpu = first_cpu(cpu_online_map); 3805 cpu = first_cpu(cpu_online_map);
3579 3806
3580 rcu_read_lock(); 3807 for_each_cpu_mask(chan_idx, net_dma->channel_mask) {
3581 list_for_each_entry(chan, &net_dma_client->channels, client_node) { 3808 chan = net_dma->channels[chan_idx];
3582 n = ((num_online_cpus() / net_dma_count) 3809
3583 + (i < (num_online_cpus() % net_dma_count) ? 1 : 0)); 3810 n = ((num_online_cpus() / cpus_weight(net_dma->channel_mask))
3811 + (i < (num_online_cpus() %
3812 cpus_weight(net_dma->channel_mask)) ? 1 : 0));
3584 3813
3585 while(n) { 3814 while(n) {
3586 per_cpu(softnet_data, cpu).net_dma = chan; 3815 per_cpu(softnet_data, cpu).net_dma = chan;
@@ -3589,7 +3818,6 @@ static void net_dma_rebalance(void)
3589 } 3818 }
3590 i++; 3819 i++;
3591 } 3820 }
3592 rcu_read_unlock();
3593} 3821}
3594 3822
3595/** 3823/**
@@ -3598,23 +3826,53 @@ static void net_dma_rebalance(void)
3598 * @chan: DMA channel for the event 3826 * @chan: DMA channel for the event
3599 * @event: event type 3827 * @event: event type
3600 */ 3828 */
3601static void netdev_dma_event(struct dma_client *client, struct dma_chan *chan, 3829static enum dma_state_client
3602 enum dma_event event) 3830netdev_dma_event(struct dma_client *client, struct dma_chan *chan,
3603{ 3831 enum dma_state state)
3604 spin_lock(&net_dma_event_lock); 3832{
3605 switch (event) { 3833 int i, found = 0, pos = -1;
3606 case DMA_RESOURCE_ADDED: 3834 struct net_dma *net_dma =
3607 net_dma_count++; 3835 container_of(client, struct net_dma, client);
3608 net_dma_rebalance(); 3836 enum dma_state_client ack = DMA_DUP; /* default: take no action */
3837
3838 spin_lock(&net_dma->lock);
3839 switch (state) {
3840 case DMA_RESOURCE_AVAILABLE:
3841 for (i = 0; i < NR_CPUS; i++)
3842 if (net_dma->channels[i] == chan) {
3843 found = 1;
3844 break;
3845 } else if (net_dma->channels[i] == NULL && pos < 0)
3846 pos = i;
3847
3848 if (!found && pos >= 0) {
3849 ack = DMA_ACK;
3850 net_dma->channels[pos] = chan;
3851 cpu_set(pos, net_dma->channel_mask);
3852 net_dma_rebalance(net_dma);
3853 }
3609 break; 3854 break;
3610 case DMA_RESOURCE_REMOVED: 3855 case DMA_RESOURCE_REMOVED:
3611 net_dma_count--; 3856 for (i = 0; i < NR_CPUS; i++)
3612 net_dma_rebalance(); 3857 if (net_dma->channels[i] == chan) {
3858 found = 1;
3859 pos = i;
3860 break;
3861 }
3862
3863 if (found) {
3864 ack = DMA_ACK;
3865 cpu_clear(pos, net_dma->channel_mask);
3866 net_dma->channels[i] = NULL;
3867 net_dma_rebalance(net_dma);
3868 }
3613 break; 3869 break;
3614 default: 3870 default:
3615 break; 3871 break;
3616 } 3872 }
3617 spin_unlock(&net_dma_event_lock); 3873 spin_unlock(&net_dma->lock);
3874
3875 return ack;
3618} 3876}
3619 3877
3620/** 3878/**
@@ -3622,12 +3880,10 @@ static void netdev_dma_event(struct dma_client *client, struct dma_chan *chan,
3622 */ 3880 */
3623static int __init netdev_dma_register(void) 3881static int __init netdev_dma_register(void)
3624{ 3882{
3625 spin_lock_init(&net_dma_event_lock); 3883 spin_lock_init(&net_dma.lock);
3626 net_dma_client = dma_async_client_register(netdev_dma_event); 3884 dma_cap_set(DMA_MEMCPY, net_dma.client.cap_mask);
3627 if (net_dma_client == NULL) 3885 dma_async_client_register(&net_dma.client);
3628 return -ENOMEM; 3886 dma_async_client_chan_request(&net_dma.client);
3629
3630 dma_async_client_chan_request(net_dma_client, num_online_cpus());
3631 return 0; 3887 return 0;
3632} 3888}
3633 3889
diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c
index 5a54053386c8..aa38100601fb 100644
--- a/net/core/dev_mcast.c
+++ b/net/core/dev_mcast.c
@@ -64,85 +64,24 @@
64 */ 64 */
65 65
66/* 66/*
67 * Update the multicast list into the physical NIC controller.
68 */
69
70static void __dev_mc_upload(struct net_device *dev)
71{
72 /* Don't do anything till we up the interface
73 * [dev_open will call this function so the list will
74 * stay sane]
75 */
76
77 if (!(dev->flags&IFF_UP))
78 return;
79
80 /*
81 * Devices with no set multicast or which have been
82 * detached don't get set.
83 */
84
85 if (dev->set_multicast_list == NULL ||
86 !netif_device_present(dev))
87 return;
88
89 dev->set_multicast_list(dev);
90}
91
92void dev_mc_upload(struct net_device *dev)
93{
94 netif_tx_lock_bh(dev);
95 __dev_mc_upload(dev);
96 netif_tx_unlock_bh(dev);
97}
98
99/*
100 * Delete a device level multicast 67 * Delete a device level multicast
101 */ 68 */
102 69
103int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl) 70int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
104{ 71{
105 int err = 0; 72 int err;
106 struct dev_mc_list *dmi, **dmip;
107 73
108 netif_tx_lock_bh(dev); 74 netif_tx_lock_bh(dev);
109 75 err = __dev_addr_delete(&dev->mc_list, &dev->mc_count,
110 for (dmip = &dev->mc_list; (dmi = *dmip) != NULL; dmip = &dmi->next) { 76 addr, alen, glbl);
77 if (!err) {
111 /* 78 /*
112 * Find the entry we want to delete. The device could 79 * We have altered the list, so the card
113 * have variable length entries so check these too. 80 * loaded filter is now wrong. Fix it
114 */ 81 */
115 if (memcmp(dmi->dmi_addr, addr, dmi->dmi_addrlen) == 0 &&
116 alen == dmi->dmi_addrlen) {
117 if (glbl) {
118 int old_glbl = dmi->dmi_gusers;
119 dmi->dmi_gusers = 0;
120 if (old_glbl == 0)
121 break;
122 }
123 if (--dmi->dmi_users)
124 goto done;
125 82
126 /* 83 __dev_set_rx_mode(dev);
127 * Last user. So delete the entry.
128 */
129 *dmip = dmi->next;
130 dev->mc_count--;
131
132 kfree(dmi);
133
134 /*
135 * We have altered the list, so the card
136 * loaded filter is now wrong. Fix it
137 */
138 __dev_mc_upload(dev);
139
140 netif_tx_unlock_bh(dev);
141 return 0;
142 }
143 } 84 }
144 err = -ENOENT;
145done:
146 netif_tx_unlock_bh(dev); 85 netif_tx_unlock_bh(dev);
147 return err; 86 return err;
148} 87}
@@ -153,46 +92,13 @@ done:
153 92
154int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl) 93int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
155{ 94{
156 int err = 0; 95 int err;
157 struct dev_mc_list *dmi, *dmi1;
158
159 dmi1 = kmalloc(sizeof(*dmi), GFP_ATOMIC);
160 96
161 netif_tx_lock_bh(dev); 97 netif_tx_lock_bh(dev);
162 for (dmi = dev->mc_list; dmi != NULL; dmi = dmi->next) { 98 err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl);
163 if (memcmp(dmi->dmi_addr, addr, dmi->dmi_addrlen) == 0 && 99 if (!err)
164 dmi->dmi_addrlen == alen) { 100 __dev_set_rx_mode(dev);
165 if (glbl) {
166 int old_glbl = dmi->dmi_gusers;
167 dmi->dmi_gusers = 1;
168 if (old_glbl)
169 goto done;
170 }
171 dmi->dmi_users++;
172 goto done;
173 }
174 }
175
176 if ((dmi = dmi1) == NULL) {
177 netif_tx_unlock_bh(dev);
178 return -ENOMEM;
179 }
180 memcpy(dmi->dmi_addr, addr, alen);
181 dmi->dmi_addrlen = alen;
182 dmi->next = dev->mc_list;
183 dmi->dmi_users = 1;
184 dmi->dmi_gusers = glbl ? 1 : 0;
185 dev->mc_list = dmi;
186 dev->mc_count++;
187
188 __dev_mc_upload(dev);
189
190 netif_tx_unlock_bh(dev);
191 return 0;
192
193done:
194 netif_tx_unlock_bh(dev); 101 netif_tx_unlock_bh(dev);
195 kfree(dmi1);
196 return err; 102 return err;
197} 103}
198 104
@@ -203,16 +109,8 @@ done:
203void dev_mc_discard(struct net_device *dev) 109void dev_mc_discard(struct net_device *dev)
204{ 110{
205 netif_tx_lock_bh(dev); 111 netif_tx_lock_bh(dev);
206 112 __dev_addr_discard(&dev->mc_list);
207 while (dev->mc_list != NULL) {
208 struct dev_mc_list *tmp = dev->mc_list;
209 dev->mc_list = tmp->next;
210 if (tmp->dmi_users > tmp->dmi_gusers)
211 printk("dev_mc_discard: multicast leakage! dmi_users=%d\n", tmp->dmi_users);
212 kfree(tmp);
213 }
214 dev->mc_count = 0; 113 dev->mc_count = 0;
215
216 netif_tx_unlock_bh(dev); 114 netif_tx_unlock_bh(dev);
217} 115}
218 116
@@ -244,7 +142,7 @@ static void dev_mc_seq_stop(struct seq_file *seq, void *v)
244 142
245static int dev_mc_seq_show(struct seq_file *seq, void *v) 143static int dev_mc_seq_show(struct seq_file *seq, void *v)
246{ 144{
247 struct dev_mc_list *m; 145 struct dev_addr_list *m;
248 struct net_device *dev = v; 146 struct net_device *dev = v;
249 147
250 netif_tx_lock_bh(dev); 148 netif_tx_lock_bh(dev);
@@ -292,4 +190,3 @@ void __init dev_mcast_init(void)
292 190
293EXPORT_SYMBOL(dev_mc_add); 191EXPORT_SYMBOL(dev_mc_add);
294EXPORT_SYMBOL(dev_mc_delete); 192EXPORT_SYMBOL(dev_mc_delete);
295EXPORT_SYMBOL(dev_mc_upload);
diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c
index 17daf4c9f793..cc84d8d8a3c7 100644
--- a/net/core/gen_estimator.c
+++ b/net/core/gen_estimator.c
@@ -128,7 +128,8 @@ static void est_timer(unsigned long arg)
128 spin_unlock(e->stats_lock); 128 spin_unlock(e->stats_lock);
129 } 129 }
130 130
131 mod_timer(&elist[idx].timer, jiffies + ((HZ<<idx)/4)); 131 if (elist[idx].list != NULL)
132 mod_timer(&elist[idx].timer, jiffies + ((HZ<<idx)/4));
132 read_unlock(&est_lock); 133 read_unlock(&est_lock);
133} 134}
134 135
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index a0efdd7a6b37..d1264e9a50a8 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -66,8 +66,9 @@ static void queue_process(struct work_struct *work)
66 66
67 local_irq_save(flags); 67 local_irq_save(flags);
68 netif_tx_lock(dev); 68 netif_tx_lock(dev);
69 if (netif_queue_stopped(dev) || 69 if ((netif_queue_stopped(dev) ||
70 dev->hard_start_xmit(skb, dev) != NETDEV_TX_OK) { 70 netif_subqueue_stopped(dev, skb->queue_mapping)) ||
71 dev->hard_start_xmit(skb, dev) != NETDEV_TX_OK) {
71 skb_queue_head(&npinfo->txq, skb); 72 skb_queue_head(&npinfo->txq, skb);
72 netif_tx_unlock(dev); 73 netif_tx_unlock(dev);
73 local_irq_restore(flags); 74 local_irq_restore(flags);
@@ -123,6 +124,13 @@ static void poll_napi(struct netpoll *np)
123 if (test_bit(__LINK_STATE_RX_SCHED, &np->dev->state) && 124 if (test_bit(__LINK_STATE_RX_SCHED, &np->dev->state) &&
124 npinfo->poll_owner != smp_processor_id() && 125 npinfo->poll_owner != smp_processor_id() &&
125 spin_trylock(&npinfo->poll_lock)) { 126 spin_trylock(&npinfo->poll_lock)) {
127 /* When calling dev->poll from poll_napi, we may end up in
128 * netif_rx_complete. However, only the CPU to which the
129 * device was queued is allowed to remove it from poll_list.
130 * Setting POLL_LIST_FROZEN tells netif_rx_complete
131 * to leave the NAPI state alone.
132 */
133 set_bit(__LINK_STATE_POLL_LIST_FROZEN, &np->dev->state);
126 npinfo->rx_flags |= NETPOLL_RX_DROP; 134 npinfo->rx_flags |= NETPOLL_RX_DROP;
127 atomic_inc(&trapped); 135 atomic_inc(&trapped);
128 136
@@ -130,6 +138,7 @@ static void poll_napi(struct netpoll *np)
130 138
131 atomic_dec(&trapped); 139 atomic_dec(&trapped);
132 npinfo->rx_flags &= ~NETPOLL_RX_DROP; 140 npinfo->rx_flags &= ~NETPOLL_RX_DROP;
141 clear_bit(__LINK_STATE_POLL_LIST_FROZEN, &np->dev->state);
133 spin_unlock(&npinfo->poll_lock); 142 spin_unlock(&npinfo->poll_lock);
134 } 143 }
135} 144}
@@ -254,7 +263,8 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
254 for (tries = jiffies_to_usecs(1)/USEC_PER_POLL; 263 for (tries = jiffies_to_usecs(1)/USEC_PER_POLL;
255 tries > 0; --tries) { 264 tries > 0; --tries) {
256 if (netif_tx_trylock(dev)) { 265 if (netif_tx_trylock(dev)) {
257 if (!netif_queue_stopped(dev)) 266 if (!netif_queue_stopped(dev) &&
267 !netif_subqueue_stopped(dev, skb->queue_mapping))
258 status = dev->hard_start_xmit(skb, dev); 268 status = dev->hard_start_xmit(skb, dev);
259 netif_tx_unlock(dev); 269 netif_tx_unlock(dev);
260 270
@@ -781,7 +791,6 @@ void netpoll_cleanup(struct netpoll *np)
781 spin_unlock_irqrestore(&npinfo->rx_lock, flags); 791 spin_unlock_irqrestore(&npinfo->rx_lock, flags);
782 } 792 }
783 793
784 np->dev->npinfo = NULL;
785 if (atomic_dec_and_test(&npinfo->refcnt)) { 794 if (atomic_dec_and_test(&npinfo->refcnt)) {
786 skb_queue_purge(&npinfo->arp_tx); 795 skb_queue_purge(&npinfo->arp_tx);
787 skb_queue_purge(&npinfo->txq); 796 skb_queue_purge(&npinfo->txq);
@@ -794,6 +803,7 @@ void netpoll_cleanup(struct netpoll *np)
794 kfree_skb(skb); 803 kfree_skb(skb);
795 } 804 }
796 kfree(npinfo); 805 kfree(npinfo);
806 np->dev->npinfo = NULL;
797 } 807 }
798 } 808 }
799 809
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 9cd3a1cb60ef..75215331b045 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -152,6 +152,9 @@
152#include <net/checksum.h> 152#include <net/checksum.h>
153#include <net/ipv6.h> 153#include <net/ipv6.h>
154#include <net/addrconf.h> 154#include <net/addrconf.h>
155#ifdef CONFIG_XFRM
156#include <net/xfrm.h>
157#endif
155#include <asm/byteorder.h> 158#include <asm/byteorder.h>
156#include <linux/rcupdate.h> 159#include <linux/rcupdate.h>
157#include <asm/bitops.h> 160#include <asm/bitops.h>
@@ -181,6 +184,8 @@
181#define F_MPLS_RND (1<<8) /* Random MPLS labels */ 184#define F_MPLS_RND (1<<8) /* Random MPLS labels */
182#define F_VID_RND (1<<9) /* Random VLAN ID */ 185#define F_VID_RND (1<<9) /* Random VLAN ID */
183#define F_SVID_RND (1<<10) /* Random SVLAN ID */ 186#define F_SVID_RND (1<<10) /* Random SVLAN ID */
187#define F_FLOW_SEQ (1<<11) /* Sequential flows */
188#define F_IPSEC_ON (1<<12) /* ipsec on for flows */
184 189
185/* Thread control flag bits */ 190/* Thread control flag bits */
186#define T_TERMINATE (1<<0) 191#define T_TERMINATE (1<<0)
@@ -207,8 +212,15 @@ static struct proc_dir_entry *pg_proc_dir = NULL;
207struct flow_state { 212struct flow_state {
208 __be32 cur_daddr; 213 __be32 cur_daddr;
209 int count; 214 int count;
215#ifdef CONFIG_XFRM
216 struct xfrm_state *x;
217#endif
218 __u32 flags;
210}; 219};
211 220
221/* flow flag bits */
222#define F_INIT (1<<0) /* flow has been initialized */
223
212struct pktgen_dev { 224struct pktgen_dev {
213 /* 225 /*
214 * Try to keep frequent/infrequent used vars. separated. 226 * Try to keep frequent/infrequent used vars. separated.
@@ -228,6 +240,7 @@ struct pktgen_dev {
228 240
229 int min_pkt_size; /* = ETH_ZLEN; */ 241 int min_pkt_size; /* = ETH_ZLEN; */
230 int max_pkt_size; /* = ETH_ZLEN; */ 242 int max_pkt_size; /* = ETH_ZLEN; */
243 int pkt_overhead; /* overhead for MPLS, VLANs, IPSEC etc */
231 int nfrags; 244 int nfrags;
232 __u32 delay_us; /* Default delay */ 245 __u32 delay_us; /* Default delay */
233 __u32 delay_ns; 246 __u32 delay_ns;
@@ -341,7 +354,11 @@ struct pktgen_dev {
341 unsigned cflows; /* Concurrent flows (config) */ 354 unsigned cflows; /* Concurrent flows (config) */
342 unsigned lflow; /* Flow length (config) */ 355 unsigned lflow; /* Flow length (config) */
343 unsigned nflows; /* accumulated flows (stats) */ 356 unsigned nflows; /* accumulated flows (stats) */
344 357 unsigned curfl; /* current sequenced flow (state)*/
358#ifdef CONFIG_XFRM
359 __u8 ipsmode; /* IPSEC mode (config) */
360 __u8 ipsproto; /* IPSEC type (config) */
361#endif
345 char result[512]; 362 char result[512];
346}; 363};
347 364
@@ -690,6 +707,18 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
690 if (pkt_dev->flags & F_MPLS_RND) 707 if (pkt_dev->flags & F_MPLS_RND)
691 seq_printf(seq, "MPLS_RND "); 708 seq_printf(seq, "MPLS_RND ");
692 709
710 if (pkt_dev->cflows) {
711 if (pkt_dev->flags & F_FLOW_SEQ)
712 seq_printf(seq, "FLOW_SEQ "); /*in sequence flows*/
713 else
714 seq_printf(seq, "FLOW_RND ");
715 }
716
717#ifdef CONFIG_XFRM
718 if (pkt_dev->flags & F_IPSEC_ON)
719 seq_printf(seq, "IPSEC ");
720#endif
721
693 if (pkt_dev->flags & F_MACSRC_RND) 722 if (pkt_dev->flags & F_MACSRC_RND)
694 seq_printf(seq, "MACSRC_RND "); 723 seq_printf(seq, "MACSRC_RND ");
695 724
@@ -1181,6 +1210,14 @@ static ssize_t pktgen_if_write(struct file *file,
1181 else if (strcmp(f, "!SVID_RND") == 0) 1210 else if (strcmp(f, "!SVID_RND") == 0)
1182 pkt_dev->flags &= ~F_SVID_RND; 1211 pkt_dev->flags &= ~F_SVID_RND;
1183 1212
1213 else if (strcmp(f, "FLOW_SEQ") == 0)
1214 pkt_dev->flags |= F_FLOW_SEQ;
1215
1216#ifdef CONFIG_XFRM
1217 else if (strcmp(f, "IPSEC") == 0)
1218 pkt_dev->flags |= F_IPSEC_ON;
1219#endif
1220
1184 else if (strcmp(f, "!IPV6") == 0) 1221 else if (strcmp(f, "!IPV6") == 0)
1185 pkt_dev->flags &= ~F_IPV6; 1222 pkt_dev->flags &= ~F_IPV6;
1186 1223
@@ -1189,7 +1226,7 @@ static ssize_t pktgen_if_write(struct file *file,
1189 "Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s", 1226 "Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s",
1190 f, 1227 f,
1191 "IPSRC_RND, IPDST_RND, UDPSRC_RND, UDPDST_RND, " 1228 "IPSRC_RND, IPDST_RND, UDPSRC_RND, UDPDST_RND, "
1192 "MACSRC_RND, MACDST_RND, TXSIZE_RND, IPV6, MPLS_RND, VID_RND, SVID_RND\n"); 1229 "MACSRC_RND, MACDST_RND, TXSIZE_RND, IPV6, MPLS_RND, VID_RND, SVID_RND, FLOW_SEQ, IPSEC\n");
1193 return count; 1230 return count;
1194 } 1231 }
1195 sprintf(pg_result, "OK: flags=0x%x", pkt_dev->flags); 1232 sprintf(pg_result, "OK: flags=0x%x", pkt_dev->flags);
@@ -2075,6 +2112,70 @@ static void spin(struct pktgen_dev *pkt_dev, __u64 spin_until_us)
2075 pkt_dev->idle_acc += now - start; 2112 pkt_dev->idle_acc += now - start;
2076} 2113}
2077 2114
2115static inline void set_pkt_overhead(struct pktgen_dev *pkt_dev)
2116{
2117 pkt_dev->pkt_overhead = 0;
2118 pkt_dev->pkt_overhead += pkt_dev->nr_labels*sizeof(u32);
2119 pkt_dev->pkt_overhead += VLAN_TAG_SIZE(pkt_dev);
2120 pkt_dev->pkt_overhead += SVLAN_TAG_SIZE(pkt_dev);
2121}
2122
2123static inline int f_seen(struct pktgen_dev *pkt_dev, int flow)
2124{
2125
2126 if (pkt_dev->flows[flow].flags & F_INIT)
2127 return 1;
2128 else
2129 return 0;
2130}
2131
2132static inline int f_pick(struct pktgen_dev *pkt_dev)
2133{
2134 int flow = pkt_dev->curfl;
2135
2136 if (pkt_dev->flags & F_FLOW_SEQ) {
2137 if (pkt_dev->flows[flow].count >= pkt_dev->lflow) {
2138 /* reset time */
2139 pkt_dev->flows[flow].count = 0;
2140 pkt_dev->curfl += 1;
2141 if (pkt_dev->curfl >= pkt_dev->cflows)
2142 pkt_dev->curfl = 0; /*reset */
2143 }
2144 } else {
2145 flow = random32() % pkt_dev->cflows;
2146
2147 if (pkt_dev->flows[flow].count > pkt_dev->lflow)
2148 pkt_dev->flows[flow].count = 0;
2149 }
2150
2151 return pkt_dev->curfl;
2152}
2153
2154
2155#ifdef CONFIG_XFRM
2156/* If there was already an IPSEC SA, we keep it as is, else
2157 * we go look for it ...
2158*/
2159inline
2160void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow)
2161{
2162 struct xfrm_state *x = pkt_dev->flows[flow].x;
2163 if (!x) {
2164 /*slow path: we dont already have xfrm_state*/
2165 x = xfrm_stateonly_find((xfrm_address_t *)&pkt_dev->cur_daddr,
2166 (xfrm_address_t *)&pkt_dev->cur_saddr,
2167 AF_INET,
2168 pkt_dev->ipsmode,
2169 pkt_dev->ipsproto, 0);
2170 if (x) {
2171 pkt_dev->flows[flow].x = x;
2172 set_pkt_overhead(pkt_dev);
2173 pkt_dev->pkt_overhead+=x->props.header_len;
2174 }
2175
2176 }
2177}
2178#endif
2078/* Increment/randomize headers according to flags and current values 2179/* Increment/randomize headers according to flags and current values
2079 * for IP src/dest, UDP src/dst port, MAC-Addr src/dst 2180 * for IP src/dest, UDP src/dst port, MAC-Addr src/dst
2080 */ 2181 */
@@ -2084,12 +2185,8 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
2084 __u32 imx; 2185 __u32 imx;
2085 int flow = 0; 2186 int flow = 0;
2086 2187
2087 if (pkt_dev->cflows) { 2188 if (pkt_dev->cflows)
2088 flow = random32() % pkt_dev->cflows; 2189 flow = f_pick(pkt_dev);
2089
2090 if (pkt_dev->flows[flow].count > pkt_dev->lflow)
2091 pkt_dev->flows[flow].count = 0;
2092 }
2093 2190
2094 /* Deal with source MAC */ 2191 /* Deal with source MAC */
2095 if (pkt_dev->src_mac_count > 1) { 2192 if (pkt_dev->src_mac_count > 1) {
@@ -2205,7 +2302,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
2205 pkt_dev->cur_saddr = htonl(t); 2302 pkt_dev->cur_saddr = htonl(t);
2206 } 2303 }
2207 2304
2208 if (pkt_dev->cflows && pkt_dev->flows[flow].count != 0) { 2305 if (pkt_dev->cflows && f_seen(pkt_dev, flow)) {
2209 pkt_dev->cur_daddr = pkt_dev->flows[flow].cur_daddr; 2306 pkt_dev->cur_daddr = pkt_dev->flows[flow].cur_daddr;
2210 } else { 2307 } else {
2211 imn = ntohl(pkt_dev->daddr_min); 2308 imn = ntohl(pkt_dev->daddr_min);
@@ -2235,8 +2332,13 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
2235 } 2332 }
2236 } 2333 }
2237 if (pkt_dev->cflows) { 2334 if (pkt_dev->cflows) {
2335 pkt_dev->flows[flow].flags |= F_INIT;
2238 pkt_dev->flows[flow].cur_daddr = 2336 pkt_dev->flows[flow].cur_daddr =
2239 pkt_dev->cur_daddr; 2337 pkt_dev->cur_daddr;
2338#ifdef CONFIG_XFRM
2339 if (pkt_dev->flags & F_IPSEC_ON)
2340 get_ipsec_sa(pkt_dev, flow);
2341#endif
2240 pkt_dev->nflows++; 2342 pkt_dev->nflows++;
2241 } 2343 }
2242 } 2344 }
@@ -2277,6 +2379,91 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
2277 pkt_dev->flows[flow].count++; 2379 pkt_dev->flows[flow].count++;
2278} 2380}
2279 2381
2382
2383#ifdef CONFIG_XFRM
2384static int pktgen_output_ipsec(struct sk_buff *skb, struct pktgen_dev *pkt_dev)
2385{
2386 struct xfrm_state *x = pkt_dev->flows[pkt_dev->curfl].x;
2387 int err = 0;
2388 struct iphdr *iph;
2389
2390 if (!x)
2391 return 0;
2392 /* XXX: we dont support tunnel mode for now until
2393 * we resolve the dst issue */
2394 if (x->props.mode != XFRM_MODE_TRANSPORT)
2395 return 0;
2396
2397 spin_lock(&x->lock);
2398 iph = ip_hdr(skb);
2399
2400 err = x->mode->output(x, skb);
2401 if (err)
2402 goto error;
2403 err = x->type->output(x, skb);
2404 if (err)
2405 goto error;
2406
2407 x->curlft.bytes +=skb->len;
2408 x->curlft.packets++;
2409 spin_unlock(&x->lock);
2410
2411error:
2412 spin_unlock(&x->lock);
2413 return err;
2414}
2415
2416static inline void free_SAs(struct pktgen_dev *pkt_dev)
2417{
2418 if (pkt_dev->cflows) {
2419 /* let go of the SAs if we have them */
2420 int i = 0;
2421 for (; i < pkt_dev->nflows; i++){
2422 struct xfrm_state *x = pkt_dev->flows[i].x;
2423 if (x) {
2424 xfrm_state_put(x);
2425 pkt_dev->flows[i].x = NULL;
2426 }
2427 }
2428 }
2429}
2430
2431static inline int process_ipsec(struct pktgen_dev *pkt_dev,
2432 struct sk_buff *skb, __be16 protocol)
2433{
2434 if (pkt_dev->flags & F_IPSEC_ON) {
2435 struct xfrm_state *x = pkt_dev->flows[pkt_dev->curfl].x;
2436 int nhead = 0;
2437 if (x) {
2438 int ret;
2439 __u8 *eth;
2440 nhead = x->props.header_len - skb_headroom(skb);
2441 if (nhead >0) {
2442 ret = pskb_expand_head(skb, nhead, 0, GFP_ATOMIC);
2443 if (ret < 0) {
2444 printk("Error expanding ipsec packet %d\n",ret);
2445 return 0;
2446 }
2447 }
2448
2449 /* ipsec is not expecting ll header */
2450 skb_pull(skb, ETH_HLEN);
2451 ret = pktgen_output_ipsec(skb, pkt_dev);
2452 if (ret) {
2453 printk("Error creating ipsec packet %d\n",ret);
2454 kfree_skb(skb);
2455 return 0;
2456 }
2457 /* restore ll */
2458 eth = (__u8 *) skb_push(skb, ETH_HLEN);
2459 memcpy(eth, pkt_dev->hh, 12);
2460 *(u16 *) & eth[12] = protocol;
2461 }
2462 }
2463 return 1;
2464}
2465#endif
2466
2280static void mpls_push(__be32 *mpls, struct pktgen_dev *pkt_dev) 2467static void mpls_push(__be32 *mpls, struct pktgen_dev *pkt_dev)
2281{ 2468{
2282 unsigned i; 2469 unsigned i;
@@ -2323,9 +2510,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
2323 2510
2324 datalen = (odev->hard_header_len + 16) & ~0xf; 2511 datalen = (odev->hard_header_len + 16) & ~0xf;
2325 skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + datalen + 2512 skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + datalen +
2326 pkt_dev->nr_labels*sizeof(u32) + 2513 pkt_dev->pkt_overhead, GFP_ATOMIC);
2327 VLAN_TAG_SIZE(pkt_dev) + SVLAN_TAG_SIZE(pkt_dev),
2328 GFP_ATOMIC);
2329 if (!skb) { 2514 if (!skb) {
2330 sprintf(pkt_dev->result, "No memory"); 2515 sprintf(pkt_dev->result, "No memory");
2331 return NULL; 2516 return NULL;
@@ -2368,7 +2553,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
2368 2553
2369 /* Eth + IPh + UDPh + mpls */ 2554 /* Eth + IPh + UDPh + mpls */
2370 datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8 - 2555 datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8 -
2371 pkt_dev->nr_labels*sizeof(u32) - VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev); 2556 pkt_dev->pkt_overhead;
2372 if (datalen < sizeof(struct pktgen_hdr)) 2557 if (datalen < sizeof(struct pktgen_hdr))
2373 datalen = sizeof(struct pktgen_hdr); 2558 datalen = sizeof(struct pktgen_hdr);
2374 2559
@@ -2391,8 +2576,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
2391 iph->check = ip_fast_csum((void *)iph, iph->ihl); 2576 iph->check = ip_fast_csum((void *)iph, iph->ihl);
2392 skb->protocol = protocol; 2577 skb->protocol = protocol;
2393 skb->mac_header = (skb->network_header - ETH_HLEN - 2578 skb->mac_header = (skb->network_header - ETH_HLEN -
2394 pkt_dev->nr_labels * sizeof(u32) - 2579 pkt_dev->pkt_overhead);
2395 VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev));
2396 skb->dev = odev; 2580 skb->dev = odev;
2397 skb->pkt_type = PACKET_HOST; 2581 skb->pkt_type = PACKET_HOST;
2398 2582
@@ -2463,6 +2647,11 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
2463 pgh->tv_usec = htonl(timestamp.tv_usec); 2647 pgh->tv_usec = htonl(timestamp.tv_usec);
2464 } 2648 }
2465 2649
2650#ifdef CONFIG_XFRM
2651 if (!process_ipsec(pkt_dev, skb, protocol))
2652 return NULL;
2653#endif
2654
2466 return skb; 2655 return skb;
2467} 2656}
2468 2657
@@ -2662,9 +2851,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
2662 mod_cur_headers(pkt_dev); 2851 mod_cur_headers(pkt_dev);
2663 2852
2664 skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16 + 2853 skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16 +
2665 pkt_dev->nr_labels*sizeof(u32) + 2854 pkt_dev->pkt_overhead, GFP_ATOMIC);
2666 VLAN_TAG_SIZE(pkt_dev) + SVLAN_TAG_SIZE(pkt_dev),
2667 GFP_ATOMIC);
2668 if (!skb) { 2855 if (!skb) {
2669 sprintf(pkt_dev->result, "No memory"); 2856 sprintf(pkt_dev->result, "No memory");
2670 return NULL; 2857 return NULL;
@@ -2708,7 +2895,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
2708 /* Eth + IPh + UDPh + mpls */ 2895 /* Eth + IPh + UDPh + mpls */
2709 datalen = pkt_dev->cur_pkt_size - 14 - 2896 datalen = pkt_dev->cur_pkt_size - 14 -
2710 sizeof(struct ipv6hdr) - sizeof(struct udphdr) - 2897 sizeof(struct ipv6hdr) - sizeof(struct udphdr) -
2711 pkt_dev->nr_labels*sizeof(u32) - VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev); 2898 pkt_dev->pkt_overhead;
2712 2899
2713 if (datalen < sizeof(struct pktgen_hdr)) { 2900 if (datalen < sizeof(struct pktgen_hdr)) {
2714 datalen = sizeof(struct pktgen_hdr); 2901 datalen = sizeof(struct pktgen_hdr);
@@ -2738,8 +2925,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
2738 ipv6_addr_copy(&iph->saddr, &pkt_dev->cur_in6_saddr); 2925 ipv6_addr_copy(&iph->saddr, &pkt_dev->cur_in6_saddr);
2739 2926
2740 skb->mac_header = (skb->network_header - ETH_HLEN - 2927 skb->mac_header = (skb->network_header - ETH_HLEN -
2741 pkt_dev->nr_labels * sizeof(u32) - 2928 pkt_dev->pkt_overhead);
2742 VLAN_TAG_SIZE(pkt_dev) - SVLAN_TAG_SIZE(pkt_dev));
2743 skb->protocol = protocol; 2929 skb->protocol = protocol;
2744 skb->dev = odev; 2930 skb->dev = odev;
2745 skb->pkt_type = PACKET_HOST; 2931 skb->pkt_type = PACKET_HOST;
@@ -2857,6 +3043,7 @@ static void pktgen_run(struct pktgen_thread *t)
2857 pkt_dev->started_at = getCurUs(); 3043 pkt_dev->started_at = getCurUs();
2858 pkt_dev->next_tx_us = getCurUs(); /* Transmit immediately */ 3044 pkt_dev->next_tx_us = getCurUs(); /* Transmit immediately */
2859 pkt_dev->next_tx_ns = 0; 3045 pkt_dev->next_tx_ns = 0;
3046 set_pkt_overhead(pkt_dev);
2860 3047
2861 strcpy(pkt_dev->result, "Starting"); 3048 strcpy(pkt_dev->result, "Starting");
2862 started++; 3049 started++;
@@ -3139,7 +3326,9 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
3139 } 3326 }
3140 } 3327 }
3141 3328
3142 if (netif_queue_stopped(odev) || need_resched()) { 3329 if ((netif_queue_stopped(odev) ||
3330 netif_subqueue_stopped(odev, pkt_dev->skb->queue_mapping)) ||
3331 need_resched()) {
3143 idle_start = getCurUs(); 3332 idle_start = getCurUs();
3144 3333
3145 if (!netif_running(odev)) { 3334 if (!netif_running(odev)) {
@@ -3154,7 +3343,8 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
3154 3343
3155 pkt_dev->idle_acc += getCurUs() - idle_start; 3344 pkt_dev->idle_acc += getCurUs() - idle_start;
3156 3345
3157 if (netif_queue_stopped(odev)) { 3346 if (netif_queue_stopped(odev) ||
3347 netif_subqueue_stopped(odev, pkt_dev->skb->queue_mapping)) {
3158 pkt_dev->next_tx_us = getCurUs(); /* TODO */ 3348 pkt_dev->next_tx_us = getCurUs(); /* TODO */
3159 pkt_dev->next_tx_ns = 0; 3349 pkt_dev->next_tx_ns = 0;
3160 goto out; /* Try the next interface */ 3350 goto out; /* Try the next interface */
@@ -3181,7 +3371,8 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
3181 } 3371 }
3182 3372
3183 netif_tx_lock_bh(odev); 3373 netif_tx_lock_bh(odev);
3184 if (!netif_queue_stopped(odev)) { 3374 if (!netif_queue_stopped(odev) &&
3375 !netif_subqueue_stopped(odev, pkt_dev->skb->queue_mapping)) {
3185 3376
3186 atomic_inc(&(pkt_dev->skb->users)); 3377 atomic_inc(&(pkt_dev->skb->users));
3187 retry_now: 3378 retry_now:
@@ -3446,11 +3637,18 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
3446 } 3637 }
3447 pkt_dev->entry->proc_fops = &pktgen_if_fops; 3638 pkt_dev->entry->proc_fops = &pktgen_if_fops;
3448 pkt_dev->entry->data = pkt_dev; 3639 pkt_dev->entry->data = pkt_dev;
3640#ifdef CONFIG_XFRM
3641 pkt_dev->ipsmode = XFRM_MODE_TRANSPORT;
3642 pkt_dev->ipsproto = IPPROTO_ESP;
3643#endif
3449 3644
3450 return add_dev_to_thread(t, pkt_dev); 3645 return add_dev_to_thread(t, pkt_dev);
3451out2: 3646out2:
3452 dev_put(pkt_dev->odev); 3647 dev_put(pkt_dev->odev);
3453out1: 3648out1:
3649#ifdef CONFIG_XFRM
3650 free_SAs(pkt_dev);
3651#endif
3454 if (pkt_dev->flows) 3652 if (pkt_dev->flows)
3455 vfree(pkt_dev->flows); 3653 vfree(pkt_dev->flows);
3456 kfree(pkt_dev); 3654 kfree(pkt_dev);
@@ -3545,6 +3743,9 @@ static int pktgen_remove_device(struct pktgen_thread *t,
3545 if (pkt_dev->entry) 3743 if (pkt_dev->entry)
3546 remove_proc_entry(pkt_dev->entry->name, pg_proc_dir); 3744 remove_proc_entry(pkt_dev->entry->name, pg_proc_dir);
3547 3745
3746#ifdef CONFIG_XFRM
3747 free_SAs(pkt_dev);
3748#endif
3548 if (pkt_dev->flows) 3749 if (pkt_dev->flows)
3549 vfree(pkt_dev->flows); 3750 vfree(pkt_dev->flows);
3550 kfree(pkt_dev); 3751 kfree(pkt_dev);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 02e8bf084277..864cbdf31ed7 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -97,6 +97,19 @@ int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len)
97 return 0; 97 return 0;
98} 98}
99 99
100int __rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
101 struct rtattr *rta, int len)
102{
103 if (RTA_PAYLOAD(rta) < len)
104 return -1;
105 if (RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr)) {
106 rta = RTA_DATA(rta) + RTA_ALIGN(len);
107 return rtattr_parse_nested(tb, maxattr, rta);
108 }
109 memset(tb, 0, sizeof(struct rtattr *) * maxattr);
110 return 0;
111}
112
100static struct rtnl_link *rtnl_msg_handlers[NPROTO]; 113static struct rtnl_link *rtnl_msg_handlers[NPROTO];
101 114
102static inline int rtm_msgindex(int msgtype) 115static inline int rtm_msgindex(int msgtype)
@@ -243,6 +256,150 @@ void rtnl_unregister_all(int protocol)
243 256
244EXPORT_SYMBOL_GPL(rtnl_unregister_all); 257EXPORT_SYMBOL_GPL(rtnl_unregister_all);
245 258
259static LIST_HEAD(link_ops);
260
261/**
262 * __rtnl_link_register - Register rtnl_link_ops with rtnetlink.
263 * @ops: struct rtnl_link_ops * to register
264 *
265 * The caller must hold the rtnl_mutex. This function should be used
266 * by drivers that create devices during module initialization. It
267 * must be called before registering the devices.
268 *
269 * Returns 0 on success or a negative error code.
270 */
271int __rtnl_link_register(struct rtnl_link_ops *ops)
272{
273 if (!ops->dellink)
274 ops->dellink = unregister_netdevice;
275
276 list_add_tail(&ops->list, &link_ops);
277 return 0;
278}
279
280EXPORT_SYMBOL_GPL(__rtnl_link_register);
281
282/**
283 * rtnl_link_register - Register rtnl_link_ops with rtnetlink.
284 * @ops: struct rtnl_link_ops * to register
285 *
286 * Returns 0 on success or a negative error code.
287 */
288int rtnl_link_register(struct rtnl_link_ops *ops)
289{
290 int err;
291
292 rtnl_lock();
293 err = __rtnl_link_register(ops);
294 rtnl_unlock();
295 return err;
296}
297
298EXPORT_SYMBOL_GPL(rtnl_link_register);
299
300/**
301 * __rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink.
302 * @ops: struct rtnl_link_ops * to unregister
303 *
304 * The caller must hold the rtnl_mutex.
305 */
306void __rtnl_link_unregister(struct rtnl_link_ops *ops)
307{
308 struct net_device *dev, *n;
309
310 for_each_netdev_safe(dev, n) {
311 if (dev->rtnl_link_ops == ops)
312 ops->dellink(dev);
313 }
314 list_del(&ops->list);
315}
316
317EXPORT_SYMBOL_GPL(__rtnl_link_unregister);
318
319/**
320 * rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink.
321 * @ops: struct rtnl_link_ops * to unregister
322 */
323void rtnl_link_unregister(struct rtnl_link_ops *ops)
324{
325 rtnl_lock();
326 __rtnl_link_unregister(ops);
327 rtnl_unlock();
328}
329
330EXPORT_SYMBOL_GPL(rtnl_link_unregister);
331
332static const struct rtnl_link_ops *rtnl_link_ops_get(const char *kind)
333{
334 const struct rtnl_link_ops *ops;
335
336 list_for_each_entry(ops, &link_ops, list) {
337 if (!strcmp(ops->kind, kind))
338 return ops;
339 }
340 return NULL;
341}
342
343static size_t rtnl_link_get_size(const struct net_device *dev)
344{
345 const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
346 size_t size;
347
348 if (!ops)
349 return 0;
350
351 size = nlmsg_total_size(sizeof(struct nlattr)) + /* IFLA_LINKINFO */
352 nlmsg_total_size(strlen(ops->kind) + 1); /* IFLA_INFO_KIND */
353
354 if (ops->get_size)
355 /* IFLA_INFO_DATA + nested data */
356 size += nlmsg_total_size(sizeof(struct nlattr)) +
357 ops->get_size(dev);
358
359 if (ops->get_xstats_size)
360 size += ops->get_xstats_size(dev); /* IFLA_INFO_XSTATS */
361
362 return size;
363}
364
365static int rtnl_link_fill(struct sk_buff *skb, const struct net_device *dev)
366{
367 const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
368 struct nlattr *linkinfo, *data;
369 int err = -EMSGSIZE;
370
371 linkinfo = nla_nest_start(skb, IFLA_LINKINFO);
372 if (linkinfo == NULL)
373 goto out;
374
375 if (nla_put_string(skb, IFLA_INFO_KIND, ops->kind) < 0)
376 goto err_cancel_link;
377 if (ops->fill_xstats) {
378 err = ops->fill_xstats(skb, dev);
379 if (err < 0)
380 goto err_cancel_link;
381 }
382 if (ops->fill_info) {
383 data = nla_nest_start(skb, IFLA_INFO_DATA);
384 if (data == NULL)
385 goto err_cancel_link;
386 err = ops->fill_info(skb, dev);
387 if (err < 0)
388 goto err_cancel_data;
389 nla_nest_end(skb, data);
390 }
391
392 nla_nest_end(skb, linkinfo);
393 return 0;
394
395err_cancel_data:
396 nla_nest_cancel(skb, data);
397err_cancel_link:
398 nla_nest_cancel(skb, linkinfo);
399out:
400 return err;
401}
402
246static const int rtm_min[RTM_NR_FAMILIES] = 403static const int rtm_min[RTM_NR_FAMILIES] =
247{ 404{
248 [RTM_FAM(RTM_NEWLINK)] = NLMSG_LENGTH(sizeof(struct ifinfomsg)), 405 [RTM_FAM(RTM_NEWLINK)] = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
@@ -437,7 +594,7 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
437 a->tx_compressed = b->tx_compressed; 594 a->tx_compressed = b->tx_compressed;
438}; 595};
439 596
440static inline size_t if_nlmsg_size(void) 597static inline size_t if_nlmsg_size(const struct net_device *dev)
441{ 598{
442 return NLMSG_ALIGN(sizeof(struct ifinfomsg)) 599 return NLMSG_ALIGN(sizeof(struct ifinfomsg))
443 + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ 600 + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
@@ -452,7 +609,8 @@ static inline size_t if_nlmsg_size(void)
452 + nla_total_size(4) /* IFLA_LINK */ 609 + nla_total_size(4) /* IFLA_LINK */
453 + nla_total_size(4) /* IFLA_MASTER */ 610 + nla_total_size(4) /* IFLA_MASTER */
454 + nla_total_size(1) /* IFLA_OPERSTATE */ 611 + nla_total_size(1) /* IFLA_OPERSTATE */
455 + nla_total_size(1); /* IFLA_LINKMODE */ 612 + nla_total_size(1) /* IFLA_LINKMODE */
613 + rtnl_link_get_size(dev); /* IFLA_LINKINFO */
456} 614}
457 615
458static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, 616static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
@@ -522,6 +680,11 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
522 } 680 }
523 } 681 }
524 682
683 if (dev->rtnl_link_ops) {
684 if (rtnl_link_fill(skb, dev) < 0)
685 goto nla_put_failure;
686 }
687
525 return nlmsg_end(skb, nlh); 688 return nlmsg_end(skb, nlh);
526 689
527nla_put_failure: 690nla_put_failure:
@@ -553,6 +716,8 @@ cont:
553 716
554static const struct nla_policy ifla_policy[IFLA_MAX+1] = { 717static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
555 [IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 }, 718 [IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 },
719 [IFLA_ADDRESS] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
720 [IFLA_BROADCAST] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
556 [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, 721 [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) },
557 [IFLA_MTU] = { .type = NLA_U32 }, 722 [IFLA_MTU] = { .type = NLA_U32 },
558 [IFLA_TXQLEN] = { .type = NLA_U32 }, 723 [IFLA_TXQLEN] = { .type = NLA_U32 },
@@ -561,44 +726,16 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
561 [IFLA_LINKMODE] = { .type = NLA_U8 }, 726 [IFLA_LINKMODE] = { .type = NLA_U8 },
562}; 727};
563 728
564static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 729static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
565{ 730 [IFLA_INFO_KIND] = { .type = NLA_STRING },
566 struct ifinfomsg *ifm; 731 [IFLA_INFO_DATA] = { .type = NLA_NESTED },
567 struct net_device *dev; 732};
568 int err, send_addr_notify = 0, modified = 0;
569 struct nlattr *tb[IFLA_MAX+1];
570 char ifname[IFNAMSIZ];
571
572 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
573 if (err < 0)
574 goto errout;
575
576 if (tb[IFLA_IFNAME])
577 nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
578 else
579 ifname[0] = '\0';
580
581 err = -EINVAL;
582 ifm = nlmsg_data(nlh);
583 if (ifm->ifi_index > 0)
584 dev = dev_get_by_index(ifm->ifi_index);
585 else if (tb[IFLA_IFNAME])
586 dev = dev_get_by_name(ifname);
587 else
588 goto errout;
589
590 if (dev == NULL) {
591 err = -ENODEV;
592 goto errout;
593 }
594
595 if (tb[IFLA_ADDRESS] &&
596 nla_len(tb[IFLA_ADDRESS]) < dev->addr_len)
597 goto errout_dev;
598 733
599 if (tb[IFLA_BROADCAST] && 734static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
600 nla_len(tb[IFLA_BROADCAST]) < dev->addr_len) 735 struct nlattr **tb, char *ifname, int modified)
601 goto errout_dev; 736{
737 int send_addr_notify = 0;
738 int err;
602 739
603 if (tb[IFLA_MAP]) { 740 if (tb[IFLA_MAP]) {
604 struct rtnl_link_ifmap *u_map; 741 struct rtnl_link_ifmap *u_map;
@@ -606,12 +743,12 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
606 743
607 if (!dev->set_config) { 744 if (!dev->set_config) {
608 err = -EOPNOTSUPP; 745 err = -EOPNOTSUPP;
609 goto errout_dev; 746 goto errout;
610 } 747 }
611 748
612 if (!netif_device_present(dev)) { 749 if (!netif_device_present(dev)) {
613 err = -ENODEV; 750 err = -ENODEV;
614 goto errout_dev; 751 goto errout;
615 } 752 }
616 753
617 u_map = nla_data(tb[IFLA_MAP]); 754 u_map = nla_data(tb[IFLA_MAP]);
@@ -624,7 +761,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
624 761
625 err = dev->set_config(dev, &k_map); 762 err = dev->set_config(dev, &k_map);
626 if (err < 0) 763 if (err < 0)
627 goto errout_dev; 764 goto errout;
628 765
629 modified = 1; 766 modified = 1;
630 } 767 }
@@ -635,19 +772,19 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
635 772
636 if (!dev->set_mac_address) { 773 if (!dev->set_mac_address) {
637 err = -EOPNOTSUPP; 774 err = -EOPNOTSUPP;
638 goto errout_dev; 775 goto errout;
639 } 776 }
640 777
641 if (!netif_device_present(dev)) { 778 if (!netif_device_present(dev)) {
642 err = -ENODEV; 779 err = -ENODEV;
643 goto errout_dev; 780 goto errout;
644 } 781 }
645 782
646 len = sizeof(sa_family_t) + dev->addr_len; 783 len = sizeof(sa_family_t) + dev->addr_len;
647 sa = kmalloc(len, GFP_KERNEL); 784 sa = kmalloc(len, GFP_KERNEL);
648 if (!sa) { 785 if (!sa) {
649 err = -ENOMEM; 786 err = -ENOMEM;
650 goto errout_dev; 787 goto errout;
651 } 788 }
652 sa->sa_family = dev->type; 789 sa->sa_family = dev->type;
653 memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]), 790 memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]),
@@ -655,7 +792,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
655 err = dev->set_mac_address(dev, sa); 792 err = dev->set_mac_address(dev, sa);
656 kfree(sa); 793 kfree(sa);
657 if (err) 794 if (err)
658 goto errout_dev; 795 goto errout;
659 send_addr_notify = 1; 796 send_addr_notify = 1;
660 modified = 1; 797 modified = 1;
661 } 798 }
@@ -663,7 +800,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
663 if (tb[IFLA_MTU]) { 800 if (tb[IFLA_MTU]) {
664 err = dev_set_mtu(dev, nla_get_u32(tb[IFLA_MTU])); 801 err = dev_set_mtu(dev, nla_get_u32(tb[IFLA_MTU]));
665 if (err < 0) 802 if (err < 0)
666 goto errout_dev; 803 goto errout;
667 modified = 1; 804 modified = 1;
668 } 805 }
669 806
@@ -675,7 +812,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
675 if (ifm->ifi_index > 0 && ifname[0]) { 812 if (ifm->ifi_index > 0 && ifname[0]) {
676 err = dev_change_name(dev, ifname); 813 err = dev_change_name(dev, ifname);
677 if (err < 0) 814 if (err < 0)
678 goto errout_dev; 815 goto errout;
679 modified = 1; 816 modified = 1;
680 } 817 }
681 818
@@ -684,7 +821,6 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
684 send_addr_notify = 1; 821 send_addr_notify = 1;
685 } 822 }
686 823
687
688 if (ifm->ifi_flags || ifm->ifi_change) { 824 if (ifm->ifi_flags || ifm->ifi_change) {
689 unsigned int flags = ifm->ifi_flags; 825 unsigned int flags = ifm->ifi_flags;
690 826
@@ -712,7 +848,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
712 848
713 err = 0; 849 err = 0;
714 850
715errout_dev: 851errout:
716 if (err < 0 && modified && net_ratelimit()) 852 if (err < 0 && modified && net_ratelimit())
717 printk(KERN_WARNING "A link change request failed with " 853 printk(KERN_WARNING "A link change request failed with "
718 "some changes comitted already. Interface %s may " 854 "some changes comitted already. Interface %s may "
@@ -721,12 +857,239 @@ errout_dev:
721 857
722 if (send_addr_notify) 858 if (send_addr_notify)
723 call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); 859 call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
860 return err;
861}
862
863static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
864{
865 struct ifinfomsg *ifm;
866 struct net_device *dev;
867 int err;
868 struct nlattr *tb[IFLA_MAX+1];
869 char ifname[IFNAMSIZ];
870
871 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
872 if (err < 0)
873 goto errout;
874
875 if (tb[IFLA_IFNAME])
876 nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
877 else
878 ifname[0] = '\0';
879
880 err = -EINVAL;
881 ifm = nlmsg_data(nlh);
882 if (ifm->ifi_index > 0)
883 dev = dev_get_by_index(ifm->ifi_index);
884 else if (tb[IFLA_IFNAME])
885 dev = dev_get_by_name(ifname);
886 else
887 goto errout;
888
889 if (dev == NULL) {
890 err = -ENODEV;
891 goto errout;
892 }
724 893
894 if (tb[IFLA_ADDRESS] &&
895 nla_len(tb[IFLA_ADDRESS]) < dev->addr_len)
896 goto errout_dev;
897
898 if (tb[IFLA_BROADCAST] &&
899 nla_len(tb[IFLA_BROADCAST]) < dev->addr_len)
900 goto errout_dev;
901
902 err = do_setlink(dev, ifm, tb, ifname, 0);
903errout_dev:
725 dev_put(dev); 904 dev_put(dev);
726errout: 905errout:
727 return err; 906 return err;
728} 907}
729 908
909static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
910{
911 const struct rtnl_link_ops *ops;
912 struct net_device *dev;
913 struct ifinfomsg *ifm;
914 char ifname[IFNAMSIZ];
915 struct nlattr *tb[IFLA_MAX+1];
916 int err;
917
918 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
919 if (err < 0)
920 return err;
921
922 if (tb[IFLA_IFNAME])
923 nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
924
925 ifm = nlmsg_data(nlh);
926 if (ifm->ifi_index > 0)
927 dev = __dev_get_by_index(ifm->ifi_index);
928 else if (tb[IFLA_IFNAME])
929 dev = __dev_get_by_name(ifname);
930 else
931 return -EINVAL;
932
933 if (!dev)
934 return -ENODEV;
935
936 ops = dev->rtnl_link_ops;
937 if (!ops)
938 return -EOPNOTSUPP;
939
940 ops->dellink(dev);
941 return 0;
942}
943
944static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
945{
946 const struct rtnl_link_ops *ops;
947 struct net_device *dev;
948 struct ifinfomsg *ifm;
949 char kind[MODULE_NAME_LEN];
950 char ifname[IFNAMSIZ];
951 struct nlattr *tb[IFLA_MAX+1];
952 struct nlattr *linkinfo[IFLA_INFO_MAX+1];
953 int err;
954
955replay:
956 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
957 if (err < 0)
958 return err;
959
960 if (tb[IFLA_IFNAME])
961 nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
962 else
963 ifname[0] = '\0';
964
965 ifm = nlmsg_data(nlh);
966 if (ifm->ifi_index > 0)
967 dev = __dev_get_by_index(ifm->ifi_index);
968 else if (ifname[0])
969 dev = __dev_get_by_name(ifname);
970 else
971 dev = NULL;
972
973 if (tb[IFLA_LINKINFO]) {
974 err = nla_parse_nested(linkinfo, IFLA_INFO_MAX,
975 tb[IFLA_LINKINFO], ifla_info_policy);
976 if (err < 0)
977 return err;
978 } else
979 memset(linkinfo, 0, sizeof(linkinfo));
980
981 if (linkinfo[IFLA_INFO_KIND]) {
982 nla_strlcpy(kind, linkinfo[IFLA_INFO_KIND], sizeof(kind));
983 ops = rtnl_link_ops_get(kind);
984 } else {
985 kind[0] = '\0';
986 ops = NULL;
987 }
988
989 if (1) {
990 struct nlattr *attr[ops ? ops->maxtype + 1 : 0], **data = NULL;
991
992 if (ops) {
993 if (ops->maxtype && linkinfo[IFLA_INFO_DATA]) {
994 err = nla_parse_nested(attr, ops->maxtype,
995 linkinfo[IFLA_INFO_DATA],
996 ops->policy);
997 if (err < 0)
998 return err;
999 data = attr;
1000 }
1001 if (ops->validate) {
1002 err = ops->validate(tb, data);
1003 if (err < 0)
1004 return err;
1005 }
1006 }
1007
1008 if (dev) {
1009 int modified = 0;
1010
1011 if (nlh->nlmsg_flags & NLM_F_EXCL)
1012 return -EEXIST;
1013 if (nlh->nlmsg_flags & NLM_F_REPLACE)
1014 return -EOPNOTSUPP;
1015
1016 if (linkinfo[IFLA_INFO_DATA]) {
1017 if (!ops || ops != dev->rtnl_link_ops ||
1018 !ops->changelink)
1019 return -EOPNOTSUPP;
1020
1021 err = ops->changelink(dev, tb, data);
1022 if (err < 0)
1023 return err;
1024 modified = 1;
1025 }
1026
1027 return do_setlink(dev, ifm, tb, ifname, modified);
1028 }
1029
1030 if (!(nlh->nlmsg_flags & NLM_F_CREATE))
1031 return -ENODEV;
1032
1033 if (ifm->ifi_index || ifm->ifi_flags || ifm->ifi_change)
1034 return -EOPNOTSUPP;
1035 if (tb[IFLA_MAP] || tb[IFLA_MASTER] || tb[IFLA_PROTINFO])
1036 return -EOPNOTSUPP;
1037
1038 if (!ops) {
1039#ifdef CONFIG_KMOD
1040 if (kind[0]) {
1041 __rtnl_unlock();
1042 request_module("rtnl-link-%s", kind);
1043 rtnl_lock();
1044 ops = rtnl_link_ops_get(kind);
1045 if (ops)
1046 goto replay;
1047 }
1048#endif
1049 return -EOPNOTSUPP;
1050 }
1051
1052 if (!ifname[0])
1053 snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind);
1054 dev = alloc_netdev(ops->priv_size, ifname, ops->setup);
1055 if (!dev)
1056 return -ENOMEM;
1057
1058 if (strchr(dev->name, '%')) {
1059 err = dev_alloc_name(dev, dev->name);
1060 if (err < 0)
1061 goto err_free;
1062 }
1063 dev->rtnl_link_ops = ops;
1064
1065 if (tb[IFLA_MTU])
1066 dev->mtu = nla_get_u32(tb[IFLA_MTU]);
1067 if (tb[IFLA_ADDRESS])
1068 memcpy(dev->dev_addr, nla_data(tb[IFLA_ADDRESS]),
1069 nla_len(tb[IFLA_ADDRESS]));
1070 if (tb[IFLA_BROADCAST])
1071 memcpy(dev->broadcast, nla_data(tb[IFLA_BROADCAST]),
1072 nla_len(tb[IFLA_BROADCAST]));
1073 if (tb[IFLA_TXQLEN])
1074 dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
1075 if (tb[IFLA_WEIGHT])
1076 dev->weight = nla_get_u32(tb[IFLA_WEIGHT]);
1077 if (tb[IFLA_OPERSTATE])
1078 set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
1079 if (tb[IFLA_LINKMODE])
1080 dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]);
1081
1082 if (ops->newlink)
1083 err = ops->newlink(dev, tb, data);
1084 else
1085 err = register_netdevice(dev);
1086err_free:
1087 if (err < 0)
1088 free_netdev(dev);
1089 return err;
1090 }
1091}
1092
730static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) 1093static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
731{ 1094{
732 struct ifinfomsg *ifm; 1095 struct ifinfomsg *ifm;
@@ -747,7 +1110,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
747 } else 1110 } else
748 return -EINVAL; 1111 return -EINVAL;
749 1112
750 nskb = nlmsg_new(if_nlmsg_size(), GFP_KERNEL); 1113 nskb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL);
751 if (nskb == NULL) { 1114 if (nskb == NULL) {
752 err = -ENOBUFS; 1115 err = -ENOBUFS;
753 goto errout; 1116 goto errout;
@@ -797,7 +1160,7 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
797 struct sk_buff *skb; 1160 struct sk_buff *skb;
798 int err = -ENOBUFS; 1161 int err = -ENOBUFS;
799 1162
800 skb = nlmsg_new(if_nlmsg_size(), GFP_KERNEL); 1163 skb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL);
801 if (skb == NULL) 1164 if (skb == NULL)
802 goto errout; 1165 goto errout;
803 1166
@@ -952,6 +1315,8 @@ void __init rtnetlink_init(void)
952 1315
953 rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink, rtnl_dump_ifinfo); 1316 rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink, rtnl_dump_ifinfo);
954 rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL); 1317 rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL);
1318 rtnl_register(PF_UNSPEC, RTM_NEWLINK, rtnl_newlink, NULL);
1319 rtnl_register(PF_UNSPEC, RTM_DELLINK, rtnl_dellink, NULL);
955 1320
956 rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all); 1321 rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all);
957 rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all); 1322 rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all);
@@ -960,6 +1325,7 @@ void __init rtnetlink_init(void)
960EXPORT_SYMBOL(__rta_fill); 1325EXPORT_SYMBOL(__rta_fill);
961EXPORT_SYMBOL(rtattr_strlcpy); 1326EXPORT_SYMBOL(rtattr_strlcpy);
962EXPORT_SYMBOL(rtattr_parse); 1327EXPORT_SYMBOL(rtattr_parse);
1328EXPORT_SYMBOL(__rtattr_parse_nested_compat);
963EXPORT_SYMBOL(rtnetlink_put_metrics); 1329EXPORT_SYMBOL(rtnetlink_put_metrics);
964EXPORT_SYMBOL(rtnl_lock); 1330EXPORT_SYMBOL(rtnl_lock);
965EXPORT_SYMBOL(rtnl_trylock); 1331EXPORT_SYMBOL(rtnl_trylock);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 3943c3ad9145..0583e8498f13 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -415,9 +415,11 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
415 C(csum); 415 C(csum);
416 C(local_df); 416 C(local_df);
417 n->cloned = 1; 417 n->cloned = 1;
418 n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len;
418 n->nohdr = 0; 419 n->nohdr = 0;
419 C(pkt_type); 420 C(pkt_type);
420 C(ip_summed); 421 C(ip_summed);
422 skb_copy_queue_mapping(n, skb);
421 C(priority); 423 C(priority);
422#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) 424#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
423 C(ipvs_property); 425 C(ipvs_property);
@@ -426,6 +428,10 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
426 n->destructor = NULL; 428 n->destructor = NULL;
427 C(mark); 429 C(mark);
428 __nf_copy(n, skb); 430 __nf_copy(n, skb);
431#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
432 defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
433 C(nf_trace);
434#endif
429#ifdef CONFIG_NET_SCHED 435#ifdef CONFIG_NET_SCHED
430 C(tc_index); 436 C(tc_index);
431#ifdef CONFIG_NET_CLS_ACT 437#ifdef CONFIG_NET_CLS_ACT
@@ -459,6 +465,7 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
459#endif 465#endif
460 new->sk = NULL; 466 new->sk = NULL;
461 new->dev = old->dev; 467 new->dev = old->dev;
468 skb_copy_queue_mapping(new, old);
462 new->priority = old->priority; 469 new->priority = old->priority;
463 new->protocol = old->protocol; 470 new->protocol = old->protocol;
464 new->dst = dst_clone(old->dst); 471 new->dst = dst_clone(old->dst);
@@ -482,6 +489,10 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
482 new->destructor = NULL; 489 new->destructor = NULL;
483 new->mark = old->mark; 490 new->mark = old->mark;
484 __nf_copy(new, old); 491 __nf_copy(new, old);
492#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
493 defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
494 new->nf_trace = old->nf_trace;
495#endif
485#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) 496#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
486 new->ipvs_property = old->ipvs_property; 497 new->ipvs_property = old->ipvs_property;
487#endif 498#endif
@@ -676,6 +687,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
676 skb->network_header += off; 687 skb->network_header += off;
677 skb->mac_header += off; 688 skb->mac_header += off;
678 skb->cloned = 0; 689 skb->cloned = 0;
690 skb->hdr_len = 0;
679 skb->nohdr = 0; 691 skb->nohdr = 0;
680 atomic_set(&skb_shinfo(skb)->dataref, 1); 692 atomic_set(&skb_shinfo(skb)->dataref, 1);
681 return 0; 693 return 0;
@@ -1930,6 +1942,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
1930 tail = nskb; 1942 tail = nskb;
1931 1943
1932 nskb->dev = skb->dev; 1944 nskb->dev = skb->dev;
1945 skb_copy_queue_mapping(nskb, skb);
1933 nskb->priority = skb->priority; 1946 nskb->priority = skb->priority;
1934 nskb->protocol = skb->protocol; 1947 nskb->protocol = skb->protocol;
1935 nskb->dst = dst_clone(skb->dst); 1948 nskb->dst = dst_clone(skb->dst);
diff --git a/net/core/sock.c b/net/core/sock.c
index c14ce0198d25..091032a250c7 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -210,7 +210,8 @@ static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen)
210 return -EDOM; 210 return -EDOM;
211 211
212 if (tv.tv_sec < 0) { 212 if (tv.tv_sec < 0) {
213 static int warned = 0; 213 static int warned __read_mostly;
214
214 *timeo_p = 0; 215 *timeo_p = 0;
215 if (warned < 10 && net_ratelimit()) 216 if (warned < 10 && net_ratelimit())
216 warned++; 217 warned++;
@@ -1851,46 +1852,15 @@ void proto_unregister(struct proto *prot)
1851EXPORT_SYMBOL(proto_unregister); 1852EXPORT_SYMBOL(proto_unregister);
1852 1853
1853#ifdef CONFIG_PROC_FS 1854#ifdef CONFIG_PROC_FS
1854static inline struct proto *__proto_head(void)
1855{
1856 return list_entry(proto_list.next, struct proto, node);
1857}
1858
1859static inline struct proto *proto_head(void)
1860{
1861 return list_empty(&proto_list) ? NULL : __proto_head();
1862}
1863
1864static inline struct proto *proto_next(struct proto *proto)
1865{
1866 return proto->node.next == &proto_list ? NULL :
1867 list_entry(proto->node.next, struct proto, node);
1868}
1869
1870static inline struct proto *proto_get_idx(loff_t pos)
1871{
1872 struct proto *proto;
1873 loff_t i = 0;
1874
1875 list_for_each_entry(proto, &proto_list, node)
1876 if (i++ == pos)
1877 goto out;
1878
1879 proto = NULL;
1880out:
1881 return proto;
1882}
1883
1884static void *proto_seq_start(struct seq_file *seq, loff_t *pos) 1855static void *proto_seq_start(struct seq_file *seq, loff_t *pos)
1885{ 1856{
1886 read_lock(&proto_list_lock); 1857 read_lock(&proto_list_lock);
1887 return *pos ? proto_get_idx(*pos - 1) : SEQ_START_TOKEN; 1858 return seq_list_start_head(&proto_list, *pos);
1888} 1859}
1889 1860
1890static void *proto_seq_next(struct seq_file *seq, void *v, loff_t *pos) 1861static void *proto_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1891{ 1862{
1892 ++*pos; 1863 return seq_list_next(v, &proto_list, pos);
1893 return v == SEQ_START_TOKEN ? proto_head() : proto_next(v);
1894} 1864}
1895 1865
1896static void proto_seq_stop(struct seq_file *seq, void *v) 1866static void proto_seq_stop(struct seq_file *seq, void *v)
@@ -1938,7 +1908,7 @@ static void proto_seq_printf(struct seq_file *seq, struct proto *proto)
1938 1908
1939static int proto_seq_show(struct seq_file *seq, void *v) 1909static int proto_seq_show(struct seq_file *seq, void *v)
1940{ 1910{
1941 if (v == SEQ_START_TOKEN) 1911 if (v == &proto_list)
1942 seq_printf(seq, "%-9s %-4s %-8s %-6s %-5s %-7s %-4s %-10s %s", 1912 seq_printf(seq, "%-9s %-4s %-8s %-6s %-5s %-7s %-4s %-10s %s",
1943 "protocol", 1913 "protocol",
1944 "size", 1914 "size",
@@ -1950,7 +1920,7 @@ static int proto_seq_show(struct seq_file *seq, void *v)
1950 "module", 1920 "module",
1951 "cl co di ac io in de sh ss gs se re sp bi br ha uh gp em\n"); 1921 "cl co di ac io in de sh ss gs se re sp bi br ha uh gp em\n");
1952 else 1922 else
1953 proto_seq_printf(seq, v); 1923 proto_seq_printf(seq, list_entry(v, struct proto, node));
1954 return 0; 1924 return 0;
1955} 1925}
1956 1926
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index ec7fa4d67f08..e91c2b9dc27b 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * net/dccp/ccids/ccid3.c 2 * net/dccp/ccids/ccid3.c
3 * 3 *
4 * Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand. 4 * Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
5 * Copyright (c) 2005-6 Ian McDonald <ian.mcdonald@jandi.co.nz> 5 * Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz>
6 * 6 *
7 * An implementation of the DCCP protocol 7 * An implementation of the DCCP protocol
8 * 8 *
@@ -49,7 +49,6 @@ static int ccid3_debug;
49 49
50static struct dccp_tx_hist *ccid3_tx_hist; 50static struct dccp_tx_hist *ccid3_tx_hist;
51static struct dccp_rx_hist *ccid3_rx_hist; 51static struct dccp_rx_hist *ccid3_rx_hist;
52static struct dccp_li_hist *ccid3_li_hist;
53 52
54/* 53/*
55 * Transmitter Half-Connection Routines 54 * Transmitter Half-Connection Routines
@@ -194,25 +193,20 @@ static inline void ccid3_hc_tx_update_s(struct ccid3_hc_tx_sock *hctx, int len)
194 * The algorithm is not applicable if RTT < 4 microseconds. 193 * The algorithm is not applicable if RTT < 4 microseconds.
195 */ 194 */
196static inline void ccid3_hc_tx_update_win_count(struct ccid3_hc_tx_sock *hctx, 195static inline void ccid3_hc_tx_update_win_count(struct ccid3_hc_tx_sock *hctx,
197 struct timeval *now) 196 ktime_t now)
198{ 197{
199 suseconds_t delta;
200 u32 quarter_rtts; 198 u32 quarter_rtts;
201 199
202 if (unlikely(hctx->ccid3hctx_rtt < 4)) /* avoid divide-by-zero */ 200 if (unlikely(hctx->ccid3hctx_rtt < 4)) /* avoid divide-by-zero */
203 return; 201 return;
204 202
205 delta = timeval_delta(now, &hctx->ccid3hctx_t_last_win_count); 203 quarter_rtts = ktime_us_delta(now, hctx->ccid3hctx_t_last_win_count);
206 DCCP_BUG_ON(delta < 0); 204 quarter_rtts /= hctx->ccid3hctx_rtt / 4;
207
208 quarter_rtts = (u32)delta / (hctx->ccid3hctx_rtt / 4);
209 205
210 if (quarter_rtts > 0) { 206 if (quarter_rtts > 0) {
211 hctx->ccid3hctx_t_last_win_count = *now; 207 hctx->ccid3hctx_t_last_win_count = now;
212 hctx->ccid3hctx_last_win_count += min_t(u32, quarter_rtts, 5); 208 hctx->ccid3hctx_last_win_count += min_t(u32, quarter_rtts, 5);
213 hctx->ccid3hctx_last_win_count &= 0xF; /* mod 16 */ 209 hctx->ccid3hctx_last_win_count &= 0xF; /* mod 16 */
214
215 ccid3_pr_debug("now at %#X\n", hctx->ccid3hctx_last_win_count);
216 } 210 }
217} 211}
218 212
@@ -312,8 +306,8 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
312{ 306{
313 struct dccp_sock *dp = dccp_sk(sk); 307 struct dccp_sock *dp = dccp_sk(sk);
314 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 308 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
315 struct timeval now; 309 ktime_t now = ktime_get_real();
316 suseconds_t delay; 310 s64 delay;
317 311
318 BUG_ON(hctx == NULL); 312 BUG_ON(hctx == NULL);
319 313
@@ -325,8 +319,6 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
325 if (unlikely(skb->len == 0)) 319 if (unlikely(skb->len == 0))
326 return -EBADMSG; 320 return -EBADMSG;
327 321
328 dccp_timestamp(sk, &now);
329
330 switch (hctx->ccid3hctx_state) { 322 switch (hctx->ccid3hctx_state) {
331 case TFRC_SSTATE_NO_SENT: 323 case TFRC_SSTATE_NO_SENT:
332 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 324 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
@@ -349,7 +341,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
349 ccid3_pr_debug("SYN RTT = %uus\n", dp->dccps_syn_rtt); 341 ccid3_pr_debug("SYN RTT = %uus\n", dp->dccps_syn_rtt);
350 hctx->ccid3hctx_rtt = dp->dccps_syn_rtt; 342 hctx->ccid3hctx_rtt = dp->dccps_syn_rtt;
351 hctx->ccid3hctx_x = rfc3390_initial_rate(sk); 343 hctx->ccid3hctx_x = rfc3390_initial_rate(sk);
352 hctx->ccid3hctx_t_ld = now; 344 hctx->ccid3hctx_t_ld = ktime_to_timeval(now);
353 } else { 345 } else {
354 /* Sender does not have RTT sample: X = MSS/second */ 346 /* Sender does not have RTT sample: X = MSS/second */
355 hctx->ccid3hctx_x = dp->dccps_mss_cache; 347 hctx->ccid3hctx_x = dp->dccps_mss_cache;
@@ -361,7 +353,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
361 break; 353 break;
362 case TFRC_SSTATE_NO_FBACK: 354 case TFRC_SSTATE_NO_FBACK:
363 case TFRC_SSTATE_FBACK: 355 case TFRC_SSTATE_FBACK:
364 delay = timeval_delta(&hctx->ccid3hctx_t_nom, &now); 356 delay = ktime_us_delta(hctx->ccid3hctx_t_nom, now);
365 ccid3_pr_debug("delay=%ld\n", (long)delay); 357 ccid3_pr_debug("delay=%ld\n", (long)delay);
366 /* 358 /*
367 * Scheduling of packet transmissions [RFC 3448, 4.6] 359 * Scheduling of packet transmissions [RFC 3448, 4.6]
@@ -371,10 +363,10 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
371 * else 363 * else
372 * // send the packet in (t_nom - t_now) milliseconds. 364 * // send the packet in (t_nom - t_now) milliseconds.
373 */ 365 */
374 if (delay - (suseconds_t)hctx->ccid3hctx_delta >= 0) 366 if (delay - (s64)hctx->ccid3hctx_delta >= 1000)
375 return delay / 1000L; 367 return (u32)delay / 1000L;
376 368
377 ccid3_hc_tx_update_win_count(hctx, &now); 369 ccid3_hc_tx_update_win_count(hctx, now);
378 break; 370 break;
379 case TFRC_SSTATE_TERM: 371 case TFRC_SSTATE_TERM:
380 DCCP_BUG("%s(%p) - Illegal state TERM", dccp_role(sk), sk); 372 DCCP_BUG("%s(%p) - Illegal state TERM", dccp_role(sk), sk);
@@ -387,8 +379,8 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
387 hctx->ccid3hctx_idle = 0; 379 hctx->ccid3hctx_idle = 0;
388 380
389 /* set the nominal send time for the next following packet */ 381 /* set the nominal send time for the next following packet */
390 timeval_add_usecs(&hctx->ccid3hctx_t_nom, hctx->ccid3hctx_t_ipi); 382 hctx->ccid3hctx_t_nom = ktime_add_us(hctx->ccid3hctx_t_nom,
391 383 hctx->ccid3hctx_t_ipi);
392 return 0; 384 return 0;
393} 385}
394 386
@@ -819,154 +811,6 @@ static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
819 return 0; 811 return 0;
820} 812}
821 813
822/* calculate first loss interval
823 *
824 * returns estimated loss interval in usecs */
825
826static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
827{
828 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
829 struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
830 u32 x_recv, p;
831 suseconds_t rtt, delta;
832 struct timeval tstamp = { 0, };
833 int interval = 0;
834 int win_count = 0;
835 int step = 0;
836 u64 fval;
837
838 list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
839 dccphrx_node) {
840 if (dccp_rx_hist_entry_data_packet(entry)) {
841 tail = entry;
842
843 switch (step) {
844 case 0:
845 tstamp = entry->dccphrx_tstamp;
846 win_count = entry->dccphrx_ccval;
847 step = 1;
848 break;
849 case 1:
850 interval = win_count - entry->dccphrx_ccval;
851 if (interval < 0)
852 interval += TFRC_WIN_COUNT_LIMIT;
853 if (interval > 4)
854 goto found;
855 break;
856 }
857 }
858 }
859
860 if (unlikely(step == 0)) {
861 DCCP_WARN("%s(%p), packet history has no data packets!\n",
862 dccp_role(sk), sk);
863 return ~0;
864 }
865
866 if (unlikely(interval == 0)) {
867 DCCP_WARN("%s(%p), Could not find a win_count interval > 0."
868 "Defaulting to 1\n", dccp_role(sk), sk);
869 interval = 1;
870 }
871found:
872 if (!tail) {
873 DCCP_CRIT("tail is null\n");
874 return ~0;
875 }
876
877 delta = timeval_delta(&tstamp, &tail->dccphrx_tstamp);
878 DCCP_BUG_ON(delta < 0);
879
880 rtt = delta * 4 / interval;
881 ccid3_pr_debug("%s(%p), approximated RTT to %dus\n",
882 dccp_role(sk), sk, (int)rtt);
883
884 /*
885 * Determine the length of the first loss interval via inverse lookup.
886 * Assume that X_recv can be computed by the throughput equation
887 * s
888 * X_recv = --------
889 * R * fval
890 * Find some p such that f(p) = fval; return 1/p [RFC 3448, 6.3.1].
891 */
892 if (rtt == 0) { /* would result in divide-by-zero */
893 DCCP_WARN("RTT==0\n");
894 return ~0;
895 }
896
897 dccp_timestamp(sk, &tstamp);
898 delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback);
899 DCCP_BUG_ON(delta <= 0);
900
901 x_recv = scaled_div32(hcrx->ccid3hcrx_bytes_recv, delta);
902 if (x_recv == 0) { /* would also trigger divide-by-zero */
903 DCCP_WARN("X_recv==0\n");
904 if ((x_recv = hcrx->ccid3hcrx_x_recv) == 0) {
905 DCCP_BUG("stored value of X_recv is zero");
906 return ~0;
907 }
908 }
909
910 fval = scaled_div(hcrx->ccid3hcrx_s, rtt);
911 fval = scaled_div32(fval, x_recv);
912 p = tfrc_calc_x_reverse_lookup(fval);
913
914 ccid3_pr_debug("%s(%p), receive rate=%u bytes/s, implied "
915 "loss rate=%u\n", dccp_role(sk), sk, x_recv, p);
916
917 if (p == 0)
918 return ~0;
919 else
920 return 1000000 / p;
921}
922
923static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
924{
925 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
926 struct dccp_li_hist_entry *head;
927 u64 seq_temp;
928
929 if (list_empty(&hcrx->ccid3hcrx_li_hist)) {
930 if (!dccp_li_hist_interval_new(ccid3_li_hist,
931 &hcrx->ccid3hcrx_li_hist, seq_loss, win_loss))
932 return;
933
934 head = list_entry(hcrx->ccid3hcrx_li_hist.next,
935 struct dccp_li_hist_entry, dccplih_node);
936 head->dccplih_interval = ccid3_hc_rx_calc_first_li(sk);
937 } else {
938 struct dccp_li_hist_entry *entry;
939 struct list_head *tail;
940
941 head = list_entry(hcrx->ccid3hcrx_li_hist.next,
942 struct dccp_li_hist_entry, dccplih_node);
943 /* FIXME win count check removed as was wrong */
944 /* should make this check with receive history */
945 /* and compare there as per section 10.2 of RFC4342 */
946
947 /* new loss event detected */
948 /* calculate last interval length */
949 seq_temp = dccp_delta_seqno(head->dccplih_seqno, seq_loss);
950 entry = dccp_li_hist_entry_new(ccid3_li_hist, GFP_ATOMIC);
951
952 if (entry == NULL) {
953 DCCP_BUG("out of memory - can not allocate entry");
954 return;
955 }
956
957 list_add(&entry->dccplih_node, &hcrx->ccid3hcrx_li_hist);
958
959 tail = hcrx->ccid3hcrx_li_hist.prev;
960 list_del(tail);
961 kmem_cache_free(ccid3_li_hist->dccplih_slab, tail);
962
963 /* Create the newest interval */
964 entry->dccplih_seqno = seq_loss;
965 entry->dccplih_interval = seq_temp;
966 entry->dccplih_win_count = win_loss;
967 }
968}
969
970static int ccid3_hc_rx_detect_loss(struct sock *sk, 814static int ccid3_hc_rx_detect_loss(struct sock *sk,
971 struct dccp_rx_hist_entry *packet) 815 struct dccp_rx_hist_entry *packet)
972{ 816{
@@ -992,8 +836,15 @@ static int ccid3_hc_rx_detect_loss(struct sock *sk,
992 while (dccp_delta_seqno(hcrx->ccid3hcrx_seqno_nonloss, seqno) 836 while (dccp_delta_seqno(hcrx->ccid3hcrx_seqno_nonloss, seqno)
993 > TFRC_RECV_NUM_LATE_LOSS) { 837 > TFRC_RECV_NUM_LATE_LOSS) {
994 loss = 1; 838 loss = 1;
995 ccid3_hc_rx_update_li(sk, hcrx->ccid3hcrx_seqno_nonloss, 839 dccp_li_update_li(sk,
996 hcrx->ccid3hcrx_ccval_nonloss); 840 &hcrx->ccid3hcrx_li_hist,
841 &hcrx->ccid3hcrx_hist,
842 &hcrx->ccid3hcrx_tstamp_last_feedback,
843 hcrx->ccid3hcrx_s,
844 hcrx->ccid3hcrx_bytes_recv,
845 hcrx->ccid3hcrx_x_recv,
846 hcrx->ccid3hcrx_seqno_nonloss,
847 hcrx->ccid3hcrx_ccval_nonloss);
997 tmp_seqno = hcrx->ccid3hcrx_seqno_nonloss; 848 tmp_seqno = hcrx->ccid3hcrx_seqno_nonloss;
998 dccp_inc_seqno(&tmp_seqno); 849 dccp_inc_seqno(&tmp_seqno);
999 hcrx->ccid3hcrx_seqno_nonloss = tmp_seqno; 850 hcrx->ccid3hcrx_seqno_nonloss = tmp_seqno;
@@ -1152,7 +1003,7 @@ static void ccid3_hc_rx_exit(struct sock *sk)
1152 dccp_rx_hist_purge(ccid3_rx_hist, &hcrx->ccid3hcrx_hist); 1003 dccp_rx_hist_purge(ccid3_rx_hist, &hcrx->ccid3hcrx_hist);
1153 1004
1154 /* Empty loss interval history */ 1005 /* Empty loss interval history */
1155 dccp_li_hist_purge(ccid3_li_hist, &hcrx->ccid3hcrx_li_hist); 1006 dccp_li_hist_purge(&hcrx->ccid3hcrx_li_hist);
1156} 1007}
1157 1008
1158static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info) 1009static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
@@ -1236,19 +1087,12 @@ static __init int ccid3_module_init(void)
1236 if (ccid3_tx_hist == NULL) 1087 if (ccid3_tx_hist == NULL)
1237 goto out_free_rx; 1088 goto out_free_rx;
1238 1089
1239 ccid3_li_hist = dccp_li_hist_new("ccid3");
1240 if (ccid3_li_hist == NULL)
1241 goto out_free_tx;
1242
1243 rc = ccid_register(&ccid3); 1090 rc = ccid_register(&ccid3);
1244 if (rc != 0) 1091 if (rc != 0)
1245 goto out_free_loss_interval_history; 1092 goto out_free_tx;
1246out: 1093out:
1247 return rc; 1094 return rc;
1248 1095
1249out_free_loss_interval_history:
1250 dccp_li_hist_delete(ccid3_li_hist);
1251 ccid3_li_hist = NULL;
1252out_free_tx: 1096out_free_tx:
1253 dccp_tx_hist_delete(ccid3_tx_hist); 1097 dccp_tx_hist_delete(ccid3_tx_hist);
1254 ccid3_tx_hist = NULL; 1098 ccid3_tx_hist = NULL;
@@ -1271,10 +1115,6 @@ static __exit void ccid3_module_exit(void)
1271 dccp_rx_hist_delete(ccid3_rx_hist); 1115 dccp_rx_hist_delete(ccid3_rx_hist);
1272 ccid3_rx_hist = NULL; 1116 ccid3_rx_hist = NULL;
1273 } 1117 }
1274 if (ccid3_li_hist != NULL) {
1275 dccp_li_hist_delete(ccid3_li_hist);
1276 ccid3_li_hist = NULL;
1277 }
1278} 1118}
1279module_exit(ccid3_module_exit); 1119module_exit(ccid3_module_exit);
1280 1120
diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h
index 8d31b389c19c..51d4b804e334 100644
--- a/net/dccp/ccids/ccid3.h
+++ b/net/dccp/ccids/ccid3.h
@@ -36,6 +36,7 @@
36#ifndef _DCCP_CCID3_H_ 36#ifndef _DCCP_CCID3_H_
37#define _DCCP_CCID3_H_ 37#define _DCCP_CCID3_H_
38 38
39#include <linux/ktime.h>
39#include <linux/list.h> 40#include <linux/list.h>
40#include <linux/time.h> 41#include <linux/time.h>
41#include <linux/types.h> 42#include <linux/types.h>
@@ -108,10 +109,10 @@ struct ccid3_hc_tx_sock {
108 enum ccid3_hc_tx_states ccid3hctx_state:8; 109 enum ccid3_hc_tx_states ccid3hctx_state:8;
109 u8 ccid3hctx_last_win_count; 110 u8 ccid3hctx_last_win_count;
110 u8 ccid3hctx_idle; 111 u8 ccid3hctx_idle;
111 struct timeval ccid3hctx_t_last_win_count; 112 ktime_t ccid3hctx_t_last_win_count;
112 struct timer_list ccid3hctx_no_feedback_timer; 113 struct timer_list ccid3hctx_no_feedback_timer;
113 struct timeval ccid3hctx_t_ld; 114 struct timeval ccid3hctx_t_ld;
114 struct timeval ccid3hctx_t_nom; 115 ktime_t ccid3hctx_t_nom;
115 u32 ccid3hctx_delta; 116 u32 ccid3hctx_delta;
116 struct list_head ccid3hctx_hist; 117 struct list_head ccid3hctx_hist;
117 struct ccid3_options_received ccid3hctx_options_received; 118 struct ccid3_options_received ccid3hctx_options_received;
diff --git a/net/dccp/ccids/lib/loss_interval.c b/net/dccp/ccids/lib/loss_interval.c
index 372d7e75cdd8..515225f3a464 100644
--- a/net/dccp/ccids/lib/loss_interval.c
+++ b/net/dccp/ccids/lib/loss_interval.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * net/dccp/ccids/lib/loss_interval.c 2 * net/dccp/ccids/lib/loss_interval.c
3 * 3 *
4 * Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand. 4 * Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
5 * Copyright (c) 2005-6 Ian McDonald <ian.mcdonald@jandi.co.nz> 5 * Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz>
6 * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br> 6 * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
@@ -15,58 +15,38 @@
15#include <net/sock.h> 15#include <net/sock.h>
16#include "../../dccp.h" 16#include "../../dccp.h"
17#include "loss_interval.h" 17#include "loss_interval.h"
18#include "packet_history.h"
19#include "tfrc.h"
18 20
19struct dccp_li_hist *dccp_li_hist_new(const char *name) 21#define DCCP_LI_HIST_IVAL_F_LENGTH 8
20{
21 struct dccp_li_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC);
22 static const char dccp_li_hist_mask[] = "li_hist_%s";
23 char *slab_name;
24
25 if (hist == NULL)
26 goto out;
27
28 slab_name = kmalloc(strlen(name) + sizeof(dccp_li_hist_mask) - 1,
29 GFP_ATOMIC);
30 if (slab_name == NULL)
31 goto out_free_hist;
32
33 sprintf(slab_name, dccp_li_hist_mask, name);
34 hist->dccplih_slab = kmem_cache_create(slab_name,
35 sizeof(struct dccp_li_hist_entry),
36 0, SLAB_HWCACHE_ALIGN,
37 NULL, NULL);
38 if (hist->dccplih_slab == NULL)
39 goto out_free_slab_name;
40out:
41 return hist;
42out_free_slab_name:
43 kfree(slab_name);
44out_free_hist:
45 kfree(hist);
46 hist = NULL;
47 goto out;
48}
49 22
50EXPORT_SYMBOL_GPL(dccp_li_hist_new); 23struct dccp_li_hist_entry {
24 struct list_head dccplih_node;
25 u64 dccplih_seqno:48,
26 dccplih_win_count:4;
27 u32 dccplih_interval;
28};
51 29
52void dccp_li_hist_delete(struct dccp_li_hist *hist) 30static struct kmem_cache *dccp_li_cachep __read_mostly;
53{
54 const char* name = kmem_cache_name(hist->dccplih_slab);
55 31
56 kmem_cache_destroy(hist->dccplih_slab); 32static inline struct dccp_li_hist_entry *dccp_li_hist_entry_new(const gfp_t prio)
57 kfree(name); 33{
58 kfree(hist); 34 return kmem_cache_alloc(dccp_li_cachep, prio);
59} 35}
60 36
61EXPORT_SYMBOL_GPL(dccp_li_hist_delete); 37static inline void dccp_li_hist_entry_delete(struct dccp_li_hist_entry *entry)
38{
39 if (entry != NULL)
40 kmem_cache_free(dccp_li_cachep, entry);
41}
62 42
63void dccp_li_hist_purge(struct dccp_li_hist *hist, struct list_head *list) 43void dccp_li_hist_purge(struct list_head *list)
64{ 44{
65 struct dccp_li_hist_entry *entry, *next; 45 struct dccp_li_hist_entry *entry, *next;
66 46
67 list_for_each_entry_safe(entry, next, list, dccplih_node) { 47 list_for_each_entry_safe(entry, next, list, dccplih_node) {
68 list_del_init(&entry->dccplih_node); 48 list_del_init(&entry->dccplih_node);
69 kmem_cache_free(hist->dccplih_slab, entry); 49 kmem_cache_free(dccp_li_cachep, entry);
70 } 50 }
71} 51}
72 52
@@ -118,16 +98,16 @@ u32 dccp_li_hist_calc_i_mean(struct list_head *list)
118 98
119EXPORT_SYMBOL_GPL(dccp_li_hist_calc_i_mean); 99EXPORT_SYMBOL_GPL(dccp_li_hist_calc_i_mean);
120 100
121int dccp_li_hist_interval_new(struct dccp_li_hist *hist, 101static int dccp_li_hist_interval_new(struct list_head *list,
122 struct list_head *list, const u64 seq_loss, const u8 win_loss) 102 const u64 seq_loss, const u8 win_loss)
123{ 103{
124 struct dccp_li_hist_entry *entry; 104 struct dccp_li_hist_entry *entry;
125 int i; 105 int i;
126 106
127 for (i = 0; i < DCCP_LI_HIST_IVAL_F_LENGTH; i++) { 107 for (i = 0; i < DCCP_LI_HIST_IVAL_F_LENGTH; i++) {
128 entry = dccp_li_hist_entry_new(hist, GFP_ATOMIC); 108 entry = dccp_li_hist_entry_new(GFP_ATOMIC);
129 if (entry == NULL) { 109 if (entry == NULL) {
130 dccp_li_hist_purge(hist, list); 110 dccp_li_hist_purge(list);
131 DCCP_BUG("loss interval list entry is NULL"); 111 DCCP_BUG("loss interval list entry is NULL");
132 return 0; 112 return 0;
133 } 113 }
@@ -140,4 +120,176 @@ int dccp_li_hist_interval_new(struct dccp_li_hist *hist,
140 return 1; 120 return 1;
141} 121}
142 122
143EXPORT_SYMBOL_GPL(dccp_li_hist_interval_new); 123/* calculate first loss interval
124 *
125 * returns estimated loss interval in usecs */
126static u32 dccp_li_calc_first_li(struct sock *sk,
127 struct list_head *hist_list,
128 struct timeval *last_feedback,
129 u16 s, u32 bytes_recv,
130 u32 previous_x_recv)
131{
132 struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
133 u32 x_recv, p;
134 suseconds_t rtt, delta;
135 struct timeval tstamp = { 0, 0 };
136 int interval = 0;
137 int win_count = 0;
138 int step = 0;
139 u64 fval;
140
141 list_for_each_entry_safe(entry, next, hist_list, dccphrx_node) {
142 if (dccp_rx_hist_entry_data_packet(entry)) {
143 tail = entry;
144
145 switch (step) {
146 case 0:
147 tstamp = entry->dccphrx_tstamp;
148 win_count = entry->dccphrx_ccval;
149 step = 1;
150 break;
151 case 1:
152 interval = win_count - entry->dccphrx_ccval;
153 if (interval < 0)
154 interval += TFRC_WIN_COUNT_LIMIT;
155 if (interval > 4)
156 goto found;
157 break;
158 }
159 }
160 }
161
162 if (unlikely(step == 0)) {
163 DCCP_WARN("%s(%p), packet history has no data packets!\n",
164 dccp_role(sk), sk);
165 return ~0;
166 }
167
168 if (unlikely(interval == 0)) {
169 DCCP_WARN("%s(%p), Could not find a win_count interval > 0."
170 "Defaulting to 1\n", dccp_role(sk), sk);
171 interval = 1;
172 }
173found:
174 if (!tail) {
175 DCCP_CRIT("tail is null\n");
176 return ~0;
177 }
178
179 delta = timeval_delta(&tstamp, &tail->dccphrx_tstamp);
180 DCCP_BUG_ON(delta < 0);
181
182 rtt = delta * 4 / interval;
183 dccp_pr_debug("%s(%p), approximated RTT to %dus\n",
184 dccp_role(sk), sk, (int)rtt);
185
186 /*
187 * Determine the length of the first loss interval via inverse lookup.
188 * Assume that X_recv can be computed by the throughput equation
189 * s
190 * X_recv = --------
191 * R * fval
192 * Find some p such that f(p) = fval; return 1/p [RFC 3448, 6.3.1].
193 */
194 if (rtt == 0) { /* would result in divide-by-zero */
195 DCCP_WARN("RTT==0\n");
196 return ~0;
197 }
198
199 dccp_timestamp(sk, &tstamp);
200 delta = timeval_delta(&tstamp, last_feedback);
201 DCCP_BUG_ON(delta <= 0);
202
203 x_recv = scaled_div32(bytes_recv, delta);
204 if (x_recv == 0) { /* would also trigger divide-by-zero */
205 DCCP_WARN("X_recv==0\n");
206 if (previous_x_recv == 0) {
207 DCCP_BUG("stored value of X_recv is zero");
208 return ~0;
209 }
210 x_recv = previous_x_recv;
211 }
212
213 fval = scaled_div(s, rtt);
214 fval = scaled_div32(fval, x_recv);
215 p = tfrc_calc_x_reverse_lookup(fval);
216
217 dccp_pr_debug("%s(%p), receive rate=%u bytes/s, implied "
218 "loss rate=%u\n", dccp_role(sk), sk, x_recv, p);
219
220 if (p == 0)
221 return ~0;
222 else
223 return 1000000 / p;
224}
225
226void dccp_li_update_li(struct sock *sk,
227 struct list_head *li_hist_list,
228 struct list_head *hist_list,
229 struct timeval *last_feedback, u16 s, u32 bytes_recv,
230 u32 previous_x_recv, u64 seq_loss, u8 win_loss)
231{
232 struct dccp_li_hist_entry *head;
233 u64 seq_temp;
234
235 if (list_empty(li_hist_list)) {
236 if (!dccp_li_hist_interval_new(li_hist_list, seq_loss,
237 win_loss))
238 return;
239
240 head = list_entry(li_hist_list->next, struct dccp_li_hist_entry,
241 dccplih_node);
242 head->dccplih_interval = dccp_li_calc_first_li(sk, hist_list,
243 last_feedback,
244 s, bytes_recv,
245 previous_x_recv);
246 } else {
247 struct dccp_li_hist_entry *entry;
248 struct list_head *tail;
249
250 head = list_entry(li_hist_list->next, struct dccp_li_hist_entry,
251 dccplih_node);
252 /* FIXME win count check removed as was wrong */
253 /* should make this check with receive history */
254 /* and compare there as per section 10.2 of RFC4342 */
255
256 /* new loss event detected */
257 /* calculate last interval length */
258 seq_temp = dccp_delta_seqno(head->dccplih_seqno, seq_loss);
259 entry = dccp_li_hist_entry_new(GFP_ATOMIC);
260
261 if (entry == NULL) {
262 DCCP_BUG("out of memory - can not allocate entry");
263 return;
264 }
265
266 list_add(&entry->dccplih_node, li_hist_list);
267
268 tail = li_hist_list->prev;
269 list_del(tail);
270 kmem_cache_free(dccp_li_cachep, tail);
271
272 /* Create the newest interval */
273 entry->dccplih_seqno = seq_loss;
274 entry->dccplih_interval = seq_temp;
275 entry->dccplih_win_count = win_loss;
276 }
277}
278
279EXPORT_SYMBOL_GPL(dccp_li_update_li);
280
281static __init int dccp_li_init(void)
282{
283 dccp_li_cachep = kmem_cache_create("dccp_li_hist",
284 sizeof(struct dccp_li_hist_entry),
285 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
286 return dccp_li_cachep == NULL ? -ENOBUFS : 0;
287}
288
289static __exit void dccp_li_exit(void)
290{
291 kmem_cache_destroy(dccp_li_cachep);
292}
293
294module_init(dccp_li_init);
295module_exit(dccp_li_exit);
diff --git a/net/dccp/ccids/lib/loss_interval.h b/net/dccp/ccids/lib/loss_interval.h
index eb257014dd74..906c806d6d9d 100644
--- a/net/dccp/ccids/lib/loss_interval.h
+++ b/net/dccp/ccids/lib/loss_interval.h
@@ -3,8 +3,8 @@
3/* 3/*
4 * net/dccp/ccids/lib/loss_interval.h 4 * net/dccp/ccids/lib/loss_interval.h
5 * 5 *
6 * Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand. 6 * Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
7 * Copyright (c) 2005 Ian McDonald <ian.mcdonald@jandi.co.nz> 7 * Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz>
8 * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br> 8 * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
@@ -14,44 +14,16 @@
14 */ 14 */
15 15
16#include <linux/list.h> 16#include <linux/list.h>
17#include <linux/slab.h>
18#include <linux/time.h> 17#include <linux/time.h>
19 18
20#define DCCP_LI_HIST_IVAL_F_LENGTH 8 19extern void dccp_li_hist_purge(struct list_head *list);
21
22struct dccp_li_hist {
23 struct kmem_cache *dccplih_slab;
24};
25
26extern struct dccp_li_hist *dccp_li_hist_new(const char *name);
27extern void dccp_li_hist_delete(struct dccp_li_hist *hist);
28
29struct dccp_li_hist_entry {
30 struct list_head dccplih_node;
31 u64 dccplih_seqno:48,
32 dccplih_win_count:4;
33 u32 dccplih_interval;
34};
35
36static inline struct dccp_li_hist_entry *
37 dccp_li_hist_entry_new(struct dccp_li_hist *hist,
38 const gfp_t prio)
39{
40 return kmem_cache_alloc(hist->dccplih_slab, prio);
41}
42
43static inline void dccp_li_hist_entry_delete(struct dccp_li_hist *hist,
44 struct dccp_li_hist_entry *entry)
45{
46 if (entry != NULL)
47 kmem_cache_free(hist->dccplih_slab, entry);
48}
49
50extern void dccp_li_hist_purge(struct dccp_li_hist *hist,
51 struct list_head *list);
52 20
53extern u32 dccp_li_hist_calc_i_mean(struct list_head *list); 21extern u32 dccp_li_hist_calc_i_mean(struct list_head *list);
54 22
55extern int dccp_li_hist_interval_new(struct dccp_li_hist *hist, 23extern void dccp_li_update_li(struct sock *sk,
56 struct list_head *list, const u64 seq_loss, const u8 win_loss); 24 struct list_head *li_hist_list,
25 struct list_head *hist_list,
26 struct timeval *last_feedback, u16 s,
27 u32 bytes_recv, u32 previous_x_recv,
28 u64 seq_loss, u8 win_loss);
57#endif /* _DCCP_LI_HIST_ */ 29#endif /* _DCCP_LI_HIST_ */
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index d8ad27bfe01a..e2d74cd7eeeb 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -184,7 +184,7 @@ DECLARE_SNMP_STAT(struct dccp_mib, dccp_statistics);
184/* 184/*
185 * Checksumming routines 185 * Checksumming routines
186 */ 186 */
187static inline int dccp_csum_coverage(const struct sk_buff *skb) 187static inline unsigned int dccp_csum_coverage(const struct sk_buff *skb)
188{ 188{
189 const struct dccp_hdr* dh = dccp_hdr(skb); 189 const struct dccp_hdr* dh = dccp_hdr(skb);
190 190
@@ -195,7 +195,7 @@ static inline int dccp_csum_coverage(const struct sk_buff *skb)
195 195
196static inline void dccp_csum_outgoing(struct sk_buff *skb) 196static inline void dccp_csum_outgoing(struct sk_buff *skb)
197{ 197{
198 int cov = dccp_csum_coverage(skb); 198 unsigned int cov = dccp_csum_coverage(skb);
199 199
200 if (cov >= skb->len) 200 if (cov >= skb->len)
201 dccp_hdr(skb)->dccph_cscov = 0; 201 dccp_hdr(skb)->dccph_cscov = 0;
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 31737cdf156a..b158c661867b 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -253,17 +253,6 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
253 253
254 if (dst == NULL) { 254 if (dst == NULL) {
255 opt = np->opt; 255 opt = np->opt;
256 if (opt == NULL &&
257 np->rxopt.bits.osrcrt == 2 &&
258 ireq6->pktopts) {
259 struct sk_buff *pktopts = ireq6->pktopts;
260 struct inet6_skb_parm *rxopt = IP6CB(pktopts);
261
262 if (rxopt->srcrt)
263 opt = ipv6_invert_rthdr(sk,
264 (struct ipv6_rt_hdr *)(skb_network_header(pktopts) +
265 rxopt->srcrt));
266 }
267 256
268 if (opt != NULL && opt->srcrt != NULL) { 257 if (opt != NULL && opt->srcrt != NULL) {
269 const struct rt0_hdr *rt0 = (struct rt0_hdr *)opt->srcrt; 258 const struct rt0_hdr *rt0 = (struct rt0_hdr *)opt->srcrt;
@@ -570,15 +559,6 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
570 if (sk_acceptq_is_full(sk)) 559 if (sk_acceptq_is_full(sk))
571 goto out_overflow; 560 goto out_overflow;
572 561
573 if (np->rxopt.bits.osrcrt == 2 && opt == NULL && ireq6->pktopts) {
574 const struct inet6_skb_parm *rxopt = IP6CB(ireq6->pktopts);
575
576 if (rxopt->srcrt)
577 opt = ipv6_invert_rthdr(sk,
578 (struct ipv6_rt_hdr *)(skb_network_header(ireq6->pktopts) +
579 rxopt->srcrt));
580 }
581
582 if (dst == NULL) { 562 if (dst == NULL) {
583 struct in6_addr *final_p = NULL, final; 563 struct in6_addr *final_p = NULL, final;
584 struct flowi fl; 564 struct flowi fl;
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index bfa910b6ad25..ed76d4aab4a9 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -2304,7 +2304,7 @@ static int dn_socket_seq_show(struct seq_file *seq, void *v)
2304 return 0; 2304 return 0;
2305} 2305}
2306 2306
2307static struct seq_operations dn_socket_seq_ops = { 2307static const struct seq_operations dn_socket_seq_ops = {
2308 .start = dn_socket_seq_start, 2308 .start = dn_socket_seq_start,
2309 .next = dn_socket_seq_next, 2309 .next = dn_socket_seq_next,
2310 .stop = dn_socket_seq_stop, 2310 .stop = dn_socket_seq_stop,
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index ab41c1879fd4..fa6604fcf0e7 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -461,7 +461,6 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa)
461 if (ifa->ifa_local != dn_eth2dn(dev->dev_addr)) { 461 if (ifa->ifa_local != dn_eth2dn(dev->dev_addr)) {
462 dn_dn2eth(mac_addr, ifa->ifa_local); 462 dn_dn2eth(mac_addr, ifa->ifa_local);
463 dev_mc_add(dev, mac_addr, ETH_ALEN, 0); 463 dev_mc_add(dev, mac_addr, ETH_ALEN, 0);
464 dev_mc_upload(dev);
465 } 464 }
466 } 465 }
467 466
@@ -1064,8 +1063,6 @@ static int dn_eth_up(struct net_device *dev)
1064 else 1063 else
1065 dev_mc_add(dev, dn_rt_all_rt_mcast, ETH_ALEN, 0); 1064 dev_mc_add(dev, dn_rt_all_rt_mcast, ETH_ALEN, 0);
1066 1065
1067 dev_mc_upload(dev);
1068
1069 dn_db->use_long = 1; 1066 dn_db->use_long = 1;
1070 1067
1071 return 0; 1068 return 0;
@@ -1419,7 +1416,7 @@ static int dn_dev_seq_show(struct seq_file *seq, void *v)
1419 return 0; 1416 return 0;
1420} 1417}
1421 1418
1422static struct seq_operations dn_dev_seq_ops = { 1419static const struct seq_operations dn_dev_seq_ops = {
1423 .start = dn_dev_seq_start, 1420 .start = dn_dev_seq_start,
1424 .next = dn_dev_seq_next, 1421 .next = dn_dev_seq_next,
1425 .stop = dn_dev_seq_stop, 1422 .stop = dn_dev_seq_stop,
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
index 4bf066c416e2..174d8a7a6dac 100644
--- a/net/decnet/dn_neigh.c
+++ b/net/decnet/dn_neigh.c
@@ -569,7 +569,7 @@ static void *dn_neigh_seq_start(struct seq_file *seq, loff_t *pos)
569 NEIGH_SEQ_NEIGH_ONLY); 569 NEIGH_SEQ_NEIGH_ONLY);
570} 570}
571 571
572static struct seq_operations dn_neigh_seq_ops = { 572static const struct seq_operations dn_neigh_seq_ops = {
573 .start = dn_neigh_seq_start, 573 .start = dn_neigh_seq_start,
574 .next = neigh_seq_next, 574 .next = neigh_seq_next,
575 .stop = neigh_seq_stop, 575 .stop = neigh_seq_stop,
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index a8bf106b7a61..82622fb6f68f 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -1726,7 +1726,7 @@ static int dn_rt_cache_seq_show(struct seq_file *seq, void *v)
1726 return 0; 1726 return 0;
1727} 1727}
1728 1728
1729static struct seq_operations dn_rt_cache_seq_ops = { 1729static const struct seq_operations dn_rt_cache_seq_ops = {
1730 .start = dn_rt_cache_seq_start, 1730 .start = dn_rt_cache_seq_start,
1731 .next = dn_rt_cache_seq_next, 1731 .next = dn_rt_cache_seq_next,
1732 .stop = dn_rt_cache_seq_stop, 1732 .stop = dn_rt_cache_seq_stop,
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index 0ac2524f3b68..12c765715acf 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -266,8 +266,11 @@ void eth_header_cache_update(struct hh_cache *hh, struct net_device *dev,
266static int eth_mac_addr(struct net_device *dev, void *p) 266static int eth_mac_addr(struct net_device *dev, void *p)
267{ 267{
268 struct sockaddr *addr = p; 268 struct sockaddr *addr = p;
269
269 if (netif_running(dev)) 270 if (netif_running(dev))
270 return -EBUSY; 271 return -EBUSY;
272 if (!is_valid_ether_addr(addr->sa_data))
273 return -EADDRNOTAVAIL;
271 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); 274 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
272 return 0; 275 return 0;
273} 276}
@@ -316,9 +319,10 @@ void ether_setup(struct net_device *dev)
316EXPORT_SYMBOL(ether_setup); 319EXPORT_SYMBOL(ether_setup);
317 320
318/** 321/**
319 * alloc_etherdev - Allocates and sets up an Ethernet device 322 * alloc_etherdev_mq - Allocates and sets up an Ethernet device
320 * @sizeof_priv: Size of additional driver-private structure to be allocated 323 * @sizeof_priv: Size of additional driver-private structure to be allocated
321 * for this Ethernet device 324 * for this Ethernet device
325 * @queue_count: The number of queues this device has.
322 * 326 *
323 * Fill in the fields of the device structure with Ethernet-generic 327 * Fill in the fields of the device structure with Ethernet-generic
324 * values. Basically does everything except registering the device. 328 * values. Basically does everything except registering the device.
@@ -328,8 +332,8 @@ EXPORT_SYMBOL(ether_setup);
328 * this private data area. 332 * this private data area.
329 */ 333 */
330 334
331struct net_device *alloc_etherdev(int sizeof_priv) 335struct net_device *alloc_etherdev_mq(int sizeof_priv, unsigned int queue_count)
332{ 336{
333 return alloc_netdev(sizeof_priv, "eth%d", ether_setup); 337 return alloc_netdev_mq(sizeof_priv, "eth%d", ether_setup, queue_count);
334} 338}
335EXPORT_SYMBOL(alloc_etherdev); 339EXPORT_SYMBOL(alloc_etherdev_mq);
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 010fbb2d45e9..fb7909774254 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -116,48 +116,6 @@ config IP_ROUTE_MULTIPATH
116 equal "cost" and chooses one of them in a non-deterministic fashion 116 equal "cost" and chooses one of them in a non-deterministic fashion
117 if a matching packet arrives. 117 if a matching packet arrives.
118 118
119config IP_ROUTE_MULTIPATH_CACHED
120 bool "IP: equal cost multipath with caching support (EXPERIMENTAL)"
121 depends on IP_ROUTE_MULTIPATH
122 help
123 Normally, equal cost multipath routing is not supported by the
124 routing cache. If you say Y here, alternative routes are cached
125 and on cache lookup a route is chosen in a configurable fashion.
126
127 If unsure, say N.
128
129config IP_ROUTE_MULTIPATH_RR
130 tristate "MULTIPATH: round robin algorithm"
131 depends on IP_ROUTE_MULTIPATH_CACHED
132 help
133 Multipath routes are chosen according to Round Robin
134
135config IP_ROUTE_MULTIPATH_RANDOM
136 tristate "MULTIPATH: random algorithm"
137 depends on IP_ROUTE_MULTIPATH_CACHED
138 help
139 Multipath routes are chosen in a random fashion. Actually,
140 there is no weight for a route. The advantage of this policy
141 is that it is implemented stateless and therefore introduces only
142 a very small delay.
143
144config IP_ROUTE_MULTIPATH_WRANDOM
145 tristate "MULTIPATH: weighted random algorithm"
146 depends on IP_ROUTE_MULTIPATH_CACHED
147 help
148 Multipath routes are chosen in a weighted random fashion.
149 The per route weights are the weights visible via ip route 2. As the
150 corresponding state management introduces some overhead routing delay
151 is increased.
152
153config IP_ROUTE_MULTIPATH_DRR
154 tristate "MULTIPATH: interface round robin algorithm"
155 depends on IP_ROUTE_MULTIPATH_CACHED
156 help
157 Connections are distributed in a round robin fashion over the
158 available interfaces. This policy makes sense if the connections
159 should be primarily distributed on interfaces and not on routes.
160
161config IP_ROUTE_VERBOSE 119config IP_ROUTE_VERBOSE
162 bool "IP: verbose route monitoring" 120 bool "IP: verbose route monitoring"
163 depends on IP_ADVANCED_ROUTER 121 depends on IP_ADVANCED_ROUTER
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index 4ff6c151d7f3..fbf1674e0c2a 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -29,14 +29,9 @@ obj-$(CONFIG_INET_TUNNEL) += tunnel4.o
29obj-$(CONFIG_INET_XFRM_MODE_TRANSPORT) += xfrm4_mode_transport.o 29obj-$(CONFIG_INET_XFRM_MODE_TRANSPORT) += xfrm4_mode_transport.o
30obj-$(CONFIG_INET_XFRM_MODE_TUNNEL) += xfrm4_mode_tunnel.o 30obj-$(CONFIG_INET_XFRM_MODE_TUNNEL) += xfrm4_mode_tunnel.o
31obj-$(CONFIG_IP_PNP) += ipconfig.o 31obj-$(CONFIG_IP_PNP) += ipconfig.o
32obj-$(CONFIG_IP_ROUTE_MULTIPATH_RR) += multipath_rr.o
33obj-$(CONFIG_IP_ROUTE_MULTIPATH_RANDOM) += multipath_random.o
34obj-$(CONFIG_IP_ROUTE_MULTIPATH_WRANDOM) += multipath_wrandom.o
35obj-$(CONFIG_IP_ROUTE_MULTIPATH_DRR) += multipath_drr.o
36obj-$(CONFIG_NETFILTER) += netfilter.o netfilter/ 32obj-$(CONFIG_NETFILTER) += netfilter.o netfilter/
37obj-$(CONFIG_IP_VS) += ipvs/ 33obj-$(CONFIG_IP_VS) += ipvs/
38obj-$(CONFIG_INET_DIAG) += inet_diag.o 34obj-$(CONFIG_INET_DIAG) += inet_diag.o
39obj-$(CONFIG_IP_ROUTE_MULTIPATH_CACHED) += multipath.o
40obj-$(CONFIG_INET_TCP_DIAG) += tcp_diag.o 35obj-$(CONFIG_INET_TCP_DIAG) += tcp_diag.o
41obj-$(CONFIG_NET_TCPPROBE) += tcp_probe.o 36obj-$(CONFIG_NET_TCPPROBE) += tcp_probe.o
42obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o 37obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 041fba3fa0aa..06c08e5740fb 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1170,6 +1170,9 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features)
1170 int ihl; 1170 int ihl;
1171 int id; 1171 int id;
1172 1172
1173 if (!(features & NETIF_F_V4_CSUM))
1174 features &= ~NETIF_F_SG;
1175
1173 if (unlikely(skb_shinfo(skb)->gso_type & 1176 if (unlikely(skb_shinfo(skb)->gso_type &
1174 ~(SKB_GSO_TCPV4 | 1177 ~(SKB_GSO_TCPV4 |
1175 SKB_GSO_UDP | 1178 SKB_GSO_UDP |
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 6da8ff597ad3..7a23e59c374a 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -339,3 +339,4 @@ static void __exit ah4_fini(void)
339module_init(ah4_init); 339module_init(ah4_init);
340module_exit(ah4_fini); 340module_exit(ah4_fini);
341MODULE_LICENSE("GPL"); 341MODULE_LICENSE("GPL");
342MODULE_ALIAS_XFRM_TYPE(AF_INET, XFRM_PROTO_AH);
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 47c95e8ef045..98767a4f1185 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -481,3 +481,4 @@ static void __exit esp4_fini(void)
481module_init(esp4_init); 481module_init(esp4_init);
482module_exit(esp4_fini); 482module_exit(esp4_fini);
483MODULE_LICENSE("GPL"); 483MODULE_LICENSE("GPL");
484MODULE_ALIAS_XFRM_TYPE(AF_INET, XFRM_PROTO_ESP);
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 311d633f7f39..2eb909be8041 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -453,7 +453,6 @@ const struct nla_policy rtm_ipv4_policy[RTA_MAX+1] = {
453 [RTA_MULTIPATH] = { .len = sizeof(struct rtnexthop) }, 453 [RTA_MULTIPATH] = { .len = sizeof(struct rtnexthop) },
454 [RTA_PROTOINFO] = { .type = NLA_U32 }, 454 [RTA_PROTOINFO] = { .type = NLA_U32 },
455 [RTA_FLOW] = { .type = NLA_U32 }, 455 [RTA_FLOW] = { .type = NLA_U32 },
456 [RTA_MP_ALGO] = { .type = NLA_U32 },
457}; 456};
458 457
459static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh, 458static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh,
@@ -515,9 +514,6 @@ static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh,
515 case RTA_FLOW: 514 case RTA_FLOW:
516 cfg->fc_flow = nla_get_u32(attr); 515 cfg->fc_flow = nla_get_u32(attr);
517 break; 516 break;
518 case RTA_MP_ALGO:
519 cfg->fc_mp_alg = nla_get_u32(attr);
520 break;
521 case RTA_TABLE: 517 case RTA_TABLE:
522 cfg->fc_table = nla_get_u32(attr); 518 cfg->fc_table = nla_get_u32(attr);
523 break; 519 break;
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index bb94550d95c3..c434119deb52 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -42,7 +42,6 @@
42#include <net/tcp.h> 42#include <net/tcp.h>
43#include <net/sock.h> 43#include <net/sock.h>
44#include <net/ip_fib.h> 44#include <net/ip_fib.h>
45#include <net/ip_mp_alg.h>
46#include <net/netlink.h> 45#include <net/netlink.h>
47#include <net/nexthop.h> 46#include <net/nexthop.h>
48 47
@@ -697,13 +696,6 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
697 goto err_inval; 696 goto err_inval;
698 } 697 }
699#endif 698#endif
700#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
701 if (cfg->fc_mp_alg) {
702 if (cfg->fc_mp_alg < IP_MP_ALG_NONE ||
703 cfg->fc_mp_alg > IP_MP_ALG_MAX)
704 goto err_inval;
705 }
706#endif
707 699
708 err = -ENOBUFS; 700 err = -ENOBUFS;
709 if (fib_info_cnt >= fib_hash_size) { 701 if (fib_info_cnt >= fib_hash_size) {
@@ -791,10 +783,6 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
791#endif 783#endif
792 } 784 }
793 785
794#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
795 fi->fib_mp_alg = cfg->fc_mp_alg;
796#endif
797
798 if (fib_props[cfg->fc_type].error) { 786 if (fib_props[cfg->fc_type].error) {
799 if (cfg->fc_gw || cfg->fc_oif || cfg->fc_mp) 787 if (cfg->fc_gw || cfg->fc_oif || cfg->fc_mp)
800 goto err_inval; 788 goto err_inval;
@@ -940,10 +928,6 @@ out_fill_res:
940 res->type = fa->fa_type; 928 res->type = fa->fa_type;
941 res->scope = fa->fa_scope; 929 res->scope = fa->fa_scope;
942 res->fi = fa->fa_info; 930 res->fi = fa->fa_info;
943#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
944 res->netmask = mask;
945 res->network = zone & inet_make_mask(prefixlen);
946#endif
947 atomic_inc(&res->fi->fib_clntref); 931 atomic_inc(&res->fi->fib_clntref);
948 return 0; 932 return 0;
949} 933}
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 63282934725e..5c14ed63e56c 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -809,7 +809,8 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
809 809
810 max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen; 810 max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen;
811 811
812 if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) { 812 if (skb_headroom(skb) < max_headroom || skb_shared(skb)||
813 (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
813 struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); 814 struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
814 if (!new_skb) { 815 if (!new_skb) {
815 ip_rt_put(rt); 816 ip_rt_put(rt);
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 34ea4547ebbe..c9e2b5e6305e 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -399,6 +399,10 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from)
399 to->tc_index = from->tc_index; 399 to->tc_index = from->tc_index;
400#endif 400#endif
401 nf_copy(to, from); 401 nf_copy(to, from);
402#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
403 defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
404 to->nf_trace = from->nf_trace;
405#endif
402#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) 406#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
403 to->ipvs_property = from->ipvs_property; 407 to->ipvs_property = from->ipvs_property;
404#endif 408#endif
@@ -837,7 +841,7 @@ int ip_append_data(struct sock *sk,
837 */ 841 */
838 if (transhdrlen && 842 if (transhdrlen &&
839 length + fragheaderlen <= mtu && 843 length + fragheaderlen <= mtu &&
840 rt->u.dst.dev->features & NETIF_F_ALL_CSUM && 844 rt->u.dst.dev->features & NETIF_F_V4_CSUM &&
841 !exthdrlen) 845 !exthdrlen)
842 csummode = CHECKSUM_PARTIAL; 846 csummode = CHECKSUM_PARTIAL;
843 847
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index ab86137c71d2..e787044a8514 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -485,3 +485,4 @@ MODULE_LICENSE("GPL");
485MODULE_DESCRIPTION("IP Payload Compression Protocol (IPComp) - RFC3173"); 485MODULE_DESCRIPTION("IP Payload Compression Protocol (IPComp) - RFC3173");
486MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); 486MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
487 487
488MODULE_ALIAS_XFRM_TYPE(AF_INET, XFRM_PROTO_COMP);
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index ebd2f2d532f6..396437242a1b 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -595,7 +595,8 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
595 */ 595 */
596 max_headroom = (LL_RESERVED_SPACE(tdev)+sizeof(struct iphdr)); 596 max_headroom = (LL_RESERVED_SPACE(tdev)+sizeof(struct iphdr));
597 597
598 if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) { 598 if (skb_headroom(skb) < max_headroom || skb_shared(skb) ||
599 (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
599 struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); 600 struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
600 if (!new_skb) { 601 if (!new_skb) {
601 ip_rt_put(rt); 602 ip_rt_put(rt);
diff --git a/net/ipv4/ipvs/ip_vs_app.c b/net/ipv4/ipvs/ip_vs_app.c
index 15ad5dd2d984..8d6901d4e94f 100644
--- a/net/ipv4/ipvs/ip_vs_app.c
+++ b/net/ipv4/ipvs/ip_vs_app.c
@@ -549,7 +549,7 @@ static int ip_vs_app_seq_show(struct seq_file *seq, void *v)
549 return 0; 549 return 0;
550} 550}
551 551
552static struct seq_operations ip_vs_app_seq_ops = { 552static const struct seq_operations ip_vs_app_seq_ops = {
553 .start = ip_vs_app_seq_start, 553 .start = ip_vs_app_seq_start,
554 .next = ip_vs_app_seq_next, 554 .next = ip_vs_app_seq_next,
555 .stop = ip_vs_app_seq_stop, 555 .stop = ip_vs_app_seq_stop,
diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c
index 7018f97c75dc..3b446b1a6b9c 100644
--- a/net/ipv4/ipvs/ip_vs_conn.c
+++ b/net/ipv4/ipvs/ip_vs_conn.c
@@ -745,7 +745,7 @@ static int ip_vs_conn_seq_show(struct seq_file *seq, void *v)
745 return 0; 745 return 0;
746} 746}
747 747
748static struct seq_operations ip_vs_conn_seq_ops = { 748static const struct seq_operations ip_vs_conn_seq_ops = {
749 .start = ip_vs_conn_seq_start, 749 .start = ip_vs_conn_seq_start,
750 .next = ip_vs_conn_seq_next, 750 .next = ip_vs_conn_seq_next,
751 .stop = ip_vs_conn_seq_stop, 751 .stop = ip_vs_conn_seq_stop,
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c
index 68fe1d4d0210..e1052bcf4ed1 100644
--- a/net/ipv4/ipvs/ip_vs_ctl.c
+++ b/net/ipv4/ipvs/ip_vs_ctl.c
@@ -1783,7 +1783,7 @@ static int ip_vs_info_seq_show(struct seq_file *seq, void *v)
1783 return 0; 1783 return 0;
1784} 1784}
1785 1785
1786static struct seq_operations ip_vs_info_seq_ops = { 1786static const struct seq_operations ip_vs_info_seq_ops = {
1787 .start = ip_vs_info_seq_start, 1787 .start = ip_vs_info_seq_start,
1788 .next = ip_vs_info_seq_next, 1788 .next = ip_vs_info_seq_next,
1789 .stop = ip_vs_info_seq_stop, 1789 .stop = ip_vs_info_seq_stop,
diff --git a/net/ipv4/multipath.c b/net/ipv4/multipath.c
deleted file mode 100644
index 4e9ca7c76407..000000000000
--- a/net/ipv4/multipath.c
+++ /dev/null
@@ -1,55 +0,0 @@
1/* multipath.c: IPV4 multipath algorithm support.
2 *
3 * Copyright (C) 2004, 2005 Einar Lueck <elueck@de.ibm.com>
4 * Copyright (C) 2005 David S. Miller <davem@davemloft.net>
5 */
6
7#include <linux/module.h>
8#include <linux/errno.h>
9#include <linux/netdevice.h>
10#include <linux/spinlock.h>
11
12#include <net/ip_mp_alg.h>
13
14static DEFINE_SPINLOCK(alg_table_lock);
15struct ip_mp_alg_ops *ip_mp_alg_table[IP_MP_ALG_MAX + 1];
16
17int multipath_alg_register(struct ip_mp_alg_ops *ops, enum ip_mp_alg n)
18{
19 struct ip_mp_alg_ops **slot;
20 int err;
21
22 if (n < IP_MP_ALG_NONE || n > IP_MP_ALG_MAX ||
23 !ops->mp_alg_select_route)
24 return -EINVAL;
25
26 spin_lock(&alg_table_lock);
27 slot = &ip_mp_alg_table[n];
28 if (*slot != NULL) {
29 err = -EBUSY;
30 } else {
31 *slot = ops;
32 err = 0;
33 }
34 spin_unlock(&alg_table_lock);
35
36 return err;
37}
38EXPORT_SYMBOL(multipath_alg_register);
39
40void multipath_alg_unregister(struct ip_mp_alg_ops *ops, enum ip_mp_alg n)
41{
42 struct ip_mp_alg_ops **slot;
43
44 if (n < IP_MP_ALG_NONE || n > IP_MP_ALG_MAX)
45 return;
46
47 spin_lock(&alg_table_lock);
48 slot = &ip_mp_alg_table[n];
49 if (*slot == ops)
50 *slot = NULL;
51 spin_unlock(&alg_table_lock);
52
53 synchronize_net();
54}
55EXPORT_SYMBOL(multipath_alg_unregister);
diff --git a/net/ipv4/multipath_drr.c b/net/ipv4/multipath_drr.c
deleted file mode 100644
index b03c5ca2c823..000000000000
--- a/net/ipv4/multipath_drr.c
+++ /dev/null
@@ -1,249 +0,0 @@
1/*
2 * Device round robin policy for multipath.
3 *
4 *
5 * Version: $Id: multipath_drr.c,v 1.1.2.1 2004/09/16 07:42:34 elueck Exp $
6 *
7 * Authors: Einar Lueck <elueck@de.ibm.com><lkml@einar-lueck.de>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version.
13 */
14
15#include <asm/system.h>
16#include <asm/uaccess.h>
17#include <linux/types.h>
18#include <linux/errno.h>
19#include <linux/timer.h>
20#include <linux/mm.h>
21#include <linux/kernel.h>
22#include <linux/fcntl.h>
23#include <linux/stat.h>
24#include <linux/socket.h>
25#include <linux/in.h>
26#include <linux/inet.h>
27#include <linux/netdevice.h>
28#include <linux/inetdevice.h>
29#include <linux/igmp.h>
30#include <linux/proc_fs.h>
31#include <linux/seq_file.h>
32#include <linux/module.h>
33#include <linux/mroute.h>
34#include <linux/init.h>
35#include <net/ip.h>
36#include <net/protocol.h>
37#include <linux/skbuff.h>
38#include <net/sock.h>
39#include <net/icmp.h>
40#include <net/udp.h>
41#include <net/raw.h>
42#include <linux/notifier.h>
43#include <linux/if_arp.h>
44#include <linux/netfilter_ipv4.h>
45#include <net/ipip.h>
46#include <net/checksum.h>
47#include <net/ip_mp_alg.h>
48
49struct multipath_device {
50 int ifi; /* interface index of device */
51 atomic_t usecount;
52 int allocated;
53};
54
55#define MULTIPATH_MAX_DEVICECANDIDATES 10
56
57static struct multipath_device state[MULTIPATH_MAX_DEVICECANDIDATES];
58static DEFINE_SPINLOCK(state_lock);
59
60static int inline __multipath_findslot(void)
61{
62 int i;
63
64 for (i = 0; i < MULTIPATH_MAX_DEVICECANDIDATES; i++) {
65 if (state[i].allocated == 0)
66 return i;
67 }
68 return -1;
69}
70
71static int inline __multipath_finddev(int ifindex)
72{
73 int i;
74
75 for (i = 0; i < MULTIPATH_MAX_DEVICECANDIDATES; i++) {
76 if (state[i].allocated != 0 &&
77 state[i].ifi == ifindex)
78 return i;
79 }
80 return -1;
81}
82
83static int drr_dev_event(struct notifier_block *this,
84 unsigned long event, void *ptr)
85{
86 struct net_device *dev = ptr;
87 int devidx;
88
89 switch (event) {
90 case NETDEV_UNREGISTER:
91 case NETDEV_DOWN:
92 spin_lock_bh(&state_lock);
93
94 devidx = __multipath_finddev(dev->ifindex);
95 if (devidx != -1) {
96 state[devidx].allocated = 0;
97 state[devidx].ifi = 0;
98 atomic_set(&state[devidx].usecount, 0);
99 }
100
101 spin_unlock_bh(&state_lock);
102 break;
103 }
104
105 return NOTIFY_DONE;
106}
107
108static struct notifier_block drr_dev_notifier = {
109 .notifier_call = drr_dev_event,
110};
111
112
113static void drr_safe_inc(atomic_t *usecount)
114{
115 int n;
116
117 atomic_inc(usecount);
118
119 n = atomic_read(usecount);
120 if (n <= 0) {
121 int i;
122
123 spin_lock_bh(&state_lock);
124
125 for (i = 0; i < MULTIPATH_MAX_DEVICECANDIDATES; i++)
126 atomic_set(&state[i].usecount, 0);
127
128 spin_unlock_bh(&state_lock);
129 }
130}
131
132static void drr_select_route(const struct flowi *flp,
133 struct rtable *first, struct rtable **rp)
134{
135 struct rtable *nh, *result, *cur_min;
136 int min_usecount = -1;
137 int devidx = -1;
138 int cur_min_devidx = -1;
139
140 /* 1. make sure all alt. nexthops have the same GC related data */
141 /* 2. determine the new candidate to be returned */
142 result = NULL;
143 cur_min = NULL;
144 for (nh = rcu_dereference(first); nh;
145 nh = rcu_dereference(nh->u.dst.rt_next)) {
146 if ((nh->u.dst.flags & DST_BALANCED) != 0 &&
147 multipath_comparekeys(&nh->fl, flp)) {
148 int nh_ifidx = nh->u.dst.dev->ifindex;
149
150 nh->u.dst.lastuse = jiffies;
151 nh->u.dst.__use++;
152 if (result != NULL)
153 continue;
154
155 /* search for the output interface */
156
157 /* this is not SMP safe, only add/remove are
158 * SMP safe as wrong usecount updates have no big
159 * impact
160 */
161 devidx = __multipath_finddev(nh_ifidx);
162 if (devidx == -1) {
163 /* add the interface to the array
164 * SMP safe
165 */
166 spin_lock_bh(&state_lock);
167
168 /* due to SMP: search again */
169 devidx = __multipath_finddev(nh_ifidx);
170 if (devidx == -1) {
171 /* add entry for device */
172 devidx = __multipath_findslot();
173 if (devidx == -1) {
174 /* unlikely but possible */
175 continue;
176 }
177
178 state[devidx].allocated = 1;
179 state[devidx].ifi = nh_ifidx;
180 atomic_set(&state[devidx].usecount, 0);
181 min_usecount = 0;
182 }
183
184 spin_unlock_bh(&state_lock);
185 }
186
187 if (min_usecount == 0) {
188 /* if the device has not been used it is
189 * the primary target
190 */
191 drr_safe_inc(&state[devidx].usecount);
192 result = nh;
193 } else {
194 int count =
195 atomic_read(&state[devidx].usecount);
196
197 if (min_usecount == -1 ||
198 count < min_usecount) {
199 cur_min = nh;
200 cur_min_devidx = devidx;
201 min_usecount = count;
202 }
203 }
204 }
205 }
206
207 if (!result) {
208 if (cur_min) {
209 drr_safe_inc(&state[cur_min_devidx].usecount);
210 result = cur_min;
211 } else {
212 result = first;
213 }
214 }
215
216 *rp = result;
217}
218
219static struct ip_mp_alg_ops drr_ops = {
220 .mp_alg_select_route = drr_select_route,
221};
222
223static int __init drr_init(void)
224{
225 int err = register_netdevice_notifier(&drr_dev_notifier);
226
227 if (err)
228 return err;
229
230 err = multipath_alg_register(&drr_ops, IP_MP_ALG_DRR);
231 if (err)
232 goto fail;
233
234 return 0;
235
236fail:
237 unregister_netdevice_notifier(&drr_dev_notifier);
238 return err;
239}
240
241static void __exit drr_exit(void)
242{
243 unregister_netdevice_notifier(&drr_dev_notifier);
244 multipath_alg_unregister(&drr_ops, IP_MP_ALG_DRR);
245}
246
247module_init(drr_init);
248module_exit(drr_exit);
249MODULE_LICENSE("GPL");
diff --git a/net/ipv4/multipath_random.c b/net/ipv4/multipath_random.c
deleted file mode 100644
index c312785d14d0..000000000000
--- a/net/ipv4/multipath_random.c
+++ /dev/null
@@ -1,114 +0,0 @@
1/*
2 * Random policy for multipath.
3 *
4 *
5 * Version: $Id: multipath_random.c,v 1.1.2.3 2004/09/21 08:42:11 elueck Exp $
6 *
7 * Authors: Einar Lueck <elueck@de.ibm.com><lkml@einar-lueck.de>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version.
13 */
14
15#include <asm/system.h>
16#include <asm/uaccess.h>
17#include <linux/types.h>
18#include <linux/errno.h>
19#include <linux/timer.h>
20#include <linux/mm.h>
21#include <linux/kernel.h>
22#include <linux/fcntl.h>
23#include <linux/stat.h>
24#include <linux/socket.h>
25#include <linux/in.h>
26#include <linux/inet.h>
27#include <linux/netdevice.h>
28#include <linux/inetdevice.h>
29#include <linux/igmp.h>
30#include <linux/proc_fs.h>
31#include <linux/seq_file.h>
32#include <linux/module.h>
33#include <linux/mroute.h>
34#include <linux/init.h>
35#include <linux/random.h>
36#include <net/ip.h>
37#include <net/protocol.h>
38#include <linux/skbuff.h>
39#include <net/sock.h>
40#include <net/icmp.h>
41#include <net/udp.h>
42#include <net/raw.h>
43#include <linux/notifier.h>
44#include <linux/if_arp.h>
45#include <linux/netfilter_ipv4.h>
46#include <net/ipip.h>
47#include <net/checksum.h>
48#include <net/ip_mp_alg.h>
49
50#define MULTIPATH_MAX_CANDIDATES 40
51
52static void random_select_route(const struct flowi *flp,
53 struct rtable *first,
54 struct rtable **rp)
55{
56 struct rtable *rt;
57 struct rtable *decision;
58 unsigned char candidate_count = 0;
59
60 /* count all candidate */
61 for (rt = rcu_dereference(first); rt;
62 rt = rcu_dereference(rt->u.dst.rt_next)) {
63 if ((rt->u.dst.flags & DST_BALANCED) != 0 &&
64 multipath_comparekeys(&rt->fl, flp))
65 ++candidate_count;
66 }
67
68 /* choose a random candidate */
69 decision = first;
70 if (candidate_count > 1) {
71 unsigned char i = 0;
72 unsigned char candidate_no = (unsigned char)
73 (random32() % candidate_count);
74
75 /* find chosen candidate and adjust GC data for all candidates
76 * to ensure they stay in cache
77 */
78 for (rt = first; rt; rt = rt->u.dst.rt_next) {
79 if ((rt->u.dst.flags & DST_BALANCED) != 0 &&
80 multipath_comparekeys(&rt->fl, flp)) {
81 rt->u.dst.lastuse = jiffies;
82
83 if (i == candidate_no)
84 decision = rt;
85
86 if (i >= candidate_count)
87 break;
88
89 i++;
90 }
91 }
92 }
93
94 decision->u.dst.__use++;
95 *rp = decision;
96}
97
98static struct ip_mp_alg_ops random_ops = {
99 .mp_alg_select_route = random_select_route,
100};
101
102static int __init random_init(void)
103{
104 return multipath_alg_register(&random_ops, IP_MP_ALG_RANDOM);
105}
106
107static void __exit random_exit(void)
108{
109 multipath_alg_unregister(&random_ops, IP_MP_ALG_RANDOM);
110}
111
112module_init(random_init);
113module_exit(random_exit);
114MODULE_LICENSE("GPL");
diff --git a/net/ipv4/multipath_rr.c b/net/ipv4/multipath_rr.c
deleted file mode 100644
index 0ad22524f450..000000000000
--- a/net/ipv4/multipath_rr.c
+++ /dev/null
@@ -1,95 +0,0 @@
1/*
2 * Round robin policy for multipath.
3 *
4 *
5 * Version: $Id: multipath_rr.c,v 1.1.2.2 2004/09/16 07:42:34 elueck Exp $
6 *
7 * Authors: Einar Lueck <elueck@de.ibm.com><lkml@einar-lueck.de>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version.
13 */
14
15#include <asm/system.h>
16#include <asm/uaccess.h>
17#include <linux/types.h>
18#include <linux/errno.h>
19#include <linux/timer.h>
20#include <linux/mm.h>
21#include <linux/kernel.h>
22#include <linux/fcntl.h>
23#include <linux/stat.h>
24#include <linux/socket.h>
25#include <linux/in.h>
26#include <linux/inet.h>
27#include <linux/netdevice.h>
28#include <linux/inetdevice.h>
29#include <linux/igmp.h>
30#include <linux/proc_fs.h>
31#include <linux/seq_file.h>
32#include <linux/module.h>
33#include <linux/mroute.h>
34#include <linux/init.h>
35#include <net/ip.h>
36#include <net/protocol.h>
37#include <linux/skbuff.h>
38#include <net/sock.h>
39#include <net/icmp.h>
40#include <net/udp.h>
41#include <net/raw.h>
42#include <linux/notifier.h>
43#include <linux/if_arp.h>
44#include <linux/netfilter_ipv4.h>
45#include <net/ipip.h>
46#include <net/checksum.h>
47#include <net/ip_mp_alg.h>
48
49static void rr_select_route(const struct flowi *flp,
50 struct rtable *first, struct rtable **rp)
51{
52 struct rtable *nh, *result, *min_use_cand = NULL;
53 int min_use = -1;
54
55 /* 1. make sure all alt. nexthops have the same GC related data
56 * 2. determine the new candidate to be returned
57 */
58 result = NULL;
59 for (nh = rcu_dereference(first); nh;
60 nh = rcu_dereference(nh->u.dst.rt_next)) {
61 if ((nh->u.dst.flags & DST_BALANCED) != 0 &&
62 multipath_comparekeys(&nh->fl, flp)) {
63 nh->u.dst.lastuse = jiffies;
64
65 if (min_use == -1 || nh->u.dst.__use < min_use) {
66 min_use = nh->u.dst.__use;
67 min_use_cand = nh;
68 }
69 }
70 }
71 result = min_use_cand;
72 if (!result)
73 result = first;
74
75 result->u.dst.__use++;
76 *rp = result;
77}
78
79static struct ip_mp_alg_ops rr_ops = {
80 .mp_alg_select_route = rr_select_route,
81};
82
83static int __init rr_init(void)
84{
85 return multipath_alg_register(&rr_ops, IP_MP_ALG_RR);
86}
87
88static void __exit rr_exit(void)
89{
90 multipath_alg_unregister(&rr_ops, IP_MP_ALG_RR);
91}
92
93module_init(rr_init);
94module_exit(rr_exit);
95MODULE_LICENSE("GPL");
diff --git a/net/ipv4/multipath_wrandom.c b/net/ipv4/multipath_wrandom.c
deleted file mode 100644
index 57c503694539..000000000000
--- a/net/ipv4/multipath_wrandom.c
+++ /dev/null
@@ -1,329 +0,0 @@
1/*
2 * Weighted random policy for multipath.
3 *
4 *
5 * Version: $Id: multipath_wrandom.c,v 1.1.2.3 2004/09/22 07:51:40 elueck Exp $
6 *
7 * Authors: Einar Lueck <elueck@de.ibm.com><lkml@einar-lueck.de>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version.
13 */
14
15#include <asm/system.h>
16#include <asm/uaccess.h>
17#include <linux/types.h>
18#include <linux/errno.h>
19#include <linux/timer.h>
20#include <linux/mm.h>
21#include <linux/kernel.h>
22#include <linux/fcntl.h>
23#include <linux/stat.h>
24#include <linux/socket.h>
25#include <linux/in.h>
26#include <linux/inet.h>
27#include <linux/netdevice.h>
28#include <linux/inetdevice.h>
29#include <linux/igmp.h>
30#include <linux/proc_fs.h>
31#include <linux/seq_file.h>
32#include <linux/module.h>
33#include <linux/mroute.h>
34#include <linux/init.h>
35#include <linux/random.h>
36#include <net/ip.h>
37#include <net/protocol.h>
38#include <linux/skbuff.h>
39#include <net/sock.h>
40#include <net/icmp.h>
41#include <net/udp.h>
42#include <net/raw.h>
43#include <linux/notifier.h>
44#include <linux/if_arp.h>
45#include <linux/netfilter_ipv4.h>
46#include <net/ipip.h>
47#include <net/checksum.h>
48#include <net/ip_fib.h>
49#include <net/ip_mp_alg.h>
50
51#define MULTIPATH_STATE_SIZE 15
52
53struct multipath_candidate {
54 struct multipath_candidate *next;
55 int power;
56 struct rtable *rt;
57};
58
59struct multipath_dest {
60 struct list_head list;
61
62 const struct fib_nh *nh_info;
63 __be32 netmask;
64 __be32 network;
65 unsigned char prefixlen;
66
67 struct rcu_head rcu;
68};
69
70struct multipath_bucket {
71 struct list_head head;
72 spinlock_t lock;
73};
74
75struct multipath_route {
76 struct list_head list;
77
78 int oif;
79 __be32 gw;
80 struct list_head dests;
81
82 struct rcu_head rcu;
83};
84
85/* state: primarily weight per route information */
86static struct multipath_bucket state[MULTIPATH_STATE_SIZE];
87
88static unsigned char __multipath_lookup_weight(const struct flowi *fl,
89 const struct rtable *rt)
90{
91 const int state_idx = rt->idev->dev->ifindex % MULTIPATH_STATE_SIZE;
92 struct multipath_route *r;
93 struct multipath_route *target_route = NULL;
94 struct multipath_dest *d;
95 int weight = 1;
96
97 /* lookup the weight information for a certain route */
98 rcu_read_lock();
99
100 /* find state entry for gateway or add one if necessary */
101 list_for_each_entry_rcu(r, &state[state_idx].head, list) {
102 if (r->gw == rt->rt_gateway &&
103 r->oif == rt->idev->dev->ifindex) {
104 target_route = r;
105 break;
106 }
107 }
108
109 if (!target_route) {
110 /* this should not happen... but we are prepared */
111 printk( KERN_CRIT"%s: missing state for gateway: %u and " \
112 "device %d\n", __FUNCTION__, rt->rt_gateway,
113 rt->idev->dev->ifindex);
114 goto out;
115 }
116
117 /* find state entry for destination */
118 list_for_each_entry_rcu(d, &target_route->dests, list) {
119 __be32 targetnetwork = fl->fl4_dst &
120 inet_make_mask(d->prefixlen);
121
122 if ((targetnetwork & d->netmask) == d->network) {
123 weight = d->nh_info->nh_weight;
124 goto out;
125 }
126 }
127
128out:
129 rcu_read_unlock();
130 return weight;
131}
132
133static void wrandom_init_state(void)
134{
135 int i;
136
137 for (i = 0; i < MULTIPATH_STATE_SIZE; ++i) {
138 INIT_LIST_HEAD(&state[i].head);
139 spin_lock_init(&state[i].lock);
140 }
141}
142
143static void wrandom_select_route(const struct flowi *flp,
144 struct rtable *first,
145 struct rtable **rp)
146{
147 struct rtable *rt;
148 struct rtable *decision;
149 struct multipath_candidate *first_mpc = NULL;
150 struct multipath_candidate *mpc, *last_mpc = NULL;
151 int power = 0;
152 int last_power;
153 int selector;
154 const size_t size_mpc = sizeof(struct multipath_candidate);
155
156 /* collect all candidates and identify their weights */
157 for (rt = rcu_dereference(first); rt;
158 rt = rcu_dereference(rt->u.dst.rt_next)) {
159 if ((rt->u.dst.flags & DST_BALANCED) != 0 &&
160 multipath_comparekeys(&rt->fl, flp)) {
161 struct multipath_candidate* mpc =
162 (struct multipath_candidate*)
163 kmalloc(size_mpc, GFP_ATOMIC);
164
165 if (!mpc)
166 return;
167
168 power += __multipath_lookup_weight(flp, rt) * 10000;
169
170 mpc->power = power;
171 mpc->rt = rt;
172 mpc->next = NULL;
173
174 if (!first_mpc)
175 first_mpc = mpc;
176 else
177 last_mpc->next = mpc;
178
179 last_mpc = mpc;
180 }
181 }
182
183 /* choose a weighted random candidate */
184 decision = first;
185 selector = random32() % power;
186 last_power = 0;
187
188 /* select candidate, adjust GC data and cleanup local state */
189 decision = first;
190 last_mpc = NULL;
191 for (mpc = first_mpc; mpc; mpc = mpc->next) {
192 mpc->rt->u.dst.lastuse = jiffies;
193 if (last_power <= selector && selector < mpc->power)
194 decision = mpc->rt;
195
196 last_power = mpc->power;
197 kfree(last_mpc);
198 last_mpc = mpc;
199 }
200
201 /* concurrent __multipath_flush may lead to !last_mpc */
202 kfree(last_mpc);
203
204 decision->u.dst.__use++;
205 *rp = decision;
206}
207
208static void wrandom_set_nhinfo(__be32 network,
209 __be32 netmask,
210 unsigned char prefixlen,
211 const struct fib_nh *nh)
212{
213 const int state_idx = nh->nh_oif % MULTIPATH_STATE_SIZE;
214 struct multipath_route *r, *target_route = NULL;
215 struct multipath_dest *d, *target_dest = NULL;
216
217 /* store the weight information for a certain route */
218 spin_lock_bh(&state[state_idx].lock);
219
220 /* find state entry for gateway or add one if necessary */
221 list_for_each_entry_rcu(r, &state[state_idx].head, list) {
222 if (r->gw == nh->nh_gw && r->oif == nh->nh_oif) {
223 target_route = r;
224 break;
225 }
226 }
227
228 if (!target_route) {
229 const size_t size_rt = sizeof(struct multipath_route);
230 target_route = (struct multipath_route *)
231 kmalloc(size_rt, GFP_ATOMIC);
232
233 target_route->gw = nh->nh_gw;
234 target_route->oif = nh->nh_oif;
235 memset(&target_route->rcu, 0, sizeof(struct rcu_head));
236 INIT_LIST_HEAD(&target_route->dests);
237
238 list_add_rcu(&target_route->list, &state[state_idx].head);
239 }
240
241 /* find state entry for destination or add one if necessary */
242 list_for_each_entry_rcu(d, &target_route->dests, list) {
243 if (d->nh_info == nh) {
244 target_dest = d;
245 break;
246 }
247 }
248
249 if (!target_dest) {
250 const size_t size_dst = sizeof(struct multipath_dest);
251 target_dest = (struct multipath_dest*)
252 kmalloc(size_dst, GFP_ATOMIC);
253
254 target_dest->nh_info = nh;
255 target_dest->network = network;
256 target_dest->netmask = netmask;
257 target_dest->prefixlen = prefixlen;
258 memset(&target_dest->rcu, 0, sizeof(struct rcu_head));
259
260 list_add_rcu(&target_dest->list, &target_route->dests);
261 }
262 /* else: we already stored this info for another destination =>
263 * we are finished
264 */
265
266 spin_unlock_bh(&state[state_idx].lock);
267}
268
269static void __multipath_free(struct rcu_head *head)
270{
271 struct multipath_route *rt = container_of(head, struct multipath_route,
272 rcu);
273 kfree(rt);
274}
275
276static void __multipath_free_dst(struct rcu_head *head)
277{
278 struct multipath_dest *dst = container_of(head,
279 struct multipath_dest,
280 rcu);
281 kfree(dst);
282}
283
284static void wrandom_flush(void)
285{
286 int i;
287
288 /* defere delete to all entries */
289 for (i = 0; i < MULTIPATH_STATE_SIZE; ++i) {
290 struct multipath_route *r;
291
292 spin_lock_bh(&state[i].lock);
293 list_for_each_entry_rcu(r, &state[i].head, list) {
294 struct multipath_dest *d;
295 list_for_each_entry_rcu(d, &r->dests, list) {
296 list_del_rcu(&d->list);
297 call_rcu(&d->rcu,
298 __multipath_free_dst);
299 }
300 list_del_rcu(&r->list);
301 call_rcu(&r->rcu,
302 __multipath_free);
303 }
304
305 spin_unlock_bh(&state[i].lock);
306 }
307}
308
309static struct ip_mp_alg_ops wrandom_ops = {
310 .mp_alg_select_route = wrandom_select_route,
311 .mp_alg_flush = wrandom_flush,
312 .mp_alg_set_nhinfo = wrandom_set_nhinfo,
313};
314
315static int __init wrandom_init(void)
316{
317 wrandom_init_state();
318
319 return multipath_alg_register(&wrandom_ops, IP_MP_ALG_WRANDOM);
320}
321
322static void __exit wrandom_exit(void)
323{
324 multipath_alg_unregister(&wrandom_ops, IP_MP_ALG_WRANDOM);
325}
326
327module_init(wrandom_init);
328module_exit(wrandom_exit);
329MODULE_LICENSE("GPL");
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 46509fae9fd8..fa97947c6ae1 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -230,7 +230,7 @@ config IP_NF_TARGET_NETMAP
230 To compile it as a module, choose M here. If unsure, say N. 230 To compile it as a module, choose M here. If unsure, say N.
231 231
232config IP_NF_TARGET_SAME 232config IP_NF_TARGET_SAME
233 tristate "SAME target support" 233 tristate "SAME target support (OBSOLETE)"
234 depends on NF_NAT 234 depends on NF_NAT
235 help 235 help
236 This option adds a `SAME' target, which works like the standard SNAT 236 This option adds a `SAME' target, which works like the standard SNAT
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index cae41215e3c7..e981232942a1 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -224,7 +224,7 @@ unsigned int arpt_do_table(struct sk_buff **pskb,
224 static const char nulldevname[IFNAMSIZ]; 224 static const char nulldevname[IFNAMSIZ];
225 unsigned int verdict = NF_DROP; 225 unsigned int verdict = NF_DROP;
226 struct arphdr *arp; 226 struct arphdr *arp;
227 int hotdrop = 0; 227 bool hotdrop = false;
228 struct arpt_entry *e, *back; 228 struct arpt_entry *e, *back;
229 const char *indev, *outdev; 229 const char *indev, *outdev;
230 void *table_base; 230 void *table_base;
@@ -1140,13 +1140,13 @@ void arpt_unregister_table(struct arpt_table *table)
1140} 1140}
1141 1141
1142/* The built-in targets: standard (NULL) and error. */ 1142/* The built-in targets: standard (NULL) and error. */
1143static struct arpt_target arpt_standard_target = { 1143static struct arpt_target arpt_standard_target __read_mostly = {
1144 .name = ARPT_STANDARD_TARGET, 1144 .name = ARPT_STANDARD_TARGET,
1145 .targetsize = sizeof(int), 1145 .targetsize = sizeof(int),
1146 .family = NF_ARP, 1146 .family = NF_ARP,
1147}; 1147};
1148 1148
1149static struct arpt_target arpt_error_target = { 1149static struct arpt_target arpt_error_target __read_mostly = {
1150 .name = ARPT_ERROR_TARGET, 1150 .name = ARPT_ERROR_TARGET,
1151 .target = arpt_error, 1151 .target = arpt_error,
1152 .targetsize = ARPT_FUNCTION_MAXNAMELEN, 1152 .targetsize = ARPT_FUNCTION_MAXNAMELEN,
diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c
index 6298d404e7c7..c4bdab47597f 100644
--- a/net/ipv4/netfilter/arpt_mangle.c
+++ b/net/ipv4/netfilter/arpt_mangle.c
@@ -65,7 +65,7 @@ target(struct sk_buff **pskb,
65 return mangle->target; 65 return mangle->target;
66} 66}
67 67
68static int 68static bool
69checkentry(const char *tablename, const void *e, const struct xt_target *target, 69checkentry(const char *tablename, const void *e, const struct xt_target *target,
70 void *targinfo, unsigned int hook_mask) 70 void *targinfo, unsigned int hook_mask)
71{ 71{
@@ -73,15 +73,15 @@ checkentry(const char *tablename, const void *e, const struct xt_target *target,
73 73
74 if (mangle->flags & ~ARPT_MANGLE_MASK || 74 if (mangle->flags & ~ARPT_MANGLE_MASK ||
75 !(mangle->flags & ARPT_MANGLE_MASK)) 75 !(mangle->flags & ARPT_MANGLE_MASK))
76 return 0; 76 return false;
77 77
78 if (mangle->target != NF_DROP && mangle->target != NF_ACCEPT && 78 if (mangle->target != NF_DROP && mangle->target != NF_ACCEPT &&
79 mangle->target != ARPT_CONTINUE) 79 mangle->target != ARPT_CONTINUE)
80 return 0; 80 return false;
81 return 1; 81 return true;
82} 82}
83 83
84static struct arpt_target arpt_mangle_reg = { 84static struct arpt_target arpt_mangle_reg __read_mostly = {
85 .name = "mangle", 85 .name = "mangle",
86 .target = target, 86 .target = target,
87 .targetsize = sizeof(struct arpt_mangle), 87 .targetsize = sizeof(struct arpt_mangle),
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 9bacf1a03630..e1b402c6b855 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -152,20 +152,20 @@ ip_packet_match(const struct iphdr *ip,
152 return 1; 152 return 1;
153} 153}
154 154
155static inline int 155static inline bool
156ip_checkentry(const struct ipt_ip *ip) 156ip_checkentry(const struct ipt_ip *ip)
157{ 157{
158 if (ip->flags & ~IPT_F_MASK) { 158 if (ip->flags & ~IPT_F_MASK) {
159 duprintf("Unknown flag bits set: %08X\n", 159 duprintf("Unknown flag bits set: %08X\n",
160 ip->flags & ~IPT_F_MASK); 160 ip->flags & ~IPT_F_MASK);
161 return 0; 161 return false;
162 } 162 }
163 if (ip->invflags & ~IPT_INV_MASK) { 163 if (ip->invflags & ~IPT_INV_MASK) {
164 duprintf("Unknown invflag bits set: %08X\n", 164 duprintf("Unknown invflag bits set: %08X\n",
165 ip->invflags & ~IPT_INV_MASK); 165 ip->invflags & ~IPT_INV_MASK);
166 return 0; 166 return false;
167 } 167 }
168 return 1; 168 return true;
169} 169}
170 170
171static unsigned int 171static unsigned int
@@ -183,19 +183,19 @@ ipt_error(struct sk_buff **pskb,
183} 183}
184 184
185static inline 185static inline
186int do_match(struct ipt_entry_match *m, 186bool do_match(struct ipt_entry_match *m,
187 const struct sk_buff *skb, 187 const struct sk_buff *skb,
188 const struct net_device *in, 188 const struct net_device *in,
189 const struct net_device *out, 189 const struct net_device *out,
190 int offset, 190 int offset,
191 int *hotdrop) 191 bool *hotdrop)
192{ 192{
193 /* Stop iteration if it doesn't match */ 193 /* Stop iteration if it doesn't match */
194 if (!m->u.kernel.match->match(skb, in, out, m->u.kernel.match, m->data, 194 if (!m->u.kernel.match->match(skb, in, out, m->u.kernel.match, m->data,
195 offset, ip_hdrlen(skb), hotdrop)) 195 offset, ip_hdrlen(skb), hotdrop))
196 return 1; 196 return true;
197 else 197 else
198 return 0; 198 return false;
199} 199}
200 200
201static inline struct ipt_entry * 201static inline struct ipt_entry *
@@ -204,6 +204,112 @@ get_entry(void *base, unsigned int offset)
204 return (struct ipt_entry *)(base + offset); 204 return (struct ipt_entry *)(base + offset);
205} 205}
206 206
207/* All zeroes == unconditional rule. */
208static inline int
209unconditional(const struct ipt_ip *ip)
210{
211 unsigned int i;
212
213 for (i = 0; i < sizeof(*ip)/sizeof(__u32); i++)
214 if (((__u32 *)ip)[i])
215 return 0;
216
217 return 1;
218}
219
220#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
221 defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
222static const char *hooknames[] = {
223 [NF_IP_PRE_ROUTING] = "PREROUTING",
224 [NF_IP_LOCAL_IN] = "INPUT",
225 [NF_IP_FORWARD] = "FORWARD",
226 [NF_IP_LOCAL_OUT] = "OUTPUT",
227 [NF_IP_POST_ROUTING] = "POSTROUTING",
228};
229
230enum nf_ip_trace_comments {
231 NF_IP_TRACE_COMMENT_RULE,
232 NF_IP_TRACE_COMMENT_RETURN,
233 NF_IP_TRACE_COMMENT_POLICY,
234};
235
236static const char *comments[] = {
237 [NF_IP_TRACE_COMMENT_RULE] = "rule",
238 [NF_IP_TRACE_COMMENT_RETURN] = "return",
239 [NF_IP_TRACE_COMMENT_POLICY] = "policy",
240};
241
242static struct nf_loginfo trace_loginfo = {
243 .type = NF_LOG_TYPE_LOG,
244 .u = {
245 .log = {
246 .level = 4,
247 .logflags = NF_LOG_MASK,
248 },
249 },
250};
251
252static inline int
253get_chainname_rulenum(struct ipt_entry *s, struct ipt_entry *e,
254 char *hookname, char **chainname,
255 char **comment, unsigned int *rulenum)
256{
257 struct ipt_standard_target *t = (void *)ipt_get_target(s);
258
259 if (strcmp(t->target.u.kernel.target->name, IPT_ERROR_TARGET) == 0) {
260 /* Head of user chain: ERROR target with chainname */
261 *chainname = t->target.data;
262 (*rulenum) = 0;
263 } else if (s == e) {
264 (*rulenum)++;
265
266 if (s->target_offset == sizeof(struct ipt_entry)
267 && strcmp(t->target.u.kernel.target->name,
268 IPT_STANDARD_TARGET) == 0
269 && t->verdict < 0
270 && unconditional(&s->ip)) {
271 /* Tail of chains: STANDARD target (return/policy) */
272 *comment = *chainname == hookname
273 ? (char *)comments[NF_IP_TRACE_COMMENT_POLICY]
274 : (char *)comments[NF_IP_TRACE_COMMENT_RETURN];
275 }
276 return 1;
277 } else
278 (*rulenum)++;
279
280 return 0;
281}
282
283static void trace_packet(struct sk_buff *skb,
284 unsigned int hook,
285 const struct net_device *in,
286 const struct net_device *out,
287 char *tablename,
288 struct xt_table_info *private,
289 struct ipt_entry *e)
290{
291 void *table_base;
292 struct ipt_entry *root;
293 char *hookname, *chainname, *comment;
294 unsigned int rulenum = 0;
295
296 table_base = (void *)private->entries[smp_processor_id()];
297 root = get_entry(table_base, private->hook_entry[hook]);
298
299 hookname = chainname = (char *)hooknames[hook];
300 comment = (char *)comments[NF_IP_TRACE_COMMENT_RULE];
301
302 IPT_ENTRY_ITERATE(root,
303 private->size - private->hook_entry[hook],
304 get_chainname_rulenum,
305 e, hookname, &chainname, &comment, &rulenum);
306
307 nf_log_packet(AF_INET, hook, skb, in, out, &trace_loginfo,
308 "TRACE: %s:%s:%s:%u ",
309 tablename, chainname, comment, rulenum);
310}
311#endif
312
207/* Returns one of the generic firewall policies, like NF_ACCEPT. */ 313/* Returns one of the generic firewall policies, like NF_ACCEPT. */
208unsigned int 314unsigned int
209ipt_do_table(struct sk_buff **pskb, 315ipt_do_table(struct sk_buff **pskb,
@@ -216,7 +322,7 @@ ipt_do_table(struct sk_buff **pskb,
216 u_int16_t offset; 322 u_int16_t offset;
217 struct iphdr *ip; 323 struct iphdr *ip;
218 u_int16_t datalen; 324 u_int16_t datalen;
219 int hotdrop = 0; 325 bool hotdrop = false;
220 /* Initializing verdict to NF_DROP keeps gcc happy. */ 326 /* Initializing verdict to NF_DROP keeps gcc happy. */
221 unsigned int verdict = NF_DROP; 327 unsigned int verdict = NF_DROP;
222 const char *indev, *outdev; 328 const char *indev, *outdev;
@@ -261,6 +367,14 @@ ipt_do_table(struct sk_buff **pskb,
261 367
262 t = ipt_get_target(e); 368 t = ipt_get_target(e);
263 IP_NF_ASSERT(t->u.kernel.target); 369 IP_NF_ASSERT(t->u.kernel.target);
370
371#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
372 defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
373 /* The packet is traced: log it */
374 if (unlikely((*pskb)->nf_trace))
375 trace_packet(*pskb, hook, in, out,
376 table->name, private, e);
377#endif
264 /* Standard target? */ 378 /* Standard target? */
265 if (!t->u.kernel.target->target) { 379 if (!t->u.kernel.target->target) {
266 int v; 380 int v;
@@ -341,19 +455,6 @@ ipt_do_table(struct sk_buff **pskb,
341#endif 455#endif
342} 456}
343 457
344/* All zeroes == unconditional rule. */
345static inline int
346unconditional(const struct ipt_ip *ip)
347{
348 unsigned int i;
349
350 for (i = 0; i < sizeof(*ip)/sizeof(__u32); i++)
351 if (((__u32 *)ip)[i])
352 return 0;
353
354 return 1;
355}
356
357/* Figures out from what hook each rule can be called: returns 0 if 458/* Figures out from what hook each rule can be called: returns 0 if
358 there are loops. Puts hook bitmask in comefrom. */ 459 there are loops. Puts hook bitmask in comefrom. */
359static int 460static int
@@ -2105,16 +2206,16 @@ void ipt_unregister_table(struct xt_table *table)
2105} 2206}
2106 2207
2107/* Returns 1 if the type and code is matched by the range, 0 otherwise */ 2208/* Returns 1 if the type and code is matched by the range, 0 otherwise */
2108static inline int 2209static inline bool
2109icmp_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code, 2210icmp_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
2110 u_int8_t type, u_int8_t code, 2211 u_int8_t type, u_int8_t code,
2111 int invert) 2212 bool invert)
2112{ 2213{
2113 return ((test_type == 0xFF) || (type == test_type && code >= min_code && code <= max_code)) 2214 return ((test_type == 0xFF) || (type == test_type && code >= min_code && code <= max_code))
2114 ^ invert; 2215 ^ invert;
2115} 2216}
2116 2217
2117static int 2218static bool
2118icmp_match(const struct sk_buff *skb, 2219icmp_match(const struct sk_buff *skb,
2119 const struct net_device *in, 2220 const struct net_device *in,
2120 const struct net_device *out, 2221 const struct net_device *out,
@@ -2122,14 +2223,14 @@ icmp_match(const struct sk_buff *skb,
2122 const void *matchinfo, 2223 const void *matchinfo,
2123 int offset, 2224 int offset,
2124 unsigned int protoff, 2225 unsigned int protoff,
2125 int *hotdrop) 2226 bool *hotdrop)
2126{ 2227{
2127 struct icmphdr _icmph, *ic; 2228 struct icmphdr _icmph, *ic;
2128 const struct ipt_icmp *icmpinfo = matchinfo; 2229 const struct ipt_icmp *icmpinfo = matchinfo;
2129 2230
2130 /* Must not be a fragment. */ 2231 /* Must not be a fragment. */
2131 if (offset) 2232 if (offset)
2132 return 0; 2233 return false;
2133 2234
2134 ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph); 2235 ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph);
2135 if (ic == NULL) { 2236 if (ic == NULL) {
@@ -2137,8 +2238,8 @@ icmp_match(const struct sk_buff *skb,
2137 * can't. Hence, no choice but to drop. 2238 * can't. Hence, no choice but to drop.
2138 */ 2239 */
2139 duprintf("Dropping evil ICMP tinygram.\n"); 2240 duprintf("Dropping evil ICMP tinygram.\n");
2140 *hotdrop = 1; 2241 *hotdrop = true;
2141 return 0; 2242 return false;
2142 } 2243 }
2143 2244
2144 return icmp_type_code_match(icmpinfo->type, 2245 return icmp_type_code_match(icmpinfo->type,
@@ -2149,7 +2250,7 @@ icmp_match(const struct sk_buff *skb,
2149} 2250}
2150 2251
2151/* Called when user tries to insert an entry of this type. */ 2252/* Called when user tries to insert an entry of this type. */
2152static int 2253static bool
2153icmp_checkentry(const char *tablename, 2254icmp_checkentry(const char *tablename,
2154 const void *info, 2255 const void *info,
2155 const struct xt_match *match, 2256 const struct xt_match *match,
@@ -2163,7 +2264,7 @@ icmp_checkentry(const char *tablename,
2163} 2264}
2164 2265
2165/* The built-in targets: standard (NULL) and error. */ 2266/* The built-in targets: standard (NULL) and error. */
2166static struct xt_target ipt_standard_target = { 2267static struct xt_target ipt_standard_target __read_mostly = {
2167 .name = IPT_STANDARD_TARGET, 2268 .name = IPT_STANDARD_TARGET,
2168 .targetsize = sizeof(int), 2269 .targetsize = sizeof(int),
2169 .family = AF_INET, 2270 .family = AF_INET,
@@ -2174,7 +2275,7 @@ static struct xt_target ipt_standard_target = {
2174#endif 2275#endif
2175}; 2276};
2176 2277
2177static struct xt_target ipt_error_target = { 2278static struct xt_target ipt_error_target __read_mostly = {
2178 .name = IPT_ERROR_TARGET, 2279 .name = IPT_ERROR_TARGET,
2179 .target = ipt_error, 2280 .target = ipt_error,
2180 .targetsize = IPT_FUNCTION_MAXNAMELEN, 2281 .targetsize = IPT_FUNCTION_MAXNAMELEN,
@@ -2197,7 +2298,7 @@ static struct nf_sockopt_ops ipt_sockopts = {
2197#endif 2298#endif
2198}; 2299};
2199 2300
2200static struct xt_match icmp_matchstruct = { 2301static struct xt_match icmp_matchstruct __read_mostly = {
2201 .name = "icmp", 2302 .name = "icmp",
2202 .match = icmp_match, 2303 .match = icmp_match,
2203 .matchsize = sizeof(struct ipt_icmp), 2304 .matchsize = sizeof(struct ipt_icmp),
@@ -2230,7 +2331,7 @@ static int __init ip_tables_init(void)
2230 if (ret < 0) 2331 if (ret < 0)
2231 goto err5; 2332 goto err5;
2232 2333
2233 printk("ip_tables: (C) 2000-2006 Netfilter Core Team\n"); 2334 printk(KERN_INFO "ip_tables: (C) 2000-2006 Netfilter Core Team\n");
2234 return 0; 2335 return 0;
2235 2336
2236err5: 2337err5:
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 40e273421398..dcc12b183474 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -30,14 +30,6 @@
30 30
31#define CLUSTERIP_VERSION "0.8" 31#define CLUSTERIP_VERSION "0.8"
32 32
33#define DEBUG_CLUSTERIP
34
35#ifdef DEBUG_CLUSTERIP
36#define DEBUGP printk
37#else
38#define DEBUGP
39#endif
40
41MODULE_LICENSE("GPL"); 33MODULE_LICENSE("GPL");
42MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 34MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
43MODULE_DESCRIPTION("iptables target for CLUSTERIP"); 35MODULE_DESCRIPTION("iptables target for CLUSTERIP");
@@ -122,9 +114,8 @@ __clusterip_config_find(__be32 clusterip)
122 list_for_each(pos, &clusterip_configs) { 114 list_for_each(pos, &clusterip_configs) {
123 struct clusterip_config *c = list_entry(pos, 115 struct clusterip_config *c = list_entry(pos,
124 struct clusterip_config, list); 116 struct clusterip_config, list);
125 if (c->clusterip == clusterip) { 117 if (c->clusterip == clusterip)
126 return c; 118 return c;
127 }
128 } 119 }
129 120
130 return NULL; 121 return NULL;
@@ -155,9 +146,8 @@ clusterip_config_init_nodelist(struct clusterip_config *c,
155{ 146{
156 int n; 147 int n;
157 148
158 for (n = 0; n < i->num_local_nodes; n++) { 149 for (n = 0; n < i->num_local_nodes; n++)
159 set_bit(i->local_nodes[n] - 1, &c->local_nodes); 150 set_bit(i->local_nodes[n] - 1, &c->local_nodes);
160 }
161} 151}
162 152
163static struct clusterip_config * 153static struct clusterip_config *
@@ -220,27 +210,28 @@ clusterip_add_node(struct clusterip_config *c, u_int16_t nodenum)
220 return 0; 210 return 0;
221} 211}
222 212
223static int 213static bool
224clusterip_del_node(struct clusterip_config *c, u_int16_t nodenum) 214clusterip_del_node(struct clusterip_config *c, u_int16_t nodenum)
225{ 215{
226 if (nodenum == 0 || 216 if (nodenum == 0 ||
227 nodenum > c->num_total_nodes) 217 nodenum > c->num_total_nodes)
228 return 1; 218 return true;
229 219
230 if (test_and_clear_bit(nodenum - 1, &c->local_nodes)) 220 if (test_and_clear_bit(nodenum - 1, &c->local_nodes))
231 return 0; 221 return false;
232 222
233 return 1; 223 return true;
234} 224}
235#endif 225#endif
236 226
237static inline u_int32_t 227static inline u_int32_t
238clusterip_hashfn(struct sk_buff *skb, struct clusterip_config *config) 228clusterip_hashfn(const struct sk_buff *skb,
229 const struct clusterip_config *config)
239{ 230{
240 struct iphdr *iph = ip_hdr(skb); 231 const struct iphdr *iph = ip_hdr(skb);
241 unsigned long hashval; 232 unsigned long hashval;
242 u_int16_t sport, dport; 233 u_int16_t sport, dport;
243 u_int16_t *ports; 234 const u_int16_t *ports;
244 235
245 switch (iph->protocol) { 236 switch (iph->protocol) {
246 case IPPROTO_TCP: 237 case IPPROTO_TCP:
@@ -249,15 +240,14 @@ clusterip_hashfn(struct sk_buff *skb, struct clusterip_config *config)
249 case IPPROTO_SCTP: 240 case IPPROTO_SCTP:
250 case IPPROTO_DCCP: 241 case IPPROTO_DCCP:
251 case IPPROTO_ICMP: 242 case IPPROTO_ICMP:
252 ports = (void *)iph+iph->ihl*4; 243 ports = (const void *)iph+iph->ihl*4;
253 sport = ports[0]; 244 sport = ports[0];
254 dport = ports[1]; 245 dport = ports[1];
255 break; 246 break;
256 default: 247 default:
257 if (net_ratelimit()) { 248 if (net_ratelimit())
258 printk(KERN_NOTICE "CLUSTERIP: unknown protocol `%u'\n", 249 printk(KERN_NOTICE "CLUSTERIP: unknown protocol `%u'\n",
259 iph->protocol); 250 iph->protocol);
260 }
261 sport = dport = 0; 251 sport = dport = 0;
262 } 252 }
263 253
@@ -285,11 +275,11 @@ clusterip_hashfn(struct sk_buff *skb, struct clusterip_config *config)
285 } 275 }
286 276
287 /* node numbers are 1..n, not 0..n */ 277 /* node numbers are 1..n, not 0..n */
288 return ((hashval % config->num_total_nodes)+1); 278 return (hashval % config->num_total_nodes) + 1;
289} 279}
290 280
291static inline int 281static inline int
292clusterip_responsible(struct clusterip_config *config, u_int32_t hash) 282clusterip_responsible(const struct clusterip_config *config, u_int32_t hash)
293{ 283{
294 return test_bit(hash - 1, &config->local_nodes); 284 return test_bit(hash - 1, &config->local_nodes);
295} 285}
@@ -353,15 +343,15 @@ target(struct sk_buff **pskb,
353 break; 343 break;
354 } 344 }
355 345
356#ifdef DEBUG_CLUSTERP 346#ifdef DEBUG
357 DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); 347 DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
358#endif 348#endif
359 DEBUGP("hash=%u ct_hash=%u ", hash, ct->mark); 349 pr_debug("hash=%u ct_hash=%u ", hash, ct->mark);
360 if (!clusterip_responsible(cipinfo->config, hash)) { 350 if (!clusterip_responsible(cipinfo->config, hash)) {
361 DEBUGP("not responsible\n"); 351 pr_debug("not responsible\n");
362 return NF_DROP; 352 return NF_DROP;
363 } 353 }
364 DEBUGP("responsible\n"); 354 pr_debug("responsible\n");
365 355
366 /* despite being received via linklayer multicast, this is 356 /* despite being received via linklayer multicast, this is
367 * actually a unicast IP packet. TCP doesn't like PACKET_MULTICAST */ 357 * actually a unicast IP packet. TCP doesn't like PACKET_MULTICAST */
@@ -370,7 +360,7 @@ target(struct sk_buff **pskb,
370 return XT_CONTINUE; 360 return XT_CONTINUE;
371} 361}
372 362
373static int 363static bool
374checkentry(const char *tablename, 364checkentry(const char *tablename,
375 const void *e_void, 365 const void *e_void,
376 const struct xt_target *target, 366 const struct xt_target *target,
@@ -387,50 +377,34 @@ checkentry(const char *tablename,
387 cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT_DPT) { 377 cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT_DPT) {
388 printk(KERN_WARNING "CLUSTERIP: unknown mode `%u'\n", 378 printk(KERN_WARNING "CLUSTERIP: unknown mode `%u'\n",
389 cipinfo->hash_mode); 379 cipinfo->hash_mode);
390 return 0; 380 return false;
391 381
392 } 382 }
393 if (e->ip.dmsk.s_addr != htonl(0xffffffff) 383 if (e->ip.dmsk.s_addr != htonl(0xffffffff)
394 || e->ip.dst.s_addr == 0) { 384 || e->ip.dst.s_addr == 0) {
395 printk(KERN_ERR "CLUSTERIP: Please specify destination IP\n"); 385 printk(KERN_ERR "CLUSTERIP: Please specify destination IP\n");
396 return 0; 386 return false;
397 } 387 }
398 388
399 /* FIXME: further sanity checks */ 389 /* FIXME: further sanity checks */
400 390
401 config = clusterip_config_find_get(e->ip.dst.s_addr, 1); 391 config = clusterip_config_find_get(e->ip.dst.s_addr, 1);
402 if (config) { 392 if (!config) {
403 if (cipinfo->config != NULL) {
404 /* Case A: This is an entry that gets reloaded, since
405 * it still has a cipinfo->config pointer. Simply
406 * increase the entry refcount and return */
407 if (cipinfo->config != config) {
408 printk(KERN_ERR "CLUSTERIP: Reloaded entry "
409 "has invalid config pointer!\n");
410 return 0;
411 }
412 } else {
413 /* Case B: This is a new rule referring to an existing
414 * clusterip config. */
415 cipinfo->config = config;
416 }
417 } else {
418 /* Case C: This is a completely new clusterip config */
419 if (!(cipinfo->flags & CLUSTERIP_FLAG_NEW)) { 393 if (!(cipinfo->flags & CLUSTERIP_FLAG_NEW)) {
420 printk(KERN_WARNING "CLUSTERIP: no config found for %u.%u.%u.%u, need 'new'\n", NIPQUAD(e->ip.dst.s_addr)); 394 printk(KERN_WARNING "CLUSTERIP: no config found for %u.%u.%u.%u, need 'new'\n", NIPQUAD(e->ip.dst.s_addr));
421 return 0; 395 return false;
422 } else { 396 } else {
423 struct net_device *dev; 397 struct net_device *dev;
424 398
425 if (e->ip.iniface[0] == '\0') { 399 if (e->ip.iniface[0] == '\0') {
426 printk(KERN_WARNING "CLUSTERIP: Please specify an interface name\n"); 400 printk(KERN_WARNING "CLUSTERIP: Please specify an interface name\n");
427 return 0; 401 return false;
428 } 402 }
429 403
430 dev = dev_get_by_name(e->ip.iniface); 404 dev = dev_get_by_name(e->ip.iniface);
431 if (!dev) { 405 if (!dev) {
432 printk(KERN_WARNING "CLUSTERIP: no such interface %s\n", e->ip.iniface); 406 printk(KERN_WARNING "CLUSTERIP: no such interface %s\n", e->ip.iniface);
433 return 0; 407 return false;
434 } 408 }
435 409
436 config = clusterip_config_init(cipinfo, 410 config = clusterip_config_init(cipinfo,
@@ -438,20 +412,20 @@ checkentry(const char *tablename,
438 if (!config) { 412 if (!config) {
439 printk(KERN_WARNING "CLUSTERIP: cannot allocate config\n"); 413 printk(KERN_WARNING "CLUSTERIP: cannot allocate config\n");
440 dev_put(dev); 414 dev_put(dev);
441 return 0; 415 return false;
442 } 416 }
443 dev_mc_add(config->dev,config->clustermac, ETH_ALEN, 0); 417 dev_mc_add(config->dev,config->clustermac, ETH_ALEN, 0);
444 } 418 }
445 cipinfo->config = config;
446 } 419 }
420 cipinfo->config = config;
447 421
448 if (nf_ct_l3proto_try_module_get(target->family) < 0) { 422 if (nf_ct_l3proto_try_module_get(target->family) < 0) {
449 printk(KERN_WARNING "can't load conntrack support for " 423 printk(KERN_WARNING "can't load conntrack support for "
450 "proto=%d\n", target->family); 424 "proto=%d\n", target->family);
451 return 0; 425 return false;
452 } 426 }
453 427
454 return 1; 428 return true;
455} 429}
456 430
457/* drop reference count of cluster config when rule is deleted */ 431/* drop reference count of cluster config when rule is deleted */
@@ -468,13 +442,30 @@ static void destroy(const struct xt_target *target, void *targinfo)
468 nf_ct_l3proto_module_put(target->family); 442 nf_ct_l3proto_module_put(target->family);
469} 443}
470 444
471static struct xt_target clusterip_tgt = { 445#ifdef CONFIG_COMPAT
446struct compat_ipt_clusterip_tgt_info
447{
448 u_int32_t flags;
449 u_int8_t clustermac[6];
450 u_int16_t num_total_nodes;
451 u_int16_t num_local_nodes;
452 u_int16_t local_nodes[CLUSTERIP_MAX_NODES];
453 u_int32_t hash_mode;
454 u_int32_t hash_initval;
455 compat_uptr_t config;
456};
457#endif /* CONFIG_COMPAT */
458
459static struct xt_target clusterip_tgt __read_mostly = {
472 .name = "CLUSTERIP", 460 .name = "CLUSTERIP",
473 .family = AF_INET, 461 .family = AF_INET,
474 .target = target, 462 .target = target,
475 .targetsize = sizeof(struct ipt_clusterip_tgt_info),
476 .checkentry = checkentry, 463 .checkentry = checkentry,
477 .destroy = destroy, 464 .destroy = destroy,
465 .targetsize = sizeof(struct ipt_clusterip_tgt_info),
466#ifdef CONFIG_COMPAT
467 .compatsize = sizeof(struct compat_ipt_clusterip_tgt_info),
468#endif /* CONFIG_COMPAT */
478 .me = THIS_MODULE 469 .me = THIS_MODULE
479}; 470};
480 471
@@ -491,7 +482,7 @@ struct arp_payload {
491 __be32 dst_ip; 482 __be32 dst_ip;
492} __attribute__ ((packed)); 483} __attribute__ ((packed));
493 484
494#ifdef CLUSTERIP_DEBUG 485#ifdef DEBUG
495static void arp_print(struct arp_payload *payload) 486static void arp_print(struct arp_payload *payload)
496{ 487{
497#define HBUFFERLEN 30 488#define HBUFFERLEN 30
@@ -547,8 +538,9 @@ arp_mangle(unsigned int hook,
547 * this wouldn't work, since we didn't subscribe the mcast group on 538 * this wouldn't work, since we didn't subscribe the mcast group on
548 * other interfaces */ 539 * other interfaces */
549 if (c->dev != out) { 540 if (c->dev != out) {
550 DEBUGP("CLUSTERIP: not mangling arp reply on different " 541 pr_debug("CLUSTERIP: not mangling arp reply on different "
551 "interface: cip'%s'-skb'%s'\n", c->dev->name, out->name); 542 "interface: cip'%s'-skb'%s'\n",
543 c->dev->name, out->name);
552 clusterip_config_put(c); 544 clusterip_config_put(c);
553 return NF_ACCEPT; 545 return NF_ACCEPT;
554 } 546 }
@@ -556,8 +548,8 @@ arp_mangle(unsigned int hook,
556 /* mangle reply hardware address */ 548 /* mangle reply hardware address */
557 memcpy(payload->src_hw, c->clustermac, arp->ar_hln); 549 memcpy(payload->src_hw, c->clustermac, arp->ar_hln);
558 550
559#ifdef CLUSTERIP_DEBUG 551#ifdef DEBUG
560 DEBUGP(KERN_DEBUG "CLUSTERIP mangled arp reply: "); 552 pr_debug(KERN_DEBUG "CLUSTERIP mangled arp reply: ");
561 arp_print(payload); 553 arp_print(payload);
562#endif 554#endif
563 555
@@ -647,7 +639,7 @@ static int clusterip_seq_show(struct seq_file *s, void *v)
647 return 0; 639 return 0;
648} 640}
649 641
650static struct seq_operations clusterip_seq_ops = { 642static const struct seq_operations clusterip_seq_ops = {
651 .start = clusterip_seq_start, 643 .start = clusterip_seq_start,
652 .next = clusterip_seq_next, 644 .next = clusterip_seq_next,
653 .stop = clusterip_seq_stop, 645 .stop = clusterip_seq_stop,
diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c
index 918ca92e534a..f1253bd3837f 100644
--- a/net/ipv4/netfilter/ipt_ECN.c
+++ b/net/ipv4/netfilter/ipt_ECN.c
@@ -24,8 +24,8 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
24MODULE_DESCRIPTION("iptables ECN modification module"); 24MODULE_DESCRIPTION("iptables ECN modification module");
25 25
26/* set ECT codepoint from IP header. 26/* set ECT codepoint from IP header.
27 * return 0 if there was an error. */ 27 * return false if there was an error. */
28static inline int 28static inline bool
29set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo) 29set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
30{ 30{
31 struct iphdr *iph = ip_hdr(*pskb); 31 struct iphdr *iph = ip_hdr(*pskb);
@@ -33,18 +33,18 @@ set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
33 if ((iph->tos & IPT_ECN_IP_MASK) != (einfo->ip_ect & IPT_ECN_IP_MASK)) { 33 if ((iph->tos & IPT_ECN_IP_MASK) != (einfo->ip_ect & IPT_ECN_IP_MASK)) {
34 __u8 oldtos; 34 __u8 oldtos;
35 if (!skb_make_writable(pskb, sizeof(struct iphdr))) 35 if (!skb_make_writable(pskb, sizeof(struct iphdr)))
36 return 0; 36 return false;
37 iph = ip_hdr(*pskb); 37 iph = ip_hdr(*pskb);
38 oldtos = iph->tos; 38 oldtos = iph->tos;
39 iph->tos &= ~IPT_ECN_IP_MASK; 39 iph->tos &= ~IPT_ECN_IP_MASK;
40 iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK); 40 iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK);
41 nf_csum_replace2(&iph->check, htons(oldtos), htons(iph->tos)); 41 nf_csum_replace2(&iph->check, htons(oldtos), htons(iph->tos));
42 } 42 }
43 return 1; 43 return true;
44} 44}
45 45
46/* Return 0 if there was an error. */ 46/* Return false if there was an error. */
47static inline int 47static inline bool
48set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo) 48set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
49{ 49{
50 struct tcphdr _tcph, *tcph; 50 struct tcphdr _tcph, *tcph;
@@ -54,16 +54,16 @@ set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
54 tcph = skb_header_pointer(*pskb, ip_hdrlen(*pskb), 54 tcph = skb_header_pointer(*pskb, ip_hdrlen(*pskb),
55 sizeof(_tcph), &_tcph); 55 sizeof(_tcph), &_tcph);
56 if (!tcph) 56 if (!tcph)
57 return 0; 57 return false;
58 58
59 if ((!(einfo->operation & IPT_ECN_OP_SET_ECE) || 59 if ((!(einfo->operation & IPT_ECN_OP_SET_ECE) ||
60 tcph->ece == einfo->proto.tcp.ece) && 60 tcph->ece == einfo->proto.tcp.ece) &&
61 ((!(einfo->operation & IPT_ECN_OP_SET_CWR) || 61 (!(einfo->operation & IPT_ECN_OP_SET_CWR) ||
62 tcph->cwr == einfo->proto.tcp.cwr))) 62 tcph->cwr == einfo->proto.tcp.cwr))
63 return 1; 63 return true;
64 64
65 if (!skb_make_writable(pskb, ip_hdrlen(*pskb) + sizeof(*tcph))) 65 if (!skb_make_writable(pskb, ip_hdrlen(*pskb) + sizeof(*tcph)))
66 return 0; 66 return false;
67 tcph = (void *)ip_hdr(*pskb) + ip_hdrlen(*pskb); 67 tcph = (void *)ip_hdr(*pskb) + ip_hdrlen(*pskb);
68 68
69 oldval = ((__be16 *)tcph)[6]; 69 oldval = ((__be16 *)tcph)[6];
@@ -74,7 +74,7 @@ set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
74 74
75 nf_proto_csum_replace2(&tcph->check, *pskb, 75 nf_proto_csum_replace2(&tcph->check, *pskb,
76 oldval, ((__be16 *)tcph)[6], 0); 76 oldval, ((__be16 *)tcph)[6], 0);
77 return 1; 77 return true;
78} 78}
79 79
80static unsigned int 80static unsigned int
@@ -99,7 +99,7 @@ target(struct sk_buff **pskb,
99 return XT_CONTINUE; 99 return XT_CONTINUE;
100} 100}
101 101
102static int 102static bool
103checkentry(const char *tablename, 103checkentry(const char *tablename,
104 const void *e_void, 104 const void *e_void,
105 const struct xt_target *target, 105 const struct xt_target *target,
@@ -112,23 +112,23 @@ checkentry(const char *tablename,
112 if (einfo->operation & IPT_ECN_OP_MASK) { 112 if (einfo->operation & IPT_ECN_OP_MASK) {
113 printk(KERN_WARNING "ECN: unsupported ECN operation %x\n", 113 printk(KERN_WARNING "ECN: unsupported ECN operation %x\n",
114 einfo->operation); 114 einfo->operation);
115 return 0; 115 return false;
116 } 116 }
117 if (einfo->ip_ect & ~IPT_ECN_IP_MASK) { 117 if (einfo->ip_ect & ~IPT_ECN_IP_MASK) {
118 printk(KERN_WARNING "ECN: new ECT codepoint %x out of mask\n", 118 printk(KERN_WARNING "ECN: new ECT codepoint %x out of mask\n",
119 einfo->ip_ect); 119 einfo->ip_ect);
120 return 0; 120 return false;
121 } 121 }
122 if ((einfo->operation & (IPT_ECN_OP_SET_ECE|IPT_ECN_OP_SET_CWR)) 122 if ((einfo->operation & (IPT_ECN_OP_SET_ECE|IPT_ECN_OP_SET_CWR))
123 && (e->ip.proto != IPPROTO_TCP || (e->ip.invflags & XT_INV_PROTO))) { 123 && (e->ip.proto != IPPROTO_TCP || (e->ip.invflags & XT_INV_PROTO))) {
124 printk(KERN_WARNING "ECN: cannot use TCP operations on a " 124 printk(KERN_WARNING "ECN: cannot use TCP operations on a "
125 "non-tcp rule\n"); 125 "non-tcp rule\n");
126 return 0; 126 return false;
127 } 127 }
128 return 1; 128 return true;
129} 129}
130 130
131static struct xt_target ipt_ecn_reg = { 131static struct xt_target ipt_ecn_reg __read_mostly = {
132 .name = "ECN", 132 .name = "ECN",
133 .family = AF_INET, 133 .family = AF_INET,
134 .target = target, 134 .target = target,
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c
index a42c5cd968b1..5937ad150b9f 100644
--- a/net/ipv4/netfilter/ipt_LOG.c
+++ b/net/ipv4/netfilter/ipt_LOG.c
@@ -27,12 +27,6 @@ MODULE_LICENSE("GPL");
27MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 27MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
28MODULE_DESCRIPTION("iptables syslog logging module"); 28MODULE_DESCRIPTION("iptables syslog logging module");
29 29
30#if 0
31#define DEBUGP printk
32#else
33#define DEBUGP(format, args...)
34#endif
35
36/* Use lock to serialize, so printks don't overlap */ 30/* Use lock to serialize, so printks don't overlap */
37static DEFINE_SPINLOCK(log_lock); 31static DEFINE_SPINLOCK(log_lock);
38 32
@@ -41,7 +35,8 @@ static void dump_packet(const struct nf_loginfo *info,
41 const struct sk_buff *skb, 35 const struct sk_buff *skb,
42 unsigned int iphoff) 36 unsigned int iphoff)
43{ 37{
44 struct iphdr _iph, *ih; 38 struct iphdr _iph;
39 const struct iphdr *ih;
45 unsigned int logflags; 40 unsigned int logflags;
46 41
47 if (info->type == NF_LOG_TYPE_LOG) 42 if (info->type == NF_LOG_TYPE_LOG)
@@ -100,7 +95,8 @@ static void dump_packet(const struct nf_loginfo *info,
100 95
101 switch (ih->protocol) { 96 switch (ih->protocol) {
102 case IPPROTO_TCP: { 97 case IPPROTO_TCP: {
103 struct tcphdr _tcph, *th; 98 struct tcphdr _tcph;
99 const struct tcphdr *th;
104 100
105 /* Max length: 10 "PROTO=TCP " */ 101 /* Max length: 10 "PROTO=TCP " */
106 printk("PROTO=TCP "); 102 printk("PROTO=TCP ");
@@ -151,7 +147,7 @@ static void dump_packet(const struct nf_loginfo *info,
151 if ((logflags & IPT_LOG_TCPOPT) 147 if ((logflags & IPT_LOG_TCPOPT)
152 && th->doff * 4 > sizeof(struct tcphdr)) { 148 && th->doff * 4 > sizeof(struct tcphdr)) {
153 unsigned char _opt[4 * 15 - sizeof(struct tcphdr)]; 149 unsigned char _opt[4 * 15 - sizeof(struct tcphdr)];
154 unsigned char *op; 150 const unsigned char *op;
155 unsigned int i, optsize; 151 unsigned int i, optsize;
156 152
157 optsize = th->doff * 4 - sizeof(struct tcphdr); 153 optsize = th->doff * 4 - sizeof(struct tcphdr);
@@ -173,7 +169,8 @@ static void dump_packet(const struct nf_loginfo *info,
173 } 169 }
174 case IPPROTO_UDP: 170 case IPPROTO_UDP:
175 case IPPROTO_UDPLITE: { 171 case IPPROTO_UDPLITE: {
176 struct udphdr _udph, *uh; 172 struct udphdr _udph;
173 const struct udphdr *uh;
177 174
178 if (ih->protocol == IPPROTO_UDP) 175 if (ih->protocol == IPPROTO_UDP)
179 /* Max length: 10 "PROTO=UDP " */ 176 /* Max length: 10 "PROTO=UDP " */
@@ -200,7 +197,8 @@ static void dump_packet(const struct nf_loginfo *info,
200 break; 197 break;
201 } 198 }
202 case IPPROTO_ICMP: { 199 case IPPROTO_ICMP: {
203 struct icmphdr _icmph, *ich; 200 struct icmphdr _icmph;
201 const struct icmphdr *ich;
204 static const size_t required_len[NR_ICMP_TYPES+1] 202 static const size_t required_len[NR_ICMP_TYPES+1]
205 = { [ICMP_ECHOREPLY] = 4, 203 = { [ICMP_ECHOREPLY] = 4,
206 [ICMP_DEST_UNREACH] 204 [ICMP_DEST_UNREACH]
@@ -285,7 +283,8 @@ static void dump_packet(const struct nf_loginfo *info,
285 } 283 }
286 /* Max Length */ 284 /* Max Length */
287 case IPPROTO_AH: { 285 case IPPROTO_AH: {
288 struct ip_auth_hdr _ahdr, *ah; 286 struct ip_auth_hdr _ahdr;
287 const struct ip_auth_hdr *ah;
289 288
290 if (ntohs(ih->frag_off) & IP_OFFSET) 289 if (ntohs(ih->frag_off) & IP_OFFSET)
291 break; 290 break;
@@ -307,7 +306,8 @@ static void dump_packet(const struct nf_loginfo *info,
307 break; 306 break;
308 } 307 }
309 case IPPROTO_ESP: { 308 case IPPROTO_ESP: {
310 struct ip_esp_hdr _esph, *eh; 309 struct ip_esp_hdr _esph;
310 const struct ip_esp_hdr *eh;
311 311
312 /* Max length: 10 "PROTO=ESP " */ 312 /* Max length: 10 "PROTO=ESP " */
313 printk("PROTO=ESP "); 313 printk("PROTO=ESP ");
@@ -385,11 +385,13 @@ ipt_log_packet(unsigned int pf,
385 out ? out->name : ""); 385 out ? out->name : "");
386#ifdef CONFIG_BRIDGE_NETFILTER 386#ifdef CONFIG_BRIDGE_NETFILTER
387 if (skb->nf_bridge) { 387 if (skb->nf_bridge) {
388 struct net_device *physindev = skb->nf_bridge->physindev; 388 const struct net_device *physindev;
389 struct net_device *physoutdev = skb->nf_bridge->physoutdev; 389 const struct net_device *physoutdev;
390 390
391 physindev = skb->nf_bridge->physindev;
391 if (physindev && in != physindev) 392 if (physindev && in != physindev)
392 printk("PHYSIN=%s ", physindev->name); 393 printk("PHYSIN=%s ", physindev->name);
394 physoutdev = skb->nf_bridge->physoutdev;
393 if (physoutdev && out != physoutdev) 395 if (physoutdev && out != physoutdev)
394 printk("PHYSOUT=%s ", physoutdev->name); 396 printk("PHYSOUT=%s ", physoutdev->name);
395 } 397 }
@@ -435,27 +437,27 @@ ipt_log_target(struct sk_buff **pskb,
435 return XT_CONTINUE; 437 return XT_CONTINUE;
436} 438}
437 439
438static int ipt_log_checkentry(const char *tablename, 440static bool ipt_log_checkentry(const char *tablename,
439 const void *e, 441 const void *e,
440 const struct xt_target *target, 442 const struct xt_target *target,
441 void *targinfo, 443 void *targinfo,
442 unsigned int hook_mask) 444 unsigned int hook_mask)
443{ 445{
444 const struct ipt_log_info *loginfo = targinfo; 446 const struct ipt_log_info *loginfo = targinfo;
445 447
446 if (loginfo->level >= 8) { 448 if (loginfo->level >= 8) {
447 DEBUGP("LOG: level %u >= 8\n", loginfo->level); 449 pr_debug("LOG: level %u >= 8\n", loginfo->level);
448 return 0; 450 return false;
449 } 451 }
450 if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') { 452 if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
451 DEBUGP("LOG: prefix term %i\n", 453 pr_debug("LOG: prefix term %i\n",
452 loginfo->prefix[sizeof(loginfo->prefix)-1]); 454 loginfo->prefix[sizeof(loginfo->prefix)-1]);
453 return 0; 455 return false;
454 } 456 }
455 return 1; 457 return true;
456} 458}
457 459
458static struct xt_target ipt_log_reg = { 460static struct xt_target ipt_log_reg __read_mostly = {
459 .name = "LOG", 461 .name = "LOG",
460 .family = AF_INET, 462 .family = AF_INET,
461 .target = ipt_log_target, 463 .target = ipt_log_target,
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index d4f2d7775330..7c4e4be7c8b3 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -27,17 +27,11 @@ MODULE_LICENSE("GPL");
27MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 27MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
28MODULE_DESCRIPTION("iptables MASQUERADE target module"); 28MODULE_DESCRIPTION("iptables MASQUERADE target module");
29 29
30#if 0
31#define DEBUGP printk
32#else
33#define DEBUGP(format, args...)
34#endif
35
36/* Lock protects masq region inside conntrack */ 30/* Lock protects masq region inside conntrack */
37static DEFINE_RWLOCK(masq_lock); 31static DEFINE_RWLOCK(masq_lock);
38 32
39/* FIXME: Multiple targets. --RR */ 33/* FIXME: Multiple targets. --RR */
40static int 34static bool
41masquerade_check(const char *tablename, 35masquerade_check(const char *tablename,
42 const void *e, 36 const void *e,
43 const struct xt_target *target, 37 const struct xt_target *target,
@@ -47,14 +41,14 @@ masquerade_check(const char *tablename,
47 const struct nf_nat_multi_range_compat *mr = targinfo; 41 const struct nf_nat_multi_range_compat *mr = targinfo;
48 42
49 if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { 43 if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
50 DEBUGP("masquerade_check: bad MAP_IPS.\n"); 44 pr_debug("masquerade_check: bad MAP_IPS.\n");
51 return 0; 45 return false;
52 } 46 }
53 if (mr->rangesize != 1) { 47 if (mr->rangesize != 1) {
54 DEBUGP("masquerade_check: bad rangesize %u.\n", mr->rangesize); 48 pr_debug("masquerade_check: bad rangesize %u\n", mr->rangesize);
55 return 0; 49 return false;
56 } 50 }
57 return 1; 51 return true;
58} 52}
59 53
60static unsigned int 54static unsigned int
@@ -70,7 +64,7 @@ masquerade_target(struct sk_buff **pskb,
70 enum ip_conntrack_info ctinfo; 64 enum ip_conntrack_info ctinfo;
71 struct nf_nat_range newrange; 65 struct nf_nat_range newrange;
72 const struct nf_nat_multi_range_compat *mr; 66 const struct nf_nat_multi_range_compat *mr;
73 struct rtable *rt; 67 const struct rtable *rt;
74 __be32 newsrc; 68 __be32 newsrc;
75 69
76 NF_CT_ASSERT(hooknum == NF_IP_POST_ROUTING); 70 NF_CT_ASSERT(hooknum == NF_IP_POST_ROUTING);
@@ -109,10 +103,10 @@ masquerade_target(struct sk_buff **pskb,
109 return nf_nat_setup_info(ct, &newrange, hooknum); 103 return nf_nat_setup_info(ct, &newrange, hooknum);
110} 104}
111 105
112static inline int 106static int
113device_cmp(struct nf_conn *i, void *ifindex) 107device_cmp(struct nf_conn *i, void *ifindex)
114{ 108{
115 struct nf_conn_nat *nat = nfct_nat(i); 109 const struct nf_conn_nat *nat = nfct_nat(i);
116 int ret; 110 int ret;
117 111
118 if (!nat) 112 if (!nat)
@@ -129,7 +123,7 @@ static int masq_device_event(struct notifier_block *this,
129 unsigned long event, 123 unsigned long event,
130 void *ptr) 124 void *ptr)
131{ 125{
132 struct net_device *dev = ptr; 126 const struct net_device *dev = ptr;
133 127
134 if (event == NETDEV_DOWN) { 128 if (event == NETDEV_DOWN) {
135 /* Device was downed. Search entire table for 129 /* Device was downed. Search entire table for
@@ -147,7 +141,7 @@ static int masq_inet_event(struct notifier_block *this,
147 unsigned long event, 141 unsigned long event,
148 void *ptr) 142 void *ptr)
149{ 143{
150 struct net_device *dev = ((struct in_ifaddr *)ptr)->ifa_dev->dev; 144 const struct net_device *dev = ((struct in_ifaddr *)ptr)->ifa_dev->dev;
151 145
152 if (event == NETDEV_DOWN) { 146 if (event == NETDEV_DOWN) {
153 /* IP address was deleted. Search entire table for 147 /* IP address was deleted. Search entire table for
@@ -169,7 +163,7 @@ static struct notifier_block masq_inet_notifier = {
169 .notifier_call = masq_inet_event, 163 .notifier_call = masq_inet_event,
170}; 164};
171 165
172static struct xt_target masquerade = { 166static struct xt_target masquerade __read_mostly = {
173 .name = "MASQUERADE", 167 .name = "MASQUERADE",
174 .family = AF_INET, 168 .family = AF_INET,
175 .target = masquerade_target, 169 .target = masquerade_target,
diff --git a/net/ipv4/netfilter/ipt_NETMAP.c b/net/ipv4/netfilter/ipt_NETMAP.c
index 068c69bce30e..41a011d5a065 100644
--- a/net/ipv4/netfilter/ipt_NETMAP.c
+++ b/net/ipv4/netfilter/ipt_NETMAP.c
@@ -18,18 +18,11 @@
18#include <linux/netfilter/x_tables.h> 18#include <linux/netfilter/x_tables.h>
19#include <net/netfilter/nf_nat_rule.h> 19#include <net/netfilter/nf_nat_rule.h>
20 20
21#define MODULENAME "NETMAP"
22MODULE_LICENSE("GPL"); 21MODULE_LICENSE("GPL");
23MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>"); 22MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>");
24MODULE_DESCRIPTION("iptables 1:1 NAT mapping of IP networks target"); 23MODULE_DESCRIPTION("iptables 1:1 NAT mapping of IP networks target");
25 24
26#if 0 25static bool
27#define DEBUGP printk
28#else
29#define DEBUGP(format, args...)
30#endif
31
32static int
33check(const char *tablename, 26check(const char *tablename,
34 const void *e, 27 const void *e,
35 const struct xt_target *target, 28 const struct xt_target *target,
@@ -39,14 +32,14 @@ check(const char *tablename,
39 const struct nf_nat_multi_range_compat *mr = targinfo; 32 const struct nf_nat_multi_range_compat *mr = targinfo;
40 33
41 if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) { 34 if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) {
42 DEBUGP(MODULENAME":check: bad MAP_IPS.\n"); 35 pr_debug("NETMAP:check: bad MAP_IPS.\n");
43 return 0; 36 return false;
44 } 37 }
45 if (mr->rangesize != 1) { 38 if (mr->rangesize != 1) {
46 DEBUGP(MODULENAME":check: bad rangesize %u.\n", mr->rangesize); 39 pr_debug("NETMAP:check: bad rangesize %u.\n", mr->rangesize);
47 return 0; 40 return false;
48 } 41 }
49 return 1; 42 return true;
50} 43}
51 44
52static unsigned int 45static unsigned int
@@ -85,8 +78,8 @@ target(struct sk_buff **pskb,
85 return nf_nat_setup_info(ct, &newrange, hooknum); 78 return nf_nat_setup_info(ct, &newrange, hooknum);
86} 79}
87 80
88static struct xt_target target_module = { 81static struct xt_target target_module __read_mostly = {
89 .name = MODULENAME, 82 .name = "NETMAP",
90 .family = AF_INET, 83 .family = AF_INET,
91 .target = target, 84 .target = target,
92 .targetsize = sizeof(struct nf_nat_multi_range_compat), 85 .targetsize = sizeof(struct nf_nat_multi_range_compat),
diff --git a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c
index 68cc76a198eb..6ac7a2373316 100644
--- a/net/ipv4/netfilter/ipt_REDIRECT.c
+++ b/net/ipv4/netfilter/ipt_REDIRECT.c
@@ -25,14 +25,8 @@ MODULE_LICENSE("GPL");
25MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 25MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
26MODULE_DESCRIPTION("iptables REDIRECT target module"); 26MODULE_DESCRIPTION("iptables REDIRECT target module");
27 27
28#if 0
29#define DEBUGP printk
30#else
31#define DEBUGP(format, args...)
32#endif
33
34/* FIXME: Take multiple ranges --RR */ 28/* FIXME: Take multiple ranges --RR */
35static int 29static bool
36redirect_check(const char *tablename, 30redirect_check(const char *tablename,
37 const void *e, 31 const void *e,
38 const struct xt_target *target, 32 const struct xt_target *target,
@@ -42,14 +36,14 @@ redirect_check(const char *tablename,
42 const struct nf_nat_multi_range_compat *mr = targinfo; 36 const struct nf_nat_multi_range_compat *mr = targinfo;
43 37
44 if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { 38 if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
45 DEBUGP("redirect_check: bad MAP_IPS.\n"); 39 pr_debug("redirect_check: bad MAP_IPS.\n");
46 return 0; 40 return false;
47 } 41 }
48 if (mr->rangesize != 1) { 42 if (mr->rangesize != 1) {
49 DEBUGP("redirect_check: bad rangesize %u.\n", mr->rangesize); 43 pr_debug("redirect_check: bad rangesize %u.\n", mr->rangesize);
50 return 0; 44 return false;
51 } 45 }
52 return 1; 46 return true;
53} 47}
54 48
55static unsigned int 49static unsigned int
@@ -101,7 +95,7 @@ redirect_target(struct sk_buff **pskb,
101 return nf_nat_setup_info(ct, &newrange, hooknum); 95 return nf_nat_setup_info(ct, &newrange, hooknum);
102} 96}
103 97
104static struct xt_target redirect_reg = { 98static struct xt_target redirect_reg __read_mostly = {
105 .name = "REDIRECT", 99 .name = "REDIRECT",
106 .family = AF_INET, 100 .family = AF_INET,
107 .target = redirect_target, 101 .target = redirect_target,
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index 9041e0741f6f..cb038c8fbc9d 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -31,12 +31,6 @@ MODULE_LICENSE("GPL");
31MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 31MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
32MODULE_DESCRIPTION("iptables REJECT target module"); 32MODULE_DESCRIPTION("iptables REJECT target module");
33 33
34#if 0
35#define DEBUGP printk
36#else
37#define DEBUGP(format, args...)
38#endif
39
40/* Send RST reply */ 34/* Send RST reply */
41static void send_reset(struct sk_buff *oldskb, int hook) 35static void send_reset(struct sk_buff *oldskb, int hook)
42{ 36{
@@ -122,7 +116,7 @@ static void send_reset(struct sk_buff *oldskb, int hook)
122 tcph->check = 0; 116 tcph->check = 0;
123 tcph->check = tcp_v4_check(sizeof(struct tcphdr), 117 tcph->check = tcp_v4_check(sizeof(struct tcphdr),
124 niph->saddr, niph->daddr, 118 niph->saddr, niph->daddr,
125 csum_partial((char *)tcph, 119 csum_partial(tcph,
126 sizeof(struct tcphdr), 0)); 120 sizeof(struct tcphdr), 0));
127 121
128 /* Set DF, id = 0 */ 122 /* Set DF, id = 0 */
@@ -217,30 +211,30 @@ static unsigned int reject(struct sk_buff **pskb,
217 return NF_DROP; 211 return NF_DROP;
218} 212}
219 213
220static int check(const char *tablename, 214static bool check(const char *tablename,
221 const void *e_void, 215 const void *e_void,
222 const struct xt_target *target, 216 const struct xt_target *target,
223 void *targinfo, 217 void *targinfo,
224 unsigned int hook_mask) 218 unsigned int hook_mask)
225{ 219{
226 const struct ipt_reject_info *rejinfo = targinfo; 220 const struct ipt_reject_info *rejinfo = targinfo;
227 const struct ipt_entry *e = e_void; 221 const struct ipt_entry *e = e_void;
228 222
229 if (rejinfo->with == IPT_ICMP_ECHOREPLY) { 223 if (rejinfo->with == IPT_ICMP_ECHOREPLY) {
230 printk("REJECT: ECHOREPLY no longer supported.\n"); 224 printk("ipt_REJECT: ECHOREPLY no longer supported.\n");
231 return 0; 225 return false;
232 } else if (rejinfo->with == IPT_TCP_RESET) { 226 } else if (rejinfo->with == IPT_TCP_RESET) {
233 /* Must specify that it's a TCP packet */ 227 /* Must specify that it's a TCP packet */
234 if (e->ip.proto != IPPROTO_TCP 228 if (e->ip.proto != IPPROTO_TCP
235 || (e->ip.invflags & XT_INV_PROTO)) { 229 || (e->ip.invflags & XT_INV_PROTO)) {
236 DEBUGP("REJECT: TCP_RESET invalid for non-tcp\n"); 230 printk("ipt_REJECT: TCP_RESET invalid for non-tcp\n");
237 return 0; 231 return false;
238 } 232 }
239 } 233 }
240 return 1; 234 return true;
241} 235}
242 236
243static struct xt_target ipt_reject_reg = { 237static struct xt_target ipt_reject_reg __read_mostly = {
244 .name = "REJECT", 238 .name = "REJECT",
245 .family = AF_INET, 239 .family = AF_INET,
246 .target = reject, 240 .target = reject,
diff --git a/net/ipv4/netfilter/ipt_SAME.c b/net/ipv4/netfilter/ipt_SAME.c
index 511e5ff84938..97641f1a97f6 100644
--- a/net/ipv4/netfilter/ipt_SAME.c
+++ b/net/ipv4/netfilter/ipt_SAME.c
@@ -27,13 +27,7 @@ MODULE_LICENSE("GPL");
27MODULE_AUTHOR("Martin Josefsson <gandalf@wlug.westbo.se>"); 27MODULE_AUTHOR("Martin Josefsson <gandalf@wlug.westbo.se>");
28MODULE_DESCRIPTION("iptables special SNAT module for consistent sourceip"); 28MODULE_DESCRIPTION("iptables special SNAT module for consistent sourceip");
29 29
30#if 0 30static bool
31#define DEBUGP printk
32#else
33#define DEBUGP(format, args...)
34#endif
35
36static int
37same_check(const char *tablename, 31same_check(const char *tablename,
38 const void *e, 32 const void *e,
39 const struct xt_target *target, 33 const struct xt_target *target,
@@ -46,58 +40,56 @@ same_check(const char *tablename,
46 mr->ipnum = 0; 40 mr->ipnum = 0;
47 41
48 if (mr->rangesize < 1) { 42 if (mr->rangesize < 1) {
49 DEBUGP("same_check: need at least one dest range.\n"); 43 pr_debug("same_check: need at least one dest range.\n");
50 return 0; 44 return false;
51 } 45 }
52 if (mr->rangesize > IPT_SAME_MAX_RANGE) { 46 if (mr->rangesize > IPT_SAME_MAX_RANGE) {
53 DEBUGP("same_check: too many ranges specified, maximum " 47 pr_debug("same_check: too many ranges specified, maximum "
54 "is %u ranges\n", 48 "is %u ranges\n", IPT_SAME_MAX_RANGE);
55 IPT_SAME_MAX_RANGE); 49 return false;
56 return 0;
57 } 50 }
58 for (count = 0; count < mr->rangesize; count++) { 51 for (count = 0; count < mr->rangesize; count++) {
59 if (ntohl(mr->range[count].min_ip) > 52 if (ntohl(mr->range[count].min_ip) >
60 ntohl(mr->range[count].max_ip)) { 53 ntohl(mr->range[count].max_ip)) {
61 DEBUGP("same_check: min_ip is larger than max_ip in " 54 pr_debug("same_check: min_ip is larger than max_ip in "
62 "range `%u.%u.%u.%u-%u.%u.%u.%u'.\n", 55 "range `%u.%u.%u.%u-%u.%u.%u.%u'.\n",
63 NIPQUAD(mr->range[count].min_ip), 56 NIPQUAD(mr->range[count].min_ip),
64 NIPQUAD(mr->range[count].max_ip)); 57 NIPQUAD(mr->range[count].max_ip));
65 return 0; 58 return false;
66 } 59 }
67 if (!(mr->range[count].flags & IP_NAT_RANGE_MAP_IPS)) { 60 if (!(mr->range[count].flags & IP_NAT_RANGE_MAP_IPS)) {
68 DEBUGP("same_check: bad MAP_IPS.\n"); 61 pr_debug("same_check: bad MAP_IPS.\n");
69 return 0; 62 return false;
70 } 63 }
71 rangeip = (ntohl(mr->range[count].max_ip) - 64 rangeip = (ntohl(mr->range[count].max_ip) -
72 ntohl(mr->range[count].min_ip) + 1); 65 ntohl(mr->range[count].min_ip) + 1);
73 mr->ipnum += rangeip; 66 mr->ipnum += rangeip;
74 67
75 DEBUGP("same_check: range %u, ipnum = %u\n", count, rangeip); 68 pr_debug("same_check: range %u, ipnum = %u\n", count, rangeip);
76 } 69 }
77 DEBUGP("same_check: total ipaddresses = %u\n", mr->ipnum); 70 pr_debug("same_check: total ipaddresses = %u\n", mr->ipnum);
78 71
79 mr->iparray = kmalloc((sizeof(u_int32_t) * mr->ipnum), GFP_KERNEL); 72 mr->iparray = kmalloc((sizeof(u_int32_t) * mr->ipnum), GFP_KERNEL);
80 if (!mr->iparray) { 73 if (!mr->iparray) {
81 DEBUGP("same_check: Couldn't allocate %u bytes " 74 pr_debug("same_check: Couldn't allocate %Zu bytes "
82 "for %u ipaddresses!\n", 75 "for %u ipaddresses!\n",
83 (sizeof(u_int32_t) * mr->ipnum), mr->ipnum); 76 (sizeof(u_int32_t) * mr->ipnum), mr->ipnum);
84 return 0; 77 return false;
85 } 78 }
86 DEBUGP("same_check: Allocated %u bytes for %u ipaddresses.\n", 79 pr_debug("same_check: Allocated %Zu bytes for %u ipaddresses.\n",
87 (sizeof(u_int32_t) * mr->ipnum), mr->ipnum); 80 (sizeof(u_int32_t) * mr->ipnum), mr->ipnum);
88 81
89 for (count = 0; count < mr->rangesize; count++) { 82 for (count = 0; count < mr->rangesize; count++) {
90 for (countess = ntohl(mr->range[count].min_ip); 83 for (countess = ntohl(mr->range[count].min_ip);
91 countess <= ntohl(mr->range[count].max_ip); 84 countess <= ntohl(mr->range[count].max_ip);
92 countess++) { 85 countess++) {
93 mr->iparray[index] = countess; 86 mr->iparray[index] = countess;
94 DEBUGP("same_check: Added ipaddress `%u.%u.%u.%u' " 87 pr_debug("same_check: Added ipaddress `%u.%u.%u.%u' "
95 "in index %u.\n", 88 "in index %u.\n", HIPQUAD(countess), index);
96 HIPQUAD(countess), index);
97 index++; 89 index++;
98 } 90 }
99 } 91 }
100 return 1; 92 return true;
101} 93}
102 94
103static void 95static void
@@ -107,8 +99,8 @@ same_destroy(const struct xt_target *target, void *targinfo)
107 99
108 kfree(mr->iparray); 100 kfree(mr->iparray);
109 101
110 DEBUGP("same_destroy: Deallocated %u bytes for %u ipaddresses.\n", 102 pr_debug("same_destroy: Deallocated %Zu bytes for %u ipaddresses.\n",
111 (sizeof(u_int32_t) * mr->ipnum), mr->ipnum); 103 (sizeof(u_int32_t) * mr->ipnum), mr->ipnum);
112} 104}
113 105
114static unsigned int 106static unsigned int
@@ -146,10 +138,9 @@ same_target(struct sk_buff **pskb,
146 138
147 new_ip = htonl(same->iparray[aindex]); 139 new_ip = htonl(same->iparray[aindex]);
148 140
149 DEBUGP("ipt_SAME: src=%u.%u.%u.%u dst=%u.%u.%u.%u, " 141 pr_debug("ipt_SAME: src=%u.%u.%u.%u dst=%u.%u.%u.%u, "
150 "new src=%u.%u.%u.%u\n", 142 "new src=%u.%u.%u.%u\n",
151 NIPQUAD(t->src.ip), NIPQUAD(t->dst.ip), 143 NIPQUAD(t->src.u3.ip), NIPQUAD(t->dst.u3.ip), NIPQUAD(new_ip));
152 NIPQUAD(new_ip));
153 144
154 /* Transfer from original range. */ 145 /* Transfer from original range. */
155 newrange = ((struct nf_nat_range) 146 newrange = ((struct nf_nat_range)
@@ -161,7 +152,7 @@ same_target(struct sk_buff **pskb,
161 return nf_nat_setup_info(ct, &newrange, hooknum); 152 return nf_nat_setup_info(ct, &newrange, hooknum);
162} 153}
163 154
164static struct xt_target same_reg = { 155static struct xt_target same_reg __read_mostly = {
165 .name = "SAME", 156 .name = "SAME",
166 .family = AF_INET, 157 .family = AF_INET,
167 .target = same_target, 158 .target = same_target,
diff --git a/net/ipv4/netfilter/ipt_TOS.c b/net/ipv4/netfilter/ipt_TOS.c
index 0ad02f249837..25f5d0b39065 100644
--- a/net/ipv4/netfilter/ipt_TOS.c
+++ b/net/ipv4/netfilter/ipt_TOS.c
@@ -43,7 +43,7 @@ target(struct sk_buff **pskb,
43 return XT_CONTINUE; 43 return XT_CONTINUE;
44} 44}
45 45
46static int 46static bool
47checkentry(const char *tablename, 47checkentry(const char *tablename,
48 const void *e_void, 48 const void *e_void,
49 const struct xt_target *target, 49 const struct xt_target *target,
@@ -58,12 +58,12 @@ checkentry(const char *tablename,
58 && tos != IPTOS_MINCOST 58 && tos != IPTOS_MINCOST
59 && tos != IPTOS_NORMALSVC) { 59 && tos != IPTOS_NORMALSVC) {
60 printk(KERN_WARNING "TOS: bad tos value %#x\n", tos); 60 printk(KERN_WARNING "TOS: bad tos value %#x\n", tos);
61 return 0; 61 return false;
62 } 62 }
63 return 1; 63 return true;
64} 64}
65 65
66static struct xt_target ipt_tos_reg = { 66static struct xt_target ipt_tos_reg __read_mostly = {
67 .name = "TOS", 67 .name = "TOS",
68 .family = AF_INET, 68 .family = AF_INET,
69 .target = target, 69 .target = target,
diff --git a/net/ipv4/netfilter/ipt_TTL.c b/net/ipv4/netfilter/ipt_TTL.c
index a991ec7bd4e7..2b54e7b0cfe8 100644
--- a/net/ipv4/netfilter/ipt_TTL.c
+++ b/net/ipv4/netfilter/ipt_TTL.c
@@ -62,25 +62,25 @@ ipt_ttl_target(struct sk_buff **pskb,
62 return XT_CONTINUE; 62 return XT_CONTINUE;
63} 63}
64 64
65static int ipt_ttl_checkentry(const char *tablename, 65static bool ipt_ttl_checkentry(const char *tablename,
66 const void *e, 66 const void *e,
67 const struct xt_target *target, 67 const struct xt_target *target,
68 void *targinfo, 68 void *targinfo,
69 unsigned int hook_mask) 69 unsigned int hook_mask)
70{ 70{
71 struct ipt_TTL_info *info = targinfo; 71 const struct ipt_TTL_info *info = targinfo;
72 72
73 if (info->mode > IPT_TTL_MAXMODE) { 73 if (info->mode > IPT_TTL_MAXMODE) {
74 printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n", 74 printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n",
75 info->mode); 75 info->mode);
76 return 0; 76 return false;
77 } 77 }
78 if ((info->mode != IPT_TTL_SET) && (info->ttl == 0)) 78 if (info->mode != IPT_TTL_SET && info->ttl == 0)
79 return 0; 79 return false;
80 return 1; 80 return true;
81} 81}
82 82
83static struct xt_target ipt_TTL = { 83static struct xt_target ipt_TTL __read_mostly = {
84 .name = "TTL", 84 .name = "TTL",
85 .family = AF_INET, 85 .family = AF_INET,
86 .target = ipt_ttl_target, 86 .target = ipt_ttl_target,
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index 23b607b33b32..6ca43e4ca7e3 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -55,13 +55,6 @@ MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NFLOG);
55#define ULOG_NL_EVENT 111 /* Harald's favorite number */ 55#define ULOG_NL_EVENT 111 /* Harald's favorite number */
56#define ULOG_MAXNLGROUPS 32 /* numer of nlgroups */ 56#define ULOG_MAXNLGROUPS 32 /* numer of nlgroups */
57 57
58#if 0
59#define DEBUGP(format, args...) printk("%s:%s:" format, \
60 __FILE__, __FUNCTION__ , ## args)
61#else
62#define DEBUGP(format, args...)
63#endif
64
65#define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0) 58#define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0)
66 59
67static unsigned int nlbufsiz = NLMSG_GOODSIZE; 60static unsigned int nlbufsiz = NLMSG_GOODSIZE;
@@ -96,12 +89,12 @@ static void ulog_send(unsigned int nlgroupnum)
96 ulog_buff_t *ub = &ulog_buffers[nlgroupnum]; 89 ulog_buff_t *ub = &ulog_buffers[nlgroupnum];
97 90
98 if (timer_pending(&ub->timer)) { 91 if (timer_pending(&ub->timer)) {
99 DEBUGP("ipt_ULOG: ulog_send: timer was pending, deleting\n"); 92 pr_debug("ipt_ULOG: ulog_send: timer was pending, deleting\n");
100 del_timer(&ub->timer); 93 del_timer(&ub->timer);
101 } 94 }
102 95
103 if (!ub->skb) { 96 if (!ub->skb) {
104 DEBUGP("ipt_ULOG: ulog_send: nothing to send\n"); 97 pr_debug("ipt_ULOG: ulog_send: nothing to send\n");
105 return; 98 return;
106 } 99 }
107 100
@@ -110,8 +103,8 @@ static void ulog_send(unsigned int nlgroupnum)
110 ub->lastnlh->nlmsg_type = NLMSG_DONE; 103 ub->lastnlh->nlmsg_type = NLMSG_DONE;
111 104
112 NETLINK_CB(ub->skb).dst_group = nlgroupnum + 1; 105 NETLINK_CB(ub->skb).dst_group = nlgroupnum + 1;
113 DEBUGP("ipt_ULOG: throwing %d packets to netlink group %u\n", 106 pr_debug("ipt_ULOG: throwing %d packets to netlink group %u\n",
114 ub->qlen, nlgroupnum + 1); 107 ub->qlen, nlgroupnum + 1);
115 netlink_broadcast(nflognl, ub->skb, 0, nlgroupnum + 1, GFP_ATOMIC); 108 netlink_broadcast(nflognl, ub->skb, 0, nlgroupnum + 1, GFP_ATOMIC);
116 109
117 ub->qlen = 0; 110 ub->qlen = 0;
@@ -123,7 +116,7 @@ static void ulog_send(unsigned int nlgroupnum)
123/* timer function to flush queue in flushtimeout time */ 116/* timer function to flush queue in flushtimeout time */
124static void ulog_timer(unsigned long data) 117static void ulog_timer(unsigned long data)
125{ 118{
126 DEBUGP("ipt_ULOG: timer function called, calling ulog_send\n"); 119 pr_debug("ipt_ULOG: timer function called, calling ulog_send\n");
127 120
128 /* lock to protect against somebody modifying our structure 121 /* lock to protect against somebody modifying our structure
129 * from ipt_ulog_target at the same time */ 122 * from ipt_ulog_target at the same time */
@@ -179,12 +172,10 @@ static void ipt_ulog_packet(unsigned int hooknum,
179 unsigned int groupnum = ffs(loginfo->nl_group) - 1; 172 unsigned int groupnum = ffs(loginfo->nl_group) - 1;
180 173
181 /* calculate the size of the skb needed */ 174 /* calculate the size of the skb needed */
182 if ((loginfo->copy_range == 0) || 175 if (loginfo->copy_range == 0 || loginfo->copy_range > skb->len)
183 (loginfo->copy_range > skb->len)) {
184 copy_len = skb->len; 176 copy_len = skb->len;
185 } else { 177 else
186 copy_len = loginfo->copy_range; 178 copy_len = loginfo->copy_range;
187 }
188 179
189 size = NLMSG_SPACE(sizeof(*pm) + copy_len); 180 size = NLMSG_SPACE(sizeof(*pm) + copy_len);
190 181
@@ -206,8 +197,8 @@ static void ipt_ulog_packet(unsigned int hooknum,
206 goto alloc_failure; 197 goto alloc_failure;
207 } 198 }
208 199
209 DEBUGP("ipt_ULOG: qlen %d, qthreshold %d\n", ub->qlen, 200 pr_debug("ipt_ULOG: qlen %d, qthreshold %Zu\n", ub->qlen,
210 loginfo->qthreshold); 201 loginfo->qthreshold);
211 202
212 /* NLMSG_PUT contains a hidden goto nlmsg_failure !!! */ 203 /* NLMSG_PUT contains a hidden goto nlmsg_failure !!! */
213 nlh = NLMSG_PUT(ub->skb, 0, ub->qlen, ULOG_NL_EVENT, 204 nlh = NLMSG_PUT(ub->skb, 0, ub->qlen, ULOG_NL_EVENT,
@@ -257,9 +248,8 @@ static void ipt_ulog_packet(unsigned int hooknum,
257 BUG(); 248 BUG();
258 249
259 /* check if we are building multi-part messages */ 250 /* check if we are building multi-part messages */
260 if (ub->qlen > 1) { 251 if (ub->qlen > 1)
261 ub->lastnlh->nlmsg_flags |= NLM_F_MULTI; 252 ub->lastnlh->nlmsg_flags |= NLM_F_MULTI;
262 }
263 253
264 ub->lastnlh = nlh; 254 ub->lastnlh = nlh;
265 255
@@ -328,25 +318,25 @@ static void ipt_logfn(unsigned int pf,
328 ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); 318 ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
329} 319}
330 320
331static int ipt_ulog_checkentry(const char *tablename, 321static bool ipt_ulog_checkentry(const char *tablename,
332 const void *e, 322 const void *e,
333 const struct xt_target *target, 323 const struct xt_target *target,
334 void *targinfo, 324 void *targinfo,
335 unsigned int hookmask) 325 unsigned int hookmask)
336{ 326{
337 struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo; 327 const struct ipt_ulog_info *loginfo = targinfo;
338 328
339 if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') { 329 if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') {
340 DEBUGP("ipt_ULOG: prefix term %i\n", 330 pr_debug("ipt_ULOG: prefix term %i\n",
341 loginfo->prefix[sizeof(loginfo->prefix) - 1]); 331 loginfo->prefix[sizeof(loginfo->prefix) - 1]);
342 return 0; 332 return false;
343 } 333 }
344 if (loginfo->qthreshold > ULOG_MAX_QLEN) { 334 if (loginfo->qthreshold > ULOG_MAX_QLEN) {
345 DEBUGP("ipt_ULOG: queue threshold %i > MAX_QLEN\n", 335 pr_debug("ipt_ULOG: queue threshold %Zu > MAX_QLEN\n",
346 loginfo->qthreshold); 336 loginfo->qthreshold);
347 return 0; 337 return false;
348 } 338 }
349 return 1; 339 return true;
350} 340}
351 341
352#ifdef CONFIG_COMPAT 342#ifdef CONFIG_COMPAT
@@ -359,7 +349,7 @@ struct compat_ipt_ulog_info {
359 349
360static void compat_from_user(void *dst, void *src) 350static void compat_from_user(void *dst, void *src)
361{ 351{
362 struct compat_ipt_ulog_info *cl = src; 352 const struct compat_ipt_ulog_info *cl = src;
363 struct ipt_ulog_info l = { 353 struct ipt_ulog_info l = {
364 .nl_group = cl->nl_group, 354 .nl_group = cl->nl_group,
365 .copy_range = cl->copy_range, 355 .copy_range = cl->copy_range,
@@ -372,7 +362,7 @@ static void compat_from_user(void *dst, void *src)
372 362
373static int compat_to_user(void __user *dst, void *src) 363static int compat_to_user(void __user *dst, void *src)
374{ 364{
375 struct ipt_ulog_info *l = src; 365 const struct ipt_ulog_info *l = src;
376 struct compat_ipt_ulog_info cl = { 366 struct compat_ipt_ulog_info cl = {
377 .nl_group = l->nl_group, 367 .nl_group = l->nl_group,
378 .copy_range = l->copy_range, 368 .copy_range = l->copy_range,
@@ -384,7 +374,7 @@ static int compat_to_user(void __user *dst, void *src)
384} 374}
385#endif /* CONFIG_COMPAT */ 375#endif /* CONFIG_COMPAT */
386 376
387static struct xt_target ipt_ulog_reg = { 377static struct xt_target ipt_ulog_reg __read_mostly = {
388 .name = "ULOG", 378 .name = "ULOG",
389 .family = AF_INET, 379 .family = AF_INET,
390 .target = ipt_ulog_target, 380 .target = ipt_ulog_target,
@@ -408,7 +398,7 @@ static int __init ipt_ulog_init(void)
408{ 398{
409 int ret, i; 399 int ret, i;
410 400
411 DEBUGP("ipt_ULOG: init module\n"); 401 pr_debug("ipt_ULOG: init module\n");
412 402
413 if (nlbufsiz > 128*1024) { 403 if (nlbufsiz > 128*1024) {
414 printk("Netlink buffer has to be <= 128kB\n"); 404 printk("Netlink buffer has to be <= 128kB\n");
@@ -440,7 +430,7 @@ static void __exit ipt_ulog_fini(void)
440 ulog_buff_t *ub; 430 ulog_buff_t *ub;
441 int i; 431 int i;
442 432
443 DEBUGP("ipt_ULOG: cleanup_module\n"); 433 pr_debug("ipt_ULOG: cleanup_module\n");
444 434
445 if (nflog) 435 if (nflog)
446 nf_log_unregister(&ipt_ulog_logger); 436 nf_log_unregister(&ipt_ulog_logger);
@@ -451,7 +441,7 @@ static void __exit ipt_ulog_fini(void)
451 for (i = 0; i < ULOG_MAXNLGROUPS; i++) { 441 for (i = 0; i < ULOG_MAXNLGROUPS; i++) {
452 ub = &ulog_buffers[i]; 442 ub = &ulog_buffers[i];
453 if (timer_pending(&ub->timer)) { 443 if (timer_pending(&ub->timer)) {
454 DEBUGP("timer was pending, deleting\n"); 444 pr_debug("timer was pending, deleting\n");
455 del_timer(&ub->timer); 445 del_timer(&ub->timer);
456 } 446 }
457 447
diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c
index a652a1451552..59f01f7ba6b4 100644
--- a/net/ipv4/netfilter/ipt_addrtype.c
+++ b/net/ipv4/netfilter/ipt_addrtype.c
@@ -22,19 +22,19 @@ MODULE_LICENSE("GPL");
22MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 22MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
23MODULE_DESCRIPTION("iptables addrtype match"); 23MODULE_DESCRIPTION("iptables addrtype match");
24 24
25static inline int match_type(__be32 addr, u_int16_t mask) 25static inline bool match_type(__be32 addr, u_int16_t mask)
26{ 26{
27 return !!(mask & (1 << inet_addr_type(addr))); 27 return !!(mask & (1 << inet_addr_type(addr)));
28} 28}
29 29
30static int match(const struct sk_buff *skb, 30static bool match(const struct sk_buff *skb,
31 const struct net_device *in, const struct net_device *out, 31 const struct net_device *in, const struct net_device *out,
32 const struct xt_match *match, const void *matchinfo, 32 const struct xt_match *match, const void *matchinfo,
33 int offset, unsigned int protoff, int *hotdrop) 33 int offset, unsigned int protoff, bool *hotdrop)
34{ 34{
35 const struct ipt_addrtype_info *info = matchinfo; 35 const struct ipt_addrtype_info *info = matchinfo;
36 const struct iphdr *iph = ip_hdr(skb); 36 const struct iphdr *iph = ip_hdr(skb);
37 int ret = 1; 37 bool ret = true;
38 38
39 if (info->source) 39 if (info->source)
40 ret &= match_type(iph->saddr, info->source)^info->invert_source; 40 ret &= match_type(iph->saddr, info->source)^info->invert_source;
@@ -44,7 +44,7 @@ static int match(const struct sk_buff *skb,
44 return ret; 44 return ret;
45} 45}
46 46
47static struct xt_match addrtype_match = { 47static struct xt_match addrtype_match __read_mostly = {
48 .name = "addrtype", 48 .name = "addrtype",
49 .family = AF_INET, 49 .family = AF_INET,
50 .match = match, 50 .match = match,
diff --git a/net/ipv4/netfilter/ipt_ah.c b/net/ipv4/netfilter/ipt_ah.c
index 18a16782cf40..61b017fd743c 100644
--- a/net/ipv4/netfilter/ipt_ah.c
+++ b/net/ipv4/netfilter/ipt_ah.c
@@ -25,10 +25,10 @@ MODULE_DESCRIPTION("iptables AH SPI match module");
25#endif 25#endif
26 26
27/* Returns 1 if the spi is matched by the range, 0 otherwise */ 27/* Returns 1 if the spi is matched by the range, 0 otherwise */
28static inline int 28static inline bool
29spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert) 29spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
30{ 30{
31 int r=0; 31 bool r;
32 duprintf("ah spi_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ', 32 duprintf("ah spi_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ',
33 min,spi,max); 33 min,spi,max);
34 r=(spi >= min && spi <= max) ^ invert; 34 r=(spi >= min && spi <= max) ^ invert;
@@ -36,7 +36,7 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert)
36 return r; 36 return r;
37} 37}
38 38
39static int 39static bool
40match(const struct sk_buff *skb, 40match(const struct sk_buff *skb,
41 const struct net_device *in, 41 const struct net_device *in,
42 const struct net_device *out, 42 const struct net_device *out,
@@ -44,14 +44,15 @@ match(const struct sk_buff *skb,
44 const void *matchinfo, 44 const void *matchinfo,
45 int offset, 45 int offset,
46 unsigned int protoff, 46 unsigned int protoff,
47 int *hotdrop) 47 bool *hotdrop)
48{ 48{
49 struct ip_auth_hdr _ahdr, *ah; 49 struct ip_auth_hdr _ahdr;
50 const struct ip_auth_hdr *ah;
50 const struct ipt_ah *ahinfo = matchinfo; 51 const struct ipt_ah *ahinfo = matchinfo;
51 52
52 /* Must not be a fragment. */ 53 /* Must not be a fragment. */
53 if (offset) 54 if (offset)
54 return 0; 55 return false;
55 56
56 ah = skb_header_pointer(skb, protoff, 57 ah = skb_header_pointer(skb, protoff,
57 sizeof(_ahdr), &_ahdr); 58 sizeof(_ahdr), &_ahdr);
@@ -60,7 +61,7 @@ match(const struct sk_buff *skb,
60 * can't. Hence, no choice but to drop. 61 * can't. Hence, no choice but to drop.
61 */ 62 */
62 duprintf("Dropping evil AH tinygram.\n"); 63 duprintf("Dropping evil AH tinygram.\n");
63 *hotdrop = 1; 64 *hotdrop = true;
64 return 0; 65 return 0;
65 } 66 }
66 67
@@ -70,7 +71,7 @@ match(const struct sk_buff *skb,
70} 71}
71 72
72/* Called when user tries to insert an entry of this type. */ 73/* Called when user tries to insert an entry of this type. */
73static int 74static bool
74checkentry(const char *tablename, 75checkentry(const char *tablename,
75 const void *ip_void, 76 const void *ip_void,
76 const struct xt_match *match, 77 const struct xt_match *match,
@@ -82,12 +83,12 @@ checkentry(const char *tablename,
82 /* Must specify no unknown invflags */ 83 /* Must specify no unknown invflags */
83 if (ahinfo->invflags & ~IPT_AH_INV_MASK) { 84 if (ahinfo->invflags & ~IPT_AH_INV_MASK) {
84 duprintf("ipt_ah: unknown flags %X\n", ahinfo->invflags); 85 duprintf("ipt_ah: unknown flags %X\n", ahinfo->invflags);
85 return 0; 86 return false;
86 } 87 }
87 return 1; 88 return true;
88} 89}
89 90
90static struct xt_match ah_match = { 91static struct xt_match ah_match __read_mostly = {
91 .name = "ah", 92 .name = "ah",
92 .family = AF_INET, 93 .family = AF_INET,
93 .match = match, 94 .match = match,
diff --git a/net/ipv4/netfilter/ipt_ecn.c b/net/ipv4/netfilter/ipt_ecn.c
index 26218122f865..d6925c674069 100644
--- a/net/ipv4/netfilter/ipt_ecn.c
+++ b/net/ipv4/netfilter/ipt_ecn.c
@@ -22,95 +22,96 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
22MODULE_DESCRIPTION("iptables ECN matching module"); 22MODULE_DESCRIPTION("iptables ECN matching module");
23MODULE_LICENSE("GPL"); 23MODULE_LICENSE("GPL");
24 24
25static inline int match_ip(const struct sk_buff *skb, 25static inline bool match_ip(const struct sk_buff *skb,
26 const struct ipt_ecn_info *einfo) 26 const struct ipt_ecn_info *einfo)
27{ 27{
28 return (ip_hdr(skb)->tos & IPT_ECN_IP_MASK) == einfo->ip_ect; 28 return (ip_hdr(skb)->tos & IPT_ECN_IP_MASK) == einfo->ip_ect;
29} 29}
30 30
31static inline int match_tcp(const struct sk_buff *skb, 31static inline bool match_tcp(const struct sk_buff *skb,
32 const struct ipt_ecn_info *einfo, 32 const struct ipt_ecn_info *einfo,
33 int *hotdrop) 33 bool *hotdrop)
34{ 34{
35 struct tcphdr _tcph, *th; 35 struct tcphdr _tcph;
36 const struct tcphdr *th;
36 37
37 /* In practice, TCP match does this, so can't fail. But let's 38 /* In practice, TCP match does this, so can't fail. But let's
38 * be good citizens. 39 * be good citizens.
39 */ 40 */
40 th = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_tcph), &_tcph); 41 th = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_tcph), &_tcph);
41 if (th == NULL) { 42 if (th == NULL) {
42 *hotdrop = 0; 43 *hotdrop = false;
43 return 0; 44 return false;
44 } 45 }
45 46
46 if (einfo->operation & IPT_ECN_OP_MATCH_ECE) { 47 if (einfo->operation & IPT_ECN_OP_MATCH_ECE) {
47 if (einfo->invert & IPT_ECN_OP_MATCH_ECE) { 48 if (einfo->invert & IPT_ECN_OP_MATCH_ECE) {
48 if (th->ece == 1) 49 if (th->ece == 1)
49 return 0; 50 return false;
50 } else { 51 } else {
51 if (th->ece == 0) 52 if (th->ece == 0)
52 return 0; 53 return false;
53 } 54 }
54 } 55 }
55 56
56 if (einfo->operation & IPT_ECN_OP_MATCH_CWR) { 57 if (einfo->operation & IPT_ECN_OP_MATCH_CWR) {
57 if (einfo->invert & IPT_ECN_OP_MATCH_CWR) { 58 if (einfo->invert & IPT_ECN_OP_MATCH_CWR) {
58 if (th->cwr == 1) 59 if (th->cwr == 1)
59 return 0; 60 return false;
60 } else { 61 } else {
61 if (th->cwr == 0) 62 if (th->cwr == 0)
62 return 0; 63 return false;
63 } 64 }
64 } 65 }
65 66
66 return 1; 67 return true;
67} 68}
68 69
69static int match(const struct sk_buff *skb, 70static bool match(const struct sk_buff *skb,
70 const struct net_device *in, const struct net_device *out, 71 const struct net_device *in, const struct net_device *out,
71 const struct xt_match *match, const void *matchinfo, 72 const struct xt_match *match, const void *matchinfo,
72 int offset, unsigned int protoff, int *hotdrop) 73 int offset, unsigned int protoff, bool *hotdrop)
73{ 74{
74 const struct ipt_ecn_info *info = matchinfo; 75 const struct ipt_ecn_info *info = matchinfo;
75 76
76 if (info->operation & IPT_ECN_OP_MATCH_IP) 77 if (info->operation & IPT_ECN_OP_MATCH_IP)
77 if (!match_ip(skb, info)) 78 if (!match_ip(skb, info))
78 return 0; 79 return false;
79 80
80 if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) { 81 if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) {
81 if (ip_hdr(skb)->protocol != IPPROTO_TCP) 82 if (ip_hdr(skb)->protocol != IPPROTO_TCP)
82 return 0; 83 return false;
83 if (!match_tcp(skb, info, hotdrop)) 84 if (!match_tcp(skb, info, hotdrop))
84 return 0; 85 return false;
85 } 86 }
86 87
87 return 1; 88 return true;
88} 89}
89 90
90static int checkentry(const char *tablename, const void *ip_void, 91static bool checkentry(const char *tablename, const void *ip_void,
91 const struct xt_match *match, 92 const struct xt_match *match,
92 void *matchinfo, unsigned int hook_mask) 93 void *matchinfo, unsigned int hook_mask)
93{ 94{
94 const struct ipt_ecn_info *info = matchinfo; 95 const struct ipt_ecn_info *info = matchinfo;
95 const struct ipt_ip *ip = ip_void; 96 const struct ipt_ip *ip = ip_void;
96 97
97 if (info->operation & IPT_ECN_OP_MATCH_MASK) 98 if (info->operation & IPT_ECN_OP_MATCH_MASK)
98 return 0; 99 return false;
99 100
100 if (info->invert & IPT_ECN_OP_MATCH_MASK) 101 if (info->invert & IPT_ECN_OP_MATCH_MASK)
101 return 0; 102 return false;
102 103
103 if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR) 104 if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)
104 && ip->proto != IPPROTO_TCP) { 105 && ip->proto != IPPROTO_TCP) {
105 printk(KERN_WARNING "ipt_ecn: can't match TCP bits in rule for" 106 printk(KERN_WARNING "ipt_ecn: can't match TCP bits in rule for"
106 " non-tcp packets\n"); 107 " non-tcp packets\n");
107 return 0; 108 return false;
108 } 109 }
109 110
110 return 1; 111 return true;
111} 112}
112 113
113static struct xt_match ecn_match = { 114static struct xt_match ecn_match __read_mostly = {
114 .name = "ecn", 115 .name = "ecn",
115 .family = AF_INET, 116 .family = AF_INET,
116 .match = match, 117 .match = match,
diff --git a/net/ipv4/netfilter/ipt_iprange.c b/net/ipv4/netfilter/ipt_iprange.c
index 33af9e940887..0106dc955a69 100644
--- a/net/ipv4/netfilter/ipt_iprange.c
+++ b/net/ipv4/netfilter/ipt_iprange.c
@@ -17,53 +17,47 @@ MODULE_LICENSE("GPL");
17MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 17MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
18MODULE_DESCRIPTION("iptables arbitrary IP range match module"); 18MODULE_DESCRIPTION("iptables arbitrary IP range match module");
19 19
20#if 0 20static bool
21#define DEBUGP printk
22#else
23#define DEBUGP(format, args...)
24#endif
25
26static int
27match(const struct sk_buff *skb, 21match(const struct sk_buff *skb,
28 const struct net_device *in, 22 const struct net_device *in,
29 const struct net_device *out, 23 const struct net_device *out,
30 const struct xt_match *match, 24 const struct xt_match *match,
31 const void *matchinfo, 25 const void *matchinfo,
32 int offset, unsigned int protoff, int *hotdrop) 26 int offset, unsigned int protoff, bool *hotdrop)
33{ 27{
34 const struct ipt_iprange_info *info = matchinfo; 28 const struct ipt_iprange_info *info = matchinfo;
35 const struct iphdr *iph = ip_hdr(skb); 29 const struct iphdr *iph = ip_hdr(skb);
36 30
37 if (info->flags & IPRANGE_SRC) { 31 if (info->flags & IPRANGE_SRC) {
38 if (((ntohl(iph->saddr) < ntohl(info->src.min_ip)) 32 if ((ntohl(iph->saddr) < ntohl(info->src.min_ip)
39 || (ntohl(iph->saddr) > ntohl(info->src.max_ip))) 33 || ntohl(iph->saddr) > ntohl(info->src.max_ip))
40 ^ !!(info->flags & IPRANGE_SRC_INV)) { 34 ^ !!(info->flags & IPRANGE_SRC_INV)) {
41 DEBUGP("src IP %u.%u.%u.%u NOT in range %s" 35 pr_debug("src IP %u.%u.%u.%u NOT in range %s"
42 "%u.%u.%u.%u-%u.%u.%u.%u\n", 36 "%u.%u.%u.%u-%u.%u.%u.%u\n",
43 NIPQUAD(iph->saddr), 37 NIPQUAD(iph->saddr),
44 info->flags & IPRANGE_SRC_INV ? "(INV) " : "", 38 info->flags & IPRANGE_SRC_INV ? "(INV) " : "",
45 NIPQUAD(info->src.min_ip), 39 NIPQUAD(info->src.min_ip),
46 NIPQUAD(info->src.max_ip)); 40 NIPQUAD(info->src.max_ip));
47 return 0; 41 return false;
48 } 42 }
49 } 43 }
50 if (info->flags & IPRANGE_DST) { 44 if (info->flags & IPRANGE_DST) {
51 if (((ntohl(iph->daddr) < ntohl(info->dst.min_ip)) 45 if ((ntohl(iph->daddr) < ntohl(info->dst.min_ip)
52 || (ntohl(iph->daddr) > ntohl(info->dst.max_ip))) 46 || ntohl(iph->daddr) > ntohl(info->dst.max_ip))
53 ^ !!(info->flags & IPRANGE_DST_INV)) { 47 ^ !!(info->flags & IPRANGE_DST_INV)) {
54 DEBUGP("dst IP %u.%u.%u.%u NOT in range %s" 48 pr_debug("dst IP %u.%u.%u.%u NOT in range %s"
55 "%u.%u.%u.%u-%u.%u.%u.%u\n", 49 "%u.%u.%u.%u-%u.%u.%u.%u\n",
56 NIPQUAD(iph->daddr), 50 NIPQUAD(iph->daddr),
57 info->flags & IPRANGE_DST_INV ? "(INV) " : "", 51 info->flags & IPRANGE_DST_INV ? "(INV) " : "",
58 NIPQUAD(info->dst.min_ip), 52 NIPQUAD(info->dst.min_ip),
59 NIPQUAD(info->dst.max_ip)); 53 NIPQUAD(info->dst.max_ip));
60 return 0; 54 return false;
61 } 55 }
62 } 56 }
63 return 1; 57 return true;
64} 58}
65 59
66static struct xt_match iprange_match = { 60static struct xt_match iprange_match __read_mostly = {
67 .name = "iprange", 61 .name = "iprange",
68 .family = AF_INET, 62 .family = AF_INET,
69 .match = match, 63 .match = match,
diff --git a/net/ipv4/netfilter/ipt_owner.c b/net/ipv4/netfilter/ipt_owner.c
index 7fae9aa8944c..b14e77da7a33 100644
--- a/net/ipv4/netfilter/ipt_owner.c
+++ b/net/ipv4/netfilter/ipt_owner.c
@@ -21,7 +21,7 @@ MODULE_LICENSE("GPL");
21MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 21MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
22MODULE_DESCRIPTION("iptables owner match"); 22MODULE_DESCRIPTION("iptables owner match");
23 23
24static int 24static bool
25match(const struct sk_buff *skb, 25match(const struct sk_buff *skb,
26 const struct net_device *in, 26 const struct net_device *in,
27 const struct net_device *out, 27 const struct net_device *out,
@@ -29,29 +29,29 @@ match(const struct sk_buff *skb,
29 const void *matchinfo, 29 const void *matchinfo,
30 int offset, 30 int offset,
31 unsigned int protoff, 31 unsigned int protoff,
32 int *hotdrop) 32 bool *hotdrop)
33{ 33{
34 const struct ipt_owner_info *info = matchinfo; 34 const struct ipt_owner_info *info = matchinfo;
35 35
36 if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file) 36 if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file)
37 return 0; 37 return false;
38 38
39 if(info->match & IPT_OWNER_UID) { 39 if(info->match & IPT_OWNER_UID) {
40 if ((skb->sk->sk_socket->file->f_uid != info->uid) ^ 40 if ((skb->sk->sk_socket->file->f_uid != info->uid) ^
41 !!(info->invert & IPT_OWNER_UID)) 41 !!(info->invert & IPT_OWNER_UID))
42 return 0; 42 return false;
43 } 43 }
44 44
45 if(info->match & IPT_OWNER_GID) { 45 if(info->match & IPT_OWNER_GID) {
46 if ((skb->sk->sk_socket->file->f_gid != info->gid) ^ 46 if ((skb->sk->sk_socket->file->f_gid != info->gid) ^
47 !!(info->invert & IPT_OWNER_GID)) 47 !!(info->invert & IPT_OWNER_GID))
48 return 0; 48 return false;
49 } 49 }
50 50
51 return 1; 51 return true;
52} 52}
53 53
54static int 54static bool
55checkentry(const char *tablename, 55checkentry(const char *tablename,
56 const void *ip, 56 const void *ip,
57 const struct xt_match *match, 57 const struct xt_match *match,
@@ -63,12 +63,12 @@ checkentry(const char *tablename,
63 if (info->match & (IPT_OWNER_PID|IPT_OWNER_SID|IPT_OWNER_COMM)) { 63 if (info->match & (IPT_OWNER_PID|IPT_OWNER_SID|IPT_OWNER_COMM)) {
64 printk("ipt_owner: pid, sid and command matching " 64 printk("ipt_owner: pid, sid and command matching "
65 "not supported anymore\n"); 65 "not supported anymore\n");
66 return 0; 66 return false;
67 } 67 }
68 return 1; 68 return true;
69} 69}
70 70
71static struct xt_match owner_match = { 71static struct xt_match owner_match __read_mostly = {
72 .name = "owner", 72 .name = "owner",
73 .family = AF_INET, 73 .family = AF_INET,
74 .match = match, 74 .match = match,
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c
index 15a9e8bbb7cc..321804315659 100644
--- a/net/ipv4/netfilter/ipt_recent.c
+++ b/net/ipv4/netfilter/ipt_recent.c
@@ -163,24 +163,23 @@ static void recent_table_flush(struct recent_table *t)
163 struct recent_entry *e, *next; 163 struct recent_entry *e, *next;
164 unsigned int i; 164 unsigned int i;
165 165
166 for (i = 0; i < ip_list_hash_size; i++) { 166 for (i = 0; i < ip_list_hash_size; i++)
167 list_for_each_entry_safe(e, next, &t->iphash[i], list) 167 list_for_each_entry_safe(e, next, &t->iphash[i], list)
168 recent_entry_remove(t, e); 168 recent_entry_remove(t, e);
169 }
170} 169}
171 170
172static int 171static bool
173ipt_recent_match(const struct sk_buff *skb, 172ipt_recent_match(const struct sk_buff *skb,
174 const struct net_device *in, const struct net_device *out, 173 const struct net_device *in, const struct net_device *out,
175 const struct xt_match *match, const void *matchinfo, 174 const struct xt_match *match, const void *matchinfo,
176 int offset, unsigned int protoff, int *hotdrop) 175 int offset, unsigned int protoff, bool *hotdrop)
177{ 176{
178 const struct ipt_recent_info *info = matchinfo; 177 const struct ipt_recent_info *info = matchinfo;
179 struct recent_table *t; 178 struct recent_table *t;
180 struct recent_entry *e; 179 struct recent_entry *e;
181 __be32 addr; 180 __be32 addr;
182 u_int8_t ttl; 181 u_int8_t ttl;
183 int ret = info->invert; 182 bool ret = info->invert;
184 183
185 if (info->side == IPT_RECENT_DEST) 184 if (info->side == IPT_RECENT_DEST)
186 addr = ip_hdr(skb)->daddr; 185 addr = ip_hdr(skb)->daddr;
@@ -201,16 +200,16 @@ ipt_recent_match(const struct sk_buff *skb,
201 goto out; 200 goto out;
202 e = recent_entry_init(t, addr, ttl); 201 e = recent_entry_init(t, addr, ttl);
203 if (e == NULL) 202 if (e == NULL)
204 *hotdrop = 1; 203 *hotdrop = true;
205 ret ^= 1; 204 ret = !ret;
206 goto out; 205 goto out;
207 } 206 }
208 207
209 if (info->check_set & IPT_RECENT_SET) 208 if (info->check_set & IPT_RECENT_SET)
210 ret ^= 1; 209 ret = !ret;
211 else if (info->check_set & IPT_RECENT_REMOVE) { 210 else if (info->check_set & IPT_RECENT_REMOVE) {
212 recent_entry_remove(t, e); 211 recent_entry_remove(t, e);
213 ret ^= 1; 212 ret = !ret;
214 } else if (info->check_set & (IPT_RECENT_CHECK | IPT_RECENT_UPDATE)) { 213 } else if (info->check_set & (IPT_RECENT_CHECK | IPT_RECENT_UPDATE)) {
215 unsigned long t = jiffies - info->seconds * HZ; 214 unsigned long t = jiffies - info->seconds * HZ;
216 unsigned int i, hits = 0; 215 unsigned int i, hits = 0;
@@ -219,7 +218,7 @@ ipt_recent_match(const struct sk_buff *skb,
219 if (info->seconds && time_after(t, e->stamps[i])) 218 if (info->seconds && time_after(t, e->stamps[i]))
220 continue; 219 continue;
221 if (++hits >= info->hit_count) { 220 if (++hits >= info->hit_count) {
222 ret ^= 1; 221 ret = !ret;
223 break; 222 break;
224 } 223 }
225 } 224 }
@@ -235,7 +234,7 @@ out:
235 return ret; 234 return ret;
236} 235}
237 236
238static int 237static bool
239ipt_recent_checkentry(const char *tablename, const void *ip, 238ipt_recent_checkentry(const char *tablename, const void *ip,
240 const struct xt_match *match, void *matchinfo, 239 const struct xt_match *match, void *matchinfo,
241 unsigned int hook_mask) 240 unsigned int hook_mask)
@@ -243,24 +242,24 @@ ipt_recent_checkentry(const char *tablename, const void *ip,
243 const struct ipt_recent_info *info = matchinfo; 242 const struct ipt_recent_info *info = matchinfo;
244 struct recent_table *t; 243 struct recent_table *t;
245 unsigned i; 244 unsigned i;
246 int ret = 0; 245 bool ret = false;
247 246
248 if (hweight8(info->check_set & 247 if (hweight8(info->check_set &
249 (IPT_RECENT_SET | IPT_RECENT_REMOVE | 248 (IPT_RECENT_SET | IPT_RECENT_REMOVE |
250 IPT_RECENT_CHECK | IPT_RECENT_UPDATE)) != 1) 249 IPT_RECENT_CHECK | IPT_RECENT_UPDATE)) != 1)
251 return 0; 250 return false;
252 if ((info->check_set & (IPT_RECENT_SET | IPT_RECENT_REMOVE)) && 251 if ((info->check_set & (IPT_RECENT_SET | IPT_RECENT_REMOVE)) &&
253 (info->seconds || info->hit_count)) 252 (info->seconds || info->hit_count))
254 return 0; 253 return false;
255 if (info->name[0] == '\0' || 254 if (info->name[0] == '\0' ||
256 strnlen(info->name, IPT_RECENT_NAME_LEN) == IPT_RECENT_NAME_LEN) 255 strnlen(info->name, IPT_RECENT_NAME_LEN) == IPT_RECENT_NAME_LEN)
257 return 0; 256 return false;
258 257
259 mutex_lock(&recent_mutex); 258 mutex_lock(&recent_mutex);
260 t = recent_table_lookup(info->name); 259 t = recent_table_lookup(info->name);
261 if (t != NULL) { 260 if (t != NULL) {
262 t->refcnt++; 261 t->refcnt++;
263 ret = 1; 262 ret = true;
264 goto out; 263 goto out;
265 } 264 }
266 265
@@ -287,7 +286,7 @@ ipt_recent_checkentry(const char *tablename, const void *ip,
287 spin_lock_bh(&recent_lock); 286 spin_lock_bh(&recent_lock);
288 list_add_tail(&t->list, &tables); 287 list_add_tail(&t->list, &tables);
289 spin_unlock_bh(&recent_lock); 288 spin_unlock_bh(&recent_lock);
290 ret = 1; 289 ret = true;
291out: 290out:
292 mutex_unlock(&recent_mutex); 291 mutex_unlock(&recent_mutex);
293 return ret; 292 return ret;
@@ -323,18 +322,16 @@ struct recent_iter_state {
323static void *recent_seq_start(struct seq_file *seq, loff_t *pos) 322static void *recent_seq_start(struct seq_file *seq, loff_t *pos)
324{ 323{
325 struct recent_iter_state *st = seq->private; 324 struct recent_iter_state *st = seq->private;
326 struct recent_table *t = st->table; 325 const struct recent_table *t = st->table;
327 struct recent_entry *e; 326 struct recent_entry *e;
328 loff_t p = *pos; 327 loff_t p = *pos;
329 328
330 spin_lock_bh(&recent_lock); 329 spin_lock_bh(&recent_lock);
331 330
332 for (st->bucket = 0; st->bucket < ip_list_hash_size; st->bucket++) { 331 for (st->bucket = 0; st->bucket < ip_list_hash_size; st->bucket++)
333 list_for_each_entry(e, &t->iphash[st->bucket], list) { 332 list_for_each_entry(e, &t->iphash[st->bucket], list)
334 if (p-- == 0) 333 if (p-- == 0)
335 return e; 334 return e;
336 }
337 }
338 return NULL; 335 return NULL;
339} 336}
340 337
@@ -373,7 +370,7 @@ static int recent_seq_show(struct seq_file *seq, void *v)
373 return 0; 370 return 0;
374} 371}
375 372
376static struct seq_operations recent_seq_ops = { 373static const struct seq_operations recent_seq_ops = {
377 .start = recent_seq_start, 374 .start = recent_seq_start,
378 .next = recent_seq_next, 375 .next = recent_seq_next,
379 .stop = recent_seq_stop, 376 .stop = recent_seq_stop,
@@ -463,7 +460,7 @@ static const struct file_operations recent_fops = {
463}; 460};
464#endif /* CONFIG_PROC_FS */ 461#endif /* CONFIG_PROC_FS */
465 462
466static struct xt_match recent_match = { 463static struct xt_match recent_match __read_mostly = {
467 .name = "recent", 464 .name = "recent",
468 .family = AF_INET, 465 .family = AF_INET,
469 .match = ipt_recent_match, 466 .match = ipt_recent_match,
diff --git a/net/ipv4/netfilter/ipt_tos.c b/net/ipv4/netfilter/ipt_tos.c
index d314844af12b..e740441c973d 100644
--- a/net/ipv4/netfilter/ipt_tos.c
+++ b/net/ipv4/netfilter/ipt_tos.c
@@ -18,7 +18,7 @@
18MODULE_LICENSE("GPL"); 18MODULE_LICENSE("GPL");
19MODULE_DESCRIPTION("iptables TOS match module"); 19MODULE_DESCRIPTION("iptables TOS match module");
20 20
21static int 21static bool
22match(const struct sk_buff *skb, 22match(const struct sk_buff *skb,
23 const struct net_device *in, 23 const struct net_device *in,
24 const struct net_device *out, 24 const struct net_device *out,
@@ -26,14 +26,14 @@ match(const struct sk_buff *skb,
26 const void *matchinfo, 26 const void *matchinfo,
27 int offset, 27 int offset,
28 unsigned int protoff, 28 unsigned int protoff,
29 int *hotdrop) 29 bool *hotdrop)
30{ 30{
31 const struct ipt_tos_info *info = matchinfo; 31 const struct ipt_tos_info *info = matchinfo;
32 32
33 return (ip_hdr(skb)->tos == info->tos) ^ info->invert; 33 return (ip_hdr(skb)->tos == info->tos) ^ info->invert;
34} 34}
35 35
36static struct xt_match tos_match = { 36static struct xt_match tos_match __read_mostly = {
37 .name = "tos", 37 .name = "tos",
38 .family = AF_INET, 38 .family = AF_INET,
39 .match = match, 39 .match = match,
diff --git a/net/ipv4/netfilter/ipt_ttl.c b/net/ipv4/netfilter/ipt_ttl.c
index ab02d9e3139c..a439900a4ba5 100644
--- a/net/ipv4/netfilter/ipt_ttl.c
+++ b/net/ipv4/netfilter/ipt_ttl.c
@@ -18,37 +18,33 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
18MODULE_DESCRIPTION("IP tables TTL matching module"); 18MODULE_DESCRIPTION("IP tables TTL matching module");
19MODULE_LICENSE("GPL"); 19MODULE_LICENSE("GPL");
20 20
21static int match(const struct sk_buff *skb, 21static bool match(const struct sk_buff *skb,
22 const struct net_device *in, const struct net_device *out, 22 const struct net_device *in, const struct net_device *out,
23 const struct xt_match *match, const void *matchinfo, 23 const struct xt_match *match, const void *matchinfo,
24 int offset, unsigned int protoff, int *hotdrop) 24 int offset, unsigned int protoff, bool *hotdrop)
25{ 25{
26 const struct ipt_ttl_info *info = matchinfo; 26 const struct ipt_ttl_info *info = matchinfo;
27 const u8 ttl = ip_hdr(skb)->ttl; 27 const u8 ttl = ip_hdr(skb)->ttl;
28 28
29 switch (info->mode) { 29 switch (info->mode) {
30 case IPT_TTL_EQ: 30 case IPT_TTL_EQ:
31 return (ttl == info->ttl); 31 return ttl == info->ttl;
32 break;
33 case IPT_TTL_NE: 32 case IPT_TTL_NE:
34 return (!(ttl == info->ttl)); 33 return ttl != info->ttl;
35 break;
36 case IPT_TTL_LT: 34 case IPT_TTL_LT:
37 return (ttl < info->ttl); 35 return ttl < info->ttl;
38 break;
39 case IPT_TTL_GT: 36 case IPT_TTL_GT:
40 return (ttl > info->ttl); 37 return ttl > info->ttl;
41 break;
42 default: 38 default:
43 printk(KERN_WARNING "ipt_ttl: unknown mode %d\n", 39 printk(KERN_WARNING "ipt_ttl: unknown mode %d\n",
44 info->mode); 40 info->mode);
45 return 0; 41 return false;
46 } 42 }
47 43
48 return 0; 44 return false;
49} 45}
50 46
51static struct xt_match ttl_match = { 47static struct xt_match ttl_match __read_mostly = {
52 .name = "ttl", 48 .name = "ttl",
53 .family = AF_INET, 49 .family = AF_INET,
54 .match = match, 50 .match = match,
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 6dc72a815f77..3c5629938487 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -24,12 +24,6 @@
24#include <net/netfilter/nf_conntrack_core.h> 24#include <net/netfilter/nf_conntrack_core.h>
25#include <net/netfilter/ipv4/nf_conntrack_ipv4.h> 25#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
26 26
27#if 0
28#define DEBUGP printk
29#else
30#define DEBUGP(format, args...)
31#endif
32
33static int ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, 27static int ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
34 struct nf_conntrack_tuple *tuple) 28 struct nf_conntrack_tuple *tuple)
35{ 29{
@@ -103,17 +97,6 @@ ipv4_prepare(struct sk_buff **pskb, unsigned int hooknum, unsigned int *dataoff,
103 return NF_ACCEPT; 97 return NF_ACCEPT;
104} 98}
105 99
106int nf_nat_module_is_loaded = 0;
107EXPORT_SYMBOL_GPL(nf_nat_module_is_loaded);
108
109static u_int32_t ipv4_get_features(const struct nf_conntrack_tuple *tuple)
110{
111 if (nf_nat_module_is_loaded)
112 return NF_CT_F_NAT;
113
114 return NF_CT_F_BASIC;
115}
116
117static unsigned int ipv4_confirm(unsigned int hooknum, 100static unsigned int ipv4_confirm(unsigned int hooknum,
118 struct sk_buff **pskb, 101 struct sk_buff **pskb,
119 const struct net_device *in, 102 const struct net_device *in,
@@ -335,17 +318,17 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len)
335 318
336 /* We only do TCP at the moment: is there a better way? */ 319 /* We only do TCP at the moment: is there a better way? */
337 if (strcmp(sk->sk_prot->name, "TCP")) { 320 if (strcmp(sk->sk_prot->name, "TCP")) {
338 DEBUGP("SO_ORIGINAL_DST: Not a TCP socket\n"); 321 pr_debug("SO_ORIGINAL_DST: Not a TCP socket\n");
339 return -ENOPROTOOPT; 322 return -ENOPROTOOPT;
340 } 323 }
341 324
342 if ((unsigned int) *len < sizeof(struct sockaddr_in)) { 325 if ((unsigned int) *len < sizeof(struct sockaddr_in)) {
343 DEBUGP("SO_ORIGINAL_DST: len %u not %u\n", 326 pr_debug("SO_ORIGINAL_DST: len %d not %Zu\n",
344 *len, sizeof(struct sockaddr_in)); 327 *len, sizeof(struct sockaddr_in));
345 return -EINVAL; 328 return -EINVAL;
346 } 329 }
347 330
348 h = nf_conntrack_find_get(&tuple, NULL); 331 h = nf_conntrack_find_get(&tuple);
349 if (h) { 332 if (h) {
350 struct sockaddr_in sin; 333 struct sockaddr_in sin;
351 struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h); 334 struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
@@ -357,17 +340,17 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len)
357 .tuple.dst.u3.ip; 340 .tuple.dst.u3.ip;
358 memset(sin.sin_zero, 0, sizeof(sin.sin_zero)); 341 memset(sin.sin_zero, 0, sizeof(sin.sin_zero));
359 342
360 DEBUGP("SO_ORIGINAL_DST: %u.%u.%u.%u %u\n", 343 pr_debug("SO_ORIGINAL_DST: %u.%u.%u.%u %u\n",
361 NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port)); 344 NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port));
362 nf_ct_put(ct); 345 nf_ct_put(ct);
363 if (copy_to_user(user, &sin, sizeof(sin)) != 0) 346 if (copy_to_user(user, &sin, sizeof(sin)) != 0)
364 return -EFAULT; 347 return -EFAULT;
365 else 348 else
366 return 0; 349 return 0;
367 } 350 }
368 DEBUGP("SO_ORIGINAL_DST: Can't find %u.%u.%u.%u/%u-%u.%u.%u.%u/%u.\n", 351 pr_debug("SO_ORIGINAL_DST: Can't find %u.%u.%u.%u/%u-%u.%u.%u.%u/%u.\n",
369 NIPQUAD(tuple.src.u3.ip), ntohs(tuple.src.u.tcp.port), 352 NIPQUAD(tuple.src.u3.ip), ntohs(tuple.src.u.tcp.port),
370 NIPQUAD(tuple.dst.u3.ip), ntohs(tuple.dst.u.tcp.port)); 353 NIPQUAD(tuple.dst.u3.ip), ntohs(tuple.dst.u.tcp.port));
371 return -ENOENT; 354 return -ENOENT;
372} 355}
373 356
@@ -425,7 +408,6 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 = {
425 .print_tuple = ipv4_print_tuple, 408 .print_tuple = ipv4_print_tuple,
426 .print_conntrack = ipv4_print_conntrack, 409 .print_conntrack = ipv4_print_conntrack,
427 .prepare = ipv4_prepare, 410 .prepare = ipv4_prepare,
428 .get_features = ipv4_get_features,
429#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 411#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
430 .tuple_to_nfattr = ipv4_tuple_to_nfattr, 412 .tuple_to_nfattr = ipv4_tuple_to_nfattr,
431 .nfattr_to_tuple = ipv4_nfattr_to_tuple, 413 .nfattr_to_tuple = ipv4_nfattr_to_tuple,
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
index 89f933e81035..3da9d73d1b52 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
@@ -18,12 +18,6 @@
18#include <net/netfilter/nf_conntrack_l4proto.h> 18#include <net/netfilter/nf_conntrack_l4proto.h>
19#include <net/netfilter/nf_conntrack_expect.h> 19#include <net/netfilter/nf_conntrack_expect.h>
20 20
21#if 0
22#define DEBUGP printk
23#else
24#define DEBUGP(format, args...)
25#endif
26
27#ifdef CONFIG_NF_CT_ACCT 21#ifdef CONFIG_NF_CT_ACCT
28static unsigned int 22static unsigned int
29seq_print_counters(struct seq_file *s, 23seq_print_counters(struct seq_file *s,
@@ -41,35 +35,36 @@ struct ct_iter_state {
41 unsigned int bucket; 35 unsigned int bucket;
42}; 36};
43 37
44static struct list_head *ct_get_first(struct seq_file *seq) 38static struct hlist_node *ct_get_first(struct seq_file *seq)
45{ 39{
46 struct ct_iter_state *st = seq->private; 40 struct ct_iter_state *st = seq->private;
47 41
48 for (st->bucket = 0; 42 for (st->bucket = 0;
49 st->bucket < nf_conntrack_htable_size; 43 st->bucket < nf_conntrack_htable_size;
50 st->bucket++) { 44 st->bucket++) {
51 if (!list_empty(&nf_conntrack_hash[st->bucket])) 45 if (!hlist_empty(&nf_conntrack_hash[st->bucket]))
52 return nf_conntrack_hash[st->bucket].next; 46 return nf_conntrack_hash[st->bucket].first;
53 } 47 }
54 return NULL; 48 return NULL;
55} 49}
56 50
57static struct list_head *ct_get_next(struct seq_file *seq, struct list_head *head) 51static struct hlist_node *ct_get_next(struct seq_file *seq,
52 struct hlist_node *head)
58{ 53{
59 struct ct_iter_state *st = seq->private; 54 struct ct_iter_state *st = seq->private;
60 55
61 head = head->next; 56 head = head->next;
62 while (head == &nf_conntrack_hash[st->bucket]) { 57 while (head == NULL) {
63 if (++st->bucket >= nf_conntrack_htable_size) 58 if (++st->bucket >= nf_conntrack_htable_size)
64 return NULL; 59 return NULL;
65 head = nf_conntrack_hash[st->bucket].next; 60 head = nf_conntrack_hash[st->bucket].first;
66 } 61 }
67 return head; 62 return head;
68} 63}
69 64
70static struct list_head *ct_get_idx(struct seq_file *seq, loff_t pos) 65static struct hlist_node *ct_get_idx(struct seq_file *seq, loff_t pos)
71{ 66{
72 struct list_head *head = ct_get_first(seq); 67 struct hlist_node *head = ct_get_first(seq);
73 68
74 if (head) 69 if (head)
75 while (pos && (head = ct_get_next(seq, head))) 70 while (pos && (head = ct_get_next(seq, head)))
@@ -169,7 +164,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
169 return 0; 164 return 0;
170} 165}
171 166
172static struct seq_operations ct_seq_ops = { 167static const struct seq_operations ct_seq_ops = {
173 .start = ct_seq_start, 168 .start = ct_seq_start,
174 .next = ct_seq_next, 169 .next = ct_seq_next,
175 .stop = ct_seq_stop, 170 .stop = ct_seq_stop,
@@ -206,47 +201,68 @@ static const struct file_operations ct_file_ops = {
206}; 201};
207 202
208/* expects */ 203/* expects */
209static void *exp_seq_start(struct seq_file *s, loff_t *pos) 204struct ct_expect_iter_state {
205 unsigned int bucket;
206};
207
208static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
210{ 209{
211 struct list_head *e = &nf_conntrack_expect_list; 210 struct ct_expect_iter_state *st = seq->private;
212 loff_t i;
213 211
214 /* strange seq_file api calls stop even if we fail, 212 for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) {
215 * thus we need to grab lock since stop unlocks */ 213 if (!hlist_empty(&nf_ct_expect_hash[st->bucket]))
216 read_lock_bh(&nf_conntrack_lock); 214 return nf_ct_expect_hash[st->bucket].first;
215 }
216 return NULL;
217}
217 218
218 if (list_empty(e)) 219static struct hlist_node *ct_expect_get_next(struct seq_file *seq,
219 return NULL; 220 struct hlist_node *head)
221{
222 struct ct_expect_iter_state *st = seq->private;
220 223
221 for (i = 0; i <= *pos; i++) { 224 head = head->next;
222 e = e->next; 225 while (head == NULL) {
223 if (e == &nf_conntrack_expect_list) 226 if (++st->bucket >= nf_ct_expect_hsize)
224 return NULL; 227 return NULL;
228 head = nf_ct_expect_hash[st->bucket].first;
225 } 229 }
226 return e; 230 return head;
227} 231}
228 232
229static void *exp_seq_next(struct seq_file *s, void *v, loff_t *pos) 233static struct hlist_node *ct_expect_get_idx(struct seq_file *seq, loff_t pos)
230{ 234{
231 struct list_head *e = v; 235 struct hlist_node *head = ct_expect_get_first(seq);
232 236
233 ++*pos; 237 if (head)
234 e = e->next; 238 while (pos && (head = ct_expect_get_next(seq, head)))
239 pos--;
240 return pos ? NULL : head;
241}
235 242
236 if (e == &nf_conntrack_expect_list) 243static void *exp_seq_start(struct seq_file *seq, loff_t *pos)
237 return NULL; 244{
245 read_lock_bh(&nf_conntrack_lock);
246 return ct_expect_get_idx(seq, *pos);
247}
238 248
239 return e; 249static void *exp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
250{
251 (*pos)++;
252 return ct_expect_get_next(seq, v);
240} 253}
241 254
242static void exp_seq_stop(struct seq_file *s, void *v) 255static void exp_seq_stop(struct seq_file *seq, void *v)
243{ 256{
244 read_unlock_bh(&nf_conntrack_lock); 257 read_unlock_bh(&nf_conntrack_lock);
245} 258}
246 259
247static int exp_seq_show(struct seq_file *s, void *v) 260static int exp_seq_show(struct seq_file *s, void *v)
248{ 261{
249 struct nf_conntrack_expect *exp = v; 262 struct nf_conntrack_expect *exp;
263 struct hlist_node *n = v;
264
265 exp = hlist_entry(n, struct nf_conntrack_expect, hnode);
250 266
251 if (exp->tuple.src.l3num != AF_INET) 267 if (exp->tuple.src.l3num != AF_INET)
252 return 0; 268 return 0;
@@ -266,7 +282,7 @@ static int exp_seq_show(struct seq_file *s, void *v)
266 return seq_putc(s, '\n'); 282 return seq_putc(s, '\n');
267} 283}
268 284
269static struct seq_operations exp_seq_ops = { 285static const struct seq_operations exp_seq_ops = {
270 .start = exp_seq_start, 286 .start = exp_seq_start,
271 .next = exp_seq_next, 287 .next = exp_seq_next,
272 .stop = exp_seq_stop, 288 .stop = exp_seq_stop,
@@ -275,7 +291,23 @@ static struct seq_operations exp_seq_ops = {
275 291
276static int exp_open(struct inode *inode, struct file *file) 292static int exp_open(struct inode *inode, struct file *file)
277{ 293{
278 return seq_open(file, &exp_seq_ops); 294 struct seq_file *seq;
295 struct ct_expect_iter_state *st;
296 int ret;
297
298 st = kmalloc(sizeof(struct ct_expect_iter_state), GFP_KERNEL);
299 if (st == NULL)
300 return -ENOMEM;
301 ret = seq_open(file, &exp_seq_ops);
302 if (ret)
303 goto out_free;
304 seq = file->private_data;
305 seq->private = st;
306 memset(st, 0, sizeof(struct ct_expect_iter_state));
307 return ret;
308out_free:
309 kfree(st);
310 return ret;
279} 311}
280 312
281static const struct file_operations ip_exp_file_ops = { 313static const struct file_operations ip_exp_file_ops = {
@@ -283,7 +315,7 @@ static const struct file_operations ip_exp_file_ops = {
283 .open = exp_open, 315 .open = exp_open,
284 .read = seq_read, 316 .read = seq_read,
285 .llseek = seq_lseek, 317 .llseek = seq_lseek,
286 .release = seq_release 318 .release = seq_release_private,
287}; 319};
288 320
289static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos) 321static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
@@ -354,7 +386,7 @@ static int ct_cpu_seq_show(struct seq_file *seq, void *v)
354 return 0; 386 return 0;
355} 387}
356 388
357static struct seq_operations ct_cpu_seq_ops = { 389static const struct seq_operations ct_cpu_seq_ops = {
358 .start = ct_cpu_seq_start, 390 .start = ct_cpu_seq_start,
359 .next = ct_cpu_seq_next, 391 .next = ct_cpu_seq_next,
360 .stop = ct_cpu_seq_stop, 392 .stop = ct_cpu_seq_stop,
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index f4fc657c1983..0fe8fb0466ef 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -21,12 +21,6 @@
21 21
22static unsigned long nf_ct_icmp_timeout __read_mostly = 30*HZ; 22static unsigned long nf_ct_icmp_timeout __read_mostly = 30*HZ;
23 23
24#if 0
25#define DEBUGP printk
26#else
27#define DEBUGP(format, args...)
28#endif
29
30static int icmp_pkt_to_tuple(const struct sk_buff *skb, 24static int icmp_pkt_to_tuple(const struct sk_buff *skb,
31 unsigned int dataoff, 25 unsigned int dataoff,
32 struct nf_conntrack_tuple *tuple) 26 struct nf_conntrack_tuple *tuple)
@@ -125,8 +119,8 @@ static int icmp_new(struct nf_conn *conntrack,
125 if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new) 119 if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new)
126 || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) { 120 || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) {
127 /* Can't create a new ICMP `conn' with this. */ 121 /* Can't create a new ICMP `conn' with this. */
128 DEBUGP("icmp: can't create new conn with type %u\n", 122 pr_debug("icmp: can't create new conn with type %u\n",
129 conntrack->tuplehash[0].tuple.dst.u.icmp.type); 123 conntrack->tuplehash[0].tuple.dst.u.icmp.type);
130 NF_CT_DUMP_TUPLE(&conntrack->tuplehash[0].tuple); 124 NF_CT_DUMP_TUPLE(&conntrack->tuplehash[0].tuple);
131 return 0; 125 return 0;
132 } 126 }
@@ -159,8 +153,8 @@ icmp_error_message(struct sk_buff *skb,
159 153
160 /* Ignore ICMP's containing fragments (shouldn't happen) */ 154 /* Ignore ICMP's containing fragments (shouldn't happen) */
161 if (inside->ip.frag_off & htons(IP_OFFSET)) { 155 if (inside->ip.frag_off & htons(IP_OFFSET)) {
162 DEBUGP("icmp_error_message: fragment of proto %u\n", 156 pr_debug("icmp_error_message: fragment of proto %u\n",
163 inside->ip.protocol); 157 inside->ip.protocol);
164 return -NF_ACCEPT; 158 return -NF_ACCEPT;
165 } 159 }
166 160
@@ -172,8 +166,8 @@ icmp_error_message(struct sk_buff *skb,
172 if (!nf_ct_get_tuple(skb, dataoff, dataoff + inside->ip.ihl*4, PF_INET, 166 if (!nf_ct_get_tuple(skb, dataoff, dataoff + inside->ip.ihl*4, PF_INET,
173 inside->ip.protocol, &origtuple, 167 inside->ip.protocol, &origtuple,
174 &nf_conntrack_l3proto_ipv4, innerproto)) { 168 &nf_conntrack_l3proto_ipv4, innerproto)) {
175 DEBUGP("icmp_error_message: ! get_tuple p=%u", 169 pr_debug("icmp_error_message: ! get_tuple p=%u",
176 inside->ip.protocol); 170 inside->ip.protocol);
177 return -NF_ACCEPT; 171 return -NF_ACCEPT;
178 } 172 }
179 173
@@ -181,22 +175,22 @@ icmp_error_message(struct sk_buff *skb,
181 been preserved inside the ICMP. */ 175 been preserved inside the ICMP. */
182 if (!nf_ct_invert_tuple(&innertuple, &origtuple, 176 if (!nf_ct_invert_tuple(&innertuple, &origtuple,
183 &nf_conntrack_l3proto_ipv4, innerproto)) { 177 &nf_conntrack_l3proto_ipv4, innerproto)) {
184 DEBUGP("icmp_error_message: no match\n"); 178 pr_debug("icmp_error_message: no match\n");
185 return -NF_ACCEPT; 179 return -NF_ACCEPT;
186 } 180 }
187 181
188 *ctinfo = IP_CT_RELATED; 182 *ctinfo = IP_CT_RELATED;
189 183
190 h = nf_conntrack_find_get(&innertuple, NULL); 184 h = nf_conntrack_find_get(&innertuple);
191 if (!h) { 185 if (!h) {
192 /* Locally generated ICMPs will match inverted if they 186 /* Locally generated ICMPs will match inverted if they
193 haven't been SNAT'ed yet */ 187 haven't been SNAT'ed yet */
194 /* FIXME: NAT code has to handle half-done double NAT --RR */ 188 /* FIXME: NAT code has to handle half-done double NAT --RR */
195 if (hooknum == NF_IP_LOCAL_OUT) 189 if (hooknum == NF_IP_LOCAL_OUT)
196 h = nf_conntrack_find_get(&origtuple, NULL); 190 h = nf_conntrack_find_get(&origtuple);
197 191
198 if (!h) { 192 if (!h) {
199 DEBUGP("icmp_error_message: no match\n"); 193 pr_debug("icmp_error_message: no match\n");
200 return -NF_ACCEPT; 194 return -NF_ACCEPT;
201 } 195 }
202 196
diff --git a/net/ipv4/netfilter/nf_nat_amanda.c b/net/ipv4/netfilter/nf_nat_amanda.c
index 0f17098917bc..bd93a1d71052 100644
--- a/net/ipv4/netfilter/nf_nat_amanda.c
+++ b/net/ipv4/netfilter/nf_nat_amanda.c
@@ -45,7 +45,7 @@ static unsigned int help(struct sk_buff **pskb,
45 /* Try to get same port: if not, try to change it. */ 45 /* Try to get same port: if not, try to change it. */
46 for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) { 46 for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
47 exp->tuple.dst.u.tcp.port = htons(port); 47 exp->tuple.dst.u.tcp.port = htons(port);
48 if (nf_conntrack_expect_related(exp) == 0) 48 if (nf_ct_expect_related(exp) == 0)
49 break; 49 break;
50 } 50 }
51 51
@@ -57,7 +57,7 @@ static unsigned int help(struct sk_buff **pskb,
57 matchoff, matchlen, 57 matchoff, matchlen,
58 buffer, strlen(buffer)); 58 buffer, strlen(buffer));
59 if (ret != NF_ACCEPT) 59 if (ret != NF_ACCEPT)
60 nf_conntrack_unexpect_related(exp); 60 nf_ct_unexpect_related(exp);
61 return ret; 61 return ret;
62} 62}
63 63
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index ea02f00d2dac..e848d8d6292f 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -12,7 +12,6 @@
12#include <linux/types.h> 12#include <linux/types.h>
13#include <linux/timer.h> 13#include <linux/timer.h>
14#include <linux/skbuff.h> 14#include <linux/skbuff.h>
15#include <linux/vmalloc.h>
16#include <net/checksum.h> 15#include <net/checksum.h>
17#include <net/icmp.h> 16#include <net/icmp.h>
18#include <net/ip.h> 17#include <net/ip.h>
@@ -32,20 +31,15 @@
32#include <net/netfilter/nf_conntrack_l3proto.h> 31#include <net/netfilter/nf_conntrack_l3proto.h>
33#include <net/netfilter/nf_conntrack_l4proto.h> 32#include <net/netfilter/nf_conntrack_l4proto.h>
34 33
35#if 0
36#define DEBUGP printk
37#else
38#define DEBUGP(format, args...)
39#endif
40
41static DEFINE_RWLOCK(nf_nat_lock); 34static DEFINE_RWLOCK(nf_nat_lock);
42 35
43static struct nf_conntrack_l3proto *l3proto = NULL; 36static struct nf_conntrack_l3proto *l3proto = NULL;
44 37
45/* Calculated at init based on memory size */ 38/* Calculated at init based on memory size */
46static unsigned int nf_nat_htable_size; 39static unsigned int nf_nat_htable_size;
40static int nf_nat_vmalloced;
47 41
48static struct list_head *bysource; 42static struct hlist_head *bysource;
49 43
50#define MAX_IP_NAT_PROTO 256 44#define MAX_IP_NAT_PROTO 256
51static struct nf_nat_protocol *nf_nat_protos[MAX_IP_NAT_PROTO]; 45static struct nf_nat_protocol *nf_nat_protos[MAX_IP_NAT_PROTO];
@@ -87,19 +81,6 @@ hash_by_src(const struct nf_conntrack_tuple *tuple)
87 tuple->dst.protonum, 0) % nf_nat_htable_size; 81 tuple->dst.protonum, 0) % nf_nat_htable_size;
88} 82}
89 83
90/* Noone using conntrack by the time this called. */
91static void nf_nat_cleanup_conntrack(struct nf_conn *conn)
92{
93 struct nf_conn_nat *nat;
94 if (!(conn->status & IPS_NAT_DONE_MASK))
95 return;
96
97 nat = nfct_nat(conn);
98 write_lock_bh(&nf_nat_lock);
99 list_del(&nat->info.bysource);
100 write_unlock_bh(&nf_nat_lock);
101}
102
103/* Is this tuple already taken? (not by us) */ 84/* Is this tuple already taken? (not by us) */
104int 85int
105nf_nat_used_tuple(const struct nf_conntrack_tuple *tuple, 86nf_nat_used_tuple(const struct nf_conntrack_tuple *tuple,
@@ -166,10 +147,11 @@ find_appropriate_src(const struct nf_conntrack_tuple *tuple,
166 unsigned int h = hash_by_src(tuple); 147 unsigned int h = hash_by_src(tuple);
167 struct nf_conn_nat *nat; 148 struct nf_conn_nat *nat;
168 struct nf_conn *ct; 149 struct nf_conn *ct;
150 struct hlist_node *n;
169 151
170 read_lock_bh(&nf_nat_lock); 152 read_lock_bh(&nf_nat_lock);
171 list_for_each_entry(nat, &bysource[h], info.bysource) { 153 hlist_for_each_entry(nat, n, &bysource[h], bysource) {
172 ct = (struct nf_conn *)((char *)nat - offsetof(struct nf_conn, data)); 154 ct = nat->ct;
173 if (same_src(ct, tuple)) { 155 if (same_src(ct, tuple)) {
174 /* Copy source part from reply tuple. */ 156 /* Copy source part from reply tuple. */
175 nf_ct_invert_tuplepr(result, 157 nf_ct_invert_tuplepr(result,
@@ -254,7 +236,7 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
254 manips not an issue. */ 236 manips not an issue. */
255 if (maniptype == IP_NAT_MANIP_SRC) { 237 if (maniptype == IP_NAT_MANIP_SRC) {
256 if (find_appropriate_src(orig_tuple, tuple, range)) { 238 if (find_appropriate_src(orig_tuple, tuple, range)) {
257 DEBUGP("get_unique_tuple: Found current src map\n"); 239 pr_debug("get_unique_tuple: Found current src map\n");
258 if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) 240 if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM))
259 if (!nf_nat_used_tuple(tuple, ct)) 241 if (!nf_nat_used_tuple(tuple, ct))
260 return; 242 return;
@@ -296,11 +278,20 @@ nf_nat_setup_info(struct nf_conn *ct,
296 unsigned int hooknum) 278 unsigned int hooknum)
297{ 279{
298 struct nf_conntrack_tuple curr_tuple, new_tuple; 280 struct nf_conntrack_tuple curr_tuple, new_tuple;
299 struct nf_conn_nat *nat = nfct_nat(ct); 281 struct nf_conn_nat *nat;
300 struct nf_nat_info *info = &nat->info;
301 int have_to_hash = !(ct->status & IPS_NAT_DONE_MASK); 282 int have_to_hash = !(ct->status & IPS_NAT_DONE_MASK);
302 enum nf_nat_manip_type maniptype = HOOK2MANIP(hooknum); 283 enum nf_nat_manip_type maniptype = HOOK2MANIP(hooknum);
303 284
285 /* nat helper or nfctnetlink also setup binding */
286 nat = nfct_nat(ct);
287 if (!nat) {
288 nat = nf_ct_ext_add(ct, NF_CT_EXT_NAT, GFP_ATOMIC);
289 if (nat == NULL) {
290 pr_debug("failed to add NAT extension\n");
291 return NF_ACCEPT;
292 }
293 }
294
304 NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING || 295 NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING ||
305 hooknum == NF_IP_POST_ROUTING || 296 hooknum == NF_IP_POST_ROUTING ||
306 hooknum == NF_IP_LOCAL_IN || 297 hooknum == NF_IP_LOCAL_IN ||
@@ -337,7 +328,10 @@ nf_nat_setup_info(struct nf_conn *ct,
337 328
338 srchash = hash_by_src(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); 329 srchash = hash_by_src(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
339 write_lock_bh(&nf_nat_lock); 330 write_lock_bh(&nf_nat_lock);
340 list_add(&info->bysource, &bysource[srchash]); 331 /* nf_conntrack_alter_reply might re-allocate exntension aera */
332 nat = nfct_nat(ct);
333 nat->ct = ct;
334 hlist_add_head(&nat->bysource, &bysource[srchash]);
341 write_unlock_bh(&nf_nat_lock); 335 write_unlock_bh(&nf_nat_lock);
342 } 336 }
343 337
@@ -462,8 +456,9 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,
462 return 0; 456 return 0;
463 } 457 }
464 458
465 DEBUGP("icmp_reply_translation: translating error %p manp %u dir %s\n", 459 pr_debug("icmp_reply_translation: translating error %p manip %u "
466 *pskb, manip, dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY"); 460 "dir %s\n", *pskb, manip,
461 dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY");
467 462
468 /* rcu_read_lock()ed by nf_hook_slow */ 463 /* rcu_read_lock()ed by nf_hook_slow */
469 l4proto = __nf_ct_l4proto_find(PF_INET, inside->ip.protocol); 464 l4proto = __nf_ct_l4proto_find(PF_INET, inside->ip.protocol);
@@ -590,17 +585,69 @@ nf_nat_port_nfattr_to_range(struct nfattr *tb[], struct nf_nat_range *range)
590EXPORT_SYMBOL_GPL(nf_nat_port_range_to_nfattr); 585EXPORT_SYMBOL_GPL(nf_nat_port_range_to_nfattr);
591#endif 586#endif
592 587
588/* Noone using conntrack by the time this called. */
589static void nf_nat_cleanup_conntrack(struct nf_conn *ct)
590{
591 struct nf_conn_nat *nat = nf_ct_ext_find(ct, NF_CT_EXT_NAT);
592
593 if (nat == NULL || nat->ct == NULL)
594 return;
595
596 NF_CT_ASSERT(nat->ct->status & IPS_NAT_DONE_MASK);
597
598 write_lock_bh(&nf_nat_lock);
599 hlist_del(&nat->bysource);
600 nat->ct = NULL;
601 write_unlock_bh(&nf_nat_lock);
602}
603
604static void nf_nat_move_storage(struct nf_conn *conntrack, void *old)
605{
606 struct nf_conn_nat *new_nat = nf_ct_ext_find(conntrack, NF_CT_EXT_NAT);
607 struct nf_conn_nat *old_nat = (struct nf_conn_nat *)old;
608 struct nf_conn *ct = old_nat->ct;
609 unsigned int srchash;
610
611 if (!(ct->status & IPS_NAT_DONE_MASK))
612 return;
613
614 srchash = hash_by_src(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
615
616 write_lock_bh(&nf_nat_lock);
617 hlist_replace_rcu(&old_nat->bysource, &new_nat->bysource);
618 new_nat->ct = ct;
619 write_unlock_bh(&nf_nat_lock);
620}
621
622static struct nf_ct_ext_type nat_extend __read_mostly = {
623 .len = sizeof(struct nf_conn_nat),
624 .align = __alignof__(struct nf_conn_nat),
625 .destroy = nf_nat_cleanup_conntrack,
626 .move = nf_nat_move_storage,
627 .id = NF_CT_EXT_NAT,
628 .flags = NF_CT_EXT_F_PREALLOC,
629};
630
593static int __init nf_nat_init(void) 631static int __init nf_nat_init(void)
594{ 632{
595 size_t i; 633 size_t i;
634 int ret;
635
636 ret = nf_ct_extend_register(&nat_extend);
637 if (ret < 0) {
638 printk(KERN_ERR "nf_nat_core: Unable to register extension\n");
639 return ret;
640 }
596 641
597 /* Leave them the same for the moment. */ 642 /* Leave them the same for the moment. */
598 nf_nat_htable_size = nf_conntrack_htable_size; 643 nf_nat_htable_size = nf_conntrack_htable_size;
599 644
600 /* One vmalloc for both hash tables */ 645 bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size,
601 bysource = vmalloc(sizeof(struct list_head) * nf_nat_htable_size); 646 &nf_nat_vmalloced);
602 if (!bysource) 647 if (!bysource) {
603 return -ENOMEM; 648 ret = -ENOMEM;
649 goto cleanup_extend;
650 }
604 651
605 /* Sew in builtin protocols. */ 652 /* Sew in builtin protocols. */
606 write_lock_bh(&nf_nat_lock); 653 write_lock_bh(&nf_nat_lock);
@@ -612,18 +659,18 @@ static int __init nf_nat_init(void)
612 write_unlock_bh(&nf_nat_lock); 659 write_unlock_bh(&nf_nat_lock);
613 660
614 for (i = 0; i < nf_nat_htable_size; i++) { 661 for (i = 0; i < nf_nat_htable_size; i++) {
615 INIT_LIST_HEAD(&bysource[i]); 662 INIT_HLIST_HEAD(&bysource[i]);
616 } 663 }
617 664
618 /* FIXME: Man, this is a hack. <SIGH> */
619 NF_CT_ASSERT(rcu_dereference(nf_conntrack_destroyed) == NULL);
620 rcu_assign_pointer(nf_conntrack_destroyed, nf_nat_cleanup_conntrack);
621
622 /* Initialize fake conntrack so that NAT will skip it */ 665 /* Initialize fake conntrack so that NAT will skip it */
623 nf_conntrack_untracked.status |= IPS_NAT_DONE_MASK; 666 nf_conntrack_untracked.status |= IPS_NAT_DONE_MASK;
624 667
625 l3proto = nf_ct_l3proto_find_get((u_int16_t)AF_INET); 668 l3proto = nf_ct_l3proto_find_get((u_int16_t)AF_INET);
626 return 0; 669 return 0;
670
671 cleanup_extend:
672 nf_ct_extend_unregister(&nat_extend);
673 return ret;
627} 674}
628 675
629/* Clear NAT section of all conntracks, in case we're loaded again. */ 676/* Clear NAT section of all conntracks, in case we're loaded again. */
@@ -641,10 +688,10 @@ static int clean_nat(struct nf_conn *i, void *data)
641static void __exit nf_nat_cleanup(void) 688static void __exit nf_nat_cleanup(void)
642{ 689{
643 nf_ct_iterate_cleanup(&clean_nat, NULL); 690 nf_ct_iterate_cleanup(&clean_nat, NULL);
644 rcu_assign_pointer(nf_conntrack_destroyed, NULL);
645 synchronize_rcu(); 691 synchronize_rcu();
646 vfree(bysource); 692 nf_ct_free_hashtable(bysource, nf_nat_vmalloced, nf_nat_htable_size);
647 nf_ct_l3proto_put(l3proto); 693 nf_ct_l3proto_put(l3proto);
694 nf_ct_extend_unregister(&nat_extend);
648} 695}
649 696
650MODULE_LICENSE("GPL"); 697MODULE_LICENSE("GPL");
diff --git a/net/ipv4/netfilter/nf_nat_ftp.c b/net/ipv4/netfilter/nf_nat_ftp.c
index e6bc8e5a72f1..3663bd879c39 100644
--- a/net/ipv4/netfilter/nf_nat_ftp.c
+++ b/net/ipv4/netfilter/nf_nat_ftp.c
@@ -25,12 +25,6 @@ MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>");
25MODULE_DESCRIPTION("ftp NAT helper"); 25MODULE_DESCRIPTION("ftp NAT helper");
26MODULE_ALIAS("ip_nat_ftp"); 26MODULE_ALIAS("ip_nat_ftp");
27 27
28#if 0
29#define DEBUGP printk
30#else
31#define DEBUGP(format, args...)
32#endif
33
34/* FIXME: Time out? --RR */ 28/* FIXME: Time out? --RR */
35 29
36static int 30static int
@@ -47,7 +41,7 @@ mangle_rfc959_packet(struct sk_buff **pskb,
47 sprintf(buffer, "%u,%u,%u,%u,%u,%u", 41 sprintf(buffer, "%u,%u,%u,%u,%u,%u",
48 NIPQUAD(newip), port>>8, port&0xFF); 42 NIPQUAD(newip), port>>8, port&0xFF);
49 43
50 DEBUGP("calling nf_nat_mangle_tcp_packet\n"); 44 pr_debug("calling nf_nat_mangle_tcp_packet\n");
51 45
52 return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff, 46 return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
53 matchlen, buffer, strlen(buffer)); 47 matchlen, buffer, strlen(buffer));
@@ -67,7 +61,7 @@ mangle_eprt_packet(struct sk_buff **pskb,
67 61
68 sprintf(buffer, "|1|%u.%u.%u.%u|%u|", NIPQUAD(newip), port); 62 sprintf(buffer, "|1|%u.%u.%u.%u|%u|", NIPQUAD(newip), port);
69 63
70 DEBUGP("calling nf_nat_mangle_tcp_packet\n"); 64 pr_debug("calling nf_nat_mangle_tcp_packet\n");
71 65
72 return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff, 66 return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
73 matchlen, buffer, strlen(buffer)); 67 matchlen, buffer, strlen(buffer));
@@ -87,7 +81,7 @@ mangle_epsv_packet(struct sk_buff **pskb,
87 81
88 sprintf(buffer, "|||%u|", port); 82 sprintf(buffer, "|||%u|", port);
89 83
90 DEBUGP("calling nf_nat_mangle_tcp_packet\n"); 84 pr_debug("calling nf_nat_mangle_tcp_packet\n");
91 85
92 return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff, 86 return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
93 matchlen, buffer, strlen(buffer)); 87 matchlen, buffer, strlen(buffer));
@@ -117,7 +111,7 @@ static unsigned int nf_nat_ftp(struct sk_buff **pskb,
117 int dir = CTINFO2DIR(ctinfo); 111 int dir = CTINFO2DIR(ctinfo);
118 struct nf_conn *ct = exp->master; 112 struct nf_conn *ct = exp->master;
119 113
120 DEBUGP("FTP_NAT: type %i, off %u len %u\n", type, matchoff, matchlen); 114 pr_debug("FTP_NAT: type %i, off %u len %u\n", type, matchoff, matchlen);
121 115
122 /* Connection will come from wherever this packet goes, hence !dir */ 116 /* Connection will come from wherever this packet goes, hence !dir */
123 newip = ct->tuplehash[!dir].tuple.dst.u3.ip; 117 newip = ct->tuplehash[!dir].tuple.dst.u3.ip;
@@ -131,7 +125,7 @@ static unsigned int nf_nat_ftp(struct sk_buff **pskb,
131 /* Try to get same port: if not, try to change it. */ 125 /* Try to get same port: if not, try to change it. */
132 for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) { 126 for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
133 exp->tuple.dst.u.tcp.port = htons(port); 127 exp->tuple.dst.u.tcp.port = htons(port);
134 if (nf_conntrack_expect_related(exp) == 0) 128 if (nf_ct_expect_related(exp) == 0)
135 break; 129 break;
136 } 130 }
137 131
@@ -139,7 +133,7 @@ static unsigned int nf_nat_ftp(struct sk_buff **pskb,
139 return NF_DROP; 133 return NF_DROP;
140 134
141 if (!mangle[type](pskb, newip, port, matchoff, matchlen, ct, ctinfo)) { 135 if (!mangle[type](pskb, newip, port, matchoff, matchlen, ct, ctinfo)) {
142 nf_conntrack_unexpect_related(exp); 136 nf_ct_unexpect_related(exp);
143 return NF_DROP; 137 return NF_DROP;
144 } 138 }
145 return NF_ACCEPT; 139 return NF_ACCEPT;
diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c
index c5d2a2d690b8..c1b059a73708 100644
--- a/net/ipv4/netfilter/nf_nat_h323.c
+++ b/net/ipv4/netfilter/nf_nat_h323.c
@@ -21,12 +21,6 @@
21#include <net/netfilter/nf_conntrack_expect.h> 21#include <net/netfilter/nf_conntrack_expect.h>
22#include <linux/netfilter/nf_conntrack_h323.h> 22#include <linux/netfilter/nf_conntrack_h323.h>
23 23
24#if 0
25#define DEBUGP printk
26#else
27#define DEBUGP(format, args...)
28#endif
29
30/****************************************************************************/ 24/****************************************************************************/
31static int set_addr(struct sk_buff **pskb, 25static int set_addr(struct sk_buff **pskb,
32 unsigned char **data, int dataoff, 26 unsigned char **data, int dataoff,
@@ -126,12 +120,11 @@ static int set_sig_addr(struct sk_buff **pskb, struct nf_conn *ct,
126 (ntohl(addr.ip) & 0xff000000) == 0x7f000000) 120 (ntohl(addr.ip) & 0xff000000) == 0x7f000000)
127 i = 0; 121 i = 0;
128 122
129 DEBUGP 123 pr_debug("nf_nat_ras: set signal address "
130 ("nf_nat_ras: set signal address " 124 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
131 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n", 125 NIPQUAD(addr.ip), port,
132 NIPQUAD(ip), port, 126 NIPQUAD(ct->tuplehash[!dir].tuple.dst.u3.ip),
133 NIPQUAD(ct->tuplehash[!dir].tuple.dst. 127 info->sig_port[!dir]);
134 ip), info->sig_port[!dir]);
135 return set_h225_addr(pskb, data, 0, &taddr[i], 128 return set_h225_addr(pskb, data, 0, &taddr[i],
136 &ct->tuplehash[!dir]. 129 &ct->tuplehash[!dir].
137 tuple.dst.u3, 130 tuple.dst.u3,
@@ -139,12 +132,11 @@ static int set_sig_addr(struct sk_buff **pskb, struct nf_conn *ct,
139 } else if (addr.ip == ct->tuplehash[dir].tuple.dst.u3.ip && 132 } else if (addr.ip == ct->tuplehash[dir].tuple.dst.u3.ip &&
140 port == info->sig_port[dir]) { 133 port == info->sig_port[dir]) {
141 /* GK->GW */ 134 /* GK->GW */
142 DEBUGP 135 pr_debug("nf_nat_ras: set signal address "
143 ("nf_nat_ras: set signal address " 136 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
144 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n", 137 NIPQUAD(addr.ip), port,
145 NIPQUAD(ip), port, 138 NIPQUAD(ct->tuplehash[!dir].tuple.src.u3.ip),
146 NIPQUAD(ct->tuplehash[!dir].tuple.src. 139 info->sig_port[!dir]);
147 ip), info->sig_port[!dir]);
148 return set_h225_addr(pskb, data, 0, &taddr[i], 140 return set_h225_addr(pskb, data, 0, &taddr[i],
149 &ct->tuplehash[!dir]. 141 &ct->tuplehash[!dir].
150 tuple.src.u3, 142 tuple.src.u3,
@@ -171,12 +163,11 @@ static int set_ras_addr(struct sk_buff **pskb, struct nf_conn *ct,
171 if (get_h225_addr(ct, *data, &taddr[i], &addr, &port) && 163 if (get_h225_addr(ct, *data, &taddr[i], &addr, &port) &&
172 addr.ip == ct->tuplehash[dir].tuple.src.u3.ip && 164 addr.ip == ct->tuplehash[dir].tuple.src.u3.ip &&
173 port == ct->tuplehash[dir].tuple.src.u.udp.port) { 165 port == ct->tuplehash[dir].tuple.src.u.udp.port) {
174 DEBUGP("nf_nat_ras: set rasAddress " 166 pr_debug("nf_nat_ras: set rasAddress "
175 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n", 167 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
176 NIPQUAD(ip), ntohs(port), 168 NIPQUAD(addr.ip), ntohs(port),
177 NIPQUAD(ct->tuplehash[!dir].tuple.dst.u3.ip), 169 NIPQUAD(ct->tuplehash[!dir].tuple.dst.u3.ip),
178 ntohs(ct->tuplehash[!dir].tuple.dst.u.udp. 170 ntohs(ct->tuplehash[!dir].tuple.dst.u.udp.port));
179 port));
180 return set_h225_addr(pskb, data, 0, &taddr[i], 171 return set_h225_addr(pskb, data, 0, &taddr[i],
181 &ct->tuplehash[!dir].tuple.dst.u3, 172 &ct->tuplehash[!dir].tuple.dst.u3,
182 ct->tuplehash[!dir].tuple. 173 ct->tuplehash[!dir].tuple.
@@ -237,12 +228,12 @@ static int nat_rtp_rtcp(struct sk_buff **pskb, struct nf_conn *ct,
237 for (nated_port = ntohs(rtp_exp->tuple.dst.u.udp.port); 228 for (nated_port = ntohs(rtp_exp->tuple.dst.u.udp.port);
238 nated_port != 0; nated_port += 2) { 229 nated_port != 0; nated_port += 2) {
239 rtp_exp->tuple.dst.u.udp.port = htons(nated_port); 230 rtp_exp->tuple.dst.u.udp.port = htons(nated_port);
240 if (nf_conntrack_expect_related(rtp_exp) == 0) { 231 if (nf_ct_expect_related(rtp_exp) == 0) {
241 rtcp_exp->tuple.dst.u.udp.port = 232 rtcp_exp->tuple.dst.u.udp.port =
242 htons(nated_port + 1); 233 htons(nated_port + 1);
243 if (nf_conntrack_expect_related(rtcp_exp) == 0) 234 if (nf_ct_expect_related(rtcp_exp) == 0)
244 break; 235 break;
245 nf_conntrack_unexpect_related(rtp_exp); 236 nf_ct_unexpect_related(rtp_exp);
246 } 237 }
247 } 238 }
248 239
@@ -261,22 +252,22 @@ static int nat_rtp_rtcp(struct sk_buff **pskb, struct nf_conn *ct,
261 info->rtp_port[i][dir] = rtp_port; 252 info->rtp_port[i][dir] = rtp_port;
262 info->rtp_port[i][!dir] = htons(nated_port); 253 info->rtp_port[i][!dir] = htons(nated_port);
263 } else { 254 } else {
264 nf_conntrack_unexpect_related(rtp_exp); 255 nf_ct_unexpect_related(rtp_exp);
265 nf_conntrack_unexpect_related(rtcp_exp); 256 nf_ct_unexpect_related(rtcp_exp);
266 return -1; 257 return -1;
267 } 258 }
268 259
269 /* Success */ 260 /* Success */
270 DEBUGP("nf_nat_h323: expect RTP %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n", 261 pr_debug("nf_nat_h323: expect RTP %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
271 NIPQUAD(rtp_exp->tuple.src.ip), 262 NIPQUAD(rtp_exp->tuple.src.u3.ip),
272 ntohs(rtp_exp->tuple.src.u.udp.port), 263 ntohs(rtp_exp->tuple.src.u.udp.port),
273 NIPQUAD(rtp_exp->tuple.dst.ip), 264 NIPQUAD(rtp_exp->tuple.dst.u3.ip),
274 ntohs(rtp_exp->tuple.dst.u.udp.port)); 265 ntohs(rtp_exp->tuple.dst.u.udp.port));
275 DEBUGP("nf_nat_h323: expect RTCP %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n", 266 pr_debug("nf_nat_h323: expect RTCP %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
276 NIPQUAD(rtcp_exp->tuple.src.ip), 267 NIPQUAD(rtcp_exp->tuple.src.u3.ip),
277 ntohs(rtcp_exp->tuple.src.u.udp.port), 268 ntohs(rtcp_exp->tuple.src.u.udp.port),
278 NIPQUAD(rtcp_exp->tuple.dst.ip), 269 NIPQUAD(rtcp_exp->tuple.dst.u3.ip),
279 ntohs(rtcp_exp->tuple.dst.u.udp.port)); 270 ntohs(rtcp_exp->tuple.dst.u.udp.port));
280 271
281 return 0; 272 return 0;
282} 273}
@@ -299,7 +290,7 @@ static int nat_t120(struct sk_buff **pskb, struct nf_conn *ct,
299 /* Try to get same port: if not, try to change it. */ 290 /* Try to get same port: if not, try to change it. */
300 for (; nated_port != 0; nated_port++) { 291 for (; nated_port != 0; nated_port++) {
301 exp->tuple.dst.u.tcp.port = htons(nated_port); 292 exp->tuple.dst.u.tcp.port = htons(nated_port);
302 if (nf_conntrack_expect_related(exp) == 0) 293 if (nf_ct_expect_related(exp) == 0)
303 break; 294 break;
304 } 295 }
305 296
@@ -313,13 +304,15 @@ static int nat_t120(struct sk_buff **pskb, struct nf_conn *ct,
313 if (set_h245_addr(pskb, data, dataoff, taddr, 304 if (set_h245_addr(pskb, data, dataoff, taddr,
314 &ct->tuplehash[!dir].tuple.dst.u3, 305 &ct->tuplehash[!dir].tuple.dst.u3,
315 htons(nated_port)) < 0) { 306 htons(nated_port)) < 0) {
316 nf_conntrack_unexpect_related(exp); 307 nf_ct_unexpect_related(exp);
317 return -1; 308 return -1;
318 } 309 }
319 310
320 DEBUGP("nf_nat_h323: expect T.120 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n", 311 pr_debug("nf_nat_h323: expect T.120 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
321 NIPQUAD(exp->tuple.src.ip), ntohs(exp->tuple.src.u.tcp.port), 312 NIPQUAD(exp->tuple.src.u3.ip),
322 NIPQUAD(exp->tuple.dst.ip), ntohs(exp->tuple.dst.u.tcp.port)); 313 ntohs(exp->tuple.src.u.tcp.port),
314 NIPQUAD(exp->tuple.dst.u3.ip),
315 ntohs(exp->tuple.dst.u.tcp.port));
323 316
324 return 0; 317 return 0;
325} 318}
@@ -347,7 +340,7 @@ static int nat_h245(struct sk_buff **pskb, struct nf_conn *ct,
347 /* Try to get same port: if not, try to change it. */ 340 /* Try to get same port: if not, try to change it. */
348 for (; nated_port != 0; nated_port++) { 341 for (; nated_port != 0; nated_port++) {
349 exp->tuple.dst.u.tcp.port = htons(nated_port); 342 exp->tuple.dst.u.tcp.port = htons(nated_port);
350 if (nf_conntrack_expect_related(exp) == 0) 343 if (nf_ct_expect_related(exp) == 0)
351 break; 344 break;
352 } 345 }
353 346
@@ -365,13 +358,15 @@ static int nat_h245(struct sk_buff **pskb, struct nf_conn *ct,
365 info->sig_port[dir] = port; 358 info->sig_port[dir] = port;
366 info->sig_port[!dir] = htons(nated_port); 359 info->sig_port[!dir] = htons(nated_port);
367 } else { 360 } else {
368 nf_conntrack_unexpect_related(exp); 361 nf_ct_unexpect_related(exp);
369 return -1; 362 return -1;
370 } 363 }
371 364
372 DEBUGP("nf_nat_q931: expect H.245 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n", 365 pr_debug("nf_nat_q931: expect H.245 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
373 NIPQUAD(exp->tuple.src.ip), ntohs(exp->tuple.src.u.tcp.port), 366 NIPQUAD(exp->tuple.src.u3.ip),
374 NIPQUAD(exp->tuple.dst.ip), ntohs(exp->tuple.dst.u.tcp.port)); 367 ntohs(exp->tuple.src.u.tcp.port),
368 NIPQUAD(exp->tuple.dst.u3.ip),
369 ntohs(exp->tuple.dst.u.tcp.port));
375 370
376 return 0; 371 return 0;
377} 372}
@@ -433,7 +428,7 @@ static int nat_q931(struct sk_buff **pskb, struct nf_conn *ct,
433 /* Try to get same port: if not, try to change it. */ 428 /* Try to get same port: if not, try to change it. */
434 for (; nated_port != 0; nated_port++) { 429 for (; nated_port != 0; nated_port++) {
435 exp->tuple.dst.u.tcp.port = htons(nated_port); 430 exp->tuple.dst.u.tcp.port = htons(nated_port);
436 if (nf_conntrack_expect_related(exp) == 0) 431 if (nf_ct_expect_related(exp) == 0)
437 break; 432 break;
438 } 433 }
439 434
@@ -460,14 +455,16 @@ static int nat_q931(struct sk_buff **pskb, struct nf_conn *ct,
460 info->sig_port[!dir]); 455 info->sig_port[!dir]);
461 } 456 }
462 } else { 457 } else {
463 nf_conntrack_unexpect_related(exp); 458 nf_ct_unexpect_related(exp);
464 return -1; 459 return -1;
465 } 460 }
466 461
467 /* Success */ 462 /* Success */
468 DEBUGP("nf_nat_ras: expect Q.931 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n", 463 pr_debug("nf_nat_ras: expect Q.931 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
469 NIPQUAD(exp->tuple.src.ip), ntohs(exp->tuple.src.u.tcp.port), 464 NIPQUAD(exp->tuple.src.u3.ip),
470 NIPQUAD(exp->tuple.dst.ip), ntohs(exp->tuple.dst.u.tcp.port)); 465 ntohs(exp->tuple.src.u.tcp.port),
466 NIPQUAD(exp->tuple.dst.u3.ip),
467 ntohs(exp->tuple.dst.u.tcp.port));
471 468
472 return 0; 469 return 0;
473} 470}
@@ -517,7 +514,7 @@ static int nat_callforwarding(struct sk_buff **pskb, struct nf_conn *ct,
517 /* Try to get same port: if not, try to change it. */ 514 /* Try to get same port: if not, try to change it. */
518 for (nated_port = ntohs(port); nated_port != 0; nated_port++) { 515 for (nated_port = ntohs(port); nated_port != 0; nated_port++) {
519 exp->tuple.dst.u.tcp.port = htons(nated_port); 516 exp->tuple.dst.u.tcp.port = htons(nated_port);
520 if (nf_conntrack_expect_related(exp) == 0) 517 if (nf_ct_expect_related(exp) == 0)
521 break; 518 break;
522 } 519 }
523 520
@@ -531,15 +528,17 @@ static int nat_callforwarding(struct sk_buff **pskb, struct nf_conn *ct,
531 if (!set_h225_addr(pskb, data, dataoff, taddr, 528 if (!set_h225_addr(pskb, data, dataoff, taddr,
532 &ct->tuplehash[!dir].tuple.dst.u3, 529 &ct->tuplehash[!dir].tuple.dst.u3,
533 htons(nated_port)) == 0) { 530 htons(nated_port)) == 0) {
534 nf_conntrack_unexpect_related(exp); 531 nf_ct_unexpect_related(exp);
535 return -1; 532 return -1;
536 } 533 }
537 534
538 /* Success */ 535 /* Success */
539 DEBUGP("nf_nat_q931: expect Call Forwarding " 536 pr_debug("nf_nat_q931: expect Call Forwarding "
540 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n", 537 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
541 NIPQUAD(exp->tuple.src.ip), ntohs(exp->tuple.src.u.tcp.port), 538 NIPQUAD(exp->tuple.src.u3.ip),
542 NIPQUAD(exp->tuple.dst.ip), ntohs(exp->tuple.dst.u.tcp.port)); 539 ntohs(exp->tuple.src.u.tcp.port),
540 NIPQUAD(exp->tuple.dst.u3.ip),
541 ntohs(exp->tuple.dst.u.tcp.port));
543 542
544 return 0; 543 return 0;
545} 544}
@@ -566,8 +565,6 @@ static int __init init(void)
566 rcu_assign_pointer(nat_h245_hook, nat_h245); 565 rcu_assign_pointer(nat_h245_hook, nat_h245);
567 rcu_assign_pointer(nat_callforwarding_hook, nat_callforwarding); 566 rcu_assign_pointer(nat_callforwarding_hook, nat_callforwarding);
568 rcu_assign_pointer(nat_q931_hook, nat_q931); 567 rcu_assign_pointer(nat_q931_hook, nat_q931);
569
570 DEBUGP("nf_nat_h323: init success\n");
571 return 0; 568 return 0;
572} 569}
573 570
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c
index 15b6e5ce3a04..93d8a0a8f035 100644
--- a/net/ipv4/netfilter/nf_nat_helper.c
+++ b/net/ipv4/netfilter/nf_nat_helper.c
@@ -26,13 +26,9 @@
26#include <net/netfilter/nf_nat_core.h> 26#include <net/netfilter/nf_nat_core.h>
27#include <net/netfilter/nf_nat_helper.h> 27#include <net/netfilter/nf_nat_helper.h>
28 28
29#if 0 29#define DUMP_OFFSET(x) \
30#define DEBUGP printk 30 pr_debug("offset_before=%d, offset_after=%d, correction_pos=%u\n", \
31#define DUMP_OFFSET(x) printk("offset_before=%d, offset_after=%d, correction_pos=%u\n", x->offset_before, x->offset_after, x->correction_pos); 31 x->offset_before, x->offset_after, x->correction_pos);
32#else
33#define DEBUGP(format, args...)
34#define DUMP_OFFSET(x)
35#endif
36 32
37static DEFINE_SPINLOCK(nf_nat_seqofs_lock); 33static DEFINE_SPINLOCK(nf_nat_seqofs_lock);
38 34
@@ -47,15 +43,15 @@ adjust_tcp_sequence(u32 seq,
47 struct nf_nat_seq *this_way, *other_way; 43 struct nf_nat_seq *this_way, *other_way;
48 struct nf_conn_nat *nat = nfct_nat(ct); 44 struct nf_conn_nat *nat = nfct_nat(ct);
49 45
50 DEBUGP("nf_nat_resize_packet: old_size = %u, new_size = %u\n", 46 pr_debug("adjust_tcp_sequence: seq = %u, sizediff = %d\n",
51 (*skb)->len, new_size); 47 ntohl(seq), seq);
52 48
53 dir = CTINFO2DIR(ctinfo); 49 dir = CTINFO2DIR(ctinfo);
54 50
55 this_way = &nat->info.seq[dir]; 51 this_way = &nat->seq[dir];
56 other_way = &nat->info.seq[!dir]; 52 other_way = &nat->seq[!dir];
57 53
58 DEBUGP("nf_nat_resize_packet: Seq_offset before: "); 54 pr_debug("nf_nat_resize_packet: Seq_offset before: ");
59 DUMP_OFFSET(this_way); 55 DUMP_OFFSET(this_way);
60 56
61 spin_lock_bh(&nf_nat_seqofs_lock); 57 spin_lock_bh(&nf_nat_seqofs_lock);
@@ -72,7 +68,7 @@ adjust_tcp_sequence(u32 seq,
72 } 68 }
73 spin_unlock_bh(&nf_nat_seqofs_lock); 69 spin_unlock_bh(&nf_nat_seqofs_lock);
74 70
75 DEBUGP("nf_nat_resize_packet: Seq_offset after: "); 71 pr_debug("nf_nat_resize_packet: Seq_offset after: ");
76 DUMP_OFFSET(this_way); 72 DUMP_OFFSET(this_way);
77} 73}
78 74
@@ -100,14 +96,12 @@ static void mangle_contents(struct sk_buff *skb,
100 96
101 /* update skb info */ 97 /* update skb info */
102 if (rep_len > match_len) { 98 if (rep_len > match_len) {
103 DEBUGP("nf_nat_mangle_packet: Extending packet by " 99 pr_debug("nf_nat_mangle_packet: Extending packet by "
104 "%u from %u bytes\n", rep_len - match_len, 100 "%u from %u bytes\n", rep_len - match_len, skb->len);
105 skb->len);
106 skb_put(skb, rep_len - match_len); 101 skb_put(skb, rep_len - match_len);
107 } else { 102 } else {
108 DEBUGP("nf_nat_mangle_packet: Shrinking packet from " 103 pr_debug("nf_nat_mangle_packet: Shrinking packet from "
109 "%u from %u bytes\n", match_len - rep_len, 104 "%u from %u bytes\n", match_len - rep_len, skb->len);
110 skb->len);
111 __skb_trim(skb, skb->len + rep_len - match_len); 105 __skb_trim(skb, skb->len + rep_len - match_len);
112 } 106 }
113 107
@@ -178,7 +172,7 @@ nf_nat_mangle_tcp_packet(struct sk_buff **pskb,
178 datalen = (*pskb)->len - iph->ihl*4; 172 datalen = (*pskb)->len - iph->ihl*4;
179 if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) { 173 if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) {
180 if (!(rt->rt_flags & RTCF_LOCAL) && 174 if (!(rt->rt_flags & RTCF_LOCAL) &&
181 (*pskb)->dev->features & NETIF_F_ALL_CSUM) { 175 (*pskb)->dev->features & NETIF_F_V4_CSUM) {
182 (*pskb)->ip_summed = CHECKSUM_PARTIAL; 176 (*pskb)->ip_summed = CHECKSUM_PARTIAL;
183 (*pskb)->csum_start = skb_headroom(*pskb) + 177 (*pskb)->csum_start = skb_headroom(*pskb) +
184 skb_network_offset(*pskb) + 178 skb_network_offset(*pskb) +
@@ -190,7 +184,7 @@ nf_nat_mangle_tcp_packet(struct sk_buff **pskb,
190 tcph->check = 0; 184 tcph->check = 0;
191 tcph->check = tcp_v4_check(datalen, 185 tcph->check = tcp_v4_check(datalen,
192 iph->saddr, iph->daddr, 186 iph->saddr, iph->daddr,
193 csum_partial((char *)tcph, 187 csum_partial(tcph,
194 datalen, 0)); 188 datalen, 0));
195 } 189 }
196 } else 190 } else
@@ -265,7 +259,7 @@ nf_nat_mangle_udp_packet(struct sk_buff **pskb,
265 259
266 if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) { 260 if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) {
267 if (!(rt->rt_flags & RTCF_LOCAL) && 261 if (!(rt->rt_flags & RTCF_LOCAL) &&
268 (*pskb)->dev->features & NETIF_F_ALL_CSUM) { 262 (*pskb)->dev->features & NETIF_F_V4_CSUM) {
269 (*pskb)->ip_summed = CHECKSUM_PARTIAL; 263 (*pskb)->ip_summed = CHECKSUM_PARTIAL;
270 (*pskb)->csum_start = skb_headroom(*pskb) + 264 (*pskb)->csum_start = skb_headroom(*pskb) +
271 skb_network_offset(*pskb) + 265 skb_network_offset(*pskb) +
@@ -278,7 +272,7 @@ nf_nat_mangle_udp_packet(struct sk_buff **pskb,
278 udph->check = 0; 272 udph->check = 0;
279 udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr, 273 udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
280 datalen, IPPROTO_UDP, 274 datalen, IPPROTO_UDP,
281 csum_partial((char *)udph, 275 csum_partial(udph,
282 datalen, 0)); 276 datalen, 0));
283 if (!udph->check) 277 if (!udph->check)
284 udph->check = CSUM_MANGLED_0; 278 udph->check = CSUM_MANGLED_0;
@@ -320,9 +314,9 @@ sack_adjust(struct sk_buff *skb,
320 new_end_seq = htonl(ntohl(sack->end_seq) 314 new_end_seq = htonl(ntohl(sack->end_seq)
321 - natseq->offset_before); 315 - natseq->offset_before);
322 316
323 DEBUGP("sack_adjust: start_seq: %d->%d, end_seq: %d->%d\n", 317 pr_debug("sack_adjust: start_seq: %d->%d, end_seq: %d->%d\n",
324 ntohl(sack->start_seq), new_start_seq, 318 ntohl(sack->start_seq), new_start_seq,
325 ntohl(sack->end_seq), new_end_seq); 319 ntohl(sack->end_seq), new_end_seq);
326 320
327 nf_proto_csum_replace4(&tcph->check, skb, 321 nf_proto_csum_replace4(&tcph->check, skb,
328 sack->start_seq, new_start_seq, 0); 322 sack->start_seq, new_start_seq, 0);
@@ -372,8 +366,7 @@ nf_nat_sack_adjust(struct sk_buff **pskb,
372 op[1] >= 2+TCPOLEN_SACK_PERBLOCK && 366 op[1] >= 2+TCPOLEN_SACK_PERBLOCK &&
373 ((op[1] - 2) % TCPOLEN_SACK_PERBLOCK) == 0) 367 ((op[1] - 2) % TCPOLEN_SACK_PERBLOCK) == 0)
374 sack_adjust(*pskb, tcph, optoff+2, 368 sack_adjust(*pskb, tcph, optoff+2,
375 optoff+op[1], 369 optoff+op[1], &nat->seq[!dir]);
376 &nat->info.seq[!dir]);
377 optoff += op[1]; 370 optoff += op[1];
378 } 371 }
379 } 372 }
@@ -394,8 +387,8 @@ nf_nat_seq_adjust(struct sk_buff **pskb,
394 387
395 dir = CTINFO2DIR(ctinfo); 388 dir = CTINFO2DIR(ctinfo);
396 389
397 this_way = &nat->info.seq[dir]; 390 this_way = &nat->seq[dir];
398 other_way = &nat->info.seq[!dir]; 391 other_way = &nat->seq[!dir];
399 392
400 if (!skb_make_writable(pskb, ip_hdrlen(*pskb) + sizeof(*tcph))) 393 if (!skb_make_writable(pskb, ip_hdrlen(*pskb) + sizeof(*tcph)))
401 return 0; 394 return 0;
@@ -415,9 +408,9 @@ nf_nat_seq_adjust(struct sk_buff **pskb,
415 nf_proto_csum_replace4(&tcph->check, *pskb, tcph->seq, newseq, 0); 408 nf_proto_csum_replace4(&tcph->check, *pskb, tcph->seq, newseq, 0);
416 nf_proto_csum_replace4(&tcph->check, *pskb, tcph->ack_seq, newack, 0); 409 nf_proto_csum_replace4(&tcph->check, *pskb, tcph->ack_seq, newack, 0);
417 410
418 DEBUGP("Adjusting sequence number from %u->%u, ack from %u->%u\n", 411 pr_debug("Adjusting sequence number from %u->%u, ack from %u->%u\n",
419 ntohl(tcph->seq), ntohl(newseq), ntohl(tcph->ack_seq), 412 ntohl(tcph->seq), ntohl(newseq), ntohl(tcph->ack_seq),
420 ntohl(newack)); 413 ntohl(newack));
421 414
422 tcph->seq = newseq; 415 tcph->seq = newseq;
423 tcph->ack_seq = newack; 416 tcph->ack_seq = newack;
diff --git a/net/ipv4/netfilter/nf_nat_irc.c b/net/ipv4/netfilter/nf_nat_irc.c
index 9b8c0daea744..bcf274bba602 100644
--- a/net/ipv4/netfilter/nf_nat_irc.c
+++ b/net/ipv4/netfilter/nf_nat_irc.c
@@ -22,12 +22,6 @@
22#include <net/netfilter/nf_conntrack_expect.h> 22#include <net/netfilter/nf_conntrack_expect.h>
23#include <linux/netfilter/nf_conntrack_irc.h> 23#include <linux/netfilter/nf_conntrack_irc.h>
24 24
25#if 0
26#define DEBUGP printk
27#else
28#define DEBUGP(format, args...)
29#endif
30
31MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>"); 25MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
32MODULE_DESCRIPTION("IRC (DCC) NAT helper"); 26MODULE_DESCRIPTION("IRC (DCC) NAT helper");
33MODULE_LICENSE("GPL"); 27MODULE_LICENSE("GPL");
@@ -44,9 +38,6 @@ static unsigned int help(struct sk_buff **pskb,
44 u_int16_t port; 38 u_int16_t port;
45 unsigned int ret; 39 unsigned int ret;
46 40
47 DEBUGP("IRC_NAT: info (seq %u + %u) in %u\n",
48 expect->seq, exp_irc_info->len, ntohl(tcph->seq));
49
50 /* Reply comes from server. */ 41 /* Reply comes from server. */
51 exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port; 42 exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
52 exp->dir = IP_CT_DIR_REPLY; 43 exp->dir = IP_CT_DIR_REPLY;
@@ -55,7 +46,7 @@ static unsigned int help(struct sk_buff **pskb,
55 /* Try to get same port: if not, try to change it. */ 46 /* Try to get same port: if not, try to change it. */
56 for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) { 47 for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
57 exp->tuple.dst.u.tcp.port = htons(port); 48 exp->tuple.dst.u.tcp.port = htons(port);
58 if (nf_conntrack_expect_related(exp) == 0) 49 if (nf_ct_expect_related(exp) == 0)
59 break; 50 break;
60 } 51 }
61 52
@@ -64,14 +55,14 @@ static unsigned int help(struct sk_buff **pskb,
64 55
65 ip = ntohl(exp->master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip); 56 ip = ntohl(exp->master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip);
66 sprintf(buffer, "%u %u", ip, port); 57 sprintf(buffer, "%u %u", ip, port);
67 DEBUGP("nf_nat_irc: inserting '%s' == %u.%u.%u.%u, port %u\n", 58 pr_debug("nf_nat_irc: inserting '%s' == %u.%u.%u.%u, port %u\n",
68 buffer, NIPQUAD(ip), port); 59 buffer, NIPQUAD(ip), port);
69 60
70 ret = nf_nat_mangle_tcp_packet(pskb, exp->master, ctinfo, 61 ret = nf_nat_mangle_tcp_packet(pskb, exp->master, ctinfo,
71 matchoff, matchlen, buffer, 62 matchoff, matchlen, buffer,
72 strlen(buffer)); 63 strlen(buffer));
73 if (ret != NF_ACCEPT) 64 if (ret != NF_ACCEPT)
74 nf_conntrack_unexpect_related(exp); 65 nf_ct_unexpect_related(exp);
75 return ret; 66 return ret;
76} 67}
77 68
diff --git a/net/ipv4/netfilter/nf_nat_pptp.c b/net/ipv4/netfilter/nf_nat_pptp.c
index a66888749ceb..984ec8308b2e 100644
--- a/net/ipv4/netfilter/nf_nat_pptp.c
+++ b/net/ipv4/netfilter/nf_nat_pptp.c
@@ -37,14 +37,6 @@ MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
37MODULE_DESCRIPTION("Netfilter NAT helper module for PPTP"); 37MODULE_DESCRIPTION("Netfilter NAT helper module for PPTP");
38MODULE_ALIAS("ip_nat_pptp"); 38MODULE_ALIAS("ip_nat_pptp");
39 39
40#if 0
41extern const char *pptp_msg_name[];
42#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, \
43 __FUNCTION__, ## args)
44#else
45#define DEBUGP(format, args...)
46#endif
47
48static void pptp_nat_expected(struct nf_conn *ct, 40static void pptp_nat_expected(struct nf_conn *ct,
49 struct nf_conntrack_expect *exp) 41 struct nf_conntrack_expect *exp)
50{ 42{
@@ -60,7 +52,7 @@ static void pptp_nat_expected(struct nf_conn *ct,
60 52
61 /* And here goes the grand finale of corrosion... */ 53 /* And here goes the grand finale of corrosion... */
62 if (exp->dir == IP_CT_DIR_ORIGINAL) { 54 if (exp->dir == IP_CT_DIR_ORIGINAL) {
63 DEBUGP("we are PNS->PAC\n"); 55 pr_debug("we are PNS->PAC\n");
64 /* therefore, build tuple for PAC->PNS */ 56 /* therefore, build tuple for PAC->PNS */
65 t.src.l3num = AF_INET; 57 t.src.l3num = AF_INET;
66 t.src.u3.ip = master->tuplehash[!exp->dir].tuple.src.u3.ip; 58 t.src.u3.ip = master->tuplehash[!exp->dir].tuple.src.u3.ip;
@@ -69,7 +61,7 @@ static void pptp_nat_expected(struct nf_conn *ct,
69 t.dst.u.gre.key = ct_pptp_info->pns_call_id; 61 t.dst.u.gre.key = ct_pptp_info->pns_call_id;
70 t.dst.protonum = IPPROTO_GRE; 62 t.dst.protonum = IPPROTO_GRE;
71 } else { 63 } else {
72 DEBUGP("we are PAC->PNS\n"); 64 pr_debug("we are PAC->PNS\n");
73 /* build tuple for PNS->PAC */ 65 /* build tuple for PNS->PAC */
74 t.src.l3num = AF_INET; 66 t.src.l3num = AF_INET;
75 t.src.u3.ip = master->tuplehash[!exp->dir].tuple.src.u3.ip; 67 t.src.u3.ip = master->tuplehash[!exp->dir].tuple.src.u3.ip;
@@ -79,15 +71,15 @@ static void pptp_nat_expected(struct nf_conn *ct,
79 t.dst.protonum = IPPROTO_GRE; 71 t.dst.protonum = IPPROTO_GRE;
80 } 72 }
81 73
82 DEBUGP("trying to unexpect other dir: "); 74 pr_debug("trying to unexpect other dir: ");
83 NF_CT_DUMP_TUPLE(&t); 75 NF_CT_DUMP_TUPLE(&t);
84 other_exp = nf_conntrack_expect_find_get(&t); 76 other_exp = nf_ct_expect_find_get(&t);
85 if (other_exp) { 77 if (other_exp) {
86 nf_conntrack_unexpect_related(other_exp); 78 nf_ct_unexpect_related(other_exp);
87 nf_conntrack_expect_put(other_exp); 79 nf_ct_expect_put(other_exp);
88 DEBUGP("success\n"); 80 pr_debug("success\n");
89 } else { 81 } else {
90 DEBUGP("not found!\n"); 82 pr_debug("not found!\n");
91 } 83 }
92 84
93 /* This must be a fresh one. */ 85 /* This must be a fresh one. */
@@ -161,9 +153,9 @@ pptp_outbound_pkt(struct sk_buff **pskb,
161 cid_off = offsetof(union pptp_ctrl_union, clrreq.callID); 153 cid_off = offsetof(union pptp_ctrl_union, clrreq.callID);
162 break; 154 break;
163 default: 155 default:
164 DEBUGP("unknown outbound packet 0x%04x:%s\n", msg, 156 pr_debug("unknown outbound packet 0x%04x:%s\n", msg,
165 (msg <= PPTP_MSG_MAX)? 157 msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] :
166 pptp_msg_name[msg]:pptp_msg_name[0]); 158 pptp_msg_name[0]);
167 /* fall through */ 159 /* fall through */
168 case PPTP_SET_LINK_INFO: 160 case PPTP_SET_LINK_INFO:
169 /* only need to NAT in case PAC is behind NAT box */ 161 /* only need to NAT in case PAC is behind NAT box */
@@ -179,8 +171,8 @@ pptp_outbound_pkt(struct sk_buff **pskb,
179 171
180 /* only OUT_CALL_REQUEST, IN_CALL_REPLY, CALL_CLEAR_REQUEST pass 172 /* only OUT_CALL_REQUEST, IN_CALL_REPLY, CALL_CLEAR_REQUEST pass
181 * down to here */ 173 * down to here */
182 DEBUGP("altering call id from 0x%04x to 0x%04x\n", 174 pr_debug("altering call id from 0x%04x to 0x%04x\n",
183 ntohs(REQ_CID(pptpReq, cid_off)), ntohs(new_callid)); 175 ntohs(REQ_CID(pptpReq, cid_off)), ntohs(new_callid));
184 176
185 /* mangle packet */ 177 /* mangle packet */
186 if (nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, 178 if (nf_nat_mangle_tcp_packet(pskb, ct, ctinfo,
@@ -255,8 +247,9 @@ pptp_inbound_pkt(struct sk_buff **pskb,
255 pcid_off = offsetof(union pptp_ctrl_union, setlink.peersCallID); 247 pcid_off = offsetof(union pptp_ctrl_union, setlink.peersCallID);
256 break; 248 break;
257 default: 249 default:
258 DEBUGP("unknown inbound packet %s\n", (msg <= PPTP_MSG_MAX)? 250 pr_debug("unknown inbound packet %s\n",
259 pptp_msg_name[msg]:pptp_msg_name[0]); 251 msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] :
252 pptp_msg_name[0]);
260 /* fall through */ 253 /* fall through */
261 case PPTP_START_SESSION_REQUEST: 254 case PPTP_START_SESSION_REQUEST:
262 case PPTP_START_SESSION_REPLY: 255 case PPTP_START_SESSION_REPLY:
@@ -272,8 +265,8 @@ pptp_inbound_pkt(struct sk_buff **pskb,
272 * WAN_ERROR_NOTIFY, CALL_DISCONNECT_NOTIFY pass down here */ 265 * WAN_ERROR_NOTIFY, CALL_DISCONNECT_NOTIFY pass down here */
273 266
274 /* mangle packet */ 267 /* mangle packet */
275 DEBUGP("altering peer call id from 0x%04x to 0x%04x\n", 268 pr_debug("altering peer call id from 0x%04x to 0x%04x\n",
276 ntohs(REQ_CID(pptpReq, pcid_off)), ntohs(new_pcid)); 269 ntohs(REQ_CID(pptpReq, pcid_off)), ntohs(new_pcid));
277 270
278 if (nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, 271 if (nf_nat_mangle_tcp_packet(pskb, ct, ctinfo,
279 pcid_off + sizeof(struct pptp_pkt_hdr) + 272 pcid_off + sizeof(struct pptp_pkt_hdr) +
diff --git a/net/ipv4/netfilter/nf_nat_proto_gre.c b/net/ipv4/netfilter/nf_nat_proto_gre.c
index c3908bc5a709..2e40cc83526a 100644
--- a/net/ipv4/netfilter/nf_nat_proto_gre.c
+++ b/net/ipv4/netfilter/nf_nat_proto_gre.c
@@ -36,13 +36,6 @@ MODULE_LICENSE("GPL");
36MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>"); 36MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
37MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE"); 37MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE");
38 38
39#if 0
40#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, \
41 __FUNCTION__, ## args)
42#else
43#define DEBUGP(x, args...)
44#endif
45
46/* is key in given range between min and max */ 39/* is key in given range between min and max */
47static int 40static int
48gre_in_range(const struct nf_conntrack_tuple *tuple, 41gre_in_range(const struct nf_conntrack_tuple *tuple,
@@ -83,7 +76,7 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple,
83 keyptr = &tuple->dst.u.gre.key; 76 keyptr = &tuple->dst.u.gre.key;
84 77
85 if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) { 78 if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) {
86 DEBUGP("%p: NATing GRE PPTP\n", conntrack); 79 pr_debug("%p: NATing GRE PPTP\n", conntrack);
87 min = 1; 80 min = 1;
88 range_size = 0xffff; 81 range_size = 0xffff;
89 } else { 82 } else {
@@ -91,7 +84,7 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple,
91 range_size = ntohs(range->max.gre.key) - min + 1; 84 range_size = ntohs(range->max.gre.key) - min + 1;
92 } 85 }
93 86
94 DEBUGP("min = %u, range_size = %u\n", min, range_size); 87 pr_debug("min = %u, range_size = %u\n", min, range_size);
95 88
96 for (i = 0; i < range_size; i++, key++) { 89 for (i = 0; i < range_size; i++, key++) {
97 *keyptr = htons(min + key % range_size); 90 *keyptr = htons(min + key % range_size);
@@ -99,7 +92,7 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple,
99 return 1; 92 return 1;
100 } 93 }
101 94
102 DEBUGP("%p: no NAT mapping\n", conntrack); 95 pr_debug("%p: no NAT mapping\n", conntrack);
103 return 0; 96 return 0;
104} 97}
105 98
@@ -132,11 +125,11 @@ gre_manip_pkt(struct sk_buff **pskb, unsigned int iphdroff,
132 * Try to behave like "nf_nat_proto_unknown" */ 125 * Try to behave like "nf_nat_proto_unknown" */
133 break; 126 break;
134 case GRE_VERSION_PPTP: 127 case GRE_VERSION_PPTP:
135 DEBUGP("call_id -> 0x%04x\n", ntohs(tuple->dst.u.gre.key)); 128 pr_debug("call_id -> 0x%04x\n", ntohs(tuple->dst.u.gre.key));
136 pgreh->call_id = tuple->dst.u.gre.key; 129 pgreh->call_id = tuple->dst.u.gre.key;
137 break; 130 break;
138 default: 131 default:
139 DEBUGP("can't nat unknown GRE version\n"); 132 pr_debug("can't nat unknown GRE version\n");
140 return 0; 133 return 0;
141 } 134 }
142 return 1; 135 return 1;
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c
index 6740736c5e79..0f45427e5fdc 100644
--- a/net/ipv4/netfilter/nf_nat_rule.c
+++ b/net/ipv4/netfilter/nf_nat_rule.c
@@ -24,12 +24,6 @@
24#include <net/netfilter/nf_nat_core.h> 24#include <net/netfilter/nf_nat_core.h>
25#include <net/netfilter/nf_nat_rule.h> 25#include <net/netfilter/nf_nat_rule.h>
26 26
27#if 0
28#define DEBUGP printk
29#else
30#define DEBUGP(format, args...)
31#endif
32
33#define NAT_VALID_HOOKS ((1<<NF_IP_PRE_ROUTING) | (1<<NF_IP_POST_ROUTING) | (1<<NF_IP_LOCAL_OUT)) 27#define NAT_VALID_HOOKS ((1<<NF_IP_PRE_ROUTING) | (1<<NF_IP_POST_ROUTING) | (1<<NF_IP_LOCAL_OUT))
34 28
35static struct 29static struct
@@ -140,39 +134,39 @@ static unsigned int ipt_dnat_target(struct sk_buff **pskb,
140 return nf_nat_setup_info(ct, &mr->range[0], hooknum); 134 return nf_nat_setup_info(ct, &mr->range[0], hooknum);
141} 135}
142 136
143static int ipt_snat_checkentry(const char *tablename, 137static bool ipt_snat_checkentry(const char *tablename,
144 const void *entry, 138 const void *entry,
145 const struct xt_target *target, 139 const struct xt_target *target,
146 void *targinfo, 140 void *targinfo,
147 unsigned int hook_mask) 141 unsigned int hook_mask)
148{ 142{
149 struct nf_nat_multi_range_compat *mr = targinfo; 143 struct nf_nat_multi_range_compat *mr = targinfo;
150 144
151 /* Must be a valid range */ 145 /* Must be a valid range */
152 if (mr->rangesize != 1) { 146 if (mr->rangesize != 1) {
153 printk("SNAT: multiple ranges no longer supported\n"); 147 printk("SNAT: multiple ranges no longer supported\n");
154 return 0; 148 return false;
155 } 149 }
156 return 1; 150 return true;
157} 151}
158 152
159static int ipt_dnat_checkentry(const char *tablename, 153static bool ipt_dnat_checkentry(const char *tablename,
160 const void *entry, 154 const void *entry,
161 const struct xt_target *target, 155 const struct xt_target *target,
162 void *targinfo, 156 void *targinfo,
163 unsigned int hook_mask) 157 unsigned int hook_mask)
164{ 158{
165 struct nf_nat_multi_range_compat *mr = targinfo; 159 struct nf_nat_multi_range_compat *mr = targinfo;
166 160
167 /* Must be a valid range */ 161 /* Must be a valid range */
168 if (mr->rangesize != 1) { 162 if (mr->rangesize != 1) {
169 printk("DNAT: multiple ranges no longer supported\n"); 163 printk("DNAT: multiple ranges no longer supported\n");
170 return 0; 164 return false;
171 } 165 }
172 return 1; 166 return true;
173} 167}
174 168
175inline unsigned int 169unsigned int
176alloc_null_binding(struct nf_conn *ct, unsigned int hooknum) 170alloc_null_binding(struct nf_conn *ct, unsigned int hooknum)
177{ 171{
178 /* Force range to this IP; let proto decide mapping for 172 /* Force range to this IP; let proto decide mapping for
@@ -186,8 +180,8 @@ alloc_null_binding(struct nf_conn *ct, unsigned int hooknum)
186 struct nf_nat_range range 180 struct nf_nat_range range
187 = { IP_NAT_RANGE_MAP_IPS, ip, ip, { 0 }, { 0 } }; 181 = { IP_NAT_RANGE_MAP_IPS, ip, ip, { 0 }, { 0 } };
188 182
189 DEBUGP("Allocating NULL binding for %p (%u.%u.%u.%u)\n", 183 pr_debug("Allocating NULL binding for %p (%u.%u.%u.%u)\n",
190 ct, NIPQUAD(ip)); 184 ct, NIPQUAD(ip));
191 return nf_nat_setup_info(ct, &range, hooknum); 185 return nf_nat_setup_info(ct, &range, hooknum);
192} 186}
193 187
@@ -205,8 +199,8 @@ alloc_null_binding_confirmed(struct nf_conn *ct, unsigned int hooknum)
205 struct nf_nat_range range 199 struct nf_nat_range range
206 = { IP_NAT_RANGE_MAP_IPS, ip, ip, { all }, { all } }; 200 = { IP_NAT_RANGE_MAP_IPS, ip, ip, { all }, { all } };
207 201
208 DEBUGP("Allocating NULL binding for confirmed %p (%u.%u.%u.%u)\n", 202 pr_debug("Allocating NULL binding for confirmed %p (%u.%u.%u.%u)\n",
209 ct, NIPQUAD(ip)); 203 ct, NIPQUAD(ip));
210 return nf_nat_setup_info(ct, &range, hooknum); 204 return nf_nat_setup_info(ct, &range, hooknum);
211} 205}
212 206
@@ -228,7 +222,7 @@ int nf_nat_rule_find(struct sk_buff **pskb,
228 return ret; 222 return ret;
229} 223}
230 224
231static struct xt_target ipt_snat_reg = { 225static struct xt_target ipt_snat_reg __read_mostly = {
232 .name = "SNAT", 226 .name = "SNAT",
233 .target = ipt_snat_target, 227 .target = ipt_snat_target,
234 .targetsize = sizeof(struct nf_nat_multi_range_compat), 228 .targetsize = sizeof(struct nf_nat_multi_range_compat),
@@ -238,7 +232,7 @@ static struct xt_target ipt_snat_reg = {
238 .family = AF_INET, 232 .family = AF_INET,
239}; 233};
240 234
241static struct xt_target ipt_dnat_reg = { 235static struct xt_target ipt_dnat_reg __read_mostly = {
242 .name = "DNAT", 236 .name = "DNAT",
243 .target = ipt_dnat_target, 237 .target = ipt_dnat_target,
244 .targetsize = sizeof(struct nf_nat_multi_range_compat), 238 .targetsize = sizeof(struct nf_nat_multi_range_compat),
diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c
index fac97cf51ae5..a889ec3ec83a 100644
--- a/net/ipv4/netfilter/nf_nat_sip.c
+++ b/net/ipv4/netfilter/nf_nat_sip.c
@@ -26,12 +26,6 @@ MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com.ar>");
26MODULE_DESCRIPTION("SIP NAT helper"); 26MODULE_DESCRIPTION("SIP NAT helper");
27MODULE_ALIAS("ip_nat_sip"); 27MODULE_ALIAS("ip_nat_sip");
28 28
29#if 0
30#define DEBUGP printk
31#else
32#define DEBUGP(format, args...)
33#endif
34
35struct addr_map { 29struct addr_map {
36 struct { 30 struct {
37 char src[sizeof("nnn.nnn.nnn.nnn:nnnnn")]; 31 char src[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
@@ -257,10 +251,12 @@ static unsigned int ip_nat_sdp(struct sk_buff **pskb,
257 __be32 newip; 251 __be32 newip;
258 u_int16_t port; 252 u_int16_t port;
259 253
260 DEBUGP("ip_nat_sdp():\n");
261
262 /* Connection will come from reply */ 254 /* Connection will come from reply */
263 newip = ct->tuplehash[!dir].tuple.dst.u3.ip; 255 if (ct->tuplehash[dir].tuple.src.u3.ip ==
256 ct->tuplehash[!dir].tuple.dst.u3.ip)
257 newip = exp->tuple.dst.u3.ip;
258 else
259 newip = ct->tuplehash[!dir].tuple.dst.u3.ip;
264 260
265 exp->saved_ip = exp->tuple.dst.u3.ip; 261 exp->saved_ip = exp->tuple.dst.u3.ip;
266 exp->tuple.dst.u3.ip = newip; 262 exp->tuple.dst.u3.ip = newip;
@@ -274,7 +270,7 @@ static unsigned int ip_nat_sdp(struct sk_buff **pskb,
274 /* Try to get same port: if not, try to change it. */ 270 /* Try to get same port: if not, try to change it. */
275 for (port = ntohs(exp->saved_proto.udp.port); port != 0; port++) { 271 for (port = ntohs(exp->saved_proto.udp.port); port != 0; port++) {
276 exp->tuple.dst.u.udp.port = htons(port); 272 exp->tuple.dst.u.udp.port = htons(port);
277 if (nf_conntrack_expect_related(exp) == 0) 273 if (nf_ct_expect_related(exp) == 0)
278 break; 274 break;
279 } 275 }
280 276
@@ -282,7 +278,7 @@ static unsigned int ip_nat_sdp(struct sk_buff **pskb,
282 return NF_DROP; 278 return NF_DROP;
283 279
284 if (!mangle_sdp(pskb, ctinfo, ct, newip, port, dptr)) { 280 if (!mangle_sdp(pskb, ctinfo, ct, newip, port, dptr)) {
285 nf_conntrack_unexpect_related(exp); 281 nf_ct_unexpect_related(exp);
286 return NF_DROP; 282 return NF_DROP;
287 } 283 }
288 return NF_ACCEPT; 284 return NF_ACCEPT;
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c
index 6e88505d6162..6bfcd3a90f08 100644
--- a/net/ipv4/netfilter/nf_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c
@@ -1276,9 +1276,6 @@ static struct nf_conntrack_helper snmp_helper __read_mostly = {
1276 .tuple.src.l3num = AF_INET, 1276 .tuple.src.l3num = AF_INET,
1277 .tuple.src.u.udp.port = __constant_htons(SNMP_PORT), 1277 .tuple.src.u.udp.port = __constant_htons(SNMP_PORT),
1278 .tuple.dst.protonum = IPPROTO_UDP, 1278 .tuple.dst.protonum = IPPROTO_UDP,
1279 .mask.src.l3num = 0xFFFF,
1280 .mask.src.u.udp.port = __constant_htons(0xFFFF),
1281 .mask.dst.protonum = 0xFF,
1282}; 1279};
1283 1280
1284static struct nf_conntrack_helper snmp_trap_helper __read_mostly = { 1281static struct nf_conntrack_helper snmp_trap_helper __read_mostly = {
@@ -1290,9 +1287,6 @@ static struct nf_conntrack_helper snmp_trap_helper __read_mostly = {
1290 .tuple.src.l3num = AF_INET, 1287 .tuple.src.l3num = AF_INET,
1291 .tuple.src.u.udp.port = __constant_htons(SNMP_TRAP_PORT), 1288 .tuple.src.u.udp.port = __constant_htons(SNMP_TRAP_PORT),
1292 .tuple.dst.protonum = IPPROTO_UDP, 1289 .tuple.dst.protonum = IPPROTO_UDP,
1293 .mask.src.l3num = 0xFFFF,
1294 .mask.src.u.udp.port = __constant_htons(0xFFFF),
1295 .mask.dst.protonum = 0xFF,
1296}; 1290};
1297 1291
1298/***************************************************************************** 1292/*****************************************************************************
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c
index 55dac36dbc85..332814dac503 100644
--- a/net/ipv4/netfilter/nf_nat_standalone.c
+++ b/net/ipv4/netfilter/nf_nat_standalone.c
@@ -19,6 +19,7 @@
19 19
20#include <net/netfilter/nf_conntrack.h> 20#include <net/netfilter/nf_conntrack.h>
21#include <net/netfilter/nf_conntrack_core.h> 21#include <net/netfilter/nf_conntrack_core.h>
22#include <net/netfilter/nf_conntrack_extend.h>
22#include <net/netfilter/nf_nat.h> 23#include <net/netfilter/nf_nat.h>
23#include <net/netfilter/nf_nat_rule.h> 24#include <net/netfilter/nf_nat_rule.h>
24#include <net/netfilter/nf_nat_protocol.h> 25#include <net/netfilter/nf_nat_protocol.h>
@@ -26,12 +27,6 @@
26#include <net/netfilter/nf_nat_helper.h> 27#include <net/netfilter/nf_nat_helper.h>
27#include <linux/netfilter_ipv4/ip_tables.h> 28#include <linux/netfilter_ipv4/ip_tables.h>
28 29
29#if 0
30#define DEBUGP printk
31#else
32#define DEBUGP(format, args...)
33#endif
34
35#ifdef CONFIG_XFRM 30#ifdef CONFIG_XFRM
36static void nat_decode_session(struct sk_buff *skb, struct flowi *fl) 31static void nat_decode_session(struct sk_buff *skb, struct flowi *fl)
37{ 32{
@@ -113,8 +108,13 @@ nf_nat_fn(unsigned int hooknum,
113 return NF_ACCEPT; 108 return NF_ACCEPT;
114 109
115 nat = nfct_nat(ct); 110 nat = nfct_nat(ct);
116 if (!nat) 111 if (!nat) {
117 return NF_ACCEPT; 112 nat = nf_ct_ext_add(ct, NF_CT_EXT_NAT, GFP_ATOMIC);
113 if (nat == NULL) {
114 pr_debug("failed to add NAT extension\n");
115 return NF_ACCEPT;
116 }
117 }
118 118
119 switch (ctinfo) { 119 switch (ctinfo) {
120 case IP_CT_RELATED: 120 case IP_CT_RELATED:
@@ -148,9 +148,9 @@ nf_nat_fn(unsigned int hooknum,
148 return ret; 148 return ret;
149 } 149 }
150 } else 150 } else
151 DEBUGP("Already setup manip %s for ct %p\n", 151 pr_debug("Already setup manip %s for ct %p\n",
152 maniptype == IP_NAT_MANIP_SRC ? "SRC" : "DST", 152 maniptype == IP_NAT_MANIP_SRC ? "SRC" : "DST",
153 ct); 153 ct);
154 break; 154 break;
155 155
156 default: 156 default:
@@ -264,7 +264,7 @@ nf_nat_adjust(unsigned int hooknum,
264 264
265 ct = nf_ct_get(*pskb, &ctinfo); 265 ct = nf_ct_get(*pskb, &ctinfo);
266 if (ct && test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) { 266 if (ct && test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) {
267 DEBUGP("nf_nat_standalone: adjusting sequence number\n"); 267 pr_debug("nf_nat_standalone: adjusting sequence number\n");
268 if (!nf_nat_seq_adjust(pskb, ct, ctinfo)) 268 if (!nf_nat_seq_adjust(pskb, ct, ctinfo))
269 return NF_DROP; 269 return NF_DROP;
270 } 270 }
@@ -326,26 +326,10 @@ static struct nf_hook_ops nf_nat_ops[] = {
326 326
327static int __init nf_nat_standalone_init(void) 327static int __init nf_nat_standalone_init(void)
328{ 328{
329 int size, ret = 0; 329 int ret = 0;
330 330
331 need_conntrack(); 331 need_conntrack();
332 332
333 size = ALIGN(sizeof(struct nf_conn), __alignof__(struct nf_conn_nat)) +
334 sizeof(struct nf_conn_nat);
335 ret = nf_conntrack_register_cache(NF_CT_F_NAT, "nf_nat:base", size);
336 if (ret < 0) {
337 printk(KERN_ERR "nf_nat_init: Unable to create slab cache\n");
338 return ret;
339 }
340
341 size = ALIGN(size, __alignof__(struct nf_conn_help)) +
342 sizeof(struct nf_conn_help);
343 ret = nf_conntrack_register_cache(NF_CT_F_NAT|NF_CT_F_HELP,
344 "nf_nat:help", size);
345 if (ret < 0) {
346 printk(KERN_ERR "nf_nat_init: Unable to create slab cache\n");
347 goto cleanup_register_cache;
348 }
349#ifdef CONFIG_XFRM 333#ifdef CONFIG_XFRM
350 BUG_ON(ip_nat_decode_session != NULL); 334 BUG_ON(ip_nat_decode_session != NULL);
351 ip_nat_decode_session = nat_decode_session; 335 ip_nat_decode_session = nat_decode_session;
@@ -360,7 +344,6 @@ static int __init nf_nat_standalone_init(void)
360 printk("nf_nat_init: can't register hooks.\n"); 344 printk("nf_nat_init: can't register hooks.\n");
361 goto cleanup_rule_init; 345 goto cleanup_rule_init;
362 } 346 }
363 nf_nat_module_is_loaded = 1;
364 return ret; 347 return ret;
365 348
366 cleanup_rule_init: 349 cleanup_rule_init:
@@ -370,9 +353,6 @@ static int __init nf_nat_standalone_init(void)
370 ip_nat_decode_session = NULL; 353 ip_nat_decode_session = NULL;
371 synchronize_net(); 354 synchronize_net();
372#endif 355#endif
373 nf_conntrack_unregister_cache(NF_CT_F_NAT|NF_CT_F_HELP);
374 cleanup_register_cache:
375 nf_conntrack_unregister_cache(NF_CT_F_NAT);
376 return ret; 356 return ret;
377} 357}
378 358
@@ -380,7 +360,6 @@ static void __exit nf_nat_standalone_fini(void)
380{ 360{
381 nf_unregister_hooks(nf_nat_ops, ARRAY_SIZE(nf_nat_ops)); 361 nf_unregister_hooks(nf_nat_ops, ARRAY_SIZE(nf_nat_ops));
382 nf_nat_rule_cleanup(); 362 nf_nat_rule_cleanup();
383 nf_nat_module_is_loaded = 0;
384#ifdef CONFIG_XFRM 363#ifdef CONFIG_XFRM
385 ip_nat_decode_session = NULL; 364 ip_nat_decode_session = NULL;
386 synchronize_net(); 365 synchronize_net();
diff --git a/net/ipv4/netfilter/nf_nat_tftp.c b/net/ipv4/netfilter/nf_nat_tftp.c
index 2566b79de224..04dfeaefec02 100644
--- a/net/ipv4/netfilter/nf_nat_tftp.c
+++ b/net/ipv4/netfilter/nf_nat_tftp.c
@@ -30,7 +30,7 @@ static unsigned int help(struct sk_buff **pskb,
30 = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port; 30 = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port;
31 exp->dir = IP_CT_DIR_REPLY; 31 exp->dir = IP_CT_DIR_REPLY;
32 exp->expectfn = nf_nat_follow_master; 32 exp->expectfn = nf_nat_follow_master;
33 if (nf_conntrack_expect_related(exp) != 0) 33 if (nf_ct_expect_related(exp) != 0)
34 return NF_DROP; 34 return NF_DROP;
35 return NF_ACCEPT; 35 return NF_ACCEPT;
36} 36}
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 29ca63e81ced..88fa648d7ba3 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -101,7 +101,6 @@
101#include <net/tcp.h> 101#include <net/tcp.h>
102#include <net/icmp.h> 102#include <net/icmp.h>
103#include <net/xfrm.h> 103#include <net/xfrm.h>
104#include <net/ip_mp_alg.h>
105#include <net/netevent.h> 104#include <net/netevent.h>
106#include <net/rtnetlink.h> 105#include <net/rtnetlink.h>
107#ifdef CONFIG_SYSCTL 106#ifdef CONFIG_SYSCTL
@@ -168,7 +167,7 @@ static struct dst_ops ipv4_dst_ops = {
168 167
169#define ECN_OR_COST(class) TC_PRIO_##class 168#define ECN_OR_COST(class) TC_PRIO_##class
170 169
171__u8 ip_tos2prio[16] = { 170const __u8 ip_tos2prio[16] = {
172 TC_PRIO_BESTEFFORT, 171 TC_PRIO_BESTEFFORT,
173 ECN_OR_COST(FILLER), 172 ECN_OR_COST(FILLER),
174 TC_PRIO_BESTEFFORT, 173 TC_PRIO_BESTEFFORT,
@@ -495,13 +494,11 @@ static const struct file_operations rt_cpu_seq_fops = {
495 494
496static __inline__ void rt_free(struct rtable *rt) 495static __inline__ void rt_free(struct rtable *rt)
497{ 496{
498 multipath_remove(rt);
499 call_rcu_bh(&rt->u.dst.rcu_head, dst_rcu_free); 497 call_rcu_bh(&rt->u.dst.rcu_head, dst_rcu_free);
500} 498}
501 499
502static __inline__ void rt_drop(struct rtable *rt) 500static __inline__ void rt_drop(struct rtable *rt)
503{ 501{
504 multipath_remove(rt);
505 ip_rt_put(rt); 502 ip_rt_put(rt);
506 call_rcu_bh(&rt->u.dst.rcu_head, dst_rcu_free); 503 call_rcu_bh(&rt->u.dst.rcu_head, dst_rcu_free);
507} 504}
@@ -574,52 +571,6 @@ static inline int compare_keys(struct flowi *fl1, struct flowi *fl2)
574 (fl1->iif ^ fl2->iif)) == 0; 571 (fl1->iif ^ fl2->iif)) == 0;
575} 572}
576 573
577#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
578static struct rtable **rt_remove_balanced_route(struct rtable **chain_head,
579 struct rtable *expentry,
580 int *removed_count)
581{
582 int passedexpired = 0;
583 struct rtable **nextstep = NULL;
584 struct rtable **rthp = chain_head;
585 struct rtable *rth;
586
587 if (removed_count)
588 *removed_count = 0;
589
590 while ((rth = *rthp) != NULL) {
591 if (rth == expentry)
592 passedexpired = 1;
593
594 if (((*rthp)->u.dst.flags & DST_BALANCED) != 0 &&
595 compare_keys(&(*rthp)->fl, &expentry->fl)) {
596 if (*rthp == expentry) {
597 *rthp = rth->u.dst.rt_next;
598 continue;
599 } else {
600 *rthp = rth->u.dst.rt_next;
601 rt_free(rth);
602 if (removed_count)
603 ++(*removed_count);
604 }
605 } else {
606 if (!((*rthp)->u.dst.flags & DST_BALANCED) &&
607 passedexpired && !nextstep)
608 nextstep = &rth->u.dst.rt_next;
609
610 rthp = &rth->u.dst.rt_next;
611 }
612 }
613
614 rt_free(expentry);
615 if (removed_count)
616 ++(*removed_count);
617
618 return nextstep;
619}
620#endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
621
622
623/* This runs via a timer and thus is always in BH context. */ 574/* This runs via a timer and thus is always in BH context. */
624static void rt_check_expire(unsigned long dummy) 575static void rt_check_expire(unsigned long dummy)
625{ 576{
@@ -658,22 +609,8 @@ static void rt_check_expire(unsigned long dummy)
658 } 609 }
659 610
660 /* Cleanup aged off entries. */ 611 /* Cleanup aged off entries. */
661#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
662 /* remove all related balanced entries if necessary */
663 if (rth->u.dst.flags & DST_BALANCED) {
664 rthp = rt_remove_balanced_route(
665 &rt_hash_table[i].chain,
666 rth, NULL);
667 if (!rthp)
668 break;
669 } else {
670 *rthp = rth->u.dst.rt_next;
671 rt_free(rth);
672 }
673#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
674 *rthp = rth->u.dst.rt_next; 612 *rthp = rth->u.dst.rt_next;
675 rt_free(rth); 613 rt_free(rth);
676#endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
677 } 614 }
678 spin_unlock(rt_hash_lock_addr(i)); 615 spin_unlock(rt_hash_lock_addr(i));
679 616
@@ -721,9 +658,6 @@ void rt_cache_flush(int delay)
721 if (delay < 0) 658 if (delay < 0)
722 delay = ip_rt_min_delay; 659 delay = ip_rt_min_delay;
723 660
724 /* flush existing multipath state*/
725 multipath_flush();
726
727 spin_lock_bh(&rt_flush_lock); 661 spin_lock_bh(&rt_flush_lock);
728 662
729 if (del_timer(&rt_flush_timer) && delay > 0 && rt_deadline) { 663 if (del_timer(&rt_flush_timer) && delay > 0 && rt_deadline) {
@@ -842,30 +776,9 @@ static int rt_garbage_collect(void)
842 rthp = &rth->u.dst.rt_next; 776 rthp = &rth->u.dst.rt_next;
843 continue; 777 continue;
844 } 778 }
845#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
846 /* remove all related balanced entries
847 * if necessary
848 */
849 if (rth->u.dst.flags & DST_BALANCED) {
850 int r;
851
852 rthp = rt_remove_balanced_route(
853 &rt_hash_table[k].chain,
854 rth,
855 &r);
856 goal -= r;
857 if (!rthp)
858 break;
859 } else {
860 *rthp = rth->u.dst.rt_next;
861 rt_free(rth);
862 goal--;
863 }
864#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
865 *rthp = rth->u.dst.rt_next; 779 *rthp = rth->u.dst.rt_next;
866 rt_free(rth); 780 rt_free(rth);
867 goal--; 781 goal--;
868#endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
869 } 782 }
870 spin_unlock_bh(rt_hash_lock_addr(k)); 783 spin_unlock_bh(rt_hash_lock_addr(k));
871 if (goal <= 0) 784 if (goal <= 0)
@@ -939,12 +852,7 @@ restart:
939 852
940 spin_lock_bh(rt_hash_lock_addr(hash)); 853 spin_lock_bh(rt_hash_lock_addr(hash));
941 while ((rth = *rthp) != NULL) { 854 while ((rth = *rthp) != NULL) {
942#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
943 if (!(rth->u.dst.flags & DST_BALANCED) &&
944 compare_keys(&rth->fl, &rt->fl)) {
945#else
946 if (compare_keys(&rth->fl, &rt->fl)) { 855 if (compare_keys(&rth->fl, &rt->fl)) {
947#endif
948 /* Put it first */ 856 /* Put it first */
949 *rthp = rth->u.dst.rt_next; 857 *rthp = rth->u.dst.rt_next;
950 /* 858 /*
@@ -1774,10 +1682,6 @@ static inline int __mkroute_input(struct sk_buff *skb,
1774 1682
1775 atomic_set(&rth->u.dst.__refcnt, 1); 1683 atomic_set(&rth->u.dst.__refcnt, 1);
1776 rth->u.dst.flags= DST_HOST; 1684 rth->u.dst.flags= DST_HOST;
1777#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
1778 if (res->fi->fib_nhs > 1)
1779 rth->u.dst.flags |= DST_BALANCED;
1780#endif
1781 if (IN_DEV_CONF_GET(in_dev, NOPOLICY)) 1685 if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
1782 rth->u.dst.flags |= DST_NOPOLICY; 1686 rth->u.dst.flags |= DST_NOPOLICY;
1783 if (IN_DEV_CONF_GET(out_dev, NOXFRM)) 1687 if (IN_DEV_CONF_GET(out_dev, NOXFRM))
@@ -1812,11 +1716,11 @@ static inline int __mkroute_input(struct sk_buff *skb,
1812 return err; 1716 return err;
1813} 1717}
1814 1718
1815static inline int ip_mkroute_input_def(struct sk_buff *skb, 1719static inline int ip_mkroute_input(struct sk_buff *skb,
1816 struct fib_result* res, 1720 struct fib_result* res,
1817 const struct flowi *fl, 1721 const struct flowi *fl,
1818 struct in_device *in_dev, 1722 struct in_device *in_dev,
1819 __be32 daddr, __be32 saddr, u32 tos) 1723 __be32 daddr, __be32 saddr, u32 tos)
1820{ 1724{
1821 struct rtable* rth = NULL; 1725 struct rtable* rth = NULL;
1822 int err; 1726 int err;
@@ -1837,63 +1741,6 @@ static inline int ip_mkroute_input_def(struct sk_buff *skb,
1837 return rt_intern_hash(hash, rth, (struct rtable**)&skb->dst); 1741 return rt_intern_hash(hash, rth, (struct rtable**)&skb->dst);
1838} 1742}
1839 1743
1840static inline int ip_mkroute_input(struct sk_buff *skb,
1841 struct fib_result* res,
1842 const struct flowi *fl,
1843 struct in_device *in_dev,
1844 __be32 daddr, __be32 saddr, u32 tos)
1845{
1846#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
1847 struct rtable* rth = NULL, *rtres;
1848 unsigned char hop, hopcount;
1849 int err = -EINVAL;
1850 unsigned int hash;
1851
1852 if (res->fi)
1853 hopcount = res->fi->fib_nhs;
1854 else
1855 hopcount = 1;
1856
1857 /* distinguish between multipath and singlepath */
1858 if (hopcount < 2)
1859 return ip_mkroute_input_def(skb, res, fl, in_dev, daddr,
1860 saddr, tos);
1861
1862 /* add all alternatives to the routing cache */
1863 for (hop = 0; hop < hopcount; hop++) {
1864 res->nh_sel = hop;
1865
1866 /* put reference to previous result */
1867 if (hop)
1868 ip_rt_put(rtres);
1869
1870 /* create a routing cache entry */
1871 err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos,
1872 &rth);
1873 if (err)
1874 return err;
1875
1876 /* put it into the cache */
1877 hash = rt_hash(daddr, saddr, fl->iif);
1878 err = rt_intern_hash(hash, rth, &rtres);
1879 if (err)
1880 return err;
1881
1882 /* forward hop information to multipath impl. */
1883 multipath_set_nhinfo(rth,
1884 FIB_RES_NETWORK(*res),
1885 FIB_RES_NETMASK(*res),
1886 res->prefixlen,
1887 &FIB_RES_NH(*res));
1888 }
1889 skb->dst = &rtres->u.dst;
1890 return err;
1891#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
1892 return ip_mkroute_input_def(skb, res, fl, in_dev, daddr, saddr, tos);
1893#endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
1894}
1895
1896
1897/* 1744/*
1898 * NOTE. We drop all the packets that has local source 1745 * NOTE. We drop all the packets that has local source
1899 * addresses, because every properly looped back packet 1746 * addresses, because every properly looped back packet
@@ -2211,13 +2058,6 @@ static inline int __mkroute_output(struct rtable **result,
2211 2058
2212 atomic_set(&rth->u.dst.__refcnt, 1); 2059 atomic_set(&rth->u.dst.__refcnt, 1);
2213 rth->u.dst.flags= DST_HOST; 2060 rth->u.dst.flags= DST_HOST;
2214#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
2215 if (res->fi) {
2216 rth->rt_multipath_alg = res->fi->fib_mp_alg;
2217 if (res->fi->fib_nhs > 1)
2218 rth->u.dst.flags |= DST_BALANCED;
2219 }
2220#endif
2221 if (IN_DEV_CONF_GET(in_dev, NOXFRM)) 2061 if (IN_DEV_CONF_GET(in_dev, NOXFRM))
2222 rth->u.dst.flags |= DST_NOXFRM; 2062 rth->u.dst.flags |= DST_NOXFRM;
2223 if (IN_DEV_CONF_GET(in_dev, NOPOLICY)) 2063 if (IN_DEV_CONF_GET(in_dev, NOPOLICY))
@@ -2277,12 +2117,12 @@ static inline int __mkroute_output(struct rtable **result,
2277 return err; 2117 return err;
2278} 2118}
2279 2119
2280static inline int ip_mkroute_output_def(struct rtable **rp, 2120static inline int ip_mkroute_output(struct rtable **rp,
2281 struct fib_result* res, 2121 struct fib_result* res,
2282 const struct flowi *fl, 2122 const struct flowi *fl,
2283 const struct flowi *oldflp, 2123 const struct flowi *oldflp,
2284 struct net_device *dev_out, 2124 struct net_device *dev_out,
2285 unsigned flags) 2125 unsigned flags)
2286{ 2126{
2287 struct rtable *rth = NULL; 2127 struct rtable *rth = NULL;
2288 int err = __mkroute_output(&rth, res, fl, oldflp, dev_out, flags); 2128 int err = __mkroute_output(&rth, res, fl, oldflp, dev_out, flags);
@@ -2295,68 +2135,6 @@ static inline int ip_mkroute_output_def(struct rtable **rp,
2295 return err; 2135 return err;
2296} 2136}
2297 2137
2298static inline int ip_mkroute_output(struct rtable** rp,
2299 struct fib_result* res,
2300 const struct flowi *fl,
2301 const struct flowi *oldflp,
2302 struct net_device *dev_out,
2303 unsigned flags)
2304{
2305#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
2306 unsigned char hop;
2307 unsigned hash;
2308 int err = -EINVAL;
2309 struct rtable *rth = NULL;
2310
2311 if (res->fi && res->fi->fib_nhs > 1) {
2312 unsigned char hopcount = res->fi->fib_nhs;
2313
2314 for (hop = 0; hop < hopcount; hop++) {
2315 struct net_device *dev2nexthop;
2316
2317 res->nh_sel = hop;
2318
2319 /* hold a work reference to the output device */
2320 dev2nexthop = FIB_RES_DEV(*res);
2321 dev_hold(dev2nexthop);
2322
2323 /* put reference to previous result */
2324 if (hop)
2325 ip_rt_put(*rp);
2326
2327 err = __mkroute_output(&rth, res, fl, oldflp,
2328 dev2nexthop, flags);
2329
2330 if (err != 0)
2331 goto cleanup;
2332
2333 hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src,
2334 oldflp->oif);
2335 err = rt_intern_hash(hash, rth, rp);
2336
2337 /* forward hop information to multipath impl. */
2338 multipath_set_nhinfo(rth,
2339 FIB_RES_NETWORK(*res),
2340 FIB_RES_NETMASK(*res),
2341 res->prefixlen,
2342 &FIB_RES_NH(*res));
2343 cleanup:
2344 /* release work reference to output device */
2345 dev_put(dev2nexthop);
2346
2347 if (err != 0)
2348 return err;
2349 }
2350 return err;
2351 } else {
2352 return ip_mkroute_output_def(rp, res, fl, oldflp, dev_out,
2353 flags);
2354 }
2355#else /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
2356 return ip_mkroute_output_def(rp, res, fl, oldflp, dev_out, flags);
2357#endif
2358}
2359
2360/* 2138/*
2361 * Major route resolver routine. 2139 * Major route resolver routine.
2362 */ 2140 */
@@ -2570,17 +2348,6 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp)
2570 rth->fl.mark == flp->mark && 2348 rth->fl.mark == flp->mark &&
2571 !((rth->fl.fl4_tos ^ flp->fl4_tos) & 2349 !((rth->fl.fl4_tos ^ flp->fl4_tos) &
2572 (IPTOS_RT_MASK | RTO_ONLINK))) { 2350 (IPTOS_RT_MASK | RTO_ONLINK))) {
2573
2574 /* check for multipath routes and choose one if
2575 * necessary
2576 */
2577 if (multipath_select_route(flp, rth, rp)) {
2578 dst_hold(&(*rp)->u.dst);
2579 RT_CACHE_STAT_INC(out_hit);
2580 rcu_read_unlock_bh();
2581 return 0;
2582 }
2583
2584 rth->u.dst.lastuse = jiffies; 2351 rth->u.dst.lastuse = jiffies;
2585 dst_hold(&rth->u.dst); 2352 dst_hold(&rth->u.dst);
2586 rth->u.dst.__use++; 2353 rth->u.dst.__use++;
@@ -2729,10 +2496,6 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
2729 if (rt->u.dst.tclassid) 2496 if (rt->u.dst.tclassid)
2730 NLA_PUT_U32(skb, RTA_FLOW, rt->u.dst.tclassid); 2497 NLA_PUT_U32(skb, RTA_FLOW, rt->u.dst.tclassid);
2731#endif 2498#endif
2732#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
2733 if (rt->rt_multipath_alg != IP_MP_ALG_NONE)
2734 NLA_PUT_U32(skb, RTA_MP_ALGO, rt->rt_multipath_alg);
2735#endif
2736 if (rt->fl.iif) 2499 if (rt->fl.iif)
2737 NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_spec_dst); 2500 NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_spec_dst);
2738 else if (rt->rt_src != rt->fl.fl4_src) 2501 else if (rt->rt_src != rt->fl.fl4_src)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 450f44bb2c8e..987b94403be5 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1116,6 +1116,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
1116 long timeo; 1116 long timeo;
1117 struct task_struct *user_recv = NULL; 1117 struct task_struct *user_recv = NULL;
1118 int copied_early = 0; 1118 int copied_early = 0;
1119 struct sk_buff *skb;
1119 1120
1120 lock_sock(sk); 1121 lock_sock(sk);
1121 1122
@@ -1142,16 +1143,26 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
1142#ifdef CONFIG_NET_DMA 1143#ifdef CONFIG_NET_DMA
1143 tp->ucopy.dma_chan = NULL; 1144 tp->ucopy.dma_chan = NULL;
1144 preempt_disable(); 1145 preempt_disable();
1145 if ((len > sysctl_tcp_dma_copybreak) && !(flags & MSG_PEEK) && 1146 skb = skb_peek_tail(&sk->sk_receive_queue);
1146 !sysctl_tcp_low_latency && __get_cpu_var(softnet_data).net_dma) { 1147 {
1147 preempt_enable_no_resched(); 1148 int available = 0;
1148 tp->ucopy.pinned_list = dma_pin_iovec_pages(msg->msg_iov, len); 1149
1149 } else 1150 if (skb)
1150 preempt_enable_no_resched(); 1151 available = TCP_SKB_CB(skb)->seq + skb->len - (*seq);
1152 if ((available < target) &&
1153 (len > sysctl_tcp_dma_copybreak) && !(flags & MSG_PEEK) &&
1154 !sysctl_tcp_low_latency &&
1155 __get_cpu_var(softnet_data).net_dma) {
1156 preempt_enable_no_resched();
1157 tp->ucopy.pinned_list =
1158 dma_pin_iovec_pages(msg->msg_iov, len);
1159 } else {
1160 preempt_enable_no_resched();
1161 }
1162 }
1151#endif 1163#endif
1152 1164
1153 do { 1165 do {
1154 struct sk_buff *skb;
1155 u32 offset; 1166 u32 offset;
1156 1167
1157 /* Are we at urgent data? Stop if we have read anything or have SIGURG pending. */ 1168 /* Are we at urgent data? Stop if we have read anything or have SIGURG pending. */
@@ -1439,7 +1450,6 @@ skip_copy:
1439 1450
1440#ifdef CONFIG_NET_DMA 1451#ifdef CONFIG_NET_DMA
1441 if (tp->ucopy.dma_chan) { 1452 if (tp->ucopy.dma_chan) {
1442 struct sk_buff *skb;
1443 dma_cookie_t done, used; 1453 dma_cookie_t done, used;
1444 1454
1445 dma_async_memcpy_issue_pending(tp->ucopy.dma_chan); 1455 dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 354721d67f69..3f5f7423b95c 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2045,10 +2045,7 @@ static void *established_get_first(struct seq_file *seq)
2045 struct hlist_node *node; 2045 struct hlist_node *node;
2046 struct inet_timewait_sock *tw; 2046 struct inet_timewait_sock *tw;
2047 2047
2048 /* We can reschedule _before_ having picked the target: */ 2048 read_lock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
2049 cond_resched_softirq();
2050
2051 read_lock(&tcp_hashinfo.ehash[st->bucket].lock);
2052 sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) { 2049 sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
2053 if (sk->sk_family != st->family) { 2050 if (sk->sk_family != st->family) {
2054 continue; 2051 continue;
@@ -2065,7 +2062,7 @@ static void *established_get_first(struct seq_file *seq)
2065 rc = tw; 2062 rc = tw;
2066 goto out; 2063 goto out;
2067 } 2064 }
2068 read_unlock(&tcp_hashinfo.ehash[st->bucket].lock); 2065 read_unlock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
2069 st->state = TCP_SEQ_STATE_ESTABLISHED; 2066 st->state = TCP_SEQ_STATE_ESTABLISHED;
2070 } 2067 }
2071out: 2068out:
@@ -2092,14 +2089,11 @@ get_tw:
2092 cur = tw; 2089 cur = tw;
2093 goto out; 2090 goto out;
2094 } 2091 }
2095 read_unlock(&tcp_hashinfo.ehash[st->bucket].lock); 2092 read_unlock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
2096 st->state = TCP_SEQ_STATE_ESTABLISHED; 2093 st->state = TCP_SEQ_STATE_ESTABLISHED;
2097 2094
2098 /* We can reschedule between buckets: */
2099 cond_resched_softirq();
2100
2101 if (++st->bucket < tcp_hashinfo.ehash_size) { 2095 if (++st->bucket < tcp_hashinfo.ehash_size) {
2102 read_lock(&tcp_hashinfo.ehash[st->bucket].lock); 2096 read_lock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
2103 sk = sk_head(&tcp_hashinfo.ehash[st->bucket].chain); 2097 sk = sk_head(&tcp_hashinfo.ehash[st->bucket].chain);
2104 } else { 2098 } else {
2105 cur = NULL; 2099 cur = NULL;
@@ -2144,7 +2138,6 @@ static void *tcp_get_idx(struct seq_file *seq, loff_t pos)
2144 2138
2145 if (!rc) { 2139 if (!rc) {
2146 inet_listen_unlock(&tcp_hashinfo); 2140 inet_listen_unlock(&tcp_hashinfo);
2147 local_bh_disable();
2148 st->state = TCP_SEQ_STATE_ESTABLISHED; 2141 st->state = TCP_SEQ_STATE_ESTABLISHED;
2149 rc = established_get_idx(seq, pos); 2142 rc = established_get_idx(seq, pos);
2150 } 2143 }
@@ -2177,7 +2170,6 @@ static void *tcp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2177 rc = listening_get_next(seq, v); 2170 rc = listening_get_next(seq, v);
2178 if (!rc) { 2171 if (!rc) {
2179 inet_listen_unlock(&tcp_hashinfo); 2172 inet_listen_unlock(&tcp_hashinfo);
2180 local_bh_disable();
2181 st->state = TCP_SEQ_STATE_ESTABLISHED; 2173 st->state = TCP_SEQ_STATE_ESTABLISHED;
2182 rc = established_get_first(seq); 2174 rc = established_get_first(seq);
2183 } 2175 }
@@ -2209,8 +2201,7 @@ static void tcp_seq_stop(struct seq_file *seq, void *v)
2209 case TCP_SEQ_STATE_TIME_WAIT: 2201 case TCP_SEQ_STATE_TIME_WAIT:
2210 case TCP_SEQ_STATE_ESTABLISHED: 2202 case TCP_SEQ_STATE_ESTABLISHED:
2211 if (v) 2203 if (v)
2212 read_unlock(&tcp_hashinfo.ehash[st->bucket].lock); 2204 read_unlock_bh(&tcp_hashinfo.ehash[st->bucket].lock);
2213 local_bh_enable();
2214 break; 2205 break;
2215 } 2206 }
2216} 2207}
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 53232dd6fb48..20aea1595c4d 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -699,6 +699,14 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
699 tp->fackets_out -= diff; 699 tp->fackets_out -= diff;
700 if ((int)tp->fackets_out < 0) 700 if ((int)tp->fackets_out < 0)
701 tp->fackets_out = 0; 701 tp->fackets_out = 0;
702 /* SACK fastpath might overwrite it unless dealt with */
703 if (tp->fastpath_skb_hint != NULL &&
704 after(TCP_SKB_CB(tp->fastpath_skb_hint)->seq,
705 TCP_SKB_CB(skb)->seq)) {
706 tp->fastpath_cnt_hint -= diff;
707 if ((int)tp->fastpath_cnt_hint < 0)
708 tp->fastpath_cnt_hint = 0;
709 }
702 } 710 }
703 } 711 }
704 712
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c
index d9323dfff826..86624fabc4bf 100644
--- a/net/ipv4/tcp_probe.c
+++ b/net/ipv4/tcp_probe.c
@@ -6,8 +6,7 @@
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or 9 * the Free Software Foundation; either version 2 of the License.
10 * (at your option) any later version.
11 * 10 *
12 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -25,23 +24,22 @@
25#include <linux/tcp.h> 24#include <linux/tcp.h>
26#include <linux/proc_fs.h> 25#include <linux/proc_fs.h>
27#include <linux/module.h> 26#include <linux/module.h>
28#include <linux/kfifo.h>
29#include <linux/ktime.h> 27#include <linux/ktime.h>
30#include <linux/time.h> 28#include <linux/time.h>
31#include <linux/vmalloc.h>
32 29
33#include <net/tcp.h> 30#include <net/tcp.h>
34 31
35MODULE_AUTHOR("Stephen Hemminger <shemminger@linux-foundation.org>"); 32MODULE_AUTHOR("Stephen Hemminger <shemminger@linux-foundation.org>");
36MODULE_DESCRIPTION("TCP cwnd snooper"); 33MODULE_DESCRIPTION("TCP cwnd snooper");
37MODULE_LICENSE("GPL"); 34MODULE_LICENSE("GPL");
35MODULE_VERSION("1.1");
38 36
39static int port __read_mostly = 0; 37static int port __read_mostly = 0;
40MODULE_PARM_DESC(port, "Port to match (0=all)"); 38MODULE_PARM_DESC(port, "Port to match (0=all)");
41module_param(port, int, 0); 39module_param(port, int, 0);
42 40
43static int bufsize __read_mostly = 64*1024; 41static int bufsize __read_mostly = 4096;
44MODULE_PARM_DESC(bufsize, "Log buffer size (default 64k)"); 42MODULE_PARM_DESC(bufsize, "Log buffer size in packets (4096)");
45module_param(bufsize, int, 0); 43module_param(bufsize, int, 0);
46 44
47static int full __read_mostly; 45static int full __read_mostly;
@@ -50,39 +48,38 @@ module_param(full, int, 0);
50 48
51static const char procname[] = "tcpprobe"; 49static const char procname[] = "tcpprobe";
52 50
53struct { 51struct tcp_log {
54 struct kfifo *fifo; 52 ktime_t tstamp;
53 __be32 saddr, daddr;
54 __be16 sport, dport;
55 u16 length;
56 u32 snd_nxt;
57 u32 snd_una;
58 u32 snd_wnd;
59 u32 snd_cwnd;
60 u32 ssthresh;
61 u32 srtt;
62};
63
64static struct {
55 spinlock_t lock; 65 spinlock_t lock;
56 wait_queue_head_t wait; 66 wait_queue_head_t wait;
57 ktime_t start; 67 ktime_t start;
58 u32 lastcwnd; 68 u32 lastcwnd;
59} tcpw;
60 69
61/* 70 unsigned long head, tail;
62 * Print to log with timestamps. 71 struct tcp_log *log;
63 * FIXME: causes an extra copy 72} tcp_probe;
64 */ 73
65static void printl(const char *fmt, ...)
66 __attribute__ ((format (printf, 1, 2)));
67 74
68static void printl(const char *fmt, ...) 75static inline int tcp_probe_used(void)
69{ 76{
70 va_list args; 77 return (tcp_probe.head - tcp_probe.tail) % bufsize;
71 int len; 78}
72 struct timespec tv; 79
73 char tbuf[256]; 80static inline int tcp_probe_avail(void)
74 81{
75 va_start(args, fmt); 82 return bufsize - tcp_probe_used();
76 /* want monotonic time since start of tcp_probe */
77 tv = ktime_to_timespec(ktime_sub(ktime_get(), tcpw.start));
78
79 len = sprintf(tbuf, "%lu.%09lu ",
80 (unsigned long) tv.tv_sec, (unsigned long) tv.tv_nsec);
81 len += vscnprintf(tbuf+len, sizeof(tbuf)-len, fmt, args);
82 va_end(args);
83
84 kfifo_put(tcpw.fifo, tbuf, len);
85 wake_up(&tcpw.wait);
86} 83}
87 84
88/* 85/*
@@ -97,63 +94,117 @@ static int jtcp_rcv_established(struct sock *sk, struct sk_buff *skb,
97 94
98 /* Only update if port matches */ 95 /* Only update if port matches */
99 if ((port == 0 || ntohs(inet->dport) == port || ntohs(inet->sport) == port) 96 if ((port == 0 || ntohs(inet->dport) == port || ntohs(inet->sport) == port)
100 && (full || tp->snd_cwnd != tcpw.lastcwnd)) { 97 && (full || tp->snd_cwnd != tcp_probe.lastcwnd)) {
101 printl("%d.%d.%d.%d:%u %d.%d.%d.%d:%u %d %#x %#x %u %u %u %u\n", 98
102 NIPQUAD(inet->saddr), ntohs(inet->sport), 99 spin_lock(&tcp_probe.lock);
103 NIPQUAD(inet->daddr), ntohs(inet->dport), 100 /* If log fills, just silently drop */
104 skb->len, tp->snd_nxt, tp->snd_una, 101 if (tcp_probe_avail() > 1) {
105 tp->snd_cwnd, tcp_current_ssthresh(sk), 102 struct tcp_log *p = tcp_probe.log + tcp_probe.head;
106 tp->snd_wnd, tp->srtt >> 3); 103
107 tcpw.lastcwnd = tp->snd_cwnd; 104 p->tstamp = ktime_get();
105 p->saddr = inet->saddr;
106 p->sport = inet->sport;
107 p->daddr = inet->daddr;
108 p->dport = inet->dport;
109 p->length = skb->len;
110 p->snd_nxt = tp->snd_nxt;
111 p->snd_una = tp->snd_una;
112 p->snd_cwnd = tp->snd_cwnd;
113 p->snd_wnd = tp->snd_wnd;
114 p->srtt = tp->srtt >> 3;
115
116 tcp_probe.head = (tcp_probe.head + 1) % bufsize;
117 }
118 tcp_probe.lastcwnd = tp->snd_cwnd;
119 spin_unlock(&tcp_probe.lock);
120
121 wake_up(&tcp_probe.wait);
108 } 122 }
109 123
110 jprobe_return(); 124 jprobe_return();
111 return 0; 125 return 0;
112} 126}
113 127
114static struct jprobe tcp_probe = { 128static struct jprobe tcp_jprobe = {
115 .kp = { 129 .kp = {
116 .symbol_name = "tcp_rcv_established", 130 .symbol_name = "tcp_rcv_established",
117 }, 131 },
118 .entry = JPROBE_ENTRY(jtcp_rcv_established), 132 .entry = JPROBE_ENTRY(jtcp_rcv_established),
119}; 133};
120 134
121
122static int tcpprobe_open(struct inode * inode, struct file * file) 135static int tcpprobe_open(struct inode * inode, struct file * file)
123{ 136{
124 kfifo_reset(tcpw.fifo); 137 /* Reset (empty) log */
125 tcpw.start = ktime_get(); 138 spin_lock_bh(&tcp_probe.lock);
139 tcp_probe.head = tcp_probe.tail = 0;
140 tcp_probe.start = ktime_get();
141 spin_unlock_bh(&tcp_probe.lock);
142
126 return 0; 143 return 0;
127} 144}
128 145
146static int tcpprobe_sprint(char *tbuf, int n)
147{
148 const struct tcp_log *p
149 = tcp_probe.log + tcp_probe.tail % bufsize;
150 struct timespec tv
151 = ktime_to_timespec(ktime_sub(p->tstamp, tcp_probe.start));
152
153 return snprintf(tbuf, n,
154 "%lu.%09lu %d.%d.%d.%d:%u %d.%d.%d.%d:%u"
155 " %d %#x %#x %u %u %u %u\n",
156 (unsigned long) tv.tv_sec,
157 (unsigned long) tv.tv_nsec,
158 NIPQUAD(p->saddr), ntohs(p->sport),
159 NIPQUAD(p->daddr), ntohs(p->dport),
160 p->length, p->snd_nxt, p->snd_una,
161 p->snd_cwnd, p->ssthresh, p->snd_wnd, p->srtt);
162}
163
129static ssize_t tcpprobe_read(struct file *file, char __user *buf, 164static ssize_t tcpprobe_read(struct file *file, char __user *buf,
130 size_t len, loff_t *ppos) 165 size_t len, loff_t *ppos)
131{ 166{
132 int error = 0, cnt = 0; 167 int error = 0, cnt = 0;
133 unsigned char *tbuf;
134 168
135 if (!buf || len < 0) 169 if (!buf || len < 0)
136 return -EINVAL; 170 return -EINVAL;
137 171
138 if (len == 0) 172 while (cnt < len) {
139 return 0; 173 char tbuf[128];
174 int width;
175
176 /* Wait for data in buffer */
177 error = wait_event_interruptible(tcp_probe.wait,
178 tcp_probe_used() > 0);
179 if (error)
180 break;
140 181
141 tbuf = vmalloc(len); 182 spin_lock_bh(&tcp_probe.lock);
142 if (!tbuf) 183 if (tcp_probe.head == tcp_probe.tail) {
143 return -ENOMEM; 184 /* multiple readers race? */
185 spin_unlock_bh(&tcp_probe.lock);
186 continue;
187 }
144 188
145 error = wait_event_interruptible(tcpw.wait, 189 width = tcpprobe_sprint(tbuf, sizeof(tbuf));
146 __kfifo_len(tcpw.fifo) != 0);
147 if (error)
148 goto out_free;
149 190
150 cnt = kfifo_get(tcpw.fifo, tbuf, len); 191 if (width < len)
151 error = copy_to_user(buf, tbuf, cnt); 192 tcp_probe.tail = (tcp_probe.tail + 1) % bufsize;
152 193
153out_free: 194 spin_unlock_bh(&tcp_probe.lock);
154 vfree(tbuf); 195
196 /* if record greater than space available
197 return partial buffer (so far) */
198 if (width >= len)
199 break;
200
201 error = copy_to_user(buf + cnt, tbuf, width);
202 if (error)
203 break;
204 cnt += width;
205 }
155 206
156 return error ? error : cnt; 207 return cnt == 0 ? error : cnt;
157} 208}
158 209
159static const struct file_operations tcpprobe_fops = { 210static const struct file_operations tcpprobe_fops = {
@@ -166,34 +217,37 @@ static __init int tcpprobe_init(void)
166{ 217{
167 int ret = -ENOMEM; 218 int ret = -ENOMEM;
168 219
169 init_waitqueue_head(&tcpw.wait); 220 init_waitqueue_head(&tcp_probe.wait);
170 spin_lock_init(&tcpw.lock); 221 spin_lock_init(&tcp_probe.lock);
171 tcpw.fifo = kfifo_alloc(bufsize, GFP_KERNEL, &tcpw.lock); 222
172 if (IS_ERR(tcpw.fifo)) 223 if (bufsize < 0)
173 return PTR_ERR(tcpw.fifo); 224 return -EINVAL;
225
226 tcp_probe.log = kcalloc(sizeof(struct tcp_log), bufsize, GFP_KERNEL);
227 if (!tcp_probe.log)
228 goto err0;
174 229
175 if (!proc_net_fops_create(procname, S_IRUSR, &tcpprobe_fops)) 230 if (!proc_net_fops_create(procname, S_IRUSR, &tcpprobe_fops))
176 goto err0; 231 goto err0;
177 232
178 ret = register_jprobe(&tcp_probe); 233 ret = register_jprobe(&tcp_jprobe);
179 if (ret) 234 if (ret)
180 goto err1; 235 goto err1;
181 236
182 pr_info("TCP watch registered (port=%d)\n", port); 237 pr_info("TCP probe registered (port=%d)\n", port);
183 return 0; 238 return 0;
184 err1: 239 err1:
185 proc_net_remove(procname); 240 proc_net_remove(procname);
186 err0: 241 err0:
187 kfifo_free(tcpw.fifo); 242 kfree(tcp_probe.log);
188 return ret; 243 return ret;
189} 244}
190module_init(tcpprobe_init); 245module_init(tcpprobe_init);
191 246
192static __exit void tcpprobe_exit(void) 247static __exit void tcpprobe_exit(void)
193{ 248{
194 kfifo_free(tcpw.fifo);
195 proc_net_remove(procname); 249 proc_net_remove(procname);
196 unregister_jprobe(&tcp_probe); 250 unregister_jprobe(&tcp_jprobe);
197 251 kfree(tcp_probe.log);
198} 252}
199module_exit(tcpprobe_exit); 253module_exit(tcpprobe_exit);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index facb7e29304e..28355350fb62 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -70,6 +70,7 @@
70 * Alexey Kuznetsov: allow both IPv4 and IPv6 sockets to bind 70 * Alexey Kuznetsov: allow both IPv4 and IPv6 sockets to bind
71 * a single port at the same time. 71 * a single port at the same time.
72 * Derek Atkins <derek@ihtfp.com>: Add Encapulation Support 72 * Derek Atkins <derek@ihtfp.com>: Add Encapulation Support
73 * James Chapman : Add L2TP encapsulation type.
73 * 74 *
74 * 75 *
75 * This program is free software; you can redistribute it and/or 76 * This program is free software; you can redistribute it and/or
@@ -919,104 +920,6 @@ int udp_disconnect(struct sock *sk, int flags)
919 return 0; 920 return 0;
920} 921}
921 922
922/* return:
923 * 1 if the UDP system should process it
924 * 0 if we should drop this packet
925 * -1 if it should get processed by xfrm4_rcv_encap
926 */
927static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb)
928{
929#ifndef CONFIG_XFRM
930 return 1;
931#else
932 struct udp_sock *up = udp_sk(sk);
933 struct udphdr *uh;
934 struct iphdr *iph;
935 int iphlen, len;
936
937 __u8 *udpdata;
938 __be32 *udpdata32;
939 __u16 encap_type = up->encap_type;
940
941 /* if we're overly short, let UDP handle it */
942 len = skb->len - sizeof(struct udphdr);
943 if (len <= 0)
944 return 1;
945
946 /* if this is not encapsulated socket, then just return now */
947 if (!encap_type)
948 return 1;
949
950 /* If this is a paged skb, make sure we pull up
951 * whatever data we need to look at. */
952 if (!pskb_may_pull(skb, sizeof(struct udphdr) + min(len, 8)))
953 return 1;
954
955 /* Now we can get the pointers */
956 uh = udp_hdr(skb);
957 udpdata = (__u8 *)uh + sizeof(struct udphdr);
958 udpdata32 = (__be32 *)udpdata;
959
960 switch (encap_type) {
961 default:
962 case UDP_ENCAP_ESPINUDP:
963 /* Check if this is a keepalive packet. If so, eat it. */
964 if (len == 1 && udpdata[0] == 0xff) {
965 return 0;
966 } else if (len > sizeof(struct ip_esp_hdr) && udpdata32[0] != 0) {
967 /* ESP Packet without Non-ESP header */
968 len = sizeof(struct udphdr);
969 } else
970 /* Must be an IKE packet.. pass it through */
971 return 1;
972 break;
973 case UDP_ENCAP_ESPINUDP_NON_IKE:
974 /* Check if this is a keepalive packet. If so, eat it. */
975 if (len == 1 && udpdata[0] == 0xff) {
976 return 0;
977 } else if (len > 2 * sizeof(u32) + sizeof(struct ip_esp_hdr) &&
978 udpdata32[0] == 0 && udpdata32[1] == 0) {
979
980 /* ESP Packet with Non-IKE marker */
981 len = sizeof(struct udphdr) + 2 * sizeof(u32);
982 } else
983 /* Must be an IKE packet.. pass it through */
984 return 1;
985 break;
986 }
987
988 /* At this point we are sure that this is an ESPinUDP packet,
989 * so we need to remove 'len' bytes from the packet (the UDP
990 * header and optional ESP marker bytes) and then modify the
991 * protocol to ESP, and then call into the transform receiver.
992 */
993 if (skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
994 return 0;
995
996 /* Now we can update and verify the packet length... */
997 iph = ip_hdr(skb);
998 iphlen = iph->ihl << 2;
999 iph->tot_len = htons(ntohs(iph->tot_len) - len);
1000 if (skb->len < iphlen + len) {
1001 /* packet is too small!?! */
1002 return 0;
1003 }
1004
1005 /* pull the data buffer up to the ESP header and set the
1006 * transport header to point to ESP. Keep UDP on the stack
1007 * for later.
1008 */
1009 __skb_pull(skb, len);
1010 skb_reset_transport_header(skb);
1011
1012 /* modify the protocol (it's ESP!) */
1013 iph->protocol = IPPROTO_ESP;
1014
1015 /* and let the caller know to send this into the ESP processor... */
1016 return -1;
1017#endif
1018}
1019
1020/* returns: 923/* returns:
1021 * -1: error 924 * -1: error
1022 * 0: success 925 * 0: success
@@ -1039,28 +942,28 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
1039 942
1040 if (up->encap_type) { 943 if (up->encap_type) {
1041 /* 944 /*
1042 * This is an encapsulation socket, so let's see if this is 945 * This is an encapsulation socket so pass the skb to
1043 * an encapsulated packet. 946 * the socket's udp_encap_rcv() hook. Otherwise, just
1044 * If it's a keepalive packet, then just eat it. 947 * fall through and pass this up the UDP socket.
1045 * If it's an encapsulateed packet, then pass it to the 948 * up->encap_rcv() returns the following value:
1046 * IPsec xfrm input and return the response 949 * =0 if skb was successfully passed to the encap
1047 * appropriately. Otherwise, just fall through and 950 * handler or was discarded by it.
1048 * pass this up the UDP socket. 951 * >0 if skb should be passed on to UDP.
952 * <0 if skb should be resubmitted as proto -N
1049 */ 953 */
1050 int ret;
1051 954
1052 ret = udp_encap_rcv(sk, skb); 955 /* if we're overly short, let UDP handle it */
1053 if (ret == 0) { 956 if (skb->len > sizeof(struct udphdr) &&
1054 /* Eat the packet .. */ 957 up->encap_rcv != NULL) {
1055 kfree_skb(skb); 958 int ret;
1056 return 0; 959
1057 } 960 ret = (*up->encap_rcv)(sk, skb);
1058 if (ret < 0) { 961 if (ret <= 0) {
1059 /* process the ESP packet */ 962 UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag);
1060 ret = xfrm4_rcv_encap(skb, up->encap_type); 963 return -ret;
1061 UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag); 964 }
1062 return -ret;
1063 } 965 }
966
1064 /* FALLTHROUGH -- it's a UDP Packet */ 967 /* FALLTHROUGH -- it's a UDP Packet */
1065 } 968 }
1066 969
@@ -1349,6 +1252,9 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
1349 case 0: 1252 case 0:
1350 case UDP_ENCAP_ESPINUDP: 1253 case UDP_ENCAP_ESPINUDP:
1351 case UDP_ENCAP_ESPINUDP_NON_IKE: 1254 case UDP_ENCAP_ESPINUDP_NON_IKE:
1255 up->encap_rcv = xfrm4_udp_encap_rcv;
1256 /* FALLTHROUGH */
1257 case UDP_ENCAP_L2TPINUDP:
1352 up->encap_type = val; 1258 up->encap_type = val;
1353 break; 1259 break;
1354 default: 1260 default:
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index fa1902dc81b8..2fa108245413 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -16,13 +16,6 @@
16#include <net/ip.h> 16#include <net/ip.h>
17#include <net/xfrm.h> 17#include <net/xfrm.h>
18 18
19int xfrm4_rcv(struct sk_buff *skb)
20{
21 return xfrm4_rcv_encap(skb, 0);
22}
23
24EXPORT_SYMBOL(xfrm4_rcv);
25
26static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq) 19static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
27{ 20{
28 switch (nexthdr) { 21 switch (nexthdr) {
@@ -53,7 +46,7 @@ drop:
53} 46}
54#endif 47#endif
55 48
56int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) 49static int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
57{ 50{
58 __be32 spi, seq; 51 __be32 spi, seq;
59 struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH]; 52 struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
@@ -167,3 +160,108 @@ drop:
167 kfree_skb(skb); 160 kfree_skb(skb);
168 return 0; 161 return 0;
169} 162}
163
164/* If it's a keepalive packet, then just eat it.
165 * If it's an encapsulated packet, then pass it to the
166 * IPsec xfrm input.
167 * Returns 0 if skb passed to xfrm or was dropped.
168 * Returns >0 if skb should be passed to UDP.
169 * Returns <0 if skb should be resubmitted (-ret is protocol)
170 */
171int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
172{
173 struct udp_sock *up = udp_sk(sk);
174 struct udphdr *uh;
175 struct iphdr *iph;
176 int iphlen, len;
177 int ret;
178
179 __u8 *udpdata;
180 __be32 *udpdata32;
181 __u16 encap_type = up->encap_type;
182
183 /* if this is not encapsulated socket, then just return now */
184 if (!encap_type)
185 return 1;
186
187 /* If this is a paged skb, make sure we pull up
188 * whatever data we need to look at. */
189 len = skb->len - sizeof(struct udphdr);
190 if (!pskb_may_pull(skb, sizeof(struct udphdr) + min(len, 8)))
191 return 1;
192
193 /* Now we can get the pointers */
194 uh = udp_hdr(skb);
195 udpdata = (__u8 *)uh + sizeof(struct udphdr);
196 udpdata32 = (__be32 *)udpdata;
197
198 switch (encap_type) {
199 default:
200 case UDP_ENCAP_ESPINUDP:
201 /* Check if this is a keepalive packet. If so, eat it. */
202 if (len == 1 && udpdata[0] == 0xff) {
203 goto drop;
204 } else if (len > sizeof(struct ip_esp_hdr) && udpdata32[0] != 0) {
205 /* ESP Packet without Non-ESP header */
206 len = sizeof(struct udphdr);
207 } else
208 /* Must be an IKE packet.. pass it through */
209 return 1;
210 break;
211 case UDP_ENCAP_ESPINUDP_NON_IKE:
212 /* Check if this is a keepalive packet. If so, eat it. */
213 if (len == 1 && udpdata[0] == 0xff) {
214 goto drop;
215 } else if (len > 2 * sizeof(u32) + sizeof(struct ip_esp_hdr) &&
216 udpdata32[0] == 0 && udpdata32[1] == 0) {
217
218 /* ESP Packet with Non-IKE marker */
219 len = sizeof(struct udphdr) + 2 * sizeof(u32);
220 } else
221 /* Must be an IKE packet.. pass it through */
222 return 1;
223 break;
224 }
225
226 /* At this point we are sure that this is an ESPinUDP packet,
227 * so we need to remove 'len' bytes from the packet (the UDP
228 * header and optional ESP marker bytes) and then modify the
229 * protocol to ESP, and then call into the transform receiver.
230 */
231 if (skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
232 goto drop;
233
234 /* Now we can update and verify the packet length... */
235 iph = ip_hdr(skb);
236 iphlen = iph->ihl << 2;
237 iph->tot_len = htons(ntohs(iph->tot_len) - len);
238 if (skb->len < iphlen + len) {
239 /* packet is too small!?! */
240 goto drop;
241 }
242
243 /* pull the data buffer up to the ESP header and set the
244 * transport header to point to ESP. Keep UDP on the stack
245 * for later.
246 */
247 __skb_pull(skb, len);
248 skb_reset_transport_header(skb);
249
250 /* modify the protocol (it's ESP!) */
251 iph->protocol = IPPROTO_ESP;
252
253 /* process ESP */
254 ret = xfrm4_rcv_encap(skb, encap_type);
255 return ret;
256
257drop:
258 kfree_skb(skb);
259 return 0;
260}
261
262int xfrm4_rcv(struct sk_buff *skb)
263{
264 return xfrm4_rcv_encap(skb, 0);
265}
266
267EXPORT_SYMBOL(xfrm4_rcv);
diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c
index 568510304553..9275c79119b6 100644
--- a/net/ipv4/xfrm4_tunnel.c
+++ b/net/ipv4/xfrm4_tunnel.c
@@ -109,3 +109,4 @@ static void __exit ipip_fini(void)
109module_init(ipip_init); 109module_init(ipip_init);
110module_exit(ipip_fini); 110module_exit(ipip_fini);
111MODULE_LICENSE("GPL"); 111MODULE_LICENSE("GPL");
112MODULE_ALIAS_XFRM_TYPE(AF_INET, XFRM_PROTO_IPIP);
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index 8e5d54f23b49..eb0b8085949b 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -109,7 +109,7 @@ config INET6_IPCOMP
109 If unsure, say Y. 109 If unsure, say Y.
110 110
111config IPV6_MIP6 111config IPV6_MIP6
112 bool "IPv6: Mobility (EXPERIMENTAL)" 112 tristate "IPv6: Mobility (EXPERIMENTAL)"
113 depends on IPV6 && EXPERIMENTAL 113 depends on IPV6 && EXPERIMENTAL
114 select XFRM 114 select XFRM
115 ---help--- 115 ---help---
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index bb33309044c9..87c23a73d284 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -14,7 +14,6 @@ ipv6-$(CONFIG_XFRM) += xfrm6_policy.o xfrm6_state.o xfrm6_input.o \
14 xfrm6_output.o 14 xfrm6_output.o
15ipv6-$(CONFIG_NETFILTER) += netfilter.o 15ipv6-$(CONFIG_NETFILTER) += netfilter.o
16ipv6-$(CONFIG_IPV6_MULTIPLE_TABLES) += fib6_rules.o 16ipv6-$(CONFIG_IPV6_MULTIPLE_TABLES) += fib6_rules.o
17ipv6-$(CONFIG_IPV6_MIP6) += mip6.o
18ipv6-$(CONFIG_PROC_FS) += proc.o 17ipv6-$(CONFIG_PROC_FS) += proc.o
19 18
20ipv6-objs += $(ipv6-y) 19ipv6-objs += $(ipv6-y)
@@ -28,6 +27,7 @@ obj-$(CONFIG_INET6_XFRM_MODE_TRANSPORT) += xfrm6_mode_transport.o
28obj-$(CONFIG_INET6_XFRM_MODE_TUNNEL) += xfrm6_mode_tunnel.o 27obj-$(CONFIG_INET6_XFRM_MODE_TUNNEL) += xfrm6_mode_tunnel.o
29obj-$(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) += xfrm6_mode_ro.o 28obj-$(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) += xfrm6_mode_ro.o
30obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o 29obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o
30obj-$(CONFIG_IPV6_MIP6) += mip6.o
31obj-$(CONFIG_NETFILTER) += netfilter/ 31obj-$(CONFIG_NETFILTER) += netfilter/
32 32
33obj-$(CONFIG_IPV6_SIT) += sit.o 33obj-$(CONFIG_IPV6_SIT) += sit.o
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 79b79f3de24c..24424c3b7dc0 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1034,7 +1034,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev,
1034 } 1034 }
1035 1035
1036 /* Rule 4: Prefer home address */ 1036 /* Rule 4: Prefer home address */
1037#ifdef CONFIG_IPV6_MIP6 1037#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
1038 if (hiscore.rule < 4) { 1038 if (hiscore.rule < 4) {
1039 if (ifa_result->flags & IFA_F_HOMEADDRESS) 1039 if (ifa_result->flags & IFA_F_HOMEADDRESS)
1040 hiscore.attrs |= IPV6_SADDR_SCORE_HOA; 1040 hiscore.attrs |= IPV6_SADDR_SCORE_HOA;
@@ -2785,7 +2785,7 @@ static int if6_seq_show(struct seq_file *seq, void *v)
2785 return 0; 2785 return 0;
2786} 2786}
2787 2787
2788static struct seq_operations if6_seq_ops = { 2788static const struct seq_operations if6_seq_ops = {
2789 .start = if6_seq_start, 2789 .start = if6_seq_start,
2790 .next = if6_seq_next, 2790 .next = if6_seq_next,
2791 .show = if6_seq_show, 2791 .show = if6_seq_show,
@@ -2835,7 +2835,7 @@ void if6_proc_exit(void)
2835} 2835}
2836#endif /* CONFIG_PROC_FS */ 2836#endif /* CONFIG_PROC_FS */
2837 2837
2838#ifdef CONFIG_IPV6_MIP6 2838#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
2839/* Check if address is a home address configured on any interface. */ 2839/* Check if address is a home address configured on any interface. */
2840int ipv6_chk_home_addr(struct in6_addr *addr) 2840int ipv6_chk_home_addr(struct in6_addr *addr)
2841{ 2841{
@@ -4243,7 +4243,6 @@ errout:
4243void __exit addrconf_cleanup(void) 4243void __exit addrconf_cleanup(void)
4244{ 4244{
4245 struct net_device *dev; 4245 struct net_device *dev;
4246 struct inet6_dev *idev;
4247 struct inet6_ifaddr *ifa; 4246 struct inet6_ifaddr *ifa;
4248 int i; 4247 int i;
4249 4248
@@ -4261,7 +4260,7 @@ void __exit addrconf_cleanup(void)
4261 */ 4260 */
4262 4261
4263 for_each_netdev(dev) { 4262 for_each_netdev(dev) {
4264 if ((idev = __in6_dev_get(dev)) == NULL) 4263 if (__in6_dev_get(dev) == NULL)
4265 continue; 4264 continue;
4266 addrconf_ifdown(dev, 1); 4265 addrconf_ifdown(dev, 1);
4267 } 4266 }
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 6dd377253cf7..eed09373a45d 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -58,9 +58,6 @@
58#ifdef CONFIG_IPV6_TUNNEL 58#ifdef CONFIG_IPV6_TUNNEL
59#include <net/ip6_tunnel.h> 59#include <net/ip6_tunnel.h>
60#endif 60#endif
61#ifdef CONFIG_IPV6_MIP6
62#include <net/mip6.h>
63#endif
64 61
65#include <asm/uaccess.h> 62#include <asm/uaccess.h>
66#include <asm/system.h> 63#include <asm/system.h>
@@ -853,9 +850,6 @@ static int __init inet6_init(void)
853 ipv6_frag_init(); 850 ipv6_frag_init();
854 ipv6_nodata_init(); 851 ipv6_nodata_init();
855 ipv6_destopt_init(); 852 ipv6_destopt_init();
856#ifdef CONFIG_IPV6_MIP6
857 mip6_init();
858#endif
859 853
860 /* Init v6 transport protocols. */ 854 /* Init v6 transport protocols. */
861 udpv6_init(); 855 udpv6_init();
@@ -921,9 +915,7 @@ static void __exit inet6_exit(void)
921 915
922 /* Cleanup code parts. */ 916 /* Cleanup code parts. */
923 ipv6_packet_cleanup(); 917 ipv6_packet_cleanup();
924#ifdef CONFIG_IPV6_MIP6 918
925 mip6_fini();
926#endif
927 addrconf_cleanup(); 919 addrconf_cleanup();
928 ip6_flowlabel_cleanup(); 920 ip6_flowlabel_cleanup();
929 ip6_route_cleanup(); 921 ip6_route_cleanup();
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 128f94c79c64..53f46ab6af70 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -74,7 +74,7 @@ bad:
74 return 0; 74 return 0;
75} 75}
76 76
77#ifdef CONFIG_IPV6_MIP6 77#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
78/** 78/**
79 * ipv6_rearrange_destopt - rearrange IPv6 destination options header 79 * ipv6_rearrange_destopt - rearrange IPv6 destination options header
80 * @iph: IPv6 header 80 * @iph: IPv6 header
@@ -132,6 +132,8 @@ static void ipv6_rearrange_destopt(struct ipv6hdr *iph, struct ipv6_opt_hdr *des
132bad: 132bad:
133 return; 133 return;
134} 134}
135#else
136static void ipv6_rearrange_destopt(struct ipv6hdr *iph, struct ipv6_opt_hdr *destopt) {}
135#endif 137#endif
136 138
137/** 139/**
@@ -189,10 +191,8 @@ static int ipv6_clear_mutable_options(struct ipv6hdr *iph, int len, int dir)
189 while (exthdr.raw < end) { 191 while (exthdr.raw < end) {
190 switch (nexthdr) { 192 switch (nexthdr) {
191 case NEXTHDR_DEST: 193 case NEXTHDR_DEST:
192#ifdef CONFIG_IPV6_MIP6
193 if (dir == XFRM_POLICY_OUT) 194 if (dir == XFRM_POLICY_OUT)
194 ipv6_rearrange_destopt(iph, exthdr.opth); 195 ipv6_rearrange_destopt(iph, exthdr.opth);
195#endif
196 case NEXTHDR_HOP: 196 case NEXTHDR_HOP:
197 if (!zero_out_mutable_opts(exthdr.opth)) { 197 if (!zero_out_mutable_opts(exthdr.opth)) {
198 LIMIT_NETDEBUG( 198 LIMIT_NETDEBUG(
@@ -228,7 +228,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
228 u8 nexthdr; 228 u8 nexthdr;
229 char tmp_base[8]; 229 char tmp_base[8];
230 struct { 230 struct {
231#ifdef CONFIG_IPV6_MIP6 231#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
232 struct in6_addr saddr; 232 struct in6_addr saddr;
233#endif 233#endif
234 struct in6_addr daddr; 234 struct in6_addr daddr;
@@ -255,7 +255,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
255 err = -ENOMEM; 255 err = -ENOMEM;
256 goto error; 256 goto error;
257 } 257 }
258#ifdef CONFIG_IPV6_MIP6 258#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
259 memcpy(tmp_ext, &top_iph->saddr, extlen); 259 memcpy(tmp_ext, &top_iph->saddr, extlen);
260#else 260#else
261 memcpy(tmp_ext, &top_iph->daddr, extlen); 261 memcpy(tmp_ext, &top_iph->daddr, extlen);
@@ -294,7 +294,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
294 294
295 memcpy(top_iph, tmp_base, sizeof(tmp_base)); 295 memcpy(top_iph, tmp_base, sizeof(tmp_base));
296 if (tmp_ext) { 296 if (tmp_ext) {
297#ifdef CONFIG_IPV6_MIP6 297#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
298 memcpy(&top_iph->saddr, tmp_ext, extlen); 298 memcpy(&top_iph->saddr, tmp_ext, extlen);
299#else 299#else
300 memcpy(&top_iph->daddr, tmp_ext, extlen); 300 memcpy(&top_iph->daddr, tmp_ext, extlen);
@@ -554,3 +554,4 @@ module_init(ah6_init);
554module_exit(ah6_fini); 554module_exit(ah6_fini);
555 555
556MODULE_LICENSE("GPL"); 556MODULE_LICENSE("GPL");
557MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_AH);
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 9b81264eb78f..b8c533fbdb63 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -539,7 +539,7 @@ static int ac6_seq_show(struct seq_file *seq, void *v)
539 return 0; 539 return 0;
540} 540}
541 541
542static struct seq_operations ac6_seq_ops = { 542static const struct seq_operations ac6_seq_ops = {
543 .start = ac6_seq_start, 543 .start = ac6_seq_start,
544 .next = ac6_seq_next, 544 .next = ac6_seq_next,
545 .stop = ac6_seq_stop, 545 .stop = ac6_seq_stop,
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index b1fe7ac5dc90..fe0f49024a0a 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -657,11 +657,10 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
657 rthdr = (struct ipv6_rt_hdr *)CMSG_DATA(cmsg); 657 rthdr = (struct ipv6_rt_hdr *)CMSG_DATA(cmsg);
658 658
659 switch (rthdr->type) { 659 switch (rthdr->type) {
660 case IPV6_SRCRT_TYPE_0: 660#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
661#ifdef CONFIG_IPV6_MIP6
662 case IPV6_SRCRT_TYPE_2: 661 case IPV6_SRCRT_TYPE_2:
663#endif
664 break; 662 break;
663#endif
665 default: 664 default:
666 err = -EINVAL; 665 err = -EINVAL;
667 goto exit_f; 666 goto exit_f;
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 7107bb7e2e62..2db31ce3c7e6 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -421,3 +421,4 @@ module_init(esp6_init);
421module_exit(esp6_fini); 421module_exit(esp6_fini);
422 422
423MODULE_LICENSE("GPL"); 423MODULE_LICENSE("GPL");
424MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_ESP);
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 14be0b9b77a5..c82d4d49f71f 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -42,7 +42,7 @@
42#include <net/ndisc.h> 42#include <net/ndisc.h>
43#include <net/ip6_route.h> 43#include <net/ip6_route.h>
44#include <net/addrconf.h> 44#include <net/addrconf.h>
45#ifdef CONFIG_IPV6_MIP6 45#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
46#include <net/xfrm.h> 46#include <net/xfrm.h>
47#endif 47#endif
48 48
@@ -90,6 +90,7 @@ int ipv6_find_tlv(struct sk_buff *skb, int offset, int type)
90 bad: 90 bad:
91 return -1; 91 return -1;
92} 92}
93EXPORT_SYMBOL_GPL(ipv6_find_tlv);
93 94
94/* 95/*
95 * Parsing tlv encoded headers. 96 * Parsing tlv encoded headers.
@@ -196,7 +197,7 @@ bad:
196 Destination options header. 197 Destination options header.
197 *****************************/ 198 *****************************/
198 199
199#ifdef CONFIG_IPV6_MIP6 200#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
200static int ipv6_dest_hao(struct sk_buff **skbp, int optoff) 201static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
201{ 202{
202 struct sk_buff *skb = *skbp; 203 struct sk_buff *skb = *skbp;
@@ -270,7 +271,7 @@ static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
270#endif 271#endif
271 272
272static struct tlvtype_proc tlvprocdestopt_lst[] = { 273static struct tlvtype_proc tlvprocdestopt_lst[] = {
273#ifdef CONFIG_IPV6_MIP6 274#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
274 { 275 {
275 .type = IPV6_TLV_HAO, 276 .type = IPV6_TLV_HAO,
276 .func = ipv6_dest_hao, 277 .func = ipv6_dest_hao,
@@ -283,7 +284,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
283{ 284{
284 struct sk_buff *skb = *skbp; 285 struct sk_buff *skb = *skbp;
285 struct inet6_skb_parm *opt = IP6CB(skb); 286 struct inet6_skb_parm *opt = IP6CB(skb);
286#ifdef CONFIG_IPV6_MIP6 287#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
287 __u16 dstbuf; 288 __u16 dstbuf;
288#endif 289#endif
289 struct dst_entry *dst; 290 struct dst_entry *dst;
@@ -298,7 +299,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
298 } 299 }
299 300
300 opt->lastopt = opt->dst1 = skb_network_header_len(skb); 301 opt->lastopt = opt->dst1 = skb_network_header_len(skb);
301#ifdef CONFIG_IPV6_MIP6 302#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
302 dstbuf = opt->dst1; 303 dstbuf = opt->dst1;
303#endif 304#endif
304 305
@@ -308,7 +309,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
308 skb = *skbp; 309 skb = *skbp;
309 skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3; 310 skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3;
310 opt = IP6CB(skb); 311 opt = IP6CB(skb);
311#ifdef CONFIG_IPV6_MIP6 312#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
312 opt->nhoff = dstbuf; 313 opt->nhoff = dstbuf;
313#else 314#else
314 opt->nhoff = opt->dst1; 315 opt->nhoff = opt->dst1;
@@ -371,22 +372,13 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
371 struct rt0_hdr *rthdr; 372 struct rt0_hdr *rthdr;
372 int accept_source_route = ipv6_devconf.accept_source_route; 373 int accept_source_route = ipv6_devconf.accept_source_route;
373 374
374 if (accept_source_route < 0 || 375 idev = in6_dev_get(skb->dev);
375 ((idev = in6_dev_get(skb->dev)) == NULL)) { 376 if (idev) {
376 kfree_skb(skb); 377 if (accept_source_route > idev->cnf.accept_source_route)
377 return -1; 378 accept_source_route = idev->cnf.accept_source_route;
378 }
379 if (idev->cnf.accept_source_route < 0) {
380 in6_dev_put(idev); 379 in6_dev_put(idev);
381 kfree_skb(skb);
382 return -1;
383 } 380 }
384 381
385 if (accept_source_route > idev->cnf.accept_source_route)
386 accept_source_route = idev->cnf.accept_source_route;
387
388 in6_dev_put(idev);
389
390 if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || 382 if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) ||
391 !pskb_may_pull(skb, (skb_transport_offset(skb) + 383 !pskb_may_pull(skb, (skb_transport_offset(skb) +
392 ((skb_transport_header(skb)[1] + 1) << 3)))) { 384 ((skb_transport_header(skb)[1] + 1) << 3)))) {
@@ -398,24 +390,6 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
398 390
399 hdr = (struct ipv6_rt_hdr *)skb_transport_header(skb); 391 hdr = (struct ipv6_rt_hdr *)skb_transport_header(skb);
400 392
401 switch (hdr->type) {
402#ifdef CONFIG_IPV6_MIP6
403 case IPV6_SRCRT_TYPE_2:
404 break;
405#endif
406 case IPV6_SRCRT_TYPE_0:
407 if (accept_source_route > 0)
408 break;
409 kfree_skb(skb);
410 return -1;
411 default:
412 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
413 IPSTATS_MIB_INHDRERRORS);
414 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
415 (&hdr->type) - skb_network_header(skb));
416 return -1;
417 }
418
419 if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) || 393 if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) ||
420 skb->pkt_type != PACKET_HOST) { 394 skb->pkt_type != PACKET_HOST) {
421 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 395 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
@@ -427,7 +401,7 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
427looped_back: 401looped_back:
428 if (hdr->segments_left == 0) { 402 if (hdr->segments_left == 0) {
429 switch (hdr->type) { 403 switch (hdr->type) {
430#ifdef CONFIG_IPV6_MIP6 404#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
431 case IPV6_SRCRT_TYPE_2: 405 case IPV6_SRCRT_TYPE_2:
432 /* Silently discard type 2 header unless it was 406 /* Silently discard type 2 header unless it was
433 * processed by own 407 * processed by own
@@ -453,18 +427,10 @@ looped_back:
453 } 427 }
454 428
455 switch (hdr->type) { 429 switch (hdr->type) {
456 case IPV6_SRCRT_TYPE_0: 430#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
457 if (hdr->hdrlen & 0x01) {
458 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
459 IPSTATS_MIB_INHDRERRORS);
460 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
461 ((&hdr->hdrlen) -
462 skb_network_header(skb)));
463 return -1;
464 }
465 break;
466#ifdef CONFIG_IPV6_MIP6
467 case IPV6_SRCRT_TYPE_2: 431 case IPV6_SRCRT_TYPE_2:
432 if (accept_source_route < 0)
433 goto unknown_rh;
468 /* Silently discard invalid RTH type 2 */ 434 /* Silently discard invalid RTH type 2 */
469 if (hdr->hdrlen != 2 || hdr->segments_left != 1) { 435 if (hdr->hdrlen != 2 || hdr->segments_left != 1) {
470 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 436 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
@@ -474,6 +440,8 @@ looped_back:
474 } 440 }
475 break; 441 break;
476#endif 442#endif
443 default:
444 goto unknown_rh;
477 } 445 }
478 446
479 /* 447 /*
@@ -520,7 +488,7 @@ looped_back:
520 addr += i - 1; 488 addr += i - 1;
521 489
522 switch (hdr->type) { 490 switch (hdr->type) {
523#ifdef CONFIG_IPV6_MIP6 491#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
524 case IPV6_SRCRT_TYPE_2: 492 case IPV6_SRCRT_TYPE_2:
525 if (xfrm6_input_addr(skb, (xfrm_address_t *)addr, 493 if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
526 (xfrm_address_t *)&ipv6_hdr(skb)->saddr, 494 (xfrm_address_t *)&ipv6_hdr(skb)->saddr,
@@ -577,6 +545,12 @@ looped_back:
577 skb_push(skb, skb->data - skb_network_header(skb)); 545 skb_push(skb, skb->data - skb_network_header(skb));
578 dst_input(skb); 546 dst_input(skb);
579 return -1; 547 return -1;
548
549unknown_rh:
550 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
551 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
552 (&hdr->type) - skb_network_header(skb));
553 return -1;
580} 554}
581 555
582static struct inet6_protocol rthdr_protocol = { 556static struct inet6_protocol rthdr_protocol = {
@@ -590,72 +564,6 @@ void __init ipv6_rthdr_init(void)
590 printk(KERN_ERR "ipv6_rthdr_init: Could not register protocol\n"); 564 printk(KERN_ERR "ipv6_rthdr_init: Could not register protocol\n");
591}; 565};
592 566
593/*
594 This function inverts received rthdr.
595 NOTE: specs allow to make it automatically only if
596 packet authenticated.
597
598 I will not discuss it here (though, I am really pissed off at
599 this stupid requirement making rthdr idea useless)
600
601 Actually, it creates severe problems for us.
602 Embryonic requests has no associated sockets,
603 so that user have no control over it and
604 cannot not only to set reply options, but
605 even to know, that someone wants to connect
606 without success. :-(
607
608 For now we need to test the engine, so that I created
609 temporary (or permanent) backdoor.
610 If listening socket set IPV6_RTHDR to 2, then we invert header.
611 --ANK (980729)
612 */
613
614struct ipv6_txoptions *
615ipv6_invert_rthdr(struct sock *sk, struct ipv6_rt_hdr *hdr)
616{
617 /* Received rthdr:
618
619 [ H1 -> H2 -> ... H_prev ] daddr=ME
620
621 Inverted result:
622 [ H_prev -> ... -> H1 ] daddr =sender
623
624 Note, that IP output engine will rewrite this rthdr
625 by rotating it left by one addr.
626 */
627
628 int n, i;
629 struct rt0_hdr *rthdr = (struct rt0_hdr*)hdr;
630 struct rt0_hdr *irthdr;
631 struct ipv6_txoptions *opt;
632 int hdrlen = ipv6_optlen(hdr);
633
634 if (hdr->segments_left ||
635 hdr->type != IPV6_SRCRT_TYPE_0 ||
636 hdr->hdrlen & 0x01)
637 return NULL;
638
639 n = hdr->hdrlen >> 1;
640 opt = sock_kmalloc(sk, sizeof(*opt) + hdrlen, GFP_ATOMIC);
641 if (opt == NULL)
642 return NULL;
643 memset(opt, 0, sizeof(*opt));
644 opt->tot_len = sizeof(*opt) + hdrlen;
645 opt->srcrt = (void*)(opt+1);
646 opt->opt_nflen = hdrlen;
647
648 memcpy(opt->srcrt, hdr, sizeof(*hdr));
649 irthdr = (struct rt0_hdr*)opt->srcrt;
650 irthdr->reserved = 0;
651 opt->srcrt->segments_left = n;
652 for (i=0; i<n; i++)
653 memcpy(irthdr->addr+i, rthdr->addr+(n-1-i), 16);
654 return opt;
655}
656
657EXPORT_SYMBOL_GPL(ipv6_invert_rthdr);
658
659/********************************** 567/**********************************
660 Hop-by-hop options. 568 Hop-by-hop options.
661 **********************************/ 569 **********************************/
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index e9bcce9e7bdf..4765a29f98a8 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -272,7 +272,7 @@ static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, st
272 return 0; 272 return 0;
273} 273}
274 274
275#ifdef CONFIG_IPV6_MIP6 275#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
276static void mip6_addr_swap(struct sk_buff *skb) 276static void mip6_addr_swap(struct sk_buff *skb)
277{ 277{
278 struct ipv6hdr *iph = ipv6_hdr(skb); 278 struct ipv6hdr *iph = ipv6_hdr(skb);
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index c206a152ed9d..413a4ebb195c 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -648,7 +648,7 @@ static int ip6fl_seq_show(struct seq_file *seq, void *v)
648 return 0; 648 return 0;
649} 649}
650 650
651static struct seq_operations ip6fl_seq_ops = { 651static const struct seq_operations ip6fl_seq_ops = {
652 .start = ip6fl_seq_start, 652 .start = ip6fl_seq_start,
653 .next = ip6fl_seq_next, 653 .next = ip6fl_seq_next,
654 .stop = ip6fl_seq_stop, 654 .stop = ip6fl_seq_stop,
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 4704b5fc3085..50d86e94d9ed 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -521,6 +521,10 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
521 to->tc_index = from->tc_index; 521 to->tc_index = from->tc_index;
522#endif 522#endif
523 nf_copy(to, from); 523 nf_copy(to, from);
524#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
525 defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
526 to->nf_trace = from->nf_trace;
527#endif
524 skb_copy_secmark(to, from); 528 skb_copy_secmark(to, from);
525} 529}
526 530
@@ -543,7 +547,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
543 found_rhdr = 1; 547 found_rhdr = 1;
544 break; 548 break;
545 case NEXTHDR_DEST: 549 case NEXTHDR_DEST:
546#ifdef CONFIG_IPV6_MIP6 550#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
547 if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0) 551 if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0)
548 break; 552 break;
549#endif 553#endif
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index a0902fbdb4e1..281aee42d3f0 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -883,8 +883,8 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
883 */ 883 */
884 max_headroom += LL_RESERVED_SPACE(tdev); 884 max_headroom += LL_RESERVED_SPACE(tdev);
885 885
886 if (skb_headroom(skb) < max_headroom || 886 if (skb_headroom(skb) < max_headroom || skb_shared(skb) ||
887 skb_cloned(skb) || skb_shared(skb)) { 887 (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
888 struct sk_buff *new_skb; 888 struct sk_buff *new_skb;
889 889
890 if (!(new_skb = skb_realloc_headroom(skb, max_headroom))) 890 if (!(new_skb = skb_realloc_headroom(skb, max_headroom)))
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 1ee50b5782e1..473f165310ea 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -500,4 +500,4 @@ MODULE_LICENSE("GPL");
500MODULE_DESCRIPTION("IP Payload Compression Protocol (IPComp) for IPv6 - RFC3173"); 500MODULE_DESCRIPTION("IP Payload Compression Protocol (IPComp) for IPv6 - RFC3173");
501MODULE_AUTHOR("Mitsuru KANDA <mk@linux-ipv6.org>"); 501MODULE_AUTHOR("Mitsuru KANDA <mk@linux-ipv6.org>");
502 502
503 503MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_COMP);
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index aa3d07c52a8f..d6846393182d 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -123,7 +123,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, int features)
123 struct ipv6hdr *ipv6h; 123 struct ipv6hdr *ipv6h;
124 struct inet6_protocol *ops; 124 struct inet6_protocol *ops;
125 125
126 if (!(features & NETIF_F_HW_CSUM)) 126 if (!(features & NETIF_F_V6_CSUM))
127 features &= ~NETIF_F_SG; 127 features &= ~NETIF_F_SG;
128 128
129 if (unlikely(skb_shinfo(skb)->gso_type & 129 if (unlikely(skb_shinfo(skb)->gso_type &
@@ -336,16 +336,12 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
336 break; 336 break;
337 337
338 case IPV6_RECVRTHDR: 338 case IPV6_RECVRTHDR:
339 if (val < 0 || val > 2) 339 np->rxopt.bits.srcrt = valbool;
340 goto e_inval;
341 np->rxopt.bits.srcrt = val;
342 retv = 0; 340 retv = 0;
343 break; 341 break;
344 342
345 case IPV6_2292RTHDR: 343 case IPV6_2292RTHDR:
346 if (val < 0 || val > 2) 344 np->rxopt.bits.osrcrt = valbool;
347 goto e_inval;
348 np->rxopt.bits.osrcrt = val;
349 retv = 0; 345 retv = 0;
350 break; 346 break;
351 347
@@ -416,11 +412,10 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
416 if (optname == IPV6_RTHDR && opt && opt->srcrt) { 412 if (optname == IPV6_RTHDR && opt && opt->srcrt) {
417 struct ipv6_rt_hdr *rthdr = opt->srcrt; 413 struct ipv6_rt_hdr *rthdr = opt->srcrt;
418 switch (rthdr->type) { 414 switch (rthdr->type) {
419 case IPV6_SRCRT_TYPE_0: 415#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
420#ifdef CONFIG_IPV6_MIP6
421 case IPV6_SRCRT_TYPE_2: 416 case IPV6_SRCRT_TYPE_2:
422#endif
423 break; 417 break;
418#endif
424 default: 419 default:
425 goto sticky_done; 420 goto sticky_done;
426 } 421 }
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 3e308fb41b49..ae9881832a7e 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -2423,7 +2423,7 @@ static int igmp6_mc_seq_show(struct seq_file *seq, void *v)
2423 return 0; 2423 return 0;
2424} 2424}
2425 2425
2426static struct seq_operations igmp6_mc_seq_ops = { 2426static const struct seq_operations igmp6_mc_seq_ops = {
2427 .start = igmp6_mc_seq_start, 2427 .start = igmp6_mc_seq_start,
2428 .next = igmp6_mc_seq_next, 2428 .next = igmp6_mc_seq_next,
2429 .stop = igmp6_mc_seq_stop, 2429 .stop = igmp6_mc_seq_stop,
@@ -2597,7 +2597,7 @@ static int igmp6_mcf_seq_show(struct seq_file *seq, void *v)
2597 return 0; 2597 return 0;
2598} 2598}
2599 2599
2600static struct seq_operations igmp6_mcf_seq_ops = { 2600static const struct seq_operations igmp6_mcf_seq_ops = {
2601 .start = igmp6_mcf_seq_start, 2601 .start = igmp6_mcf_seq_start,
2602 .next = igmp6_mcf_seq_next, 2602 .next = igmp6_mcf_seq_next,
2603 .stop = igmp6_mcf_seq_stop, 2603 .stop = igmp6_mcf_seq_stop,
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index 13b7160fb892..8a1399ce38ce 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -30,6 +30,7 @@
30#include <net/sock.h> 30#include <net/sock.h>
31#include <net/ipv6.h> 31#include <net/ipv6.h>
32#include <net/ip6_checksum.h> 32#include <net/ip6_checksum.h>
33#include <net/rawv6.h>
33#include <net/xfrm.h> 34#include <net/xfrm.h>
34#include <net/mip6.h> 35#include <net/mip6.h>
35 36
@@ -86,7 +87,7 @@ static int mip6_mh_len(int type)
86 return len; 87 return len;
87} 88}
88 89
89int mip6_mh_filter(struct sock *sk, struct sk_buff *skb) 90static int mip6_mh_filter(struct sock *sk, struct sk_buff *skb)
90{ 91{
91 struct ip6_mh *mh; 92 struct ip6_mh *mh;
92 93
@@ -471,7 +472,7 @@ static struct xfrm_type mip6_rthdr_type =
471 .remote_addr = mip6_xfrm_addr, 472 .remote_addr = mip6_xfrm_addr,
472}; 473};
473 474
474int __init mip6_init(void) 475static int __init mip6_init(void)
475{ 476{
476 printk(KERN_INFO "Mobile IPv6\n"); 477 printk(KERN_INFO "Mobile IPv6\n");
477 478
@@ -483,18 +484,35 @@ int __init mip6_init(void)
483 printk(KERN_INFO "%s: can't add xfrm type(rthdr)\n", __FUNCTION__); 484 printk(KERN_INFO "%s: can't add xfrm type(rthdr)\n", __FUNCTION__);
484 goto mip6_rthdr_xfrm_fail; 485 goto mip6_rthdr_xfrm_fail;
485 } 486 }
487 if (rawv6_mh_filter_register(mip6_mh_filter) < 0) {
488 printk(KERN_INFO "%s: can't add rawv6 mh filter\n", __FUNCTION__);
489 goto mip6_rawv6_mh_fail;
490 }
491
492
486 return 0; 493 return 0;
487 494
495 mip6_rawv6_mh_fail:
496 xfrm_unregister_type(&mip6_rthdr_type, AF_INET6);
488 mip6_rthdr_xfrm_fail: 497 mip6_rthdr_xfrm_fail:
489 xfrm_unregister_type(&mip6_destopt_type, AF_INET6); 498 xfrm_unregister_type(&mip6_destopt_type, AF_INET6);
490 mip6_destopt_xfrm_fail: 499 mip6_destopt_xfrm_fail:
491 return -EAGAIN; 500 return -EAGAIN;
492} 501}
493 502
494void __exit mip6_fini(void) 503static void __exit mip6_fini(void)
495{ 504{
505 if (rawv6_mh_filter_unregister(mip6_mh_filter) < 0)
506 printk(KERN_INFO "%s: can't remove rawv6 mh filter\n", __FUNCTION__);
496 if (xfrm_unregister_type(&mip6_rthdr_type, AF_INET6) < 0) 507 if (xfrm_unregister_type(&mip6_rthdr_type, AF_INET6) < 0)
497 printk(KERN_INFO "%s: can't remove xfrm type(rthdr)\n", __FUNCTION__); 508 printk(KERN_INFO "%s: can't remove xfrm type(rthdr)\n", __FUNCTION__);
498 if (xfrm_unregister_type(&mip6_destopt_type, AF_INET6) < 0) 509 if (xfrm_unregister_type(&mip6_destopt_type, AF_INET6) < 0)
499 printk(KERN_INFO "%s: can't remove xfrm type(destopt)\n", __FUNCTION__); 510 printk(KERN_INFO "%s: can't remove xfrm type(destopt)\n", __FUNCTION__);
500} 511}
512
513module_init(mip6_init);
514module_exit(mip6_fini);
515
516MODULE_LICENSE("GPL");
517MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_DSTOPTS);
518MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_ROUTING);
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 9aa624026688..254c769b750a 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -96,13 +96,13 @@ ip6t_ext_hdr(u8 nexthdr)
96} 96}
97 97
98/* Returns whether matches rule or not. */ 98/* Returns whether matches rule or not. */
99static inline int 99static inline bool
100ip6_packet_match(const struct sk_buff *skb, 100ip6_packet_match(const struct sk_buff *skb,
101 const char *indev, 101 const char *indev,
102 const char *outdev, 102 const char *outdev,
103 const struct ip6t_ip6 *ip6info, 103 const struct ip6t_ip6 *ip6info,
104 unsigned int *protoff, 104 unsigned int *protoff,
105 int *fragoff, int *hotdrop) 105 int *fragoff, bool *hotdrop)
106{ 106{
107 size_t i; 107 size_t i;
108 unsigned long ret; 108 unsigned long ret;
@@ -122,7 +122,7 @@ ip6_packet_match(const struct sk_buff *skb,
122 dprintf("DST: %u. Mask: %u. Target: %u.%s\n", ip->daddr, 122 dprintf("DST: %u. Mask: %u. Target: %u.%s\n", ip->daddr,
123 ipinfo->dmsk.s_addr, ipinfo->dst.s_addr, 123 ipinfo->dmsk.s_addr, ipinfo->dst.s_addr,
124 ipinfo->invflags & IP6T_INV_DSTIP ? " (INV)" : "");*/ 124 ipinfo->invflags & IP6T_INV_DSTIP ? " (INV)" : "");*/
125 return 0; 125 return false;
126 } 126 }
127 127
128 /* Look for ifname matches; this should unroll nicely. */ 128 /* Look for ifname matches; this should unroll nicely. */
@@ -136,7 +136,7 @@ ip6_packet_match(const struct sk_buff *skb,
136 dprintf("VIA in mismatch (%s vs %s).%s\n", 136 dprintf("VIA in mismatch (%s vs %s).%s\n",
137 indev, ip6info->iniface, 137 indev, ip6info->iniface,
138 ip6info->invflags&IP6T_INV_VIA_IN ?" (INV)":""); 138 ip6info->invflags&IP6T_INV_VIA_IN ?" (INV)":"");
139 return 0; 139 return false;
140 } 140 }
141 141
142 for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) { 142 for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
@@ -149,7 +149,7 @@ ip6_packet_match(const struct sk_buff *skb,
149 dprintf("VIA out mismatch (%s vs %s).%s\n", 149 dprintf("VIA out mismatch (%s vs %s).%s\n",
150 outdev, ip6info->outiface, 150 outdev, ip6info->outiface,
151 ip6info->invflags&IP6T_INV_VIA_OUT ?" (INV)":""); 151 ip6info->invflags&IP6T_INV_VIA_OUT ?" (INV)":"");
152 return 0; 152 return false;
153 } 153 }
154 154
155/* ... might want to do something with class and flowlabel here ... */ 155/* ... might want to do something with class and flowlabel here ... */
@@ -162,8 +162,8 @@ ip6_packet_match(const struct sk_buff *skb,
162 protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off); 162 protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off);
163 if (protohdr < 0) { 163 if (protohdr < 0) {
164 if (_frag_off == 0) 164 if (_frag_off == 0)
165 *hotdrop = 1; 165 *hotdrop = true;
166 return 0; 166 return false;
167 } 167 }
168 *fragoff = _frag_off; 168 *fragoff = _frag_off;
169 169
@@ -174,34 +174,34 @@ ip6_packet_match(const struct sk_buff *skb,
174 174
175 if (ip6info->proto == protohdr) { 175 if (ip6info->proto == protohdr) {
176 if(ip6info->invflags & IP6T_INV_PROTO) { 176 if(ip6info->invflags & IP6T_INV_PROTO) {
177 return 0; 177 return false;
178 } 178 }
179 return 1; 179 return true;
180 } 180 }
181 181
182 /* We need match for the '-p all', too! */ 182 /* We need match for the '-p all', too! */
183 if ((ip6info->proto != 0) && 183 if ((ip6info->proto != 0) &&
184 !(ip6info->invflags & IP6T_INV_PROTO)) 184 !(ip6info->invflags & IP6T_INV_PROTO))
185 return 0; 185 return false;
186 } 186 }
187 return 1; 187 return true;
188} 188}
189 189
190/* should be ip6 safe */ 190/* should be ip6 safe */
191static inline int 191static inline bool
192ip6_checkentry(const struct ip6t_ip6 *ipv6) 192ip6_checkentry(const struct ip6t_ip6 *ipv6)
193{ 193{
194 if (ipv6->flags & ~IP6T_F_MASK) { 194 if (ipv6->flags & ~IP6T_F_MASK) {
195 duprintf("Unknown flag bits set: %08X\n", 195 duprintf("Unknown flag bits set: %08X\n",
196 ipv6->flags & ~IP6T_F_MASK); 196 ipv6->flags & ~IP6T_F_MASK);
197 return 0; 197 return false;
198 } 198 }
199 if (ipv6->invflags & ~IP6T_INV_MASK) { 199 if (ipv6->invflags & ~IP6T_INV_MASK) {
200 duprintf("Unknown invflag bits set: %08X\n", 200 duprintf("Unknown invflag bits set: %08X\n",
201 ipv6->invflags & ~IP6T_INV_MASK); 201 ipv6->invflags & ~IP6T_INV_MASK);
202 return 0; 202 return false;
203 } 203 }
204 return 1; 204 return true;
205} 205}
206 206
207static unsigned int 207static unsigned int
@@ -219,20 +219,20 @@ ip6t_error(struct sk_buff **pskb,
219} 219}
220 220
221static inline 221static inline
222int do_match(struct ip6t_entry_match *m, 222bool do_match(struct ip6t_entry_match *m,
223 const struct sk_buff *skb, 223 const struct sk_buff *skb,
224 const struct net_device *in, 224 const struct net_device *in,
225 const struct net_device *out, 225 const struct net_device *out,
226 int offset, 226 int offset,
227 unsigned int protoff, 227 unsigned int protoff,
228 int *hotdrop) 228 bool *hotdrop)
229{ 229{
230 /* Stop iteration if it doesn't match */ 230 /* Stop iteration if it doesn't match */
231 if (!m->u.kernel.match->match(skb, in, out, m->u.kernel.match, m->data, 231 if (!m->u.kernel.match->match(skb, in, out, m->u.kernel.match, m->data,
232 offset, protoff, hotdrop)) 232 offset, protoff, hotdrop))
233 return 1; 233 return true;
234 else 234 else
235 return 0; 235 return false;
236} 236}
237 237
238static inline struct ip6t_entry * 238static inline struct ip6t_entry *
@@ -241,6 +241,113 @@ get_entry(void *base, unsigned int offset)
241 return (struct ip6t_entry *)(base + offset); 241 return (struct ip6t_entry *)(base + offset);
242} 242}
243 243
244/* All zeroes == unconditional rule. */
245static inline int
246unconditional(const struct ip6t_ip6 *ipv6)
247{
248 unsigned int i;
249
250 for (i = 0; i < sizeof(*ipv6); i++)
251 if (((char *)ipv6)[i])
252 break;
253
254 return (i == sizeof(*ipv6));
255}
256
257#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
258 defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
259/* This cries for unification! */
260static const char *hooknames[] = {
261 [NF_IP6_PRE_ROUTING] = "PREROUTING",
262 [NF_IP6_LOCAL_IN] = "INPUT",
263 [NF_IP6_FORWARD] = "FORWARD",
264 [NF_IP6_LOCAL_OUT] = "OUTPUT",
265 [NF_IP6_POST_ROUTING] = "POSTROUTING",
266};
267
268enum nf_ip_trace_comments {
269 NF_IP6_TRACE_COMMENT_RULE,
270 NF_IP6_TRACE_COMMENT_RETURN,
271 NF_IP6_TRACE_COMMENT_POLICY,
272};
273
274static const char *comments[] = {
275 [NF_IP6_TRACE_COMMENT_RULE] = "rule",
276 [NF_IP6_TRACE_COMMENT_RETURN] = "return",
277 [NF_IP6_TRACE_COMMENT_POLICY] = "policy",
278};
279
280static struct nf_loginfo trace_loginfo = {
281 .type = NF_LOG_TYPE_LOG,
282 .u = {
283 .log = {
284 .level = 4,
285 .logflags = NF_LOG_MASK,
286 },
287 },
288};
289
290static inline int
291get_chainname_rulenum(struct ip6t_entry *s, struct ip6t_entry *e,
292 char *hookname, char **chainname,
293 char **comment, unsigned int *rulenum)
294{
295 struct ip6t_standard_target *t = (void *)ip6t_get_target(s);
296
297 if (strcmp(t->target.u.kernel.target->name, IP6T_ERROR_TARGET) == 0) {
298 /* Head of user chain: ERROR target with chainname */
299 *chainname = t->target.data;
300 (*rulenum) = 0;
301 } else if (s == e) {
302 (*rulenum)++;
303
304 if (s->target_offset == sizeof(struct ip6t_entry)
305 && strcmp(t->target.u.kernel.target->name,
306 IP6T_STANDARD_TARGET) == 0
307 && t->verdict < 0
308 && unconditional(&s->ipv6)) {
309 /* Tail of chains: STANDARD target (return/policy) */
310 *comment = *chainname == hookname
311 ? (char *)comments[NF_IP6_TRACE_COMMENT_POLICY]
312 : (char *)comments[NF_IP6_TRACE_COMMENT_RETURN];
313 }
314 return 1;
315 } else
316 (*rulenum)++;
317
318 return 0;
319}
320
321static void trace_packet(struct sk_buff *skb,
322 unsigned int hook,
323 const struct net_device *in,
324 const struct net_device *out,
325 char *tablename,
326 struct xt_table_info *private,
327 struct ip6t_entry *e)
328{
329 void *table_base;
330 struct ip6t_entry *root;
331 char *hookname, *chainname, *comment;
332 unsigned int rulenum = 0;
333
334 table_base = (void *)private->entries[smp_processor_id()];
335 root = get_entry(table_base, private->hook_entry[hook]);
336
337 hookname = chainname = (char *)hooknames[hook];
338 comment = (char *)comments[NF_IP6_TRACE_COMMENT_RULE];
339
340 IP6T_ENTRY_ITERATE(root,
341 private->size - private->hook_entry[hook],
342 get_chainname_rulenum,
343 e, hookname, &chainname, &comment, &rulenum);
344
345 nf_log_packet(AF_INET6, hook, skb, in, out, &trace_loginfo,
346 "TRACE: %s:%s:%s:%u ",
347 tablename, chainname, comment, rulenum);
348}
349#endif
350
244/* Returns one of the generic firewall policies, like NF_ACCEPT. */ 351/* Returns one of the generic firewall policies, like NF_ACCEPT. */
245unsigned int 352unsigned int
246ip6t_do_table(struct sk_buff **pskb, 353ip6t_do_table(struct sk_buff **pskb,
@@ -252,7 +359,7 @@ ip6t_do_table(struct sk_buff **pskb,
252 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); 359 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
253 int offset = 0; 360 int offset = 0;
254 unsigned int protoff = 0; 361 unsigned int protoff = 0;
255 int hotdrop = 0; 362 bool hotdrop = false;
256 /* Initializing verdict to NF_DROP keeps gcc happy. */ 363 /* Initializing verdict to NF_DROP keeps gcc happy. */
257 unsigned int verdict = NF_DROP; 364 unsigned int verdict = NF_DROP;
258 const char *indev, *outdev; 365 const char *indev, *outdev;
@@ -298,6 +405,14 @@ ip6t_do_table(struct sk_buff **pskb,
298 405
299 t = ip6t_get_target(e); 406 t = ip6t_get_target(e);
300 IP_NF_ASSERT(t->u.kernel.target); 407 IP_NF_ASSERT(t->u.kernel.target);
408
409#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
410 defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
411 /* The packet is traced: log it */
412 if (unlikely((*pskb)->nf_trace))
413 trace_packet(*pskb, hook, in, out,
414 table->name, private, e);
415#endif
301 /* Standard target? */ 416 /* Standard target? */
302 if (!t->u.kernel.target->target) { 417 if (!t->u.kernel.target->target) {
303 int v; 418 int v;
@@ -377,19 +492,6 @@ ip6t_do_table(struct sk_buff **pskb,
377#endif 492#endif
378} 493}
379 494
380/* All zeroes == unconditional rule. */
381static inline int
382unconditional(const struct ip6t_ip6 *ipv6)
383{
384 unsigned int i;
385
386 for (i = 0; i < sizeof(*ipv6); i++)
387 if (((char *)ipv6)[i])
388 break;
389
390 return (i == sizeof(*ipv6));
391}
392
393/* Figures out from what hook each rule can be called: returns 0 if 495/* Figures out from what hook each rule can be called: returns 0 if
394 there are loops. Puts hook bitmask in comefrom. */ 496 there are loops. Puts hook bitmask in comefrom. */
395static int 497static int
@@ -1282,16 +1384,16 @@ void ip6t_unregister_table(struct xt_table *table)
1282} 1384}
1283 1385
1284/* Returns 1 if the type and code is matched by the range, 0 otherwise */ 1386/* Returns 1 if the type and code is matched by the range, 0 otherwise */
1285static inline int 1387static inline bool
1286icmp6_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code, 1388icmp6_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
1287 u_int8_t type, u_int8_t code, 1389 u_int8_t type, u_int8_t code,
1288 int invert) 1390 bool invert)
1289{ 1391{
1290 return (type == test_type && code >= min_code && code <= max_code) 1392 return (type == test_type && code >= min_code && code <= max_code)
1291 ^ invert; 1393 ^ invert;
1292} 1394}
1293 1395
1294static int 1396static bool
1295icmp6_match(const struct sk_buff *skb, 1397icmp6_match(const struct sk_buff *skb,
1296 const struct net_device *in, 1398 const struct net_device *in,
1297 const struct net_device *out, 1399 const struct net_device *out,
@@ -1299,22 +1401,22 @@ icmp6_match(const struct sk_buff *skb,
1299 const void *matchinfo, 1401 const void *matchinfo,
1300 int offset, 1402 int offset,
1301 unsigned int protoff, 1403 unsigned int protoff,
1302 int *hotdrop) 1404 bool *hotdrop)
1303{ 1405{
1304 struct icmp6hdr _icmp, *ic; 1406 struct icmp6hdr _icmp, *ic;
1305 const struct ip6t_icmp *icmpinfo = matchinfo; 1407 const struct ip6t_icmp *icmpinfo = matchinfo;
1306 1408
1307 /* Must not be a fragment. */ 1409 /* Must not be a fragment. */
1308 if (offset) 1410 if (offset)
1309 return 0; 1411 return false;
1310 1412
1311 ic = skb_header_pointer(skb, protoff, sizeof(_icmp), &_icmp); 1413 ic = skb_header_pointer(skb, protoff, sizeof(_icmp), &_icmp);
1312 if (ic == NULL) { 1414 if (ic == NULL) {
1313 /* We've been asked to examine this packet, and we 1415 /* We've been asked to examine this packet, and we
1314 can't. Hence, no choice but to drop. */ 1416 can't. Hence, no choice but to drop. */
1315 duprintf("Dropping evil ICMP tinygram.\n"); 1417 duprintf("Dropping evil ICMP tinygram.\n");
1316 *hotdrop = 1; 1418 *hotdrop = true;
1317 return 0; 1419 return false;
1318 } 1420 }
1319 1421
1320 return icmp6_type_code_match(icmpinfo->type, 1422 return icmp6_type_code_match(icmpinfo->type,
@@ -1325,7 +1427,7 @@ icmp6_match(const struct sk_buff *skb,
1325} 1427}
1326 1428
1327/* Called when user tries to insert an entry of this type. */ 1429/* Called when user tries to insert an entry of this type. */
1328static int 1430static bool
1329icmp6_checkentry(const char *tablename, 1431icmp6_checkentry(const char *tablename,
1330 const void *entry, 1432 const void *entry,
1331 const struct xt_match *match, 1433 const struct xt_match *match,
@@ -1339,13 +1441,13 @@ icmp6_checkentry(const char *tablename,
1339} 1441}
1340 1442
1341/* The built-in targets: standard (NULL) and error. */ 1443/* The built-in targets: standard (NULL) and error. */
1342static struct xt_target ip6t_standard_target = { 1444static struct xt_target ip6t_standard_target __read_mostly = {
1343 .name = IP6T_STANDARD_TARGET, 1445 .name = IP6T_STANDARD_TARGET,
1344 .targetsize = sizeof(int), 1446 .targetsize = sizeof(int),
1345 .family = AF_INET6, 1447 .family = AF_INET6,
1346}; 1448};
1347 1449
1348static struct xt_target ip6t_error_target = { 1450static struct xt_target ip6t_error_target __read_mostly = {
1349 .name = IP6T_ERROR_TARGET, 1451 .name = IP6T_ERROR_TARGET,
1350 .target = ip6t_error, 1452 .target = ip6t_error,
1351 .targetsize = IP6T_FUNCTION_MAXNAMELEN, 1453 .targetsize = IP6T_FUNCTION_MAXNAMELEN,
@@ -1362,7 +1464,7 @@ static struct nf_sockopt_ops ip6t_sockopts = {
1362 .get = do_ip6t_get_ctl, 1464 .get = do_ip6t_get_ctl,
1363}; 1465};
1364 1466
1365static struct xt_match icmp6_matchstruct = { 1467static struct xt_match icmp6_matchstruct __read_mostly = {
1366 .name = "icmp6", 1468 .name = "icmp6",
1367 .match = &icmp6_match, 1469 .match = &icmp6_match,
1368 .matchsize = sizeof(struct ip6t_icmp), 1470 .matchsize = sizeof(struct ip6t_icmp),
diff --git a/net/ipv6/netfilter/ip6t_HL.c b/net/ipv6/netfilter/ip6t_HL.c
index 4115a576ba25..ad4d94310b87 100644
--- a/net/ipv6/netfilter/ip6t_HL.c
+++ b/net/ipv6/netfilter/ip6t_HL.c
@@ -58,28 +58,28 @@ static unsigned int ip6t_hl_target(struct sk_buff **pskb,
58 return XT_CONTINUE; 58 return XT_CONTINUE;
59} 59}
60 60
61static int ip6t_hl_checkentry(const char *tablename, 61static bool ip6t_hl_checkentry(const char *tablename,
62 const void *entry, 62 const void *entry,
63 const struct xt_target *target, 63 const struct xt_target *target,
64 void *targinfo, 64 void *targinfo,
65 unsigned int hook_mask) 65 unsigned int hook_mask)
66{ 66{
67 struct ip6t_HL_info *info = targinfo; 67 const struct ip6t_HL_info *info = targinfo;
68 68
69 if (info->mode > IP6T_HL_MAXMODE) { 69 if (info->mode > IP6T_HL_MAXMODE) {
70 printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n", 70 printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n",
71 info->mode); 71 info->mode);
72 return 0; 72 return false;
73 } 73 }
74 if ((info->mode != IP6T_HL_SET) && (info->hop_limit == 0)) { 74 if (info->mode != IP6T_HL_SET && info->hop_limit == 0) {
75 printk(KERN_WARNING "ip6t_HL: increment/decrement doesn't " 75 printk(KERN_WARNING "ip6t_HL: increment/decrement doesn't "
76 "make sense with value 0\n"); 76 "make sense with value 0\n");
77 return 0; 77 return false;
78 } 78 }
79 return 1; 79 return true;
80} 80}
81 81
82static struct xt_target ip6t_HL = { 82static struct xt_target ip6t_HL __read_mostly = {
83 .name = "HL", 83 .name = "HL",
84 .family = AF_INET6, 84 .family = AF_INET6,
85 .target = ip6t_hl_target, 85 .target = ip6t_hl_target,
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index 5bb9cd349350..b05327ebd332 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -32,12 +32,6 @@ struct in_device;
32#include <net/route.h> 32#include <net/route.h>
33#include <linux/netfilter_ipv6/ip6t_LOG.h> 33#include <linux/netfilter_ipv6/ip6t_LOG.h>
34 34
35#if 0
36#define DEBUGP printk
37#else
38#define DEBUGP(format, args...)
39#endif
40
41/* Use lock to serialize, so printks don't overlap */ 35/* Use lock to serialize, so printks don't overlap */
42static DEFINE_SPINLOCK(log_lock); 36static DEFINE_SPINLOCK(log_lock);
43 37
@@ -48,7 +42,8 @@ static void dump_packet(const struct nf_loginfo *info,
48{ 42{
49 u_int8_t currenthdr; 43 u_int8_t currenthdr;
50 int fragment; 44 int fragment;
51 struct ipv6hdr _ip6h, *ih; 45 struct ipv6hdr _ip6h;
46 const struct ipv6hdr *ih;
52 unsigned int ptr; 47 unsigned int ptr;
53 unsigned int hdrlen = 0; 48 unsigned int hdrlen = 0;
54 unsigned int logflags; 49 unsigned int logflags;
@@ -78,7 +73,8 @@ static void dump_packet(const struct nf_loginfo *info,
78 ptr = ip6hoff + sizeof(struct ipv6hdr); 73 ptr = ip6hoff + sizeof(struct ipv6hdr);
79 currenthdr = ih->nexthdr; 74 currenthdr = ih->nexthdr;
80 while (currenthdr != NEXTHDR_NONE && ip6t_ext_hdr(currenthdr)) { 75 while (currenthdr != NEXTHDR_NONE && ip6t_ext_hdr(currenthdr)) {
81 struct ipv6_opt_hdr _hdr, *hp; 76 struct ipv6_opt_hdr _hdr;
77 const struct ipv6_opt_hdr *hp;
82 78
83 hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr); 79 hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr);
84 if (hp == NULL) { 80 if (hp == NULL) {
@@ -92,7 +88,8 @@ static void dump_packet(const struct nf_loginfo *info,
92 88
93 switch (currenthdr) { 89 switch (currenthdr) {
94 case IPPROTO_FRAGMENT: { 90 case IPPROTO_FRAGMENT: {
95 struct frag_hdr _fhdr, *fh; 91 struct frag_hdr _fhdr;
92 const struct frag_hdr *fh;
96 93
97 printk("FRAG:"); 94 printk("FRAG:");
98 fh = skb_header_pointer(skb, ptr, sizeof(_fhdr), 95 fh = skb_header_pointer(skb, ptr, sizeof(_fhdr),
@@ -131,7 +128,8 @@ static void dump_packet(const struct nf_loginfo *info,
131 /* Max Length */ 128 /* Max Length */
132 case IPPROTO_AH: 129 case IPPROTO_AH:
133 if (logflags & IP6T_LOG_IPOPT) { 130 if (logflags & IP6T_LOG_IPOPT) {
134 struct ip_auth_hdr _ahdr, *ah; 131 struct ip_auth_hdr _ahdr;
132 const struct ip_auth_hdr *ah;
135 133
136 /* Max length: 3 "AH " */ 134 /* Max length: 3 "AH " */
137 printk("AH "); 135 printk("AH ");
@@ -162,7 +160,8 @@ static void dump_packet(const struct nf_loginfo *info,
162 break; 160 break;
163 case IPPROTO_ESP: 161 case IPPROTO_ESP:
164 if (logflags & IP6T_LOG_IPOPT) { 162 if (logflags & IP6T_LOG_IPOPT) {
165 struct ip_esp_hdr _esph, *eh; 163 struct ip_esp_hdr _esph;
164 const struct ip_esp_hdr *eh;
166 165
167 /* Max length: 4 "ESP " */ 166 /* Max length: 4 "ESP " */
168 printk("ESP "); 167 printk("ESP ");
@@ -202,7 +201,8 @@ static void dump_packet(const struct nf_loginfo *info,
202 201
203 switch (currenthdr) { 202 switch (currenthdr) {
204 case IPPROTO_TCP: { 203 case IPPROTO_TCP: {
205 struct tcphdr _tcph, *th; 204 struct tcphdr _tcph;
205 const struct tcphdr *th;
206 206
207 /* Max length: 10 "PROTO=TCP " */ 207 /* Max length: 10 "PROTO=TCP " */
208 printk("PROTO=TCP "); 208 printk("PROTO=TCP ");
@@ -250,7 +250,8 @@ static void dump_packet(const struct nf_loginfo *info,
250 250
251 if ((logflags & IP6T_LOG_TCPOPT) 251 if ((logflags & IP6T_LOG_TCPOPT)
252 && th->doff * 4 > sizeof(struct tcphdr)) { 252 && th->doff * 4 > sizeof(struct tcphdr)) {
253 u_int8_t _opt[60 - sizeof(struct tcphdr)], *op; 253 u_int8_t _opt[60 - sizeof(struct tcphdr)];
254 const u_int8_t *op;
254 unsigned int i; 255 unsigned int i;
255 unsigned int optsize = th->doff * 4 256 unsigned int optsize = th->doff * 4
256 - sizeof(struct tcphdr); 257 - sizeof(struct tcphdr);
@@ -273,7 +274,8 @@ static void dump_packet(const struct nf_loginfo *info,
273 } 274 }
274 case IPPROTO_UDP: 275 case IPPROTO_UDP:
275 case IPPROTO_UDPLITE: { 276 case IPPROTO_UDPLITE: {
276 struct udphdr _udph, *uh; 277 struct udphdr _udph;
278 const struct udphdr *uh;
277 279
278 if (currenthdr == IPPROTO_UDP) 280 if (currenthdr == IPPROTO_UDP)
279 /* Max length: 10 "PROTO=UDP " */ 281 /* Max length: 10 "PROTO=UDP " */
@@ -298,7 +300,8 @@ static void dump_packet(const struct nf_loginfo *info,
298 break; 300 break;
299 } 301 }
300 case IPPROTO_ICMPV6: { 302 case IPPROTO_ICMPV6: {
301 struct icmp6hdr _icmp6h, *ic; 303 struct icmp6hdr _icmp6h;
304 const struct icmp6hdr *ic;
302 305
303 /* Max length: 13 "PROTO=ICMPv6 " */ 306 /* Max length: 13 "PROTO=ICMPv6 " */
304 printk("PROTO=ICMPv6 "); 307 printk("PROTO=ICMPv6 ");
@@ -448,27 +451,27 @@ ip6t_log_target(struct sk_buff **pskb,
448} 451}
449 452
450 453
451static int ip6t_log_checkentry(const char *tablename, 454static bool ip6t_log_checkentry(const char *tablename,
452 const void *entry, 455 const void *entry,
453 const struct xt_target *target, 456 const struct xt_target *target,
454 void *targinfo, 457 void *targinfo,
455 unsigned int hook_mask) 458 unsigned int hook_mask)
456{ 459{
457 const struct ip6t_log_info *loginfo = targinfo; 460 const struct ip6t_log_info *loginfo = targinfo;
458 461
459 if (loginfo->level >= 8) { 462 if (loginfo->level >= 8) {
460 DEBUGP("LOG: level %u >= 8\n", loginfo->level); 463 pr_debug("LOG: level %u >= 8\n", loginfo->level);
461 return 0; 464 return false;
462 } 465 }
463 if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') { 466 if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
464 DEBUGP("LOG: prefix term %i\n", 467 pr_debug("LOG: prefix term %i\n",
465 loginfo->prefix[sizeof(loginfo->prefix)-1]); 468 loginfo->prefix[sizeof(loginfo->prefix)-1]);
466 return 0; 469 return false;
467 } 470 }
468 return 1; 471 return true;
469} 472}
470 473
471static struct xt_target ip6t_log_reg = { 474static struct xt_target ip6t_log_reg __read_mostly = {
472 .name = "LOG", 475 .name = "LOG",
473 .family = AF_INET6, 476 .family = AF_INET6,
474 .target = ip6t_log_target, 477 .target = ip6t_log_target,
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index cb3d2415a064..2f487cda3b6b 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -34,12 +34,6 @@ MODULE_AUTHOR("Yasuyuki KOZAKAI <yasuyuki.kozakai@toshiba.co.jp>");
34MODULE_DESCRIPTION("IP6 tables REJECT target module"); 34MODULE_DESCRIPTION("IP6 tables REJECT target module");
35MODULE_LICENSE("GPL"); 35MODULE_LICENSE("GPL");
36 36
37#if 0
38#define DEBUGP printk
39#else
40#define DEBUGP(format, args...)
41#endif
42
43/* Send RST reply */ 37/* Send RST reply */
44static void send_reset(struct sk_buff *oldskb) 38static void send_reset(struct sk_buff *oldskb)
45{ 39{
@@ -54,7 +48,7 @@ static void send_reset(struct sk_buff *oldskb)
54 48
55 if ((!(ipv6_addr_type(&oip6h->saddr) & IPV6_ADDR_UNICAST)) || 49 if ((!(ipv6_addr_type(&oip6h->saddr) & IPV6_ADDR_UNICAST)) ||
56 (!(ipv6_addr_type(&oip6h->daddr) & IPV6_ADDR_UNICAST))) { 50 (!(ipv6_addr_type(&oip6h->daddr) & IPV6_ADDR_UNICAST))) {
57 DEBUGP("ip6t_REJECT: addr is not unicast.\n"); 51 pr_debug("ip6t_REJECT: addr is not unicast.\n");
58 return; 52 return;
59 } 53 }
60 54
@@ -62,16 +56,17 @@ static void send_reset(struct sk_buff *oldskb)
62 tcphoff = ipv6_skip_exthdr(oldskb, ((u8*)(oip6h+1) - oldskb->data), &proto); 56 tcphoff = ipv6_skip_exthdr(oldskb, ((u8*)(oip6h+1) - oldskb->data), &proto);
63 57
64 if ((tcphoff < 0) || (tcphoff > oldskb->len)) { 58 if ((tcphoff < 0) || (tcphoff > oldskb->len)) {
65 DEBUGP("ip6t_REJECT: Can't get TCP header.\n"); 59 pr_debug("ip6t_REJECT: Can't get TCP header.\n");
66 return; 60 return;
67 } 61 }
68 62
69 otcplen = oldskb->len - tcphoff; 63 otcplen = oldskb->len - tcphoff;
70 64
71 /* IP header checks: fragment, too short. */ 65 /* IP header checks: fragment, too short. */
72 if ((proto != IPPROTO_TCP) || (otcplen < sizeof(struct tcphdr))) { 66 if (proto != IPPROTO_TCP || otcplen < sizeof(struct tcphdr)) {
73 DEBUGP("ip6t_REJECT: proto(%d) != IPPROTO_TCP, or too short. otcplen = %d\n", 67 pr_debug("ip6t_REJECT: proto(%d) != IPPROTO_TCP, "
74 proto, otcplen); 68 "or too short. otcplen = %d\n",
69 proto, otcplen);
75 return; 70 return;
76 } 71 }
77 72
@@ -80,14 +75,14 @@ static void send_reset(struct sk_buff *oldskb)
80 75
81 /* No RST for RST. */ 76 /* No RST for RST. */
82 if (otcph.rst) { 77 if (otcph.rst) {
83 DEBUGP("ip6t_REJECT: RST is set\n"); 78 pr_debug("ip6t_REJECT: RST is set\n");
84 return; 79 return;
85 } 80 }
86 81
87 /* Check checksum. */ 82 /* Check checksum. */
88 if (csum_ipv6_magic(&oip6h->saddr, &oip6h->daddr, otcplen, IPPROTO_TCP, 83 if (csum_ipv6_magic(&oip6h->saddr, &oip6h->daddr, otcplen, IPPROTO_TCP,
89 skb_checksum(oldskb, tcphoff, otcplen, 0))) { 84 skb_checksum(oldskb, tcphoff, otcplen, 0))) {
90 DEBUGP("ip6t_REJECT: TCP checksum is invalid\n"); 85 pr_debug("ip6t_REJECT: TCP checksum is invalid\n");
91 return; 86 return;
92 } 87 }
93 88
@@ -159,7 +154,7 @@ static void send_reset(struct sk_buff *oldskb)
159 tcph->check = csum_ipv6_magic(&ipv6_hdr(nskb)->saddr, 154 tcph->check = csum_ipv6_magic(&ipv6_hdr(nskb)->saddr,
160 &ipv6_hdr(nskb)->daddr, 155 &ipv6_hdr(nskb)->daddr,
161 sizeof(struct tcphdr), IPPROTO_TCP, 156 sizeof(struct tcphdr), IPPROTO_TCP,
162 csum_partial((char *)tcph, 157 csum_partial(tcph,
163 sizeof(struct tcphdr), 0)); 158 sizeof(struct tcphdr), 0));
164 159
165 nf_ct_attach(nskb, oldskb); 160 nf_ct_attach(nskb, oldskb);
@@ -186,7 +181,7 @@ static unsigned int reject6_target(struct sk_buff **pskb,
186{ 181{
187 const struct ip6t_reject_info *reject = targinfo; 182 const struct ip6t_reject_info *reject = targinfo;
188 183
189 DEBUGP(KERN_DEBUG "%s: medium point\n", __FUNCTION__); 184 pr_debug("%s: medium point\n", __FUNCTION__);
190 /* WARNING: This code causes reentry within ip6tables. 185 /* WARNING: This code causes reentry within ip6tables.
191 This means that the ip6tables jump stack is now crap. We 186 This means that the ip6tables jump stack is now crap. We
192 must return an absolute verdict. --RR */ 187 must return an absolute verdict. --RR */
@@ -221,30 +216,30 @@ static unsigned int reject6_target(struct sk_buff **pskb,
221 return NF_DROP; 216 return NF_DROP;
222} 217}
223 218
224static int check(const char *tablename, 219static bool check(const char *tablename,
225 const void *entry, 220 const void *entry,
226 const struct xt_target *target, 221 const struct xt_target *target,
227 void *targinfo, 222 void *targinfo,
228 unsigned int hook_mask) 223 unsigned int hook_mask)
229{ 224{
230 const struct ip6t_reject_info *rejinfo = targinfo; 225 const struct ip6t_reject_info *rejinfo = targinfo;
231 const struct ip6t_entry *e = entry; 226 const struct ip6t_entry *e = entry;
232 227
233 if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) { 228 if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
234 printk("ip6t_REJECT: ECHOREPLY is not supported.\n"); 229 printk("ip6t_REJECT: ECHOREPLY is not supported.\n");
235 return 0; 230 return false;
236 } else if (rejinfo->with == IP6T_TCP_RESET) { 231 } else if (rejinfo->with == IP6T_TCP_RESET) {
237 /* Must specify that it's a TCP packet */ 232 /* Must specify that it's a TCP packet */
238 if (e->ipv6.proto != IPPROTO_TCP 233 if (e->ipv6.proto != IPPROTO_TCP
239 || (e->ipv6.invflags & XT_INV_PROTO)) { 234 || (e->ipv6.invflags & XT_INV_PROTO)) {
240 DEBUGP("ip6t_REJECT: TCP_RESET illegal for non-tcp\n"); 235 printk("ip6t_REJECT: TCP_RESET illegal for non-tcp\n");
241 return 0; 236 return false;
242 } 237 }
243 } 238 }
244 return 1; 239 return true;
245} 240}
246 241
247static struct xt_target ip6t_reject_reg = { 242static struct xt_target ip6t_reject_reg __read_mostly = {
248 .name = "REJECT", 243 .name = "REJECT",
249 .family = AF_INET6, 244 .family = AF_INET6,
250 .target = reject6_target, 245 .target = reject6_target,
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c
index d3c154371b41..2a25fe25e0e0 100644
--- a/net/ipv6/netfilter/ip6t_ah.c
+++ b/net/ipv6/netfilter/ip6t_ah.c
@@ -23,25 +23,20 @@ MODULE_LICENSE("GPL");
23MODULE_DESCRIPTION("IPv6 AH match"); 23MODULE_DESCRIPTION("IPv6 AH match");
24MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>"); 24MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
25 25
26#if 0
27#define DEBUGP printk
28#else
29#define DEBUGP(format, args...)
30#endif
31
32/* Returns 1 if the spi is matched by the range, 0 otherwise */ 26/* Returns 1 if the spi is matched by the range, 0 otherwise */
33static inline int 27static inline bool
34spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert) 28spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
35{ 29{
36 int r=0; 30 bool r;
37 DEBUGP("ah spi_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ', 31
38 min,spi,max); 32 pr_debug("ah spi_match:%c 0x%x <= 0x%x <= 0x%x",
33 invert ? '!' : ' ', min, spi, max);
39 r = (spi >= min && spi <= max) ^ invert; 34 r = (spi >= min && spi <= max) ^ invert;
40 DEBUGP(" result %s\n",r? "PASS\n" : "FAILED\n"); 35 pr_debug(" result %s\n", r ? "PASS" : "FAILED");
41 return r; 36 return r;
42} 37}
43 38
44static int 39static bool
45match(const struct sk_buff *skb, 40match(const struct sk_buff *skb,
46 const struct net_device *in, 41 const struct net_device *in,
47 const struct net_device *out, 42 const struct net_device *out,
@@ -49,9 +44,10 @@ match(const struct sk_buff *skb,
49 const void *matchinfo, 44 const void *matchinfo,
50 int offset, 45 int offset,
51 unsigned int protoff, 46 unsigned int protoff,
52 int *hotdrop) 47 bool *hotdrop)
53{ 48{
54 struct ip_auth_hdr *ah, _ah; 49 struct ip_auth_hdr _ah;
50 const struct ip_auth_hdr *ah;
55 const struct ip6t_ah *ahinfo = matchinfo; 51 const struct ip6t_ah *ahinfo = matchinfo;
56 unsigned int ptr; 52 unsigned int ptr;
57 unsigned int hdrlen = 0; 53 unsigned int hdrlen = 0;
@@ -60,40 +56,40 @@ match(const struct sk_buff *skb,
60 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL); 56 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL);
61 if (err < 0) { 57 if (err < 0) {
62 if (err != -ENOENT) 58 if (err != -ENOENT)
63 *hotdrop = 1; 59 *hotdrop = true;
64 return 0; 60 return false;
65 } 61 }
66 62
67 ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah); 63 ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah);
68 if (ah == NULL) { 64 if (ah == NULL) {
69 *hotdrop = 1; 65 *hotdrop = true;
70 return 0; 66 return false;
71 } 67 }
72 68
73 hdrlen = (ah->hdrlen + 2) << 2; 69 hdrlen = (ah->hdrlen + 2) << 2;
74 70
75 DEBUGP("IPv6 AH LEN %u %u ", hdrlen, ah->hdrlen); 71 pr_debug("IPv6 AH LEN %u %u ", hdrlen, ah->hdrlen);
76 DEBUGP("RES %04X ", ah->reserved); 72 pr_debug("RES %04X ", ah->reserved);
77 DEBUGP("SPI %u %08X\n", ntohl(ah->spi), ntohl(ah->spi)); 73 pr_debug("SPI %u %08X\n", ntohl(ah->spi), ntohl(ah->spi));
78 74
79 DEBUGP("IPv6 AH spi %02X ", 75 pr_debug("IPv6 AH spi %02X ",
80 (spi_match(ahinfo->spis[0], ahinfo->spis[1], 76 spi_match(ahinfo->spis[0], ahinfo->spis[1],
81 ntohl(ah->spi), 77 ntohl(ah->spi),
82 !!(ahinfo->invflags & IP6T_AH_INV_SPI)))); 78 !!(ahinfo->invflags & IP6T_AH_INV_SPI)));
83 DEBUGP("len %02X %04X %02X ", 79 pr_debug("len %02X %04X %02X ",
84 ahinfo->hdrlen, hdrlen, 80 ahinfo->hdrlen, hdrlen,
85 (!ahinfo->hdrlen || 81 (!ahinfo->hdrlen ||
86 (ahinfo->hdrlen == hdrlen) ^ 82 (ahinfo->hdrlen == hdrlen) ^
87 !!(ahinfo->invflags & IP6T_AH_INV_LEN))); 83 !!(ahinfo->invflags & IP6T_AH_INV_LEN)));
88 DEBUGP("res %02X %04X %02X\n", 84 pr_debug("res %02X %04X %02X\n",
89 ahinfo->hdrres, ah->reserved, 85 ahinfo->hdrres, ah->reserved,
90 !(ahinfo->hdrres && ah->reserved)); 86 !(ahinfo->hdrres && ah->reserved));
91 87
92 return (ah != NULL) 88 return (ah != NULL)
93 && 89 &&
94 (spi_match(ahinfo->spis[0], ahinfo->spis[1], 90 spi_match(ahinfo->spis[0], ahinfo->spis[1],
95 ntohl(ah->spi), 91 ntohl(ah->spi),
96 !!(ahinfo->invflags & IP6T_AH_INV_SPI))) 92 !!(ahinfo->invflags & IP6T_AH_INV_SPI))
97 && 93 &&
98 (!ahinfo->hdrlen || 94 (!ahinfo->hdrlen ||
99 (ahinfo->hdrlen == hdrlen) ^ 95 (ahinfo->hdrlen == hdrlen) ^
@@ -103,7 +99,7 @@ match(const struct sk_buff *skb,
103} 99}
104 100
105/* Called when user tries to insert an entry of this type. */ 101/* Called when user tries to insert an entry of this type. */
106static int 102static bool
107checkentry(const char *tablename, 103checkentry(const char *tablename,
108 const void *entry, 104 const void *entry,
109 const struct xt_match *match, 105 const struct xt_match *match,
@@ -113,13 +109,13 @@ checkentry(const char *tablename,
113 const struct ip6t_ah *ahinfo = matchinfo; 109 const struct ip6t_ah *ahinfo = matchinfo;
114 110
115 if (ahinfo->invflags & ~IP6T_AH_INV_MASK) { 111 if (ahinfo->invflags & ~IP6T_AH_INV_MASK) {
116 DEBUGP("ip6t_ah: unknown flags %X\n", ahinfo->invflags); 112 pr_debug("ip6t_ah: unknown flags %X\n", ahinfo->invflags);
117 return 0; 113 return false;
118 } 114 }
119 return 1; 115 return true;
120} 116}
121 117
122static struct xt_match ah_match = { 118static struct xt_match ah_match __read_mostly = {
123 .name = "ah", 119 .name = "ah",
124 .family = AF_INET6, 120 .family = AF_INET6,
125 .match = match, 121 .match = match,
diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c
index 0f3dd932f0a6..34ba150bfe5d 100644
--- a/net/ipv6/netfilter/ip6t_eui64.c
+++ b/net/ipv6/netfilter/ip6t_eui64.c
@@ -19,7 +19,7 @@ MODULE_DESCRIPTION("IPv6 EUI64 address checking match");
19MODULE_LICENSE("GPL"); 19MODULE_LICENSE("GPL");
20MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>"); 20MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
21 21
22static int 22static bool
23match(const struct sk_buff *skb, 23match(const struct sk_buff *skb,
24 const struct net_device *in, 24 const struct net_device *in,
25 const struct net_device *out, 25 const struct net_device *out,
@@ -27,16 +27,16 @@ match(const struct sk_buff *skb,
27 const void *matchinfo, 27 const void *matchinfo,
28 int offset, 28 int offset,
29 unsigned int protoff, 29 unsigned int protoff,
30 int *hotdrop) 30 bool *hotdrop)
31{ 31{
32 unsigned char eui64[8]; 32 unsigned char eui64[8];
33 int i = 0; 33 int i = 0;
34 34
35 if (!(skb_mac_header(skb) >= skb->head && 35 if (!(skb_mac_header(skb) >= skb->head &&
36 (skb_mac_header(skb) + ETH_HLEN) <= skb->data) && 36 skb_mac_header(skb) + ETH_HLEN <= skb->data) &&
37 offset != 0) { 37 offset != 0) {
38 *hotdrop = 1; 38 *hotdrop = true;
39 return 0; 39 return false;
40 } 40 }
41 41
42 memset(eui64, 0, sizeof(eui64)); 42 memset(eui64, 0, sizeof(eui64));
@@ -50,19 +50,19 @@ match(const struct sk_buff *skb,
50 eui64[0] |= 0x02; 50 eui64[0] |= 0x02;
51 51
52 i = 0; 52 i = 0;
53 while ((ipv6_hdr(skb)->saddr.s6_addr[8 + i] == eui64[i]) 53 while (ipv6_hdr(skb)->saddr.s6_addr[8 + i] == eui64[i]
54 && (i < 8)) 54 && i < 8)
55 i++; 55 i++;
56 56
57 if (i == 8) 57 if (i == 8)
58 return 1; 58 return true;
59 } 59 }
60 } 60 }
61 61
62 return 0; 62 return false;
63} 63}
64 64
65static struct xt_match eui64_match = { 65static struct xt_match eui64_match __read_mostly = {
66 .name = "eui64", 66 .name = "eui64",
67 .family = AF_INET6, 67 .family = AF_INET6,
68 .match = match, 68 .match = match,
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c
index 5a5da71321b6..968aeba02073 100644
--- a/net/ipv6/netfilter/ip6t_frag.c
+++ b/net/ipv6/netfilter/ip6t_frag.c
@@ -22,25 +22,19 @@ MODULE_LICENSE("GPL");
22MODULE_DESCRIPTION("IPv6 FRAG match"); 22MODULE_DESCRIPTION("IPv6 FRAG match");
23MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>"); 23MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
24 24
25#if 0
26#define DEBUGP printk
27#else
28#define DEBUGP(format, args...)
29#endif
30
31/* Returns 1 if the id is matched by the range, 0 otherwise */ 25/* Returns 1 if the id is matched by the range, 0 otherwise */
32static inline int 26static inline bool
33id_match(u_int32_t min, u_int32_t max, u_int32_t id, int invert) 27id_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert)
34{ 28{
35 int r = 0; 29 bool r;
36 DEBUGP("frag id_match:%c 0x%x <= 0x%x <= 0x%x", invert ? '!' : ' ', 30 pr_debug("frag id_match:%c 0x%x <= 0x%x <= 0x%x", invert ? '!' : ' ',
37 min, id, max); 31 min, id, max);
38 r = (id >= min && id <= max) ^ invert; 32 r = (id >= min && id <= max) ^ invert;
39 DEBUGP(" result %s\n", r ? "PASS" : "FAILED"); 33 pr_debug(" result %s\n", r ? "PASS" : "FAILED");
40 return r; 34 return r;
41} 35}
42 36
43static int 37static bool
44match(const struct sk_buff *skb, 38match(const struct sk_buff *skb,
45 const struct net_device *in, 39 const struct net_device *in,
46 const struct net_device *out, 40 const struct net_device *out,
@@ -48,9 +42,10 @@ match(const struct sk_buff *skb,
48 const void *matchinfo, 42 const void *matchinfo,
49 int offset, 43 int offset,
50 unsigned int protoff, 44 unsigned int protoff,
51 int *hotdrop) 45 bool *hotdrop)
52{ 46{
53 struct frag_hdr _frag, *fh; 47 struct frag_hdr _frag;
48 const struct frag_hdr *fh;
54 const struct ip6t_frag *fraginfo = matchinfo; 49 const struct ip6t_frag *fraginfo = matchinfo;
55 unsigned int ptr; 50 unsigned int ptr;
56 int err; 51 int err;
@@ -58,53 +53,53 @@ match(const struct sk_buff *skb,
58 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL); 53 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL);
59 if (err < 0) { 54 if (err < 0) {
60 if (err != -ENOENT) 55 if (err != -ENOENT)
61 *hotdrop = 1; 56 *hotdrop = true;
62 return 0; 57 return false;
63 } 58 }
64 59
65 fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag); 60 fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag);
66 if (fh == NULL) { 61 if (fh == NULL) {
67 *hotdrop = 1; 62 *hotdrop = true;
68 return 0; 63 return false;
69 } 64 }
70 65
71 DEBUGP("INFO %04X ", fh->frag_off); 66 pr_debug("INFO %04X ", fh->frag_off);
72 DEBUGP("OFFSET %04X ", ntohs(fh->frag_off) & ~0x7); 67 pr_debug("OFFSET %04X ", ntohs(fh->frag_off) & ~0x7);
73 DEBUGP("RES %02X %04X", fh->reserved, ntohs(fh->frag_off) & 0x6); 68 pr_debug("RES %02X %04X", fh->reserved, ntohs(fh->frag_off) & 0x6);
74 DEBUGP("MF %04X ", fh->frag_off & htons(IP6_MF)); 69 pr_debug("MF %04X ", fh->frag_off & htons(IP6_MF));
75 DEBUGP("ID %u %08X\n", ntohl(fh->identification), 70 pr_debug("ID %u %08X\n", ntohl(fh->identification),
76 ntohl(fh->identification)); 71 ntohl(fh->identification));
77 72
78 DEBUGP("IPv6 FRAG id %02X ", 73 pr_debug("IPv6 FRAG id %02X ",
79 (id_match(fraginfo->ids[0], fraginfo->ids[1], 74 id_match(fraginfo->ids[0], fraginfo->ids[1],
80 ntohl(fh->identification), 75 ntohl(fh->identification),
81 !!(fraginfo->invflags & IP6T_FRAG_INV_IDS)))); 76 !!(fraginfo->invflags & IP6T_FRAG_INV_IDS)));
82 DEBUGP("res %02X %02X%04X %02X ", 77 pr_debug("res %02X %02X%04X %02X ",
83 (fraginfo->flags & IP6T_FRAG_RES), fh->reserved, 78 fraginfo->flags & IP6T_FRAG_RES, fh->reserved,
84 ntohs(fh->frag_off) & 0x6, 79 ntohs(fh->frag_off) & 0x6,
85 !((fraginfo->flags & IP6T_FRAG_RES) 80 !((fraginfo->flags & IP6T_FRAG_RES)
86 && (fh->reserved || (ntohs(fh->frag_off) & 0x06)))); 81 && (fh->reserved || (ntohs(fh->frag_off) & 0x06))));
87 DEBUGP("first %02X %02X %02X ", 82 pr_debug("first %02X %02X %02X ",
88 (fraginfo->flags & IP6T_FRAG_FST), 83 fraginfo->flags & IP6T_FRAG_FST,
89 ntohs(fh->frag_off) & ~0x7, 84 ntohs(fh->frag_off) & ~0x7,
90 !((fraginfo->flags & IP6T_FRAG_FST) 85 !((fraginfo->flags & IP6T_FRAG_FST)
91 && (ntohs(fh->frag_off) & ~0x7))); 86 && (ntohs(fh->frag_off) & ~0x7)));
92 DEBUGP("mf %02X %02X %02X ", 87 pr_debug("mf %02X %02X %02X ",
93 (fraginfo->flags & IP6T_FRAG_MF), 88 fraginfo->flags & IP6T_FRAG_MF,
94 ntohs(fh->frag_off) & IP6_MF, 89 ntohs(fh->frag_off) & IP6_MF,
95 !((fraginfo->flags & IP6T_FRAG_MF) 90 !((fraginfo->flags & IP6T_FRAG_MF)
96 && !((ntohs(fh->frag_off) & IP6_MF)))); 91 && !((ntohs(fh->frag_off) & IP6_MF))));
97 DEBUGP("last %02X %02X %02X\n", 92 pr_debug("last %02X %02X %02X\n",
98 (fraginfo->flags & IP6T_FRAG_NMF), 93 fraginfo->flags & IP6T_FRAG_NMF,
99 ntohs(fh->frag_off) & IP6_MF, 94 ntohs(fh->frag_off) & IP6_MF,
100 !((fraginfo->flags & IP6T_FRAG_NMF) 95 !((fraginfo->flags & IP6T_FRAG_NMF)
101 && (ntohs(fh->frag_off) & IP6_MF))); 96 && (ntohs(fh->frag_off) & IP6_MF)));
102 97
103 return (fh != NULL) 98 return (fh != NULL)
104 && 99 &&
105 (id_match(fraginfo->ids[0], fraginfo->ids[1], 100 id_match(fraginfo->ids[0], fraginfo->ids[1],
106 ntohl(fh->identification), 101 ntohl(fh->identification),
107 !!(fraginfo->invflags & IP6T_FRAG_INV_IDS))) 102 !!(fraginfo->invflags & IP6T_FRAG_INV_IDS))
108 && 103 &&
109 !((fraginfo->flags & IP6T_FRAG_RES) 104 !((fraginfo->flags & IP6T_FRAG_RES)
110 && (fh->reserved || (ntohs(fh->frag_off) & 0x6))) 105 && (fh->reserved || (ntohs(fh->frag_off) & 0x6)))
@@ -120,7 +115,7 @@ match(const struct sk_buff *skb,
120} 115}
121 116
122/* Called when user tries to insert an entry of this type. */ 117/* Called when user tries to insert an entry of this type. */
123static int 118static bool
124checkentry(const char *tablename, 119checkentry(const char *tablename,
125 const void *ip, 120 const void *ip,
126 const struct xt_match *match, 121 const struct xt_match *match,
@@ -130,13 +125,13 @@ checkentry(const char *tablename,
130 const struct ip6t_frag *fraginfo = matchinfo; 125 const struct ip6t_frag *fraginfo = matchinfo;
131 126
132 if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) { 127 if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) {
133 DEBUGP("ip6t_frag: unknown flags %X\n", fraginfo->invflags); 128 pr_debug("ip6t_frag: unknown flags %X\n", fraginfo->invflags);
134 return 0; 129 return false;
135 } 130 }
136 return 1; 131 return true;
137} 132}
138 133
139static struct xt_match frag_match = { 134static struct xt_match frag_match __read_mostly = {
140 .name = "frag", 135 .name = "frag",
141 .family = AF_INET6, 136 .family = AF_INET6,
142 .match = match, 137 .match = match,
diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c
index d2373c7cd354..e6ca6018b1ea 100644
--- a/net/ipv6/netfilter/ip6t_hbh.c
+++ b/net/ipv6/netfilter/ip6t_hbh.c
@@ -25,12 +25,6 @@ MODULE_DESCRIPTION("IPv6 opts match");
25MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>"); 25MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
26MODULE_ALIAS("ip6t_dst"); 26MODULE_ALIAS("ip6t_dst");
27 27
28#if 0
29#define DEBUGP printk
30#else
31#define DEBUGP(format, args...)
32#endif
33
34/* 28/*
35 * (Type & 0xC0) >> 6 29 * (Type & 0xC0) >> 6
36 * 0 -> ignorable 30 * 0 -> ignorable
@@ -47,7 +41,7 @@ MODULE_ALIAS("ip6t_dst");
47 * 5 -> RTALERT 2 x x 41 * 5 -> RTALERT 2 x x
48 */ 42 */
49 43
50static int 44static bool
51match(const struct sk_buff *skb, 45match(const struct sk_buff *skb,
52 const struct net_device *in, 46 const struct net_device *in,
53 const struct net_device *out, 47 const struct net_device *out,
@@ -55,45 +49,48 @@ match(const struct sk_buff *skb,
55 const void *matchinfo, 49 const void *matchinfo,
56 int offset, 50 int offset,
57 unsigned int protoff, 51 unsigned int protoff,
58 int *hotdrop) 52 bool *hotdrop)
59{ 53{
60 struct ipv6_opt_hdr _optsh, *oh; 54 struct ipv6_opt_hdr _optsh;
55 const struct ipv6_opt_hdr *oh;
61 const struct ip6t_opts *optinfo = matchinfo; 56 const struct ip6t_opts *optinfo = matchinfo;
62 unsigned int temp; 57 unsigned int temp;
63 unsigned int ptr; 58 unsigned int ptr;
64 unsigned int hdrlen = 0; 59 unsigned int hdrlen = 0;
65 unsigned int ret = 0; 60 bool ret = false;
66 u8 _opttype, *tp = NULL; 61 u8 _opttype;
67 u8 _optlen, *lp = NULL; 62 u8 _optlen;
63 const u_int8_t *tp = NULL;
64 const u_int8_t *lp = NULL;
68 unsigned int optlen; 65 unsigned int optlen;
69 int err; 66 int err;
70 67
71 err = ipv6_find_hdr(skb, &ptr, match->data, NULL); 68 err = ipv6_find_hdr(skb, &ptr, match->data, NULL);
72 if (err < 0) { 69 if (err < 0) {
73 if (err != -ENOENT) 70 if (err != -ENOENT)
74 *hotdrop = 1; 71 *hotdrop = true;
75 return 0; 72 return false;
76 } 73 }
77 74
78 oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh); 75 oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
79 if (oh == NULL) { 76 if (oh == NULL) {
80 *hotdrop = 1; 77 *hotdrop = true;
81 return 0; 78 return false;
82 } 79 }
83 80
84 hdrlen = ipv6_optlen(oh); 81 hdrlen = ipv6_optlen(oh);
85 if (skb->len - ptr < hdrlen) { 82 if (skb->len - ptr < hdrlen) {
86 /* Packet smaller than it's length field */ 83 /* Packet smaller than it's length field */
87 return 0; 84 return false;
88 } 85 }
89 86
90 DEBUGP("IPv6 OPTS LEN %u %u ", hdrlen, oh->hdrlen); 87 pr_debug("IPv6 OPTS LEN %u %u ", hdrlen, oh->hdrlen);
91 88
92 DEBUGP("len %02X %04X %02X ", 89 pr_debug("len %02X %04X %02X ",
93 optinfo->hdrlen, hdrlen, 90 optinfo->hdrlen, hdrlen,
94 (!(optinfo->flags & IP6T_OPTS_LEN) || 91 (!(optinfo->flags & IP6T_OPTS_LEN) ||
95 ((optinfo->hdrlen == hdrlen) ^ 92 ((optinfo->hdrlen == hdrlen) ^
96 !!(optinfo->invflags & IP6T_OPTS_INV_LEN)))); 93 !!(optinfo->invflags & IP6T_OPTS_INV_LEN))));
97 94
98 ret = (oh != NULL) && 95 ret = (oh != NULL) &&
99 (!(optinfo->flags & IP6T_OPTS_LEN) || 96 (!(optinfo->flags & IP6T_OPTS_LEN) ||
@@ -105,10 +102,10 @@ match(const struct sk_buff *skb,
105 if (!(optinfo->flags & IP6T_OPTS_OPTS)) { 102 if (!(optinfo->flags & IP6T_OPTS_OPTS)) {
106 return ret; 103 return ret;
107 } else if (optinfo->flags & IP6T_OPTS_NSTRICT) { 104 } else if (optinfo->flags & IP6T_OPTS_NSTRICT) {
108 DEBUGP("Not strict - not implemented"); 105 pr_debug("Not strict - not implemented");
109 } else { 106 } else {
110 DEBUGP("Strict "); 107 pr_debug("Strict ");
111 DEBUGP("#%d ", optinfo->optsnr); 108 pr_debug("#%d ", optinfo->optsnr);
112 for (temp = 0; temp < optinfo->optsnr; temp++) { 109 for (temp = 0; temp < optinfo->optsnr; temp++) {
113 /* type field exists ? */ 110 /* type field exists ? */
114 if (hdrlen < 1) 111 if (hdrlen < 1)
@@ -120,12 +117,11 @@ match(const struct sk_buff *skb,
120 117
121 /* Type check */ 118 /* Type check */
122 if (*tp != (optinfo->opts[temp] & 0xFF00) >> 8) { 119 if (*tp != (optinfo->opts[temp] & 0xFF00) >> 8) {
123 DEBUGP("Tbad %02X %02X\n", 120 pr_debug("Tbad %02X %02X\n", *tp,
124 *tp, 121 (optinfo->opts[temp] & 0xFF00) >> 8);
125 (optinfo->opts[temp] & 0xFF00) >> 8); 122 return false;
126 return 0;
127 } else { 123 } else {
128 DEBUGP("Tok "); 124 pr_debug("Tok ");
129 } 125 }
130 /* Length check */ 126 /* Length check */
131 if (*tp) { 127 if (*tp) {
@@ -142,23 +138,23 @@ match(const struct sk_buff *skb,
142 spec_len = optinfo->opts[temp] & 0x00FF; 138 spec_len = optinfo->opts[temp] & 0x00FF;
143 139
144 if (spec_len != 0x00FF && spec_len != *lp) { 140 if (spec_len != 0x00FF && spec_len != *lp) {
145 DEBUGP("Lbad %02X %04X\n", *lp, 141 pr_debug("Lbad %02X %04X\n", *lp,
146 spec_len); 142 spec_len);
147 return 0; 143 return false;
148 } 144 }
149 DEBUGP("Lok "); 145 pr_debug("Lok ");
150 optlen = *lp + 2; 146 optlen = *lp + 2;
151 } else { 147 } else {
152 DEBUGP("Pad1\n"); 148 pr_debug("Pad1\n");
153 optlen = 1; 149 optlen = 1;
154 } 150 }
155 151
156 /* Step to the next */ 152 /* Step to the next */
157 DEBUGP("len%04X \n", optlen); 153 pr_debug("len%04X \n", optlen);
158 154
159 if ((ptr > skb->len - optlen || hdrlen < optlen) && 155 if ((ptr > skb->len - optlen || hdrlen < optlen) &&
160 (temp < optinfo->optsnr - 1)) { 156 temp < optinfo->optsnr - 1) {
161 DEBUGP("new pointer is too large! \n"); 157 pr_debug("new pointer is too large! \n");
162 break; 158 break;
163 } 159 }
164 ptr += optlen; 160 ptr += optlen;
@@ -167,14 +163,14 @@ match(const struct sk_buff *skb,
167 if (temp == optinfo->optsnr) 163 if (temp == optinfo->optsnr)
168 return ret; 164 return ret;
169 else 165 else
170 return 0; 166 return false;
171 } 167 }
172 168
173 return 0; 169 return false;
174} 170}
175 171
176/* Called when user tries to insert an entry of this type. */ 172/* Called when user tries to insert an entry of this type. */
177static int 173static bool
178checkentry(const char *tablename, 174checkentry(const char *tablename,
179 const void *entry, 175 const void *entry,
180 const struct xt_match *match, 176 const struct xt_match *match,
@@ -184,13 +180,13 @@ checkentry(const char *tablename,
184 const struct ip6t_opts *optsinfo = matchinfo; 180 const struct ip6t_opts *optsinfo = matchinfo;
185 181
186 if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) { 182 if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) {
187 DEBUGP("ip6t_opts: unknown flags %X\n", optsinfo->invflags); 183 pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags);
188 return 0; 184 return false;
189 } 185 }
190 return 1; 186 return true;
191} 187}
192 188
193static struct xt_match opts_match[] = { 189static struct xt_match opts_match[] __read_mostly = {
194 { 190 {
195 .name = "hbh", 191 .name = "hbh",
196 .family = AF_INET6, 192 .family = AF_INET6,
diff --git a/net/ipv6/netfilter/ip6t_hl.c b/net/ipv6/netfilter/ip6t_hl.c
index d606c0e6d6fd..ca29ec00dc18 100644
--- a/net/ipv6/netfilter/ip6t_hl.c
+++ b/net/ipv6/netfilter/ip6t_hl.c
@@ -19,37 +19,37 @@ MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
19MODULE_DESCRIPTION("IP tables Hop Limit matching module"); 19MODULE_DESCRIPTION("IP tables Hop Limit matching module");
20MODULE_LICENSE("GPL"); 20MODULE_LICENSE("GPL");
21 21
22static int match(const struct sk_buff *skb, 22static bool match(const struct sk_buff *skb,
23 const struct net_device *in, const struct net_device *out, 23 const struct net_device *in, const struct net_device *out,
24 const struct xt_match *match, const void *matchinfo, 24 const struct xt_match *match, const void *matchinfo,
25 int offset, unsigned int protoff, int *hotdrop) 25 int offset, unsigned int protoff, bool *hotdrop)
26{ 26{
27 const struct ip6t_hl_info *info = matchinfo; 27 const struct ip6t_hl_info *info = matchinfo;
28 const struct ipv6hdr *ip6h = ipv6_hdr(skb); 28 const struct ipv6hdr *ip6h = ipv6_hdr(skb);
29 29
30 switch (info->mode) { 30 switch (info->mode) {
31 case IP6T_HL_EQ: 31 case IP6T_HL_EQ:
32 return (ip6h->hop_limit == info->hop_limit); 32 return ip6h->hop_limit == info->hop_limit;
33 break; 33 break;
34 case IP6T_HL_NE: 34 case IP6T_HL_NE:
35 return (!(ip6h->hop_limit == info->hop_limit)); 35 return ip6h->hop_limit != info->hop_limit;
36 break; 36 break;
37 case IP6T_HL_LT: 37 case IP6T_HL_LT:
38 return (ip6h->hop_limit < info->hop_limit); 38 return ip6h->hop_limit < info->hop_limit;
39 break; 39 break;
40 case IP6T_HL_GT: 40 case IP6T_HL_GT:
41 return (ip6h->hop_limit > info->hop_limit); 41 return ip6h->hop_limit > info->hop_limit;
42 break; 42 break;
43 default: 43 default:
44 printk(KERN_WARNING "ip6t_hl: unknown mode %d\n", 44 printk(KERN_WARNING "ip6t_hl: unknown mode %d\n",
45 info->mode); 45 info->mode);
46 return 0; 46 return false;
47 } 47 }
48 48
49 return 0; 49 return false;
50} 50}
51 51
52static struct xt_match hl_match = { 52static struct xt_match hl_match __read_mostly = {
53 .name = "hl", 53 .name = "hl",
54 .family = AF_INET6, 54 .family = AF_INET6,
55 .match = match, 55 .match = match,
diff --git a/net/ipv6/netfilter/ip6t_ipv6header.c b/net/ipv6/netfilter/ip6t_ipv6header.c
index fd6a0869099b..2c65c2f9a4ab 100644
--- a/net/ipv6/netfilter/ip6t_ipv6header.c
+++ b/net/ipv6/netfilter/ip6t_ipv6header.c
@@ -26,7 +26,7 @@ MODULE_LICENSE("GPL");
26MODULE_DESCRIPTION("IPv6 headers match"); 26MODULE_DESCRIPTION("IPv6 headers match");
27MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>"); 27MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
28 28
29static int 29static bool
30ipv6header_match(const struct sk_buff *skb, 30ipv6header_match(const struct sk_buff *skb,
31 const struct net_device *in, 31 const struct net_device *in,
32 const struct net_device *out, 32 const struct net_device *out,
@@ -34,7 +34,7 @@ ipv6header_match(const struct sk_buff *skb,
34 const void *matchinfo, 34 const void *matchinfo,
35 int offset, 35 int offset,
36 unsigned int protoff, 36 unsigned int protoff,
37 int *hotdrop) 37 bool *hotdrop)
38{ 38{
39 const struct ip6t_ipv6header_info *info = matchinfo; 39 const struct ip6t_ipv6header_info *info = matchinfo;
40 unsigned int temp; 40 unsigned int temp;
@@ -58,7 +58,7 @@ ipv6header_match(const struct sk_buff *skb,
58 58
59 /* Is there enough space for the next ext header? */ 59 /* Is there enough space for the next ext header? */
60 if (len < (int)sizeof(struct ipv6_opt_hdr)) 60 if (len < (int)sizeof(struct ipv6_opt_hdr))
61 return 0; 61 return false;
62 /* No more exthdr -> evaluate */ 62 /* No more exthdr -> evaluate */
63 if (nexthdr == NEXTHDR_NONE) { 63 if (nexthdr == NEXTHDR_NONE) {
64 temp |= MASK_NONE; 64 temp |= MASK_NONE;
@@ -74,9 +74,9 @@ ipv6header_match(const struct sk_buff *skb,
74 BUG_ON(hp == NULL); 74 BUG_ON(hp == NULL);
75 75
76 /* Calculate the header length */ 76 /* Calculate the header length */
77 if (nexthdr == NEXTHDR_FRAGMENT) { 77 if (nexthdr == NEXTHDR_FRAGMENT)
78 hdrlen = 8; 78 hdrlen = 8;
79 } else if (nexthdr == NEXTHDR_AUTH) 79 else if (nexthdr == NEXTHDR_AUTH)
80 hdrlen = (hp->hdrlen + 2) << 2; 80 hdrlen = (hp->hdrlen + 2) << 2;
81 else 81 else
82 hdrlen = ipv6_optlen(hp); 82 hdrlen = ipv6_optlen(hp);
@@ -99,7 +99,7 @@ ipv6header_match(const struct sk_buff *skb,
99 temp |= MASK_DSTOPTS; 99 temp |= MASK_DSTOPTS;
100 break; 100 break;
101 default: 101 default:
102 return 0; 102 return false;
103 break; 103 break;
104 } 104 }
105 105
@@ -110,7 +110,7 @@ ipv6header_match(const struct sk_buff *skb,
110 break; 110 break;
111 } 111 }
112 112
113 if ((nexthdr != NEXTHDR_NONE) && (nexthdr != NEXTHDR_ESP)) 113 if (nexthdr != NEXTHDR_NONE && nexthdr != NEXTHDR_ESP)
114 temp |= MASK_PROTO; 114 temp |= MASK_PROTO;
115 115
116 if (info->modeflag) 116 if (info->modeflag)
@@ -124,7 +124,7 @@ ipv6header_match(const struct sk_buff *skb,
124 } 124 }
125} 125}
126 126
127static int 127static bool
128ipv6header_checkentry(const char *tablename, 128ipv6header_checkentry(const char *tablename,
129 const void *ip, 129 const void *ip,
130 const struct xt_match *match, 130 const struct xt_match *match,
@@ -136,12 +136,12 @@ ipv6header_checkentry(const char *tablename,
136 /* invflags is 0 or 0xff in hard mode */ 136 /* invflags is 0 or 0xff in hard mode */
137 if ((!info->modeflag) && info->invflags != 0x00 && 137 if ((!info->modeflag) && info->invflags != 0x00 &&
138 info->invflags != 0xFF) 138 info->invflags != 0xFF)
139 return 0; 139 return false;
140 140
141 return 1; 141 return true;
142} 142}
143 143
144static struct xt_match ip6t_ipv6header_match = { 144static struct xt_match ip6t_ipv6header_match __read_mostly = {
145 .name = "ipv6header", 145 .name = "ipv6header",
146 .family = AF_INET6, 146 .family = AF_INET6,
147 .match = &ipv6header_match, 147 .match = &ipv6header_match,
diff --git a/net/ipv6/netfilter/ip6t_mh.c b/net/ipv6/netfilter/ip6t_mh.c
index c2a909893a64..0fa714092dc9 100644
--- a/net/ipv6/netfilter/ip6t_mh.c
+++ b/net/ipv6/netfilter/ip6t_mh.c
@@ -31,16 +31,13 @@ MODULE_LICENSE("GPL");
31#endif 31#endif
32 32
33/* Returns 1 if the type is matched by the range, 0 otherwise */ 33/* Returns 1 if the type is matched by the range, 0 otherwise */
34static inline int 34static inline bool
35type_match(u_int8_t min, u_int8_t max, u_int8_t type, int invert) 35type_match(u_int8_t min, u_int8_t max, u_int8_t type, bool invert)
36{ 36{
37 int ret; 37 return (type >= min && type <= max) ^ invert;
38
39 ret = (type >= min && type <= max) ^ invert;
40 return ret;
41} 38}
42 39
43static int 40static bool
44match(const struct sk_buff *skb, 41match(const struct sk_buff *skb,
45 const struct net_device *in, 42 const struct net_device *in,
46 const struct net_device *out, 43 const struct net_device *out,
@@ -48,29 +45,30 @@ match(const struct sk_buff *skb,
48 const void *matchinfo, 45 const void *matchinfo,
49 int offset, 46 int offset,
50 unsigned int protoff, 47 unsigned int protoff,
51 int *hotdrop) 48 bool *hotdrop)
52{ 49{
53 struct ip6_mh _mh, *mh; 50 struct ip6_mh _mh;
51 const struct ip6_mh *mh;
54 const struct ip6t_mh *mhinfo = matchinfo; 52 const struct ip6t_mh *mhinfo = matchinfo;
55 53
56 /* Must not be a fragment. */ 54 /* Must not be a fragment. */
57 if (offset) 55 if (offset)
58 return 0; 56 return false;
59 57
60 mh = skb_header_pointer(skb, protoff, sizeof(_mh), &_mh); 58 mh = skb_header_pointer(skb, protoff, sizeof(_mh), &_mh);
61 if (mh == NULL) { 59 if (mh == NULL) {
62 /* We've been asked to examine this packet, and we 60 /* We've been asked to examine this packet, and we
63 can't. Hence, no choice but to drop. */ 61 can't. Hence, no choice but to drop. */
64 duprintf("Dropping evil MH tinygram.\n"); 62 duprintf("Dropping evil MH tinygram.\n");
65 *hotdrop = 1; 63 *hotdrop = true;
66 return 0; 64 return false;
67 } 65 }
68 66
69 if (mh->ip6mh_proto != IPPROTO_NONE) { 67 if (mh->ip6mh_proto != IPPROTO_NONE) {
70 duprintf("Dropping invalid MH Payload Proto: %u\n", 68 duprintf("Dropping invalid MH Payload Proto: %u\n",
71 mh->ip6mh_proto); 69 mh->ip6mh_proto);
72 *hotdrop = 1; 70 *hotdrop = true;
73 return 0; 71 return false;
74 } 72 }
75 73
76 return type_match(mhinfo->types[0], mhinfo->types[1], mh->ip6mh_type, 74 return type_match(mhinfo->types[0], mhinfo->types[1], mh->ip6mh_type,
@@ -78,7 +76,7 @@ match(const struct sk_buff *skb,
78} 76}
79 77
80/* Called when user tries to insert an entry of this type. */ 78/* Called when user tries to insert an entry of this type. */
81static int 79static bool
82mh_checkentry(const char *tablename, 80mh_checkentry(const char *tablename,
83 const void *entry, 81 const void *entry,
84 const struct xt_match *match, 82 const struct xt_match *match,
@@ -91,7 +89,7 @@ mh_checkentry(const char *tablename,
91 return !(mhinfo->invflags & ~IP6T_MH_INV_MASK); 89 return !(mhinfo->invflags & ~IP6T_MH_INV_MASK);
92} 90}
93 91
94static struct xt_match mh_match = { 92static struct xt_match mh_match __read_mostly = {
95 .name = "mh", 93 .name = "mh",
96 .family = AF_INET6, 94 .family = AF_INET6,
97 .checkentry = mh_checkentry, 95 .checkentry = mh_checkentry,
diff --git a/net/ipv6/netfilter/ip6t_owner.c b/net/ipv6/netfilter/ip6t_owner.c
index 43738bba00b5..6036613aef36 100644
--- a/net/ipv6/netfilter/ip6t_owner.c
+++ b/net/ipv6/netfilter/ip6t_owner.c
@@ -23,7 +23,7 @@ MODULE_DESCRIPTION("IP6 tables owner matching module");
23MODULE_LICENSE("GPL"); 23MODULE_LICENSE("GPL");
24 24
25 25
26static int 26static bool
27match(const struct sk_buff *skb, 27match(const struct sk_buff *skb,
28 const struct net_device *in, 28 const struct net_device *in,
29 const struct net_device *out, 29 const struct net_device *out,
@@ -31,29 +31,27 @@ match(const struct sk_buff *skb,
31 const void *matchinfo, 31 const void *matchinfo,
32 int offset, 32 int offset,
33 unsigned int protoff, 33 unsigned int protoff,
34 int *hotdrop) 34 bool *hotdrop)
35{ 35{
36 const struct ip6t_owner_info *info = matchinfo; 36 const struct ip6t_owner_info *info = matchinfo;
37 37
38 if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file) 38 if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file)
39 return 0; 39 return false;
40 40
41 if (info->match & IP6T_OWNER_UID) { 41 if (info->match & IP6T_OWNER_UID)
42 if ((skb->sk->sk_socket->file->f_uid != info->uid) ^ 42 if ((skb->sk->sk_socket->file->f_uid != info->uid) ^
43 !!(info->invert & IP6T_OWNER_UID)) 43 !!(info->invert & IP6T_OWNER_UID))
44 return 0; 44 return false;
45 }
46 45
47 if (info->match & IP6T_OWNER_GID) { 46 if (info->match & IP6T_OWNER_GID)
48 if ((skb->sk->sk_socket->file->f_gid != info->gid) ^ 47 if ((skb->sk->sk_socket->file->f_gid != info->gid) ^
49 !!(info->invert & IP6T_OWNER_GID)) 48 !!(info->invert & IP6T_OWNER_GID))
50 return 0; 49 return false;
51 }
52 50
53 return 1; 51 return true;
54} 52}
55 53
56static int 54static bool
57checkentry(const char *tablename, 55checkentry(const char *tablename,
58 const void *ip, 56 const void *ip,
59 const struct xt_match *match, 57 const struct xt_match *match,
@@ -65,12 +63,12 @@ checkentry(const char *tablename,
65 if (info->match & (IP6T_OWNER_PID | IP6T_OWNER_SID)) { 63 if (info->match & (IP6T_OWNER_PID | IP6T_OWNER_SID)) {
66 printk("ipt_owner: pid and sid matching " 64 printk("ipt_owner: pid and sid matching "
67 "not supported anymore\n"); 65 "not supported anymore\n");
68 return 0; 66 return false;
69 } 67 }
70 return 1; 68 return true;
71} 69}
72 70
73static struct xt_match owner_match = { 71static struct xt_match owner_match __read_mostly = {
74 .name = "owner", 72 .name = "owner",
75 .family = AF_INET6, 73 .family = AF_INET6,
76 .match = match, 74 .match = match,
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c
index 81ab00d8c182..357cea703bd9 100644
--- a/net/ipv6/netfilter/ip6t_rt.c
+++ b/net/ipv6/netfilter/ip6t_rt.c
@@ -24,25 +24,19 @@ MODULE_LICENSE("GPL");
24MODULE_DESCRIPTION("IPv6 RT match"); 24MODULE_DESCRIPTION("IPv6 RT match");
25MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>"); 25MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
26 26
27#if 0
28#define DEBUGP printk
29#else
30#define DEBUGP(format, args...)
31#endif
32
33/* Returns 1 if the id is matched by the range, 0 otherwise */ 27/* Returns 1 if the id is matched by the range, 0 otherwise */
34static inline int 28static inline bool
35segsleft_match(u_int32_t min, u_int32_t max, u_int32_t id, int invert) 29segsleft_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert)
36{ 30{
37 int r = 0; 31 bool r;
38 DEBUGP("rt segsleft_match:%c 0x%x <= 0x%x <= 0x%x", 32 pr_debug("rt segsleft_match:%c 0x%x <= 0x%x <= 0x%x",
39 invert ? '!' : ' ', min, id, max); 33 invert ? '!' : ' ', min, id, max);
40 r = (id >= min && id <= max) ^ invert; 34 r = (id >= min && id <= max) ^ invert;
41 DEBUGP(" result %s\n", r ? "PASS" : "FAILED"); 35 pr_debug(" result %s\n", r ? "PASS" : "FAILED");
42 return r; 36 return r;
43} 37}
44 38
45static int 39static bool
46match(const struct sk_buff *skb, 40match(const struct sk_buff *skb,
47 const struct net_device *in, 41 const struct net_device *in,
48 const struct net_device *out, 42 const struct net_device *out,
@@ -50,59 +44,61 @@ match(const struct sk_buff *skb,
50 const void *matchinfo, 44 const void *matchinfo,
51 int offset, 45 int offset,
52 unsigned int protoff, 46 unsigned int protoff,
53 int *hotdrop) 47 bool *hotdrop)
54{ 48{
55 struct ipv6_rt_hdr _route, *rh; 49 struct ipv6_rt_hdr _route;
50 const struct ipv6_rt_hdr *rh;
56 const struct ip6t_rt *rtinfo = matchinfo; 51 const struct ip6t_rt *rtinfo = matchinfo;
57 unsigned int temp; 52 unsigned int temp;
58 unsigned int ptr; 53 unsigned int ptr;
59 unsigned int hdrlen = 0; 54 unsigned int hdrlen = 0;
60 unsigned int ret = 0; 55 bool ret = false;
61 struct in6_addr *ap, _addr; 56 struct in6_addr _addr;
57 const struct in6_addr *ap;
62 int err; 58 int err;
63 59
64 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL); 60 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL);
65 if (err < 0) { 61 if (err < 0) {
66 if (err != -ENOENT) 62 if (err != -ENOENT)
67 *hotdrop = 1; 63 *hotdrop = true;
68 return 0; 64 return false;
69 } 65 }
70 66
71 rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route); 67 rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route);
72 if (rh == NULL) { 68 if (rh == NULL) {
73 *hotdrop = 1; 69 *hotdrop = true;
74 return 0; 70 return false;
75 } 71 }
76 72
77 hdrlen = ipv6_optlen(rh); 73 hdrlen = ipv6_optlen(rh);
78 if (skb->len - ptr < hdrlen) { 74 if (skb->len - ptr < hdrlen) {
79 /* Pcket smaller than its length field */ 75 /* Pcket smaller than its length field */
80 return 0; 76 return false;
81 } 77 }
82 78
83 DEBUGP("IPv6 RT LEN %u %u ", hdrlen, rh->hdrlen); 79 pr_debug("IPv6 RT LEN %u %u ", hdrlen, rh->hdrlen);
84 DEBUGP("TYPE %04X ", rh->type); 80 pr_debug("TYPE %04X ", rh->type);
85 DEBUGP("SGS_LEFT %u %02X\n", rh->segments_left, rh->segments_left); 81 pr_debug("SGS_LEFT %u %02X\n", rh->segments_left, rh->segments_left);
86 82
87 DEBUGP("IPv6 RT segsleft %02X ", 83 pr_debug("IPv6 RT segsleft %02X ",
88 (segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1], 84 segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1],
89 rh->segments_left, 85 rh->segments_left,
90 !!(rtinfo->invflags & IP6T_RT_INV_SGS)))); 86 !!(rtinfo->invflags & IP6T_RT_INV_SGS)));
91 DEBUGP("type %02X %02X %02X ", 87 pr_debug("type %02X %02X %02X ",
92 rtinfo->rt_type, rh->type, 88 rtinfo->rt_type, rh->type,
93 (!(rtinfo->flags & IP6T_RT_TYP) || 89 (!(rtinfo->flags & IP6T_RT_TYP) ||
94 ((rtinfo->rt_type == rh->type) ^ 90 ((rtinfo->rt_type == rh->type) ^
95 !!(rtinfo->invflags & IP6T_RT_INV_TYP)))); 91 !!(rtinfo->invflags & IP6T_RT_INV_TYP))));
96 DEBUGP("len %02X %04X %02X ", 92 pr_debug("len %02X %04X %02X ",
97 rtinfo->hdrlen, hdrlen, 93 rtinfo->hdrlen, hdrlen,
98 (!(rtinfo->flags & IP6T_RT_LEN) || 94 !(rtinfo->flags & IP6T_RT_LEN) ||
99 ((rtinfo->hdrlen == hdrlen) ^ 95 ((rtinfo->hdrlen == hdrlen) ^
100 !!(rtinfo->invflags & IP6T_RT_INV_LEN)))); 96 !!(rtinfo->invflags & IP6T_RT_INV_LEN)));
101 DEBUGP("res %02X %02X %02X ", 97 pr_debug("res %02X %02X %02X ",
102 (rtinfo->flags & IP6T_RT_RES), 98 rtinfo->flags & IP6T_RT_RES,
103 ((struct rt0_hdr *)rh)->reserved, 99 ((const struct rt0_hdr *)rh)->reserved,
104 !((rtinfo->flags & IP6T_RT_RES) && 100 !((rtinfo->flags & IP6T_RT_RES) &&
105 (((struct rt0_hdr *)rh)->reserved))); 101 (((const struct rt0_hdr *)rh)->reserved)));
106 102
107 ret = (rh != NULL) 103 ret = (rh != NULL)
108 && 104 &&
@@ -129,18 +125,18 @@ match(const struct sk_buff *skb,
129 ret = (*rp == 0); 125 ret = (*rp == 0);
130 } 126 }
131 127
132 DEBUGP("#%d ", rtinfo->addrnr); 128 pr_debug("#%d ", rtinfo->addrnr);
133 if (!(rtinfo->flags & IP6T_RT_FST)) { 129 if (!(rtinfo->flags & IP6T_RT_FST)) {
134 return ret; 130 return ret;
135 } else if (rtinfo->flags & IP6T_RT_FST_NSTRICT) { 131 } else if (rtinfo->flags & IP6T_RT_FST_NSTRICT) {
136 DEBUGP("Not strict "); 132 pr_debug("Not strict ");
137 if (rtinfo->addrnr > (unsigned int)((hdrlen - 8) / 16)) { 133 if (rtinfo->addrnr > (unsigned int)((hdrlen - 8) / 16)) {
138 DEBUGP("There isn't enough space\n"); 134 pr_debug("There isn't enough space\n");
139 return 0; 135 return false;
140 } else { 136 } else {
141 unsigned int i = 0; 137 unsigned int i = 0;
142 138
143 DEBUGP("#%d ", rtinfo->addrnr); 139 pr_debug("#%d ", rtinfo->addrnr);
144 for (temp = 0; 140 for (temp = 0;
145 temp < (unsigned int)((hdrlen - 8) / 16); 141 temp < (unsigned int)((hdrlen - 8) / 16);
146 temp++) { 142 temp++) {
@@ -154,25 +150,25 @@ match(const struct sk_buff *skb,
154 BUG_ON(ap == NULL); 150 BUG_ON(ap == NULL);
155 151
156 if (ipv6_addr_equal(ap, &rtinfo->addrs[i])) { 152 if (ipv6_addr_equal(ap, &rtinfo->addrs[i])) {
157 DEBUGP("i=%d temp=%d;\n", i, temp); 153 pr_debug("i=%d temp=%d;\n", i, temp);
158 i++; 154 i++;
159 } 155 }
160 if (i == rtinfo->addrnr) 156 if (i == rtinfo->addrnr)
161 break; 157 break;
162 } 158 }
163 DEBUGP("i=%d #%d\n", i, rtinfo->addrnr); 159 pr_debug("i=%d #%d\n", i, rtinfo->addrnr);
164 if (i == rtinfo->addrnr) 160 if (i == rtinfo->addrnr)
165 return ret; 161 return ret;
166 else 162 else
167 return 0; 163 return false;
168 } 164 }
169 } else { 165 } else {
170 DEBUGP("Strict "); 166 pr_debug("Strict ");
171 if (rtinfo->addrnr > (unsigned int)((hdrlen - 8) / 16)) { 167 if (rtinfo->addrnr > (unsigned int)((hdrlen - 8) / 16)) {
172 DEBUGP("There isn't enough space\n"); 168 pr_debug("There isn't enough space\n");
173 return 0; 169 return false;
174 } else { 170 } else {
175 DEBUGP("#%d ", rtinfo->addrnr); 171 pr_debug("#%d ", rtinfo->addrnr);
176 for (temp = 0; temp < rtinfo->addrnr; temp++) { 172 for (temp = 0; temp < rtinfo->addrnr; temp++) {
177 ap = skb_header_pointer(skb, 173 ap = skb_header_pointer(skb,
178 ptr 174 ptr
@@ -185,20 +181,20 @@ match(const struct sk_buff *skb,
185 if (!ipv6_addr_equal(ap, &rtinfo->addrs[temp])) 181 if (!ipv6_addr_equal(ap, &rtinfo->addrs[temp]))
186 break; 182 break;
187 } 183 }
188 DEBUGP("temp=%d #%d\n", temp, rtinfo->addrnr); 184 pr_debug("temp=%d #%d\n", temp, rtinfo->addrnr);
189 if ((temp == rtinfo->addrnr) && 185 if (temp == rtinfo->addrnr &&
190 (temp == (unsigned int)((hdrlen - 8) / 16))) 186 temp == (unsigned int)((hdrlen - 8) / 16))
191 return ret; 187 return ret;
192 else 188 else
193 return 0; 189 return false;
194 } 190 }
195 } 191 }
196 192
197 return 0; 193 return false;
198} 194}
199 195
200/* Called when user tries to insert an entry of this type. */ 196/* Called when user tries to insert an entry of this type. */
201static int 197static bool
202checkentry(const char *tablename, 198checkentry(const char *tablename,
203 const void *entry, 199 const void *entry,
204 const struct xt_match *match, 200 const struct xt_match *match,
@@ -208,21 +204,21 @@ checkentry(const char *tablename,
208 const struct ip6t_rt *rtinfo = matchinfo; 204 const struct ip6t_rt *rtinfo = matchinfo;
209 205
210 if (rtinfo->invflags & ~IP6T_RT_INV_MASK) { 206 if (rtinfo->invflags & ~IP6T_RT_INV_MASK) {
211 DEBUGP("ip6t_rt: unknown flags %X\n", rtinfo->invflags); 207 pr_debug("ip6t_rt: unknown flags %X\n", rtinfo->invflags);
212 return 0; 208 return false;
213 } 209 }
214 if ((rtinfo->flags & (IP6T_RT_RES | IP6T_RT_FST_MASK)) && 210 if ((rtinfo->flags & (IP6T_RT_RES | IP6T_RT_FST_MASK)) &&
215 (!(rtinfo->flags & IP6T_RT_TYP) || 211 (!(rtinfo->flags & IP6T_RT_TYP) ||
216 (rtinfo->rt_type != 0) || 212 (rtinfo->rt_type != 0) ||
217 (rtinfo->invflags & IP6T_RT_INV_TYP))) { 213 (rtinfo->invflags & IP6T_RT_INV_TYP))) {
218 DEBUGP("`--rt-type 0' required before `--rt-0-*'"); 214 pr_debug("`--rt-type 0' required before `--rt-0-*'");
219 return 0; 215 return false;
220 } 216 }
221 217
222 return 1; 218 return true;
223} 219}
224 220
225static struct xt_match rt_match = { 221static struct xt_match rt_match __read_mostly = {
226 .name = "rt", 222 .name = "rt",
227 .family = AF_INET6, 223 .family = AF_INET6,
228 .match = match, 224 .match = match,
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index f2d26495f413..f0a9efa67fb5 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -21,12 +21,6 @@ MODULE_DESCRIPTION("ip6tables mangle table");
21 (1 << NF_IP6_LOCAL_OUT) | \ 21 (1 << NF_IP6_LOCAL_OUT) | \
22 (1 << NF_IP6_POST_ROUTING)) 22 (1 << NF_IP6_POST_ROUTING))
23 23
24#if 0
25#define DEBUGP(x, args...) printk(KERN_DEBUG x, ## args)
26#else
27#define DEBUGP(x, args...)
28#endif
29
30static struct 24static struct
31{ 25{
32 struct ip6t_replace repl; 26 struct ip6t_replace repl;
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index 0acda45d455d..ec290e4ebdd8 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -8,12 +8,6 @@
8 8
9#define RAW_VALID_HOOKS ((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_OUT)) 9#define RAW_VALID_HOOKS ((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_OUT))
10 10
11#if 0
12#define DEBUGP(x, args...) printk(KERN_DEBUG x, ## args)
13#else
14#define DEBUGP(x, args...)
15#endif
16
17static struct 11static struct
18{ 12{
19 struct ip6t_replace repl; 13 struct ip6t_replace repl;
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 1b1797f1f33d..89e20ab494b8 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -26,12 +26,6 @@
26#include <net/netfilter/nf_conntrack_l3proto.h> 26#include <net/netfilter/nf_conntrack_l3proto.h>
27#include <net/netfilter/nf_conntrack_core.h> 27#include <net/netfilter/nf_conntrack_core.h>
28 28
29#if 0
30#define DEBUGP printk
31#else
32#define DEBUGP(format, args...)
33#endif
34
35static int ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, 29static int ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
36 struct nf_conntrack_tuple *tuple) 30 struct nf_conntrack_tuple *tuple)
37{ 31{
@@ -136,7 +130,7 @@ ipv6_prepare(struct sk_buff **pskb, unsigned int hooknum, unsigned int *dataoff,
136 * except of IPv6 & ext headers. but it's tracked anyway. - YK 130 * except of IPv6 & ext headers. but it's tracked anyway. - YK
137 */ 131 */
138 if ((protoff < 0) || (protoff > (*pskb)->len)) { 132 if ((protoff < 0) || (protoff > (*pskb)->len)) {
139 DEBUGP("ip6_conntrack_core: can't find proto in pkt\n"); 133 pr_debug("ip6_conntrack_core: can't find proto in pkt\n");
140 NF_CT_STAT_INC_ATOMIC(error); 134 NF_CT_STAT_INC_ATOMIC(error);
141 NF_CT_STAT_INC_ATOMIC(invalid); 135 NF_CT_STAT_INC_ATOMIC(invalid);
142 return -NF_ACCEPT; 136 return -NF_ACCEPT;
@@ -147,11 +141,6 @@ ipv6_prepare(struct sk_buff **pskb, unsigned int hooknum, unsigned int *dataoff,
147 return NF_ACCEPT; 141 return NF_ACCEPT;
148} 142}
149 143
150static u_int32_t ipv6_get_features(const struct nf_conntrack_tuple *tuple)
151{
152 return NF_CT_F_BASIC;
153}
154
155static unsigned int ipv6_confirm(unsigned int hooknum, 144static unsigned int ipv6_confirm(unsigned int hooknum,
156 struct sk_buff **pskb, 145 struct sk_buff **pskb,
157 const struct net_device *in, 146 const struct net_device *in,
@@ -183,7 +172,7 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
183 protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum, 172 protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum,
184 (*pskb)->len - extoff); 173 (*pskb)->len - extoff);
185 if (protoff > (*pskb)->len || pnum == NEXTHDR_FRAGMENT) { 174 if (protoff > (*pskb)->len || pnum == NEXTHDR_FRAGMENT) {
186 DEBUGP("proto header not found\n"); 175 pr_debug("proto header not found\n");
187 return NF_ACCEPT; 176 return NF_ACCEPT;
188 } 177 }
189 178
@@ -397,7 +386,6 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 = {
397 .ctl_table_path = nf_net_netfilter_sysctl_path, 386 .ctl_table_path = nf_net_netfilter_sysctl_path,
398 .ctl_table = nf_ct_ipv6_sysctl_table, 387 .ctl_table = nf_ct_ipv6_sysctl_table,
399#endif 388#endif
400 .get_features = ipv6_get_features,
401 .me = THIS_MODULE, 389 .me = THIS_MODULE,
402}; 390};
403 391
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 8814b95b2326..9defc7e14554 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -27,12 +27,6 @@
27 27
28static unsigned long nf_ct_icmpv6_timeout __read_mostly = 30*HZ; 28static unsigned long nf_ct_icmpv6_timeout __read_mostly = 30*HZ;
29 29
30#if 0
31#define DEBUGP printk
32#else
33#define DEBUGP(format, args...)
34#endif
35
36static int icmpv6_pkt_to_tuple(const struct sk_buff *skb, 30static int icmpv6_pkt_to_tuple(const struct sk_buff *skb,
37 unsigned int dataoff, 31 unsigned int dataoff,
38 struct nf_conntrack_tuple *tuple) 32 struct nf_conntrack_tuple *tuple)
@@ -125,8 +119,8 @@ static int icmpv6_new(struct nf_conn *conntrack,
125 119
126 if (type < 0 || type >= sizeof(valid_new) || !valid_new[type]) { 120 if (type < 0 || type >= sizeof(valid_new) || !valid_new[type]) {
127 /* Can't create a new ICMPv6 `conn' with this. */ 121 /* Can't create a new ICMPv6 `conn' with this. */
128 DEBUGP("icmpv6: can't create new conn with type %u\n", 122 pr_debug("icmpv6: can't create new conn with type %u\n",
129 type + 128); 123 type + 128);
130 NF_CT_DUMP_TUPLE(&conntrack->tuplehash[0].tuple); 124 NF_CT_DUMP_TUPLE(&conntrack->tuplehash[0].tuple);
131 return 0; 125 return 0;
132 } 126 }
@@ -152,14 +146,15 @@ icmpv6_error_message(struct sk_buff *skb,
152 146
153 hp = skb_header_pointer(skb, icmp6off, sizeof(_hdr), &_hdr); 147 hp = skb_header_pointer(skb, icmp6off, sizeof(_hdr), &_hdr);
154 if (hp == NULL) { 148 if (hp == NULL) {
155 DEBUGP("icmpv6_error: Can't get ICMPv6 hdr.\n"); 149 pr_debug("icmpv6_error: Can't get ICMPv6 hdr.\n");
156 return -NF_ACCEPT; 150 return -NF_ACCEPT;
157 } 151 }
158 152
159 inip6off = icmp6off + sizeof(_hdr); 153 inip6off = icmp6off + sizeof(_hdr);
160 if (skb_copy_bits(skb, inip6off+offsetof(struct ipv6hdr, nexthdr), 154 if (skb_copy_bits(skb, inip6off+offsetof(struct ipv6hdr, nexthdr),
161 &inprotonum, sizeof(inprotonum)) != 0) { 155 &inprotonum, sizeof(inprotonum)) != 0) {
162 DEBUGP("icmpv6_error: Can't get nexthdr in inner IPv6 header.\n"); 156 pr_debug("icmpv6_error: Can't get nexthdr in inner IPv6 "
157 "header.\n");
163 return -NF_ACCEPT; 158 return -NF_ACCEPT;
164 } 159 }
165 inprotoff = nf_ct_ipv6_skip_exthdr(skb, 160 inprotoff = nf_ct_ipv6_skip_exthdr(skb,
@@ -169,7 +164,8 @@ icmpv6_error_message(struct sk_buff *skb,
169 - sizeof(struct ipv6hdr)); 164 - sizeof(struct ipv6hdr));
170 165
171 if ((inprotoff > skb->len) || (inprotonum == NEXTHDR_FRAGMENT)) { 166 if ((inprotoff > skb->len) || (inprotonum == NEXTHDR_FRAGMENT)) {
172 DEBUGP("icmpv6_error: Can't get protocol header in ICMPv6 payload.\n"); 167 pr_debug("icmpv6_error: Can't get protocol header in ICMPv6 "
168 "payload.\n");
173 return -NF_ACCEPT; 169 return -NF_ACCEPT;
174 } 170 }
175 171
@@ -179,7 +175,7 @@ icmpv6_error_message(struct sk_buff *skb,
179 /* Are they talking about one of our connections? */ 175 /* Are they talking about one of our connections? */
180 if (!nf_ct_get_tuple(skb, inip6off, inprotoff, PF_INET6, inprotonum, 176 if (!nf_ct_get_tuple(skb, inip6off, inprotoff, PF_INET6, inprotonum,
181 &origtuple, &nf_conntrack_l3proto_ipv6, inproto)) { 177 &origtuple, &nf_conntrack_l3proto_ipv6, inproto)) {
182 DEBUGP("icmpv6_error: Can't get tuple\n"); 178 pr_debug("icmpv6_error: Can't get tuple\n");
183 return -NF_ACCEPT; 179 return -NF_ACCEPT;
184 } 180 }
185 181
@@ -187,15 +183,15 @@ icmpv6_error_message(struct sk_buff *skb,
187 been preserved inside the ICMP. */ 183 been preserved inside the ICMP. */
188 if (!nf_ct_invert_tuple(&intuple, &origtuple, 184 if (!nf_ct_invert_tuple(&intuple, &origtuple,
189 &nf_conntrack_l3proto_ipv6, inproto)) { 185 &nf_conntrack_l3proto_ipv6, inproto)) {
190 DEBUGP("icmpv6_error: Can't invert tuple\n"); 186 pr_debug("icmpv6_error: Can't invert tuple\n");
191 return -NF_ACCEPT; 187 return -NF_ACCEPT;
192 } 188 }
193 189
194 *ctinfo = IP_CT_RELATED; 190 *ctinfo = IP_CT_RELATED;
195 191
196 h = nf_conntrack_find_get(&intuple, NULL); 192 h = nf_conntrack_find_get(&intuple);
197 if (!h) { 193 if (!h) {
198 DEBUGP("icmpv6_error: no match\n"); 194 pr_debug("icmpv6_error: no match\n");
199 return -NF_ACCEPT; 195 return -NF_ACCEPT;
200 } else { 196 } else {
201 if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY) 197 if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY)
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 347ab7608231..25442a8c1ba8 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -44,12 +44,6 @@
44#include <linux/kernel.h> 44#include <linux/kernel.h>
45#include <linux/module.h> 45#include <linux/module.h>
46 46
47#if 0
48#define DEBUGP printk
49#else
50#define DEBUGP(format, args...)
51#endif
52
53#define NF_CT_FRAG6_HIGH_THRESH 262144 /* == 256*1024 */ 47#define NF_CT_FRAG6_HIGH_THRESH 262144 /* == 256*1024 */
54#define NF_CT_FRAG6_LOW_THRESH 196608 /* == 192*1024 */ 48#define NF_CT_FRAG6_LOW_THRESH 196608 /* == 192*1024 */
55#define NF_CT_FRAG6_TIMEOUT IPV6_FRAG_TIMEOUT 49#define NF_CT_FRAG6_TIMEOUT IPV6_FRAG_TIMEOUT
@@ -343,7 +337,7 @@ nf_ct_frag6_create(unsigned int hash, __be32 id, struct in6_addr *src, str
343 struct nf_ct_frag6_queue *fq; 337 struct nf_ct_frag6_queue *fq;
344 338
345 if ((fq = frag_alloc_queue()) == NULL) { 339 if ((fq = frag_alloc_queue()) == NULL) {
346 DEBUGP("Can't alloc new queue\n"); 340 pr_debug("Can't alloc new queue\n");
347 goto oom; 341 goto oom;
348 } 342 }
349 343
@@ -393,7 +387,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
393 int offset, end; 387 int offset, end;
394 388
395 if (fq->last_in & COMPLETE) { 389 if (fq->last_in & COMPLETE) {
396 DEBUGP("Allready completed\n"); 390 pr_debug("Allready completed\n");
397 goto err; 391 goto err;
398 } 392 }
399 393
@@ -402,7 +396,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
402 ((u8 *)(fhdr + 1) - (u8 *)(ipv6_hdr(skb) + 1))); 396 ((u8 *)(fhdr + 1) - (u8 *)(ipv6_hdr(skb) + 1)));
403 397
404 if ((unsigned int)end > IPV6_MAXPLEN) { 398 if ((unsigned int)end > IPV6_MAXPLEN) {
405 DEBUGP("offset is too large.\n"); 399 pr_debug("offset is too large.\n");
406 return -1; 400 return -1;
407 } 401 }
408 402
@@ -420,7 +414,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
420 */ 414 */
421 if (end < fq->len || 415 if (end < fq->len ||
422 ((fq->last_in & LAST_IN) && end != fq->len)) { 416 ((fq->last_in & LAST_IN) && end != fq->len)) {
423 DEBUGP("already received last fragment\n"); 417 pr_debug("already received last fragment\n");
424 goto err; 418 goto err;
425 } 419 }
426 fq->last_in |= LAST_IN; 420 fq->last_in |= LAST_IN;
@@ -433,13 +427,13 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
433 /* RFC2460 says always send parameter problem in 427 /* RFC2460 says always send parameter problem in
434 * this case. -DaveM 428 * this case. -DaveM
435 */ 429 */
436 DEBUGP("the end of this fragment is not rounded to 8 bytes.\n"); 430 pr_debug("end of fragment not rounded to 8 bytes.\n");
437 return -1; 431 return -1;
438 } 432 }
439 if (end > fq->len) { 433 if (end > fq->len) {
440 /* Some bits beyond end -> corruption. */ 434 /* Some bits beyond end -> corruption. */
441 if (fq->last_in & LAST_IN) { 435 if (fq->last_in & LAST_IN) {
442 DEBUGP("last packet already reached.\n"); 436 pr_debug("last packet already reached.\n");
443 goto err; 437 goto err;
444 } 438 }
445 fq->len = end; 439 fq->len = end;
@@ -451,11 +445,11 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
451 445
452 /* Point into the IP datagram 'data' part. */ 446 /* Point into the IP datagram 'data' part. */
453 if (!pskb_pull(skb, (u8 *) (fhdr + 1) - skb->data)) { 447 if (!pskb_pull(skb, (u8 *) (fhdr + 1) - skb->data)) {
454 DEBUGP("queue: message is too short.\n"); 448 pr_debug("queue: message is too short.\n");
455 goto err; 449 goto err;
456 } 450 }
457 if (pskb_trim_rcsum(skb, end - offset)) { 451 if (pskb_trim_rcsum(skb, end - offset)) {
458 DEBUGP("Can't trim\n"); 452 pr_debug("Can't trim\n");
459 goto err; 453 goto err;
460 } 454 }
461 455
@@ -480,11 +474,11 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
480 if (i > 0) { 474 if (i > 0) {
481 offset += i; 475 offset += i;
482 if (end <= offset) { 476 if (end <= offset) {
483 DEBUGP("overlap\n"); 477 pr_debug("overlap\n");
484 goto err; 478 goto err;
485 } 479 }
486 if (!pskb_pull(skb, i)) { 480 if (!pskb_pull(skb, i)) {
487 DEBUGP("Can't pull\n"); 481 pr_debug("Can't pull\n");
488 goto err; 482 goto err;
489 } 483 }
490 if (skb->ip_summed != CHECKSUM_UNNECESSARY) 484 if (skb->ip_summed != CHECKSUM_UNNECESSARY)
@@ -503,7 +497,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
503 /* Eat head of the next overlapped fragment 497 /* Eat head of the next overlapped fragment
504 * and leave the loop. The next ones cannot overlap. 498 * and leave the loop. The next ones cannot overlap.
505 */ 499 */
506 DEBUGP("Eat head of the overlapped parts.: %d", i); 500 pr_debug("Eat head of the overlapped parts.: %d", i);
507 if (!pskb_pull(next, i)) 501 if (!pskb_pull(next, i))
508 goto err; 502 goto err;
509 503
@@ -586,13 +580,13 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
586 sizeof(struct ipv6hdr) + fq->len - 580 sizeof(struct ipv6hdr) + fq->len -
587 sizeof(struct frag_hdr)); 581 sizeof(struct frag_hdr));
588 if (payload_len > IPV6_MAXPLEN) { 582 if (payload_len > IPV6_MAXPLEN) {
589 DEBUGP("payload len is too large.\n"); 583 pr_debug("payload len is too large.\n");
590 goto out_oversize; 584 goto out_oversize;
591 } 585 }
592 586
593 /* Head of list must not be cloned. */ 587 /* Head of list must not be cloned. */
594 if (skb_cloned(head) && pskb_expand_head(head, 0, 0, GFP_ATOMIC)) { 588 if (skb_cloned(head) && pskb_expand_head(head, 0, 0, GFP_ATOMIC)) {
595 DEBUGP("skb is cloned but can't expand head"); 589 pr_debug("skb is cloned but can't expand head");
596 goto out_oom; 590 goto out_oom;
597 } 591 }
598 592
@@ -604,7 +598,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
604 int i, plen = 0; 598 int i, plen = 0;
605 599
606 if ((clone = alloc_skb(0, GFP_ATOMIC)) == NULL) { 600 if ((clone = alloc_skb(0, GFP_ATOMIC)) == NULL) {
607 DEBUGP("Can't alloc skb\n"); 601 pr_debug("Can't alloc skb\n");
608 goto out_oom; 602 goto out_oom;
609 } 603 }
610 clone->next = head->next; 604 clone->next = head->next;
@@ -719,11 +713,11 @@ find_prev_fhdr(struct sk_buff *skb, u8 *prevhdrp, int *prevhoff, int *fhoff)
719 return -1; 713 return -1;
720 } 714 }
721 if (len < (int)sizeof(struct ipv6_opt_hdr)) { 715 if (len < (int)sizeof(struct ipv6_opt_hdr)) {
722 DEBUGP("too short\n"); 716 pr_debug("too short\n");
723 return -1; 717 return -1;
724 } 718 }
725 if (nexthdr == NEXTHDR_NONE) { 719 if (nexthdr == NEXTHDR_NONE) {
726 DEBUGP("next header is none\n"); 720 pr_debug("next header is none\n");
727 return -1; 721 return -1;
728 } 722 }
729 if (skb_copy_bits(skb, start, &hdr, sizeof(hdr))) 723 if (skb_copy_bits(skb, start, &hdr, sizeof(hdr)))
@@ -764,7 +758,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
764 758
765 /* Jumbo payload inhibits frag. header */ 759 /* Jumbo payload inhibits frag. header */
766 if (ipv6_hdr(skb)->payload_len == 0) { 760 if (ipv6_hdr(skb)->payload_len == 0) {
767 DEBUGP("payload len = 0\n"); 761 pr_debug("payload len = 0\n");
768 return skb; 762 return skb;
769 } 763 }
770 764
@@ -773,14 +767,14 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
773 767
774 clone = skb_clone(skb, GFP_ATOMIC); 768 clone = skb_clone(skb, GFP_ATOMIC);
775 if (clone == NULL) { 769 if (clone == NULL) {
776 DEBUGP("Can't clone skb\n"); 770 pr_debug("Can't clone skb\n");
777 return skb; 771 return skb;
778 } 772 }
779 773
780 NFCT_FRAG6_CB(clone)->orig = skb; 774 NFCT_FRAG6_CB(clone)->orig = skb;
781 775
782 if (!pskb_may_pull(clone, fhoff + sizeof(*fhdr))) { 776 if (!pskb_may_pull(clone, fhoff + sizeof(*fhdr))) {
783 DEBUGP("message is too short.\n"); 777 pr_debug("message is too short.\n");
784 goto ret_orig; 778 goto ret_orig;
785 } 779 }
786 780
@@ -789,7 +783,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
789 fhdr = (struct frag_hdr *)skb_transport_header(clone); 783 fhdr = (struct frag_hdr *)skb_transport_header(clone);
790 784
791 if (!(fhdr->frag_off & htons(0xFFF9))) { 785 if (!(fhdr->frag_off & htons(0xFFF9))) {
792 DEBUGP("Invalid fragment offset\n"); 786 pr_debug("Invalid fragment offset\n");
793 /* It is not a fragmented frame */ 787 /* It is not a fragmented frame */
794 goto ret_orig; 788 goto ret_orig;
795 } 789 }
@@ -799,7 +793,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
799 793
800 fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr); 794 fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr);
801 if (fq == NULL) { 795 if (fq == NULL) {
802 DEBUGP("Can't find and can't create new queue\n"); 796 pr_debug("Can't find and can't create new queue\n");
803 goto ret_orig; 797 goto ret_orig;
804 } 798 }
805 799
@@ -807,7 +801,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
807 801
808 if (nf_ct_frag6_queue(fq, clone, fhdr, nhoff) < 0) { 802 if (nf_ct_frag6_queue(fq, clone, fhdr, nhoff) < 0) {
809 spin_unlock(&fq->lock); 803 spin_unlock(&fq->lock);
810 DEBUGP("Can't insert skb to queue\n"); 804 pr_debug("Can't insert skb to queue\n");
811 fq_put(fq, NULL); 805 fq_put(fq, NULL);
812 goto ret_orig; 806 goto ret_orig;
813 } 807 }
@@ -815,7 +809,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
815 if (fq->last_in == (FIRST_IN|LAST_IN) && fq->meat == fq->len) { 809 if (fq->last_in == (FIRST_IN|LAST_IN) && fq->meat == fq->len) {
816 ret_skb = nf_ct_frag6_reasm(fq, dev); 810 ret_skb = nf_ct_frag6_reasm(fq, dev);
817 if (ret_skb == NULL) 811 if (ret_skb == NULL)
818 DEBUGP("Can't reassemble fragmented packets\n"); 812 pr_debug("Can't reassemble fragmented packets\n");
819 } 813 }
820 spin_unlock(&fq->lock); 814 spin_unlock(&fq->lock);
821 815
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index a58459a76684..e27383d855de 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -49,7 +49,7 @@
49#include <net/udp.h> 49#include <net/udp.h>
50#include <net/inet_common.h> 50#include <net/inet_common.h>
51#include <net/tcp_states.h> 51#include <net/tcp_states.h>
52#ifdef CONFIG_IPV6_MIP6 52#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
53#include <net/mip6.h> 53#include <net/mip6.h>
54#endif 54#endif
55 55
@@ -137,6 +137,28 @@ static __inline__ int icmpv6_filter(struct sock *sk, struct sk_buff *skb)
137 return 0; 137 return 0;
138} 138}
139 139
140#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
141static int (*mh_filter)(struct sock *sock, struct sk_buff *skb);
142
143int rawv6_mh_filter_register(int (*filter)(struct sock *sock,
144 struct sk_buff *skb))
145{
146 rcu_assign_pointer(mh_filter, filter);
147 return 0;
148}
149EXPORT_SYMBOL(rawv6_mh_filter_register);
150
151int rawv6_mh_filter_unregister(int (*filter)(struct sock *sock,
152 struct sk_buff *skb))
153{
154 rcu_assign_pointer(mh_filter, NULL);
155 synchronize_rcu();
156 return 0;
157}
158EXPORT_SYMBOL(rawv6_mh_filter_unregister);
159
160#endif
161
140/* 162/*
141 * demultiplex raw sockets. 163 * demultiplex raw sockets.
142 * (should consider queueing the skb in the sock receive_queue 164 * (should consider queueing the skb in the sock receive_queue
@@ -178,16 +200,22 @@ int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
178 case IPPROTO_ICMPV6: 200 case IPPROTO_ICMPV6:
179 filtered = icmpv6_filter(sk, skb); 201 filtered = icmpv6_filter(sk, skb);
180 break; 202 break;
181#ifdef CONFIG_IPV6_MIP6 203
204#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
182 case IPPROTO_MH: 205 case IPPROTO_MH:
206 {
183 /* XXX: To validate MH only once for each packet, 207 /* XXX: To validate MH only once for each packet,
184 * this is placed here. It should be after checking 208 * this is placed here. It should be after checking
185 * xfrm policy, however it doesn't. The checking xfrm 209 * xfrm policy, however it doesn't. The checking xfrm
186 * policy is placed in rawv6_rcv() because it is 210 * policy is placed in rawv6_rcv() because it is
187 * required for each socket. 211 * required for each socket.
188 */ 212 */
189 filtered = mip6_mh_filter(sk, skb); 213 int (*filter)(struct sock *sock, struct sk_buff *skb);
214
215 filter = rcu_dereference(mh_filter);
216 filtered = filter ? filter(sk, skb) : 0;
190 break; 217 break;
218 }
191#endif 219#endif
192 default: 220 default:
193 filtered = 0; 221 filtered = 0;
@@ -611,9 +639,7 @@ static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
611 struct iovec *iov; 639 struct iovec *iov;
612 u8 __user *type = NULL; 640 u8 __user *type = NULL;
613 u8 __user *code = NULL; 641 u8 __user *code = NULL;
614#ifdef CONFIG_IPV6_MIP6
615 u8 len = 0; 642 u8 len = 0;
616#endif
617 int probed = 0; 643 int probed = 0;
618 int i; 644 int i;
619 645
@@ -646,7 +672,6 @@ static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
646 probed = 1; 672 probed = 1;
647 } 673 }
648 break; 674 break;
649#ifdef CONFIG_IPV6_MIP6
650 case IPPROTO_MH: 675 case IPPROTO_MH:
651 if (iov->iov_base && iov->iov_len < 1) 676 if (iov->iov_base && iov->iov_len < 1)
652 break; 677 break;
@@ -660,7 +685,6 @@ static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
660 len += iov->iov_len; 685 len += iov->iov_len;
661 686
662 break; 687 break;
663#endif
664 default: 688 default:
665 probed = 1; 689 probed = 1;
666 break; 690 break;
@@ -1256,7 +1280,7 @@ static int raw6_seq_show(struct seq_file *seq, void *v)
1256 return 0; 1280 return 0;
1257} 1281}
1258 1282
1259static struct seq_operations raw6_seq_ops = { 1283static const struct seq_operations raw6_seq_ops = {
1260 .start = raw6_seq_start, 1284 .start = raw6_seq_start,
1261 .next = raw6_seq_next, 1285 .next = raw6_seq_next,
1262 .stop = raw6_seq_stop, 1286 .stop = raw6_seq_stop,
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 1efa95a99f45..eb20bb690abd 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -532,7 +532,8 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
532 */ 532 */
533 max_headroom = LL_RESERVED_SPACE(tdev)+sizeof(struct iphdr); 533 max_headroom = LL_RESERVED_SPACE(tdev)+sizeof(struct iphdr);
534 534
535 if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) { 535 if (skb_headroom(skb) < max_headroom || skb_shared(skb) ||
536 (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
536 struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); 537 struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
537 if (!new_skb) { 538 if (!new_skb) {
538 ip_rt_put(rt); 539 ip_rt_put(rt);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 193d9d60bb7a..d67fb1ef751e 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -484,17 +484,6 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
484 484
485 if (dst == NULL) { 485 if (dst == NULL) {
486 opt = np->opt; 486 opt = np->opt;
487 if (opt == NULL &&
488 np->rxopt.bits.osrcrt == 2 &&
489 treq->pktopts) {
490 struct sk_buff *pktopts = treq->pktopts;
491 struct inet6_skb_parm *rxopt = IP6CB(pktopts);
492 if (rxopt->srcrt)
493 opt = ipv6_invert_rthdr(sk,
494 (struct ipv6_rt_hdr *)(skb_network_header(pktopts) +
495 rxopt->srcrt));
496 }
497
498 if (opt && opt->srcrt) { 487 if (opt && opt->srcrt) {
499 struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt; 488 struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
500 ipv6_addr_copy(&final, &fl.fl6_dst); 489 ipv6_addr_copy(&final, &fl.fl6_dst);
@@ -1391,15 +1380,6 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1391 if (sk_acceptq_is_full(sk)) 1380 if (sk_acceptq_is_full(sk))
1392 goto out_overflow; 1381 goto out_overflow;
1393 1382
1394 if (np->rxopt.bits.osrcrt == 2 &&
1395 opt == NULL && treq->pktopts) {
1396 struct inet6_skb_parm *rxopt = IP6CB(treq->pktopts);
1397 if (rxopt->srcrt)
1398 opt = ipv6_invert_rthdr(sk,
1399 (struct ipv6_rt_hdr *)(skb_network_header(treq->pktopts) +
1400 rxopt->srcrt));
1401 }
1402
1403 if (dst == NULL) { 1383 if (dst == NULL) {
1404 struct in6_addr *final_p = NULL, final; 1384 struct in6_addr *final_p = NULL, final;
1405 struct flowi fl; 1385 struct flowi fl;
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 1faa2ea80afc..3ec0c4770ee3 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -18,7 +18,7 @@
18#include <net/ip.h> 18#include <net/ip.h>
19#include <net/ipv6.h> 19#include <net/ipv6.h>
20#include <net/ip6_route.h> 20#include <net/ip6_route.h>
21#ifdef CONFIG_IPV6_MIP6 21#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
22#include <net/mip6.h> 22#include <net/mip6.h>
23#endif 23#endif
24 24
@@ -318,7 +318,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl)
318 fl->proto = nexthdr; 318 fl->proto = nexthdr;
319 return; 319 return;
320 320
321#ifdef CONFIG_IPV6_MIP6 321#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
322 case IPPROTO_MH: 322 case IPPROTO_MH:
323 if (pskb_may_pull(skb, nh + offset + 3 - skb->data)) { 323 if (pskb_may_pull(skb, nh + offset + 3 - skb->data)) {
324 struct ip6_mh *mh; 324 struct ip6_mh *mh;
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
index baa461b9f74e..cdadb4847469 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -65,7 +65,7 @@ __xfrm6_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n)
65 goto end; 65 goto end;
66 66
67 /* Rule 2: select MIPv6 RO or inbound trigger */ 67 /* Rule 2: select MIPv6 RO or inbound trigger */
68#ifdef CONFIG_IPV6_MIP6 68#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
69 for (i = 0; i < n; i++) { 69 for (i = 0; i < n; i++) {
70 if (src[i] && 70 if (src[i] &&
71 (src[i]->props.mode == XFRM_MODE_ROUTEOPTIMIZATION || 71 (src[i]->props.mode == XFRM_MODE_ROUTEOPTIMIZATION ||
@@ -130,7 +130,7 @@ __xfrm6_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n)
130 goto end; 130 goto end;
131 131
132 /* Rule 2: select MIPv6 RO or inbound trigger */ 132 /* Rule 2: select MIPv6 RO or inbound trigger */
133#ifdef CONFIG_IPV6_MIP6 133#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
134 for (i = 0; i < n; i++) { 134 for (i = 0; i < n; i++) {
135 if (src[i] && 135 if (src[i] &&
136 (src[i]->mode == XFRM_MODE_ROUTEOPTIMIZATION || 136 (src[i]->mode == XFRM_MODE_ROUTEOPTIMIZATION ||
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 5502cc948dfb..6f87dd568ded 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -379,3 +379,4 @@ static void __exit xfrm6_tunnel_fini(void)
379module_init(xfrm6_tunnel_init); 379module_init(xfrm6_tunnel_init);
380module_exit(xfrm6_tunnel_fini); 380module_exit(xfrm6_tunnel_fini);
381MODULE_LICENSE("GPL"); 381MODULE_LICENSE("GPL");
382MODULE_ALIAS_XFRM_TYPE(AF_INET6, XFRM_PROTO_IPV6);
diff --git a/net/ipx/ipx_proc.c b/net/ipx/ipx_proc.c
index db32ac8e79bd..4226e71ae1e3 100644
--- a/net/ipx/ipx_proc.c
+++ b/net/ipx/ipx_proc.c
@@ -286,21 +286,21 @@ out:
286 return 0; 286 return 0;
287} 287}
288 288
289static struct seq_operations ipx_seq_interface_ops = { 289static const struct seq_operations ipx_seq_interface_ops = {
290 .start = ipx_seq_interface_start, 290 .start = ipx_seq_interface_start,
291 .next = ipx_seq_interface_next, 291 .next = ipx_seq_interface_next,
292 .stop = ipx_seq_interface_stop, 292 .stop = ipx_seq_interface_stop,
293 .show = ipx_seq_interface_show, 293 .show = ipx_seq_interface_show,
294}; 294};
295 295
296static struct seq_operations ipx_seq_route_ops = { 296static const struct seq_operations ipx_seq_route_ops = {
297 .start = ipx_seq_route_start, 297 .start = ipx_seq_route_start,
298 .next = ipx_seq_route_next, 298 .next = ipx_seq_route_next,
299 .stop = ipx_seq_route_stop, 299 .stop = ipx_seq_route_stop,
300 .show = ipx_seq_route_show, 300 .show = ipx_seq_route_show,
301}; 301};
302 302
303static struct seq_operations ipx_seq_socket_ops = { 303static const struct seq_operations ipx_seq_socket_ops = {
304 .start = ipx_seq_socket_start, 304 .start = ipx_seq_socket_start,
305 .next = ipx_seq_socket_next, 305 .next = ipx_seq_socket_next,
306 .stop = ipx_seq_interface_stop, 306 .stop = ipx_seq_interface_stop,
diff --git a/net/irda/Makefile b/net/irda/Makefile
index d1366c2a39cb..187f6c563a4b 100644
--- a/net/irda/Makefile
+++ b/net/irda/Makefile
@@ -10,6 +10,6 @@ obj-$(CONFIG_IRCOMM) += ircomm/
10irda-y := iriap.o iriap_event.o irlmp.o irlmp_event.o irlmp_frame.o \ 10irda-y := iriap.o iriap_event.o irlmp.o irlmp_event.o irlmp_frame.o \
11 irlap.o irlap_event.o irlap_frame.o timer.o qos.o irqueue.o \ 11 irlap.o irlap_event.o irlap_frame.o timer.o qos.o irqueue.o \
12 irttp.o irda_device.o irias_object.o wrapper.o af_irda.o \ 12 irttp.o irda_device.o irias_object.o wrapper.o af_irda.o \
13 discovery.o parameters.o irmod.o 13 discovery.o parameters.o irnetlink.o irmod.o
14irda-$(CONFIG_PROC_FS) += irproc.o 14irda-$(CONFIG_PROC_FS) += irproc.o
15irda-$(CONFIG_SYSCTL) += irsysctl.o 15irda-$(CONFIG_SYSCTL) += irsysctl.o
diff --git a/net/irda/discovery.c b/net/irda/discovery.c
index f09734128674..af0cea721d2a 100644
--- a/net/irda/discovery.c
+++ b/net/irda/discovery.c
@@ -395,7 +395,7 @@ static int discovery_seq_show(struct seq_file *seq, void *v)
395 return 0; 395 return 0;
396} 396}
397 397
398static struct seq_operations discovery_seq_ops = { 398static const struct seq_operations discovery_seq_ops = {
399 .start = discovery_seq_start, 399 .start = discovery_seq_start,
400 .next = discovery_seq_next, 400 .next = discovery_seq_next,
401 .stop = discovery_seq_stop, 401 .stop = discovery_seq_stop,
diff --git a/net/irda/ircomm/ircomm_core.c b/net/irda/ircomm/ircomm_core.c
index 4749f8f55391..2d63fa8e1556 100644
--- a/net/irda/ircomm/ircomm_core.c
+++ b/net/irda/ircomm/ircomm_core.c
@@ -562,7 +562,7 @@ static int ircomm_seq_show(struct seq_file *seq, void *v)
562 return 0; 562 return 0;
563} 563}
564 564
565static struct seq_operations ircomm_seq_ops = { 565static const struct seq_operations ircomm_seq_ops = {
566 .start = ircomm_seq_start, 566 .start = ircomm_seq_start,
567 .next = ircomm_seq_next, 567 .next = ircomm_seq_next,
568 .stop = ircomm_seq_stop, 568 .stop = ircomm_seq_stop,
diff --git a/net/irda/iriap.c b/net/irda/iriap.c
index 915d9384f36a..774eb707940c 100644
--- a/net/irda/iriap.c
+++ b/net/irda/iriap.c
@@ -1066,7 +1066,7 @@ static int irias_seq_show(struct seq_file *seq, void *v)
1066 return 0; 1066 return 0;
1067} 1067}
1068 1068
1069static struct seq_operations irias_seq_ops = { 1069static const struct seq_operations irias_seq_ops = {
1070 .start = irias_seq_start, 1070 .start = irias_seq_start,
1071 .next = irias_seq_next, 1071 .next = irias_seq_next,
1072 .stop = irias_seq_stop, 1072 .stop = irias_seq_stop,
diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c
index ed69773b0f8e..f5778ef3ccc7 100644
--- a/net/irda/irlan/irlan_common.c
+++ b/net/irda/irlan/irlan_common.c
@@ -1217,7 +1217,7 @@ static int irlan_seq_show(struct seq_file *seq, void *v)
1217 return 0; 1217 return 0;
1218} 1218}
1219 1219
1220static struct seq_operations irlan_seq_ops = { 1220static const struct seq_operations irlan_seq_ops = {
1221 .start = irlan_seq_start, 1221 .start = irlan_seq_start,
1222 .next = irlan_seq_next, 1222 .next = irlan_seq_next,
1223 .stop = irlan_seq_stop, 1223 .stop = irlan_seq_stop,
diff --git a/net/irda/irlap.c b/net/irda/irlap.c
index d93ebd11431e..2fc9f518f89d 100644
--- a/net/irda/irlap.c
+++ b/net/irda/irlap.c
@@ -1210,7 +1210,7 @@ static int irlap_seq_show(struct seq_file *seq, void *v)
1210 return 0; 1210 return 0;
1211} 1211}
1212 1212
1213static struct seq_operations irlap_seq_ops = { 1213static const struct seq_operations irlap_seq_ops = {
1214 .start = irlap_seq_start, 1214 .start = irlap_seq_start,
1215 .next = irlap_seq_next, 1215 .next = irlap_seq_next,
1216 .stop = irlap_seq_stop, 1216 .stop = irlap_seq_stop,
diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c
index 3013c49ab975..25a3444a9234 100644
--- a/net/irda/irlap_frame.c
+++ b/net/irda/irlap_frame.c
@@ -101,6 +101,13 @@ void irlap_queue_xmit(struct irlap_cb *self, struct sk_buff *skb)
101 101
102 irlap_insert_info(self, skb); 102 irlap_insert_info(self, skb);
103 103
104 if (unlikely(self->mode & IRDA_MODE_MONITOR)) {
105 IRDA_DEBUG(3, "%s(): %s is in monitor mode\n", __FUNCTION__,
106 self->netdev->name);
107 dev_kfree_skb(skb);
108 return;
109 }
110
104 dev_queue_xmit(skb); 111 dev_queue_xmit(skb);
105} 112}
106 113
diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c
index 9df0461b6d18..24a5e3f23778 100644
--- a/net/irda/irlmp.c
+++ b/net/irda/irlmp.c
@@ -1994,7 +1994,7 @@ static int irlmp_seq_show(struct seq_file *seq, void *v)
1994 return 0; 1994 return 0;
1995} 1995}
1996 1996
1997static struct seq_operations irlmp_seq_ops = { 1997static const struct seq_operations irlmp_seq_ops = {
1998 .start = irlmp_seq_start, 1998 .start = irlmp_seq_start,
1999 .next = irlmp_seq_next, 1999 .next = irlmp_seq_next,
2000 .stop = irlmp_seq_stop, 2000 .stop = irlmp_seq_stop,
diff --git a/net/irda/irmod.c b/net/irda/irmod.c
index c7fad2c5b9f3..1900937b3328 100644
--- a/net/irda/irmod.c
+++ b/net/irda/irmod.c
@@ -88,16 +88,23 @@ EXPORT_SYMBOL(irda_notify_init);
88 */ 88 */
89static int __init irda_init(void) 89static int __init irda_init(void)
90{ 90{
91 int ret = 0;
92
91 IRDA_DEBUG(0, "%s()\n", __FUNCTION__); 93 IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
92 94
93 /* Lower layer of the stack */ 95 /* Lower layer of the stack */
94 irlmp_init(); 96 irlmp_init();
95 irlap_init(); 97 irlap_init();
96 98
99 /* Driver/dongle support */
100 irda_device_init();
101
97 /* Higher layers of the stack */ 102 /* Higher layers of the stack */
98 iriap_init(); 103 iriap_init();
99 irttp_init(); 104 irttp_init();
100 irsock_init(); 105 ret = irsock_init();
106 if (ret < 0)
107 goto out_err_1;
101 108
102 /* Add IrDA packet type (Start receiving packets) */ 109 /* Add IrDA packet type (Start receiving packets) */
103 dev_add_pack(&irda_packet_type); 110 dev_add_pack(&irda_packet_type);
@@ -107,13 +114,44 @@ static int __init irda_init(void)
107 irda_proc_register(); 114 irda_proc_register();
108#endif 115#endif
109#ifdef CONFIG_SYSCTL 116#ifdef CONFIG_SYSCTL
110 irda_sysctl_register(); 117 ret = irda_sysctl_register();
118 if (ret < 0)
119 goto out_err_2;
111#endif 120#endif
112 121
113 /* Driver/dongle support */ 122 ret = irda_nl_register();
114 irda_device_init(); 123 if (ret < 0)
124 goto out_err_3;
115 125
116 return 0; 126 return 0;
127
128 out_err_3:
129#ifdef CONFIG_SYSCTL
130 irda_sysctl_unregister();
131#endif
132 out_err_2:
133#ifdef CONFIG_PROC_FS
134 irda_proc_unregister();
135#endif
136
137 /* Remove IrDA packet type (stop receiving packets) */
138 dev_remove_pack(&irda_packet_type);
139
140 /* Remove higher layers */
141 irsock_cleanup();
142 out_err_1:
143 irttp_cleanup();
144 iriap_cleanup();
145
146 /* Remove lower layers */
147 irda_device_cleanup();
148 irlap_cleanup(); /* Must be done before irlmp_cleanup()! DB */
149
150 /* Remove middle layer */
151 irlmp_cleanup();
152
153
154 return ret;
117} 155}
118 156
119/* 157/*
@@ -125,6 +163,8 @@ static int __init irda_init(void)
125static void __exit irda_cleanup(void) 163static void __exit irda_cleanup(void)
126{ 164{
127 /* Remove External APIs */ 165 /* Remove External APIs */
166 irda_nl_unregister();
167
128#ifdef CONFIG_SYSCTL 168#ifdef CONFIG_SYSCTL
129 irda_sysctl_unregister(); 169 irda_sysctl_unregister();
130#endif 170#endif
diff --git a/net/irda/irnetlink.c b/net/irda/irnetlink.c
new file mode 100644
index 000000000000..db716580e1ae
--- /dev/null
+++ b/net/irda/irnetlink.c
@@ -0,0 +1,170 @@
1/*
2 * IrDA netlink layer, for stack configuration.
3 *
4 * Copyright (c) 2007 Samuel Ortiz <samuel@sortiz>
5 *
6 * Partly based on the 802.11 nelink implementation
7 * (see net/wireless/nl80211.c) which is:
8 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 */
15
16#include <linux/socket.h>
17#include <linux/irda.h>
18#include <net/sock.h>
19#include <net/irda/irda.h>
20#include <net/irda/irlap.h>
21#include <net/genetlink.h>
22
23
24
25static struct genl_family irda_nl_family = {
26 .id = GENL_ID_GENERATE,
27 .name = IRDA_NL_NAME,
28 .hdrsize = 0,
29 .version = IRDA_NL_VERSION,
30 .maxattr = IRDA_NL_CMD_MAX,
31};
32
33static struct net_device * ifname_to_netdev(struct genl_info *info)
34{
35 char * ifname;
36
37 if (!info->attrs[IRDA_NL_ATTR_IFNAME])
38 return NULL;
39
40 ifname = nla_data(info->attrs[IRDA_NL_ATTR_IFNAME]);
41
42 IRDA_DEBUG(5, "%s(): Looking for %s\n", __FUNCTION__, ifname);
43
44 return dev_get_by_name(ifname);
45}
46
47static int irda_nl_set_mode(struct sk_buff *skb, struct genl_info *info)
48{
49 struct net_device * dev;
50 struct irlap_cb * irlap;
51 u32 mode;
52
53 if (!info->attrs[IRDA_NL_ATTR_MODE])
54 return -EINVAL;
55
56 mode = nla_get_u32(info->attrs[IRDA_NL_ATTR_MODE]);
57
58 IRDA_DEBUG(5, "%s(): Switching to mode: %d\n", __FUNCTION__, mode);
59
60 dev = ifname_to_netdev(info);
61 if (!dev)
62 return -ENODEV;
63
64 irlap = (struct irlap_cb *)dev->atalk_ptr;
65 if (!irlap) {
66 dev_put(dev);
67 return -ENODEV;
68 }
69
70 irlap->mode = mode;
71
72 dev_put(dev);
73
74 return 0;
75}
76
77static int irda_nl_get_mode(struct sk_buff *skb, struct genl_info *info)
78{
79 struct net_device * dev;
80 struct irlap_cb * irlap;
81 struct sk_buff *msg;
82 void *hdr;
83 int ret = -ENOBUFS;
84
85 dev = ifname_to_netdev(info);
86 if (!dev)
87 return -ENODEV;
88
89 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
90 if (!msg) {
91 dev_put(dev);
92 return -ENOMEM;
93 }
94
95 irlap = (struct irlap_cb *)dev->atalk_ptr;
96 if (!irlap) {
97 ret = -ENODEV;
98 goto err_out;
99 }
100
101 hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq,
102 &irda_nl_family, 0, IRDA_NL_CMD_GET_MODE);
103 if (IS_ERR(hdr)) {
104 ret = PTR_ERR(hdr);
105 goto err_out;
106 }
107
108 if(nla_put_string(msg, IRDA_NL_ATTR_IFNAME,
109 dev->name));
110 goto err_out;
111
112 if(nla_put_u32(msg, IRDA_NL_ATTR_MODE, irlap->mode))
113 goto err_out;
114
115 genlmsg_end(msg, hdr);
116
117 return genlmsg_unicast(msg, info->snd_pid);
118
119 err_out:
120 nlmsg_free(msg);
121 dev_put(dev);
122
123 return ret;
124}
125
126static struct nla_policy irda_nl_policy[IRDA_NL_ATTR_MAX + 1] = {
127 [IRDA_NL_ATTR_IFNAME] = { .type = NLA_NUL_STRING,
128 .len = IFNAMSIZ-1 },
129 [IRDA_NL_ATTR_MODE] = { .type = NLA_U32 },
130};
131
132static struct genl_ops irda_nl_ops[] = {
133 {
134 .cmd = IRDA_NL_CMD_SET_MODE,
135 .doit = irda_nl_set_mode,
136 .policy = irda_nl_policy,
137 .flags = GENL_ADMIN_PERM,
138 },
139 {
140 .cmd = IRDA_NL_CMD_GET_MODE,
141 .doit = irda_nl_get_mode,
142 .policy = irda_nl_policy,
143 /* can be retrieved by unprivileged users */
144 },
145
146};
147
148int irda_nl_register(void)
149{
150 int err, i;
151
152 err = genl_register_family(&irda_nl_family);
153 if (err)
154 return err;
155
156 for (i = 0; i < ARRAY_SIZE(irda_nl_ops); i++) {
157 err = genl_register_ops(&irda_nl_family, &irda_nl_ops[i]);
158 if (err)
159 goto err_out;
160 }
161 return 0;
162 err_out:
163 genl_unregister_family(&irda_nl_family);
164 return err;
165}
166
167void irda_nl_unregister(void)
168{
169 genl_unregister_family(&irda_nl_family);
170}
diff --git a/net/irda/irttp.c b/net/irda/irttp.c
index 7069e4a58257..7f50832a2cd5 100644
--- a/net/irda/irttp.c
+++ b/net/irda/irttp.c
@@ -369,6 +369,20 @@ static int irttp_param_max_sdu_size(void *instance, irda_param_t *param,
369/* Everything is happily mixed up. Waiting for next clean up - Jean II */ 369/* Everything is happily mixed up. Waiting for next clean up - Jean II */
370 370
371/* 371/*
372 * Initialization, that has to be done on new tsap
373 * instance allocation and on duplication
374 */
375static void irttp_init_tsap(struct tsap_cb *tsap)
376{
377 spin_lock_init(&tsap->lock);
378 init_timer(&tsap->todo_timer);
379
380 skb_queue_head_init(&tsap->rx_queue);
381 skb_queue_head_init(&tsap->tx_queue);
382 skb_queue_head_init(&tsap->rx_fragments);
383}
384
385/*
372 * Function irttp_open_tsap (stsap, notify) 386 * Function irttp_open_tsap (stsap, notify)
373 * 387 *
374 * Create TSAP connection endpoint, 388 * Create TSAP connection endpoint,
@@ -395,10 +409,11 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify)
395 IRDA_DEBUG(0, "%s(), unable to kmalloc!\n", __FUNCTION__); 409 IRDA_DEBUG(0, "%s(), unable to kmalloc!\n", __FUNCTION__);
396 return NULL; 410 return NULL;
397 } 411 }
398 spin_lock_init(&self->lock); 412
413 /* Initialize internal objects */
414 irttp_init_tsap(self);
399 415
400 /* Initialise todo timer */ 416 /* Initialise todo timer */
401 init_timer(&self->todo_timer);
402 self->todo_timer.data = (unsigned long) self; 417 self->todo_timer.data = (unsigned long) self;
403 self->todo_timer.function = &irttp_todo_expired; 418 self->todo_timer.function = &irttp_todo_expired;
404 419
@@ -418,9 +433,6 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify)
418 self->magic = TTP_TSAP_MAGIC; 433 self->magic = TTP_TSAP_MAGIC;
419 self->connected = FALSE; 434 self->connected = FALSE;
420 435
421 skb_queue_head_init(&self->rx_queue);
422 skb_queue_head_init(&self->tx_queue);
423 skb_queue_head_init(&self->rx_fragments);
424 /* 436 /*
425 * Create LSAP at IrLMP layer 437 * Create LSAP at IrLMP layer
426 */ 438 */
@@ -1455,12 +1467,9 @@ struct tsap_cb *irttp_dup(struct tsap_cb *orig, void *instance)
1455 1467
1456 /* Not everything should be copied */ 1468 /* Not everything should be copied */
1457 new->notify.instance = instance; 1469 new->notify.instance = instance;
1458 spin_lock_init(&new->lock);
1459 init_timer(&new->todo_timer);
1460 1470
1461 skb_queue_head_init(&new->rx_queue); 1471 /* Initialize internal objects */
1462 skb_queue_head_init(&new->tx_queue); 1472 irttp_init_tsap(new);
1463 skb_queue_head_init(&new->rx_fragments);
1464 1473
1465 /* This is locked */ 1474 /* This is locked */
1466 hashbin_insert(irttp->tsaps, (irda_queue_t *) new, (long) new, NULL); 1475 hashbin_insert(irttp->tsaps, (irda_queue_t *) new, (long) new, NULL);
@@ -1866,7 +1875,7 @@ static int irttp_seq_show(struct seq_file *seq, void *v)
1866 return 0; 1875 return 0;
1867} 1876}
1868 1877
1869static struct seq_operations irttp_seq_ops = { 1878static const struct seq_operations irttp_seq_ops = {
1870 .start = irttp_seq_start, 1879 .start = irttp_seq_start,
1871 .next = irttp_seq_next, 1880 .next = irttp_seq_next,
1872 .stop = irttp_seq_stop, 1881 .stop = irttp_seq_stop,
diff --git a/net/llc/llc_proc.c b/net/llc/llc_proc.c
index 3ab9d9f8b17f..49be6c902c83 100644
--- a/net/llc/llc_proc.c
+++ b/net/llc/llc_proc.c
@@ -184,14 +184,14 @@ out:
184 return 0; 184 return 0;
185} 185}
186 186
187static struct seq_operations llc_seq_socket_ops = { 187static const struct seq_operations llc_seq_socket_ops = {
188 .start = llc_seq_start, 188 .start = llc_seq_start,
189 .next = llc_seq_next, 189 .next = llc_seq_next,
190 .stop = llc_seq_stop, 190 .stop = llc_seq_stop,
191 .show = llc_seq_socket_show, 191 .show = llc_seq_socket_show,
192}; 192};
193 193
194static struct seq_operations llc_seq_core_ops = { 194static const struct seq_operations llc_seq_core_ops = {
195 .start = llc_seq_start, 195 .start = llc_seq_start,
196 .next = llc_seq_next, 196 .next = llc_seq_next,
197 .stop = llc_seq_stop, 197 .stop = llc_seq_stop,
diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c
index 352f03bd8a3a..66e8a976b311 100644
--- a/net/mac80211/ieee80211_ioctl.c
+++ b/net/mac80211/ieee80211_ioctl.c
@@ -838,6 +838,29 @@ static int ieee80211_ioctl_giwscan(struct net_device *dev,
838} 838}
839 839
840 840
841static int ieee80211_ioctl_giwrate(struct net_device *dev,
842 struct iw_request_info *info,
843 struct iw_param *rate, char *extra)
844{
845 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
846 struct sta_info *sta;
847 struct ieee80211_sub_if_data *sdata;
848
849 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
850 if (sdata->type == IEEE80211_IF_TYPE_STA)
851 sta = sta_info_get(local, sdata->u.sta.bssid);
852 else
853 return -EOPNOTSUPP;
854 if (!sta)
855 return -ENODEV;
856 if (sta->txrate < local->oper_hw_mode->num_rates)
857 rate->value = local->oper_hw_mode->rates[sta->txrate].rate * 100000;
858 else
859 rate->value = 0;
860 sta_info_put(sta);
861 return 0;
862}
863
841static int ieee80211_ioctl_siwrts(struct net_device *dev, 864static int ieee80211_ioctl_siwrts(struct net_device *dev,
842 struct iw_request_info *info, 865 struct iw_request_info *info,
843 struct iw_param *rts, char *extra) 866 struct iw_param *rts, char *extra)
@@ -1779,7 +1802,7 @@ static const iw_handler ieee80211_handler[] =
1779 (iw_handler) NULL, /* -- hole -- */ 1802 (iw_handler) NULL, /* -- hole -- */
1780 (iw_handler) NULL, /* -- hole -- */ 1803 (iw_handler) NULL, /* -- hole -- */
1781 (iw_handler) NULL, /* SIOCSIWRATE */ 1804 (iw_handler) NULL, /* SIOCSIWRATE */
1782 (iw_handler) NULL, /* SIOCGIWRATE */ 1805 (iw_handler) ieee80211_ioctl_giwrate, /* SIOCGIWRATE */
1783 (iw_handler) ieee80211_ioctl_siwrts, /* SIOCSIWRTS */ 1806 (iw_handler) ieee80211_ioctl_siwrts, /* SIOCSIWRTS */
1784 (iw_handler) ieee80211_ioctl_giwrts, /* SIOCGIWRTS */ 1807 (iw_handler) ieee80211_ioctl_giwrts, /* SIOCGIWRTS */
1785 (iw_handler) ieee80211_ioctl_siwfrag, /* SIOCSIWFRAG */ 1808 (iw_handler) ieee80211_ioctl_siwfrag, /* SIOCSIWFRAG */
diff --git a/net/mac80211/rc80211_simple.c b/net/mac80211/rc80211_simple.c
index 2048cfd1ca70..5ae7fc454665 100644
--- a/net/mac80211/rc80211_simple.c
+++ b/net/mac80211/rc80211_simple.c
@@ -283,14 +283,16 @@ static void rate_control_simple_rate_init(void *priv, void *priv_sta,
283 int i; 283 int i;
284 sta->txrate = 0; 284 sta->txrate = 0;
285 mode = local->oper_hw_mode; 285 mode = local->oper_hw_mode;
286 /* TODO: what is a good starting rate for STA? About middle? Maybe not 286 /* TODO: This routine should consider using RSSI from previous packets
287 * the lowest or the highest rate.. Could consider using RSSI from 287 * as we need to have IEEE 802.1X auth succeed immediately after assoc..
288 * previous packets? Need to have IEEE 802.1X auth succeed immediately 288 * Until that method is implemented, we will use the lowest supported rate
289 * after assoc.. */ 289 * as a workaround, */
290 for (i = 0; i < mode->num_rates; i++) { 290 for (i = 0; i < mode->num_rates; i++) {
291 if ((sta->supp_rates & BIT(i)) && 291 if ((sta->supp_rates & BIT(i)) &&
292 (mode->rates[i].flags & IEEE80211_RATE_SUPPORTED)) 292 (mode->rates[i].flags & IEEE80211_RATE_SUPPORTED)) {
293 sta->txrate = i; 293 sta->txrate = i;
294 break;
295 }
294 } 296 }
295} 297}
296 298
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index a567dae8e5fd..df5e8dab871d 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -343,6 +343,18 @@ config NETFILTER_XT_TARGET_NOTRACK
343 If you want to compile it as a module, say M here and read 343 If you want to compile it as a module, say M here and read
344 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. 344 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
345 345
346config NETFILTER_XT_TARGET_TRACE
347 tristate '"TRACE" target support'
348 depends on NETFILTER_XTABLES
349 depends on IP_NF_RAW || IP6_NF_RAW
350 help
351 The TRACE target allows you to mark packets so that the kernel
352 will log every rule which match the packets as those traverse
353 the tables, chains, rules.
354
355 If you want to compile it as a module, say M here and read
356 <file:Documentation/modules.txt>. If unsure, say `N'.
357
346config NETFILTER_XT_TARGET_SECMARK 358config NETFILTER_XT_TARGET_SECMARK
347 tristate '"SECMARK" target support' 359 tristate '"SECMARK" target support'
348 depends on NETFILTER_XTABLES && NETWORK_SECMARK 360 depends on NETFILTER_XTABLES && NETWORK_SECMARK
@@ -635,6 +647,19 @@ config NETFILTER_XT_MATCH_TCPMSS
635 647
636 To compile it as a module, choose M here. If unsure, say N. 648 To compile it as a module, choose M here. If unsure, say N.
637 649
650config NETFILTER_XT_MATCH_U32
651 tristate '"u32" match support'
652 depends on NETFILTER_XTABLES
653 ---help---
654 u32 allows you to extract quantities of up to 4 bytes from a packet,
655 AND them with specified masks, shift them by specified amounts and
656 test whether the results are in any of a set of specified ranges.
657 The specification of what to extract is general enough to skip over
658 headers with lengths stored in the packet, as in IP or TCP header
659 lengths.
660
661 Details and examples are in the kernel module source.
662
638config NETFILTER_XT_MATCH_HASHLIMIT 663config NETFILTER_XT_MATCH_HASHLIMIT
639 tristate '"hashlimit" match support' 664 tristate '"hashlimit" match support'
640 depends on NETFILTER_XTABLES && (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n) 665 depends on NETFILTER_XTABLES && (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n)
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index b2b5c7566b26..58b4245a1723 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -1,6 +1,6 @@
1netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o 1netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o
2 2
3nf_conntrack-y := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_expect.o nf_conntrack_helper.o nf_conntrack_proto.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o 3nf_conntrack-y := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_expect.o nf_conntrack_helper.o nf_conntrack_proto.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o nf_conntrack_extend.o
4nf_conntrack-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o 4nf_conntrack-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o
5 5
6obj-$(CONFIG_NETFILTER) = netfilter.o 6obj-$(CONFIG_NETFILTER) = netfilter.o
@@ -44,6 +44,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o
44obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o 44obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
45obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o 45obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
46obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o 46obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
47obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
47obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o 48obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
48obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o 49obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
49obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o 50obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
@@ -72,4 +73,5 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o
72obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o 73obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o
73obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o 74obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o
74obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o 75obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o
76obj-$(CONFIG_NETFILTER_XT_MATCH_U32) += xt_u32.o
75obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o 77obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index a84478ee2ded..381a77cf0c9e 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -203,7 +203,9 @@ int skb_make_writable(struct sk_buff **pskb, unsigned int writable_len)
203 return 0; 203 return 0;
204 204
205 /* Not exclusive use of packet? Must copy. */ 205 /* Not exclusive use of packet? Must copy. */
206 if (skb_shared(*pskb) || skb_cloned(*pskb)) 206 if (skb_cloned(*pskb) && !skb_clone_writable(*pskb, writable_len))
207 goto copy_skb;
208 if (skb_shared(*pskb))
207 goto copy_skb; 209 goto copy_skb;
208 210
209 return pskb_may_pull(*pskb, writable_len); 211 return pskb_may_pull(*pskb, writable_len);
@@ -229,13 +231,13 @@ void nf_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
229{ 231{
230 __be32 diff[] = { ~from, to }; 232 __be32 diff[] = { ~from, to };
231 if (skb->ip_summed != CHECKSUM_PARTIAL) { 233 if (skb->ip_summed != CHECKSUM_PARTIAL) {
232 *sum = csum_fold(csum_partial((char *)diff, sizeof(diff), 234 *sum = csum_fold(csum_partial(diff, sizeof(diff),
233 ~csum_unfold(*sum))); 235 ~csum_unfold(*sum)));
234 if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr) 236 if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr)
235 skb->csum = ~csum_partial((char *)diff, sizeof(diff), 237 skb->csum = ~csum_partial(diff, sizeof(diff),
236 ~skb->csum); 238 ~skb->csum);
237 } else if (pseudohdr) 239 } else if (pseudohdr)
238 *sum = ~csum_fold(csum_partial((char *)diff, sizeof(diff), 240 *sum = ~csum_fold(csum_partial(diff, sizeof(diff),
239 csum_unfold(*sum))); 241 csum_unfold(*sum)));
240} 242}
241EXPORT_SYMBOL(nf_proto_csum_replace4); 243EXPORT_SYMBOL(nf_proto_csum_replace4);
diff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c
index 0568f2e86b59..e42ab230ad88 100644
--- a/net/netfilter/nf_conntrack_amanda.c
+++ b/net/netfilter/nf_conntrack_amanda.c
@@ -142,23 +142,22 @@ static int amanda_help(struct sk_buff **pskb,
142 if (port == 0 || len > 5) 142 if (port == 0 || len > 5)
143 break; 143 break;
144 144
145 exp = nf_conntrack_expect_alloc(ct); 145 exp = nf_ct_expect_alloc(ct);
146 if (exp == NULL) { 146 if (exp == NULL) {
147 ret = NF_DROP; 147 ret = NF_DROP;
148 goto out; 148 goto out;
149 } 149 }
150 tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; 150 tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
151 nf_conntrack_expect_init(exp, family, 151 nf_ct_expect_init(exp, family, &tuple->src.u3, &tuple->dst.u3,
152 &tuple->src.u3, &tuple->dst.u3, 152 IPPROTO_TCP, NULL, &port);
153 IPPROTO_TCP, NULL, &port);
154 153
155 nf_nat_amanda = rcu_dereference(nf_nat_amanda_hook); 154 nf_nat_amanda = rcu_dereference(nf_nat_amanda_hook);
156 if (nf_nat_amanda && ct->status & IPS_NAT_MASK) 155 if (nf_nat_amanda && ct->status & IPS_NAT_MASK)
157 ret = nf_nat_amanda(pskb, ctinfo, off - dataoff, 156 ret = nf_nat_amanda(pskb, ctinfo, off - dataoff,
158 len, exp); 157 len, exp);
159 else if (nf_conntrack_expect_related(exp) != 0) 158 else if (nf_ct_expect_related(exp) != 0)
160 ret = NF_DROP; 159 ret = NF_DROP;
161 nf_conntrack_expect_put(exp); 160 nf_ct_expect_put(exp);
162 } 161 }
163 162
164out: 163out:
@@ -175,9 +174,6 @@ static struct nf_conntrack_helper amanda_helper[2] __read_mostly = {
175 .tuple.src.l3num = AF_INET, 174 .tuple.src.l3num = AF_INET,
176 .tuple.src.u.udp.port = __constant_htons(10080), 175 .tuple.src.u.udp.port = __constant_htons(10080),
177 .tuple.dst.protonum = IPPROTO_UDP, 176 .tuple.dst.protonum = IPPROTO_UDP,
178 .mask.src.l3num = 0xFFFF,
179 .mask.src.u.udp.port = __constant_htons(0xFFFF),
180 .mask.dst.protonum = 0xFF,
181 }, 177 },
182 { 178 {
183 .name = "amanda", 179 .name = "amanda",
@@ -188,9 +184,6 @@ static struct nf_conntrack_helper amanda_helper[2] __read_mostly = {
188 .tuple.src.l3num = AF_INET6, 184 .tuple.src.l3num = AF_INET6,
189 .tuple.src.u.udp.port = __constant_htons(10080), 185 .tuple.src.u.udp.port = __constant_htons(10080),
190 .tuple.dst.protonum = IPPROTO_UDP, 186 .tuple.dst.protonum = IPPROTO_UDP,
191 .mask.src.l3num = 0xFFFF,
192 .mask.src.u.udp.port = __constant_htons(0xFFFF),
193 .mask.dst.protonum = 0xFF,
194 }, 187 },
195}; 188};
196 189
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 7a15e30356f2..3d1411012a2c 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -36,15 +36,10 @@
36#include <net/netfilter/nf_conntrack_expect.h> 36#include <net/netfilter/nf_conntrack_expect.h>
37#include <net/netfilter/nf_conntrack_helper.h> 37#include <net/netfilter/nf_conntrack_helper.h>
38#include <net/netfilter/nf_conntrack_core.h> 38#include <net/netfilter/nf_conntrack_core.h>
39#include <net/netfilter/nf_conntrack_extend.h>
39 40
40#define NF_CONNTRACK_VERSION "0.5.0" 41#define NF_CONNTRACK_VERSION "0.5.0"
41 42
42#if 0
43#define DEBUGP printk
44#else
45#define DEBUGP(format, args...)
46#endif
47
48DEFINE_RWLOCK(nf_conntrack_lock); 43DEFINE_RWLOCK(nf_conntrack_lock);
49EXPORT_SYMBOL_GPL(nf_conntrack_lock); 44EXPORT_SYMBOL_GPL(nf_conntrack_lock);
50 45
@@ -52,57 +47,27 @@ EXPORT_SYMBOL_GPL(nf_conntrack_lock);
52atomic_t nf_conntrack_count = ATOMIC_INIT(0); 47atomic_t nf_conntrack_count = ATOMIC_INIT(0);
53EXPORT_SYMBOL_GPL(nf_conntrack_count); 48EXPORT_SYMBOL_GPL(nf_conntrack_count);
54 49
55void (*nf_conntrack_destroyed)(struct nf_conn *conntrack);
56EXPORT_SYMBOL_GPL(nf_conntrack_destroyed);
57
58unsigned int nf_conntrack_htable_size __read_mostly; 50unsigned int nf_conntrack_htable_size __read_mostly;
59EXPORT_SYMBOL_GPL(nf_conntrack_htable_size); 51EXPORT_SYMBOL_GPL(nf_conntrack_htable_size);
60 52
61int nf_conntrack_max __read_mostly; 53int nf_conntrack_max __read_mostly;
62EXPORT_SYMBOL_GPL(nf_conntrack_max); 54EXPORT_SYMBOL_GPL(nf_conntrack_max);
63 55
64struct list_head *nf_conntrack_hash __read_mostly; 56struct hlist_head *nf_conntrack_hash __read_mostly;
65EXPORT_SYMBOL_GPL(nf_conntrack_hash); 57EXPORT_SYMBOL_GPL(nf_conntrack_hash);
66 58
67struct nf_conn nf_conntrack_untracked __read_mostly; 59struct nf_conn nf_conntrack_untracked __read_mostly;
68EXPORT_SYMBOL_GPL(nf_conntrack_untracked); 60EXPORT_SYMBOL_GPL(nf_conntrack_untracked);
69 61
70unsigned int nf_ct_log_invalid __read_mostly; 62unsigned int nf_ct_log_invalid __read_mostly;
71LIST_HEAD(unconfirmed); 63HLIST_HEAD(unconfirmed);
72static int nf_conntrack_vmalloc __read_mostly; 64static int nf_conntrack_vmalloc __read_mostly;
73 65static struct kmem_cache *nf_conntrack_cachep __read_mostly;
74static unsigned int nf_conntrack_next_id; 66static unsigned int nf_conntrack_next_id;
75 67
76DEFINE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat); 68DEFINE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat);
77EXPORT_PER_CPU_SYMBOL(nf_conntrack_stat); 69EXPORT_PER_CPU_SYMBOL(nf_conntrack_stat);
78 70
79/*
80 * This scheme offers various size of "struct nf_conn" dependent on
81 * features(helper, nat, ...)
82 */
83
84#define NF_CT_FEATURES_NAMELEN 256
85static struct {
86 /* name of slab cache. printed in /proc/slabinfo */
87 char *name;
88
89 /* size of slab cache */
90 size_t size;
91
92 /* slab cache pointer */
93 struct kmem_cache *cachep;
94
95 /* allocated slab cache + modules which uses this slab cache */
96 int use;
97
98} nf_ct_cache[NF_CT_F_NUM];
99
100/* protect members of nf_ct_cache except of "use" */
101DEFINE_RWLOCK(nf_ct_cache_lock);
102
103/* This avoids calling kmem_cache_create() with same name simultaneously */
104static DEFINE_MUTEX(nf_ct_cache_mutex);
105
106static int nf_conntrack_hash_rnd_initted; 71static int nf_conntrack_hash_rnd_initted;
107static unsigned int nf_conntrack_hash_rnd; 72static unsigned int nf_conntrack_hash_rnd;
108 73
@@ -125,122 +90,6 @@ static inline u_int32_t hash_conntrack(const struct nf_conntrack_tuple *tuple)
125 nf_conntrack_hash_rnd); 90 nf_conntrack_hash_rnd);
126} 91}
127 92
128int nf_conntrack_register_cache(u_int32_t features, const char *name,
129 size_t size)
130{
131 int ret = 0;
132 char *cache_name;
133 struct kmem_cache *cachep;
134
135 DEBUGP("nf_conntrack_register_cache: features=0x%x, name=%s, size=%d\n",
136 features, name, size);
137
138 if (features < NF_CT_F_BASIC || features >= NF_CT_F_NUM) {
139 DEBUGP("nf_conntrack_register_cache: invalid features.: 0x%x\n",
140 features);
141 return -EINVAL;
142 }
143
144 mutex_lock(&nf_ct_cache_mutex);
145
146 write_lock_bh(&nf_ct_cache_lock);
147 /* e.g: multiple helpers are loaded */
148 if (nf_ct_cache[features].use > 0) {
149 DEBUGP("nf_conntrack_register_cache: already resisterd.\n");
150 if ((!strncmp(nf_ct_cache[features].name, name,
151 NF_CT_FEATURES_NAMELEN))
152 && nf_ct_cache[features].size == size) {
153 DEBUGP("nf_conntrack_register_cache: reusing.\n");
154 nf_ct_cache[features].use++;
155 ret = 0;
156 } else
157 ret = -EBUSY;
158
159 write_unlock_bh(&nf_ct_cache_lock);
160 mutex_unlock(&nf_ct_cache_mutex);
161 return ret;
162 }
163 write_unlock_bh(&nf_ct_cache_lock);
164
165 /*
166 * The memory space for name of slab cache must be alive until
167 * cache is destroyed.
168 */
169 cache_name = kmalloc(sizeof(char)*NF_CT_FEATURES_NAMELEN, GFP_ATOMIC);
170 if (cache_name == NULL) {
171 DEBUGP("nf_conntrack_register_cache: can't alloc cache_name\n");
172 ret = -ENOMEM;
173 goto out_up_mutex;
174 }
175
176 if (strlcpy(cache_name, name, NF_CT_FEATURES_NAMELEN)
177 >= NF_CT_FEATURES_NAMELEN) {
178 printk("nf_conntrack_register_cache: name too long\n");
179 ret = -EINVAL;
180 goto out_free_name;
181 }
182
183 cachep = kmem_cache_create(cache_name, size, 0, 0,
184 NULL, NULL);
185 if (!cachep) {
186 printk("nf_conntrack_register_cache: Can't create slab cache "
187 "for the features = 0x%x\n", features);
188 ret = -ENOMEM;
189 goto out_free_name;
190 }
191
192 write_lock_bh(&nf_ct_cache_lock);
193 nf_ct_cache[features].use = 1;
194 nf_ct_cache[features].size = size;
195 nf_ct_cache[features].cachep = cachep;
196 nf_ct_cache[features].name = cache_name;
197 write_unlock_bh(&nf_ct_cache_lock);
198
199 goto out_up_mutex;
200
201out_free_name:
202 kfree(cache_name);
203out_up_mutex:
204 mutex_unlock(&nf_ct_cache_mutex);
205 return ret;
206}
207EXPORT_SYMBOL_GPL(nf_conntrack_register_cache);
208
209/* FIXME: In the current, only nf_conntrack_cleanup() can call this function. */
210void nf_conntrack_unregister_cache(u_int32_t features)
211{
212 struct kmem_cache *cachep;
213 char *name;
214
215 /*
216 * This assures that kmem_cache_create() isn't called before destroying
217 * slab cache.
218 */
219 DEBUGP("nf_conntrack_unregister_cache: 0x%04x\n", features);
220 mutex_lock(&nf_ct_cache_mutex);
221
222 write_lock_bh(&nf_ct_cache_lock);
223 if (--nf_ct_cache[features].use > 0) {
224 write_unlock_bh(&nf_ct_cache_lock);
225 mutex_unlock(&nf_ct_cache_mutex);
226 return;
227 }
228 cachep = nf_ct_cache[features].cachep;
229 name = nf_ct_cache[features].name;
230 nf_ct_cache[features].cachep = NULL;
231 nf_ct_cache[features].name = NULL;
232 nf_ct_cache[features].size = 0;
233 write_unlock_bh(&nf_ct_cache_lock);
234
235 synchronize_net();
236
237 kmem_cache_destroy(cachep);
238 kfree(name);
239
240 mutex_unlock(&nf_ct_cache_mutex);
241}
242EXPORT_SYMBOL_GPL(nf_conntrack_unregister_cache);
243
244int 93int
245nf_ct_get_tuple(const struct sk_buff *skb, 94nf_ct_get_tuple(const struct sk_buff *skb,
246 unsigned int nhoff, 95 unsigned int nhoff,
@@ -286,9 +135,9 @@ EXPORT_SYMBOL_GPL(nf_ct_invert_tuple);
286static void 135static void
287clean_from_lists(struct nf_conn *ct) 136clean_from_lists(struct nf_conn *ct)
288{ 137{
289 DEBUGP("clean_from_lists(%p)\n", ct); 138 pr_debug("clean_from_lists(%p)\n", ct);
290 list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list); 139 hlist_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode);
291 list_del(&ct->tuplehash[IP_CT_DIR_REPLY].list); 140 hlist_del(&ct->tuplehash[IP_CT_DIR_REPLY].hnode);
292 141
293 /* Destroy all pending expectations */ 142 /* Destroy all pending expectations */
294 nf_ct_remove_expectations(ct); 143 nf_ct_remove_expectations(ct);
@@ -299,9 +148,8 @@ destroy_conntrack(struct nf_conntrack *nfct)
299{ 148{
300 struct nf_conn *ct = (struct nf_conn *)nfct; 149 struct nf_conn *ct = (struct nf_conn *)nfct;
301 struct nf_conntrack_l4proto *l4proto; 150 struct nf_conntrack_l4proto *l4proto;
302 typeof(nf_conntrack_destroyed) destroyed;
303 151
304 DEBUGP("destroy_conntrack(%p)\n", ct); 152 pr_debug("destroy_conntrack(%p)\n", ct);
305 NF_CT_ASSERT(atomic_read(&nfct->use) == 0); 153 NF_CT_ASSERT(atomic_read(&nfct->use) == 0);
306 NF_CT_ASSERT(!timer_pending(&ct->timeout)); 154 NF_CT_ASSERT(!timer_pending(&ct->timeout));
307 155
@@ -317,9 +165,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
317 if (l4proto && l4proto->destroy) 165 if (l4proto && l4proto->destroy)
318 l4proto->destroy(ct); 166 l4proto->destroy(ct);
319 167
320 destroyed = rcu_dereference(nf_conntrack_destroyed); 168 nf_ct_ext_destroy(ct);
321 if (destroyed)
322 destroyed(ct);
323 169
324 rcu_read_unlock(); 170 rcu_read_unlock();
325 171
@@ -332,8 +178,8 @@ destroy_conntrack(struct nf_conntrack *nfct)
332 178
333 /* We overload first tuple to link into unconfirmed list. */ 179 /* We overload first tuple to link into unconfirmed list. */
334 if (!nf_ct_is_confirmed(ct)) { 180 if (!nf_ct_is_confirmed(ct)) {
335 BUG_ON(list_empty(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list)); 181 BUG_ON(hlist_unhashed(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode));
336 list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list); 182 hlist_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode);
337 } 183 }
338 184
339 NF_CT_STAT_INC(delete); 185 NF_CT_STAT_INC(delete);
@@ -342,7 +188,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
342 if (ct->master) 188 if (ct->master)
343 nf_ct_put(ct->master); 189 nf_ct_put(ct->master);
344 190
345 DEBUGP("destroy_conntrack: returning ct=%p to slab\n", ct); 191 pr_debug("destroy_conntrack: returning ct=%p to slab\n", ct);
346 nf_conntrack_free(ct); 192 nf_conntrack_free(ct);
347} 193}
348 194
@@ -374,9 +220,10 @@ __nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
374 const struct nf_conn *ignored_conntrack) 220 const struct nf_conn *ignored_conntrack)
375{ 221{
376 struct nf_conntrack_tuple_hash *h; 222 struct nf_conntrack_tuple_hash *h;
223 struct hlist_node *n;
377 unsigned int hash = hash_conntrack(tuple); 224 unsigned int hash = hash_conntrack(tuple);
378 225
379 list_for_each_entry(h, &nf_conntrack_hash[hash], list) { 226 hlist_for_each_entry(h, n, &nf_conntrack_hash[hash], hnode) {
380 if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack && 227 if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack &&
381 nf_ct_tuple_equal(tuple, &h->tuple)) { 228 nf_ct_tuple_equal(tuple, &h->tuple)) {
382 NF_CT_STAT_INC(found); 229 NF_CT_STAT_INC(found);
@@ -391,13 +238,12 @@ EXPORT_SYMBOL_GPL(__nf_conntrack_find);
391 238
392/* Find a connection corresponding to a tuple. */ 239/* Find a connection corresponding to a tuple. */
393struct nf_conntrack_tuple_hash * 240struct nf_conntrack_tuple_hash *
394nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple, 241nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple)
395 const struct nf_conn *ignored_conntrack)
396{ 242{
397 struct nf_conntrack_tuple_hash *h; 243 struct nf_conntrack_tuple_hash *h;
398 244
399 read_lock_bh(&nf_conntrack_lock); 245 read_lock_bh(&nf_conntrack_lock);
400 h = __nf_conntrack_find(tuple, ignored_conntrack); 246 h = __nf_conntrack_find(tuple, NULL);
401 if (h) 247 if (h)
402 atomic_inc(&nf_ct_tuplehash_to_ctrack(h)->ct_general.use); 248 atomic_inc(&nf_ct_tuplehash_to_ctrack(h)->ct_general.use);
403 read_unlock_bh(&nf_conntrack_lock); 249 read_unlock_bh(&nf_conntrack_lock);
@@ -411,10 +257,10 @@ static void __nf_conntrack_hash_insert(struct nf_conn *ct,
411 unsigned int repl_hash) 257 unsigned int repl_hash)
412{ 258{
413 ct->id = ++nf_conntrack_next_id; 259 ct->id = ++nf_conntrack_next_id;
414 list_add(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list, 260 hlist_add_head(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode,
415 &nf_conntrack_hash[hash]); 261 &nf_conntrack_hash[hash]);
416 list_add(&ct->tuplehash[IP_CT_DIR_REPLY].list, 262 hlist_add_head(&ct->tuplehash[IP_CT_DIR_REPLY].hnode,
417 &nf_conntrack_hash[repl_hash]); 263 &nf_conntrack_hash[repl_hash]);
418} 264}
419 265
420void nf_conntrack_hash_insert(struct nf_conn *ct) 266void nf_conntrack_hash_insert(struct nf_conn *ct)
@@ -438,6 +284,7 @@ __nf_conntrack_confirm(struct sk_buff **pskb)
438 struct nf_conntrack_tuple_hash *h; 284 struct nf_conntrack_tuple_hash *h;
439 struct nf_conn *ct; 285 struct nf_conn *ct;
440 struct nf_conn_help *help; 286 struct nf_conn_help *help;
287 struct hlist_node *n;
441 enum ip_conntrack_info ctinfo; 288 enum ip_conntrack_info ctinfo;
442 289
443 ct = nf_ct_get(*pskb, &ctinfo); 290 ct = nf_ct_get(*pskb, &ctinfo);
@@ -460,24 +307,24 @@ __nf_conntrack_confirm(struct sk_buff **pskb)
460 /* No external references means noone else could have 307 /* No external references means noone else could have
461 confirmed us. */ 308 confirmed us. */
462 NF_CT_ASSERT(!nf_ct_is_confirmed(ct)); 309 NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
463 DEBUGP("Confirming conntrack %p\n", ct); 310 pr_debug("Confirming conntrack %p\n", ct);
464 311
465 write_lock_bh(&nf_conntrack_lock); 312 write_lock_bh(&nf_conntrack_lock);
466 313
467 /* See if there's one in the list already, including reverse: 314 /* See if there's one in the list already, including reverse:
468 NAT could have grabbed it without realizing, since we're 315 NAT could have grabbed it without realizing, since we're
469 not in the hash. If there is, we lost race. */ 316 not in the hash. If there is, we lost race. */
470 list_for_each_entry(h, &nf_conntrack_hash[hash], list) 317 hlist_for_each_entry(h, n, &nf_conntrack_hash[hash], hnode)
471 if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, 318 if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
472 &h->tuple)) 319 &h->tuple))
473 goto out; 320 goto out;
474 list_for_each_entry(h, &nf_conntrack_hash[repl_hash], list) 321 hlist_for_each_entry(h, n, &nf_conntrack_hash[repl_hash], hnode)
475 if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_REPLY].tuple, 322 if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_REPLY].tuple,
476 &h->tuple)) 323 &h->tuple))
477 goto out; 324 goto out;
478 325
479 /* Remove from unconfirmed list */ 326 /* Remove from unconfirmed list */
480 list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list); 327 hlist_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode);
481 328
482 __nf_conntrack_hash_insert(ct, hash, repl_hash); 329 __nf_conntrack_hash_insert(ct, hash, repl_hash);
483 /* Timer relative to confirmation time, not original 330 /* Timer relative to confirmation time, not original
@@ -524,24 +371,33 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
524} 371}
525EXPORT_SYMBOL_GPL(nf_conntrack_tuple_taken); 372EXPORT_SYMBOL_GPL(nf_conntrack_tuple_taken);
526 373
374#define NF_CT_EVICTION_RANGE 8
375
527/* There's a small race here where we may free a just-assured 376/* There's a small race here where we may free a just-assured
528 connection. Too bad: we're in trouble anyway. */ 377 connection. Too bad: we're in trouble anyway. */
529static int early_drop(struct list_head *chain) 378static int early_drop(unsigned int hash)
530{ 379{
531 /* Traverse backwards: gives us oldest, which is roughly LRU */ 380 /* Use oldest entry, which is roughly LRU */
532 struct nf_conntrack_tuple_hash *h; 381 struct nf_conntrack_tuple_hash *h;
533 struct nf_conn *ct = NULL, *tmp; 382 struct nf_conn *ct = NULL, *tmp;
383 struct hlist_node *n;
384 unsigned int i, cnt = 0;
534 int dropped = 0; 385 int dropped = 0;
535 386
536 read_lock_bh(&nf_conntrack_lock); 387 read_lock_bh(&nf_conntrack_lock);
537 list_for_each_entry_reverse(h, chain, list) { 388 for (i = 0; i < nf_conntrack_htable_size; i++) {
538 tmp = nf_ct_tuplehash_to_ctrack(h); 389 hlist_for_each_entry(h, n, &nf_conntrack_hash[hash], hnode) {
539 if (!test_bit(IPS_ASSURED_BIT, &tmp->status)) { 390 tmp = nf_ct_tuplehash_to_ctrack(h);
540 ct = tmp; 391 if (!test_bit(IPS_ASSURED_BIT, &tmp->status))
541 atomic_inc(&ct->ct_general.use); 392 ct = tmp;
542 break; 393 cnt++;
543 } 394 }
395 if (ct || cnt >= NF_CT_EVICTION_RANGE)
396 break;
397 hash = (hash + 1) % nf_conntrack_htable_size;
544 } 398 }
399 if (ct)
400 atomic_inc(&ct->ct_general.use);
545 read_unlock_bh(&nf_conntrack_lock); 401 read_unlock_bh(&nf_conntrack_lock);
546 402
547 if (!ct) 403 if (!ct)
@@ -556,14 +412,10 @@ static int early_drop(struct list_head *chain)
556 return dropped; 412 return dropped;
557} 413}
558 414
559static struct nf_conn * 415struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
560__nf_conntrack_alloc(const struct nf_conntrack_tuple *orig, 416 const struct nf_conntrack_tuple *repl)
561 const struct nf_conntrack_tuple *repl,
562 const struct nf_conntrack_l3proto *l3proto,
563 u_int32_t features)
564{ 417{
565 struct nf_conn *conntrack = NULL; 418 struct nf_conn *conntrack = NULL;
566 struct nf_conntrack_helper *helper;
567 419
568 if (unlikely(!nf_conntrack_hash_rnd_initted)) { 420 if (unlikely(!nf_conntrack_hash_rnd_initted)) {
569 get_random_bytes(&nf_conntrack_hash_rnd, 4); 421 get_random_bytes(&nf_conntrack_hash_rnd, 4);
@@ -576,8 +428,7 @@ __nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
576 if (nf_conntrack_max 428 if (nf_conntrack_max
577 && atomic_read(&nf_conntrack_count) > nf_conntrack_max) { 429 && atomic_read(&nf_conntrack_count) > nf_conntrack_max) {
578 unsigned int hash = hash_conntrack(orig); 430 unsigned int hash = hash_conntrack(orig);
579 /* Try dropping from this hash chain. */ 431 if (!early_drop(hash)) {
580 if (!early_drop(&nf_conntrack_hash[hash])) {
581 atomic_dec(&nf_conntrack_count); 432 atomic_dec(&nf_conntrack_count);
582 if (net_ratelimit()) 433 if (net_ratelimit())
583 printk(KERN_WARNING 434 printk(KERN_WARNING
@@ -587,72 +438,28 @@ __nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
587 } 438 }
588 } 439 }
589 440
590 /* find features needed by this conntrack. */ 441 conntrack = kmem_cache_zalloc(nf_conntrack_cachep, GFP_ATOMIC);
591 features |= l3proto->get_features(orig);
592
593 /* FIXME: protect helper list per RCU */
594 read_lock_bh(&nf_conntrack_lock);
595 helper = __nf_ct_helper_find(repl);
596 /* NAT might want to assign a helper later */
597 if (helper || features & NF_CT_F_NAT)
598 features |= NF_CT_F_HELP;
599 read_unlock_bh(&nf_conntrack_lock);
600
601 DEBUGP("nf_conntrack_alloc: features=0x%x\n", features);
602
603 read_lock_bh(&nf_ct_cache_lock);
604
605 if (unlikely(!nf_ct_cache[features].use)) {
606 DEBUGP("nf_conntrack_alloc: not supported features = 0x%x\n",
607 features);
608 goto out;
609 }
610
611 conntrack = kmem_cache_alloc(nf_ct_cache[features].cachep, GFP_ATOMIC);
612 if (conntrack == NULL) { 442 if (conntrack == NULL) {
613 DEBUGP("nf_conntrack_alloc: Can't alloc conntrack from cache\n"); 443 pr_debug("nf_conntrack_alloc: Can't alloc conntrack.\n");
614 goto out; 444 atomic_dec(&nf_conntrack_count);
445 return ERR_PTR(-ENOMEM);
615 } 446 }
616 447
617 memset(conntrack, 0, nf_ct_cache[features].size);
618 conntrack->features = features;
619 atomic_set(&conntrack->ct_general.use, 1); 448 atomic_set(&conntrack->ct_general.use, 1);
620 conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig; 449 conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig;
621 conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *repl; 450 conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
622 /* Don't set timer yet: wait for confirmation */ 451 /* Don't set timer yet: wait for confirmation */
623 setup_timer(&conntrack->timeout, death_by_timeout, 452 setup_timer(&conntrack->timeout, death_by_timeout,
624 (unsigned long)conntrack); 453 (unsigned long)conntrack);
625 read_unlock_bh(&nf_ct_cache_lock);
626 454
627 return conntrack; 455 return conntrack;
628out:
629 read_unlock_bh(&nf_ct_cache_lock);
630 atomic_dec(&nf_conntrack_count);
631 return conntrack;
632}
633
634struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
635 const struct nf_conntrack_tuple *repl)
636{
637 struct nf_conntrack_l3proto *l3proto;
638 struct nf_conn *ct;
639
640 rcu_read_lock();
641 l3proto = __nf_ct_l3proto_find(orig->src.l3num);
642 ct = __nf_conntrack_alloc(orig, repl, l3proto, 0);
643 rcu_read_unlock();
644
645 return ct;
646} 456}
647EXPORT_SYMBOL_GPL(nf_conntrack_alloc); 457EXPORT_SYMBOL_GPL(nf_conntrack_alloc);
648 458
649void nf_conntrack_free(struct nf_conn *conntrack) 459void nf_conntrack_free(struct nf_conn *conntrack)
650{ 460{
651 u_int32_t features = conntrack->features; 461 nf_ct_ext_free(conntrack);
652 NF_CT_ASSERT(features >= NF_CT_F_BASIC && features < NF_CT_F_NUM); 462 kmem_cache_free(nf_conntrack_cachep, conntrack);
653 DEBUGP("nf_conntrack_free: features = 0x%x, conntrack=%p\n", features,
654 conntrack);
655 kmem_cache_free(nf_ct_cache[features].cachep, conntrack);
656 atomic_dec(&nf_conntrack_count); 463 atomic_dec(&nf_conntrack_count);
657} 464}
658EXPORT_SYMBOL_GPL(nf_conntrack_free); 465EXPORT_SYMBOL_GPL(nf_conntrack_free);
@@ -670,43 +477,38 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
670 struct nf_conn_help *help; 477 struct nf_conn_help *help;
671 struct nf_conntrack_tuple repl_tuple; 478 struct nf_conntrack_tuple repl_tuple;
672 struct nf_conntrack_expect *exp; 479 struct nf_conntrack_expect *exp;
673 u_int32_t features = 0;
674 480
675 if (!nf_ct_invert_tuple(&repl_tuple, tuple, l3proto, l4proto)) { 481 if (!nf_ct_invert_tuple(&repl_tuple, tuple, l3proto, l4proto)) {
676 DEBUGP("Can't invert tuple.\n"); 482 pr_debug("Can't invert tuple.\n");
677 return NULL; 483 return NULL;
678 } 484 }
679 485
680 read_lock_bh(&nf_conntrack_lock); 486 conntrack = nf_conntrack_alloc(tuple, &repl_tuple);
681 exp = __nf_conntrack_expect_find(tuple);
682 if (exp && exp->helper)
683 features = NF_CT_F_HELP;
684 read_unlock_bh(&nf_conntrack_lock);
685
686 conntrack = __nf_conntrack_alloc(tuple, &repl_tuple, l3proto, features);
687 if (conntrack == NULL || IS_ERR(conntrack)) { 487 if (conntrack == NULL || IS_ERR(conntrack)) {
688 DEBUGP("Can't allocate conntrack.\n"); 488 pr_debug("Can't allocate conntrack.\n");
689 return (struct nf_conntrack_tuple_hash *)conntrack; 489 return (struct nf_conntrack_tuple_hash *)conntrack;
690 } 490 }
691 491
692 if (!l4proto->new(conntrack, skb, dataoff)) { 492 if (!l4proto->new(conntrack, skb, dataoff)) {
693 nf_conntrack_free(conntrack); 493 nf_conntrack_free(conntrack);
694 DEBUGP("init conntrack: can't track with proto module\n"); 494 pr_debug("init conntrack: can't track with proto module\n");
695 return NULL; 495 return NULL;
696 } 496 }
697 497
698 write_lock_bh(&nf_conntrack_lock); 498 write_lock_bh(&nf_conntrack_lock);
699 exp = find_expectation(tuple); 499 exp = nf_ct_find_expectation(tuple);
700
701 help = nfct_help(conntrack);
702 if (exp) { 500 if (exp) {
703 DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n", 501 pr_debug("conntrack: expectation arrives ct=%p exp=%p\n",
704 conntrack, exp); 502 conntrack, exp);
705 /* Welcome, Mr. Bond. We've been expecting you... */ 503 /* Welcome, Mr. Bond. We've been expecting you... */
706 __set_bit(IPS_EXPECTED_BIT, &conntrack->status); 504 __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
707 conntrack->master = exp->master; 505 conntrack->master = exp->master;
708 if (exp->helper) 506 if (exp->helper) {
709 rcu_assign_pointer(help->helper, exp->helper); 507 help = nf_ct_helper_ext_add(conntrack, GFP_ATOMIC);
508 if (help)
509 rcu_assign_pointer(help->helper, exp->helper);
510 }
511
710#ifdef CONFIG_NF_CONNTRACK_MARK 512#ifdef CONFIG_NF_CONNTRACK_MARK
711 conntrack->mark = exp->master->mark; 513 conntrack->mark = exp->master->mark;
712#endif 514#endif
@@ -716,23 +518,27 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
716 nf_conntrack_get(&conntrack->master->ct_general); 518 nf_conntrack_get(&conntrack->master->ct_general);
717 NF_CT_STAT_INC(expect_new); 519 NF_CT_STAT_INC(expect_new);
718 } else { 520 } else {
719 if (help) { 521 struct nf_conntrack_helper *helper;
720 /* not in hash table yet, so not strictly necessary */ 522
721 rcu_assign_pointer(help->helper, 523 helper = __nf_ct_helper_find(&repl_tuple);
722 __nf_ct_helper_find(&repl_tuple)); 524 if (helper) {
525 help = nf_ct_helper_ext_add(conntrack, GFP_ATOMIC);
526 if (help)
527 rcu_assign_pointer(help->helper, helper);
723 } 528 }
724 NF_CT_STAT_INC(new); 529 NF_CT_STAT_INC(new);
725 } 530 }
726 531
727 /* Overload tuple linked list to put us in unconfirmed list. */ 532 /* Overload tuple linked list to put us in unconfirmed list. */
728 list_add(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].list, &unconfirmed); 533 hlist_add_head(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].hnode,
534 &unconfirmed);
729 535
730 write_unlock_bh(&nf_conntrack_lock); 536 write_unlock_bh(&nf_conntrack_lock);
731 537
732 if (exp) { 538 if (exp) {
733 if (exp->expectfn) 539 if (exp->expectfn)
734 exp->expectfn(conntrack, exp); 540 exp->expectfn(conntrack, exp);
735 nf_conntrack_expect_put(exp); 541 nf_ct_expect_put(exp);
736 } 542 }
737 543
738 return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL]; 544 return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
@@ -756,12 +562,12 @@ resolve_normal_ct(struct sk_buff *skb,
756 if (!nf_ct_get_tuple(skb, skb_network_offset(skb), 562 if (!nf_ct_get_tuple(skb, skb_network_offset(skb),
757 dataoff, l3num, protonum, &tuple, l3proto, 563 dataoff, l3num, protonum, &tuple, l3proto,
758 l4proto)) { 564 l4proto)) {
759 DEBUGP("resolve_normal_ct: Can't get tuple\n"); 565 pr_debug("resolve_normal_ct: Can't get tuple\n");
760 return NULL; 566 return NULL;
761 } 567 }
762 568
763 /* look for tuple match */ 569 /* look for tuple match */
764 h = nf_conntrack_find_get(&tuple, NULL); 570 h = nf_conntrack_find_get(&tuple);
765 if (!h) { 571 if (!h) {
766 h = init_conntrack(&tuple, l3proto, l4proto, skb, dataoff); 572 h = init_conntrack(&tuple, l3proto, l4proto, skb, dataoff);
767 if (!h) 573 if (!h)
@@ -779,13 +585,14 @@ resolve_normal_ct(struct sk_buff *skb,
779 } else { 585 } else {
780 /* Once we've had two way comms, always ESTABLISHED. */ 586 /* Once we've had two way comms, always ESTABLISHED. */
781 if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) { 587 if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
782 DEBUGP("nf_conntrack_in: normal packet for %p\n", ct); 588 pr_debug("nf_conntrack_in: normal packet for %p\n", ct);
783 *ctinfo = IP_CT_ESTABLISHED; 589 *ctinfo = IP_CT_ESTABLISHED;
784 } else if (test_bit(IPS_EXPECTED_BIT, &ct->status)) { 590 } else if (test_bit(IPS_EXPECTED_BIT, &ct->status)) {
785 DEBUGP("nf_conntrack_in: related packet for %p\n", ct); 591 pr_debug("nf_conntrack_in: related packet for %p\n",
592 ct);
786 *ctinfo = IP_CT_RELATED; 593 *ctinfo = IP_CT_RELATED;
787 } else { 594 } else {
788 DEBUGP("nf_conntrack_in: new packet for %p\n", ct); 595 pr_debug("nf_conntrack_in: new packet for %p\n", ct);
789 *ctinfo = IP_CT_NEW; 596 *ctinfo = IP_CT_NEW;
790 } 597 }
791 *set_reply = 0; 598 *set_reply = 0;
@@ -817,7 +624,7 @@ nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff **pskb)
817 l3proto = __nf_ct_l3proto_find((u_int16_t)pf); 624 l3proto = __nf_ct_l3proto_find((u_int16_t)pf);
818 625
819 if ((ret = l3proto->prepare(pskb, hooknum, &dataoff, &protonum)) <= 0) { 626 if ((ret = l3proto->prepare(pskb, hooknum, &dataoff, &protonum)) <= 0) {
820 DEBUGP("not prepared to track yet or error occured\n"); 627 pr_debug("not prepared to track yet or error occured\n");
821 return -ret; 628 return -ret;
822 } 629 }
823 630
@@ -853,7 +660,7 @@ nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff **pskb)
853 if (ret < 0) { 660 if (ret < 0) {
854 /* Invalid: inverse of the return code tells 661 /* Invalid: inverse of the return code tells
855 * the netfilter core what to do */ 662 * the netfilter core what to do */
856 DEBUGP("nf_conntrack_in: Can't track with proto module\n"); 663 pr_debug("nf_conntrack_in: Can't track with proto module\n");
857 nf_conntrack_put((*pskb)->nfct); 664 nf_conntrack_put((*pskb)->nfct);
858 (*pskb)->nfct = NULL; 665 (*pskb)->nfct = NULL;
859 NF_CT_STAT_INC_ATOMIC(invalid); 666 NF_CT_STAT_INC_ATOMIC(invalid);
@@ -888,23 +695,36 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
888 const struct nf_conntrack_tuple *newreply) 695 const struct nf_conntrack_tuple *newreply)
889{ 696{
890 struct nf_conn_help *help = nfct_help(ct); 697 struct nf_conn_help *help = nfct_help(ct);
698 struct nf_conntrack_helper *helper;
891 699
892 write_lock_bh(&nf_conntrack_lock); 700 write_lock_bh(&nf_conntrack_lock);
893 /* Should be unconfirmed, so not in hash table yet */ 701 /* Should be unconfirmed, so not in hash table yet */
894 NF_CT_ASSERT(!nf_ct_is_confirmed(ct)); 702 NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
895 703
896 DEBUGP("Altering reply tuple of %p to ", ct); 704 pr_debug("Altering reply tuple of %p to ", ct);
897 NF_CT_DUMP_TUPLE(newreply); 705 NF_CT_DUMP_TUPLE(newreply);
898 706
899 ct->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply; 707 ct->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
900 if (!ct->master && help && help->expecting == 0) { 708 if (ct->master || (help && help->expecting != 0))
901 struct nf_conntrack_helper *helper; 709 goto out;
902 helper = __nf_ct_helper_find(newreply); 710
903 if (helper) 711 helper = __nf_ct_helper_find(newreply);
904 memset(&help->help, 0, sizeof(help->help)); 712 if (helper == NULL) {
905 /* not in hash table yet, so not strictly necessary */ 713 if (help)
906 rcu_assign_pointer(help->helper, helper); 714 rcu_assign_pointer(help->helper, NULL);
715 goto out;
907 } 716 }
717
718 if (help == NULL) {
719 help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
720 if (help == NULL)
721 goto out;
722 } else {
723 memset(&help->help, 0, sizeof(help->help));
724 }
725
726 rcu_assign_pointer(help->helper, helper);
727out:
908 write_unlock_bh(&nf_conntrack_lock); 728 write_unlock_bh(&nf_conntrack_lock);
909} 729}
910EXPORT_SYMBOL_GPL(nf_conntrack_alter_reply); 730EXPORT_SYMBOL_GPL(nf_conntrack_alter_reply);
@@ -1048,16 +868,17 @@ get_next_corpse(int (*iter)(struct nf_conn *i, void *data),
1048{ 868{
1049 struct nf_conntrack_tuple_hash *h; 869 struct nf_conntrack_tuple_hash *h;
1050 struct nf_conn *ct; 870 struct nf_conn *ct;
871 struct hlist_node *n;
1051 872
1052 write_lock_bh(&nf_conntrack_lock); 873 write_lock_bh(&nf_conntrack_lock);
1053 for (; *bucket < nf_conntrack_htable_size; (*bucket)++) { 874 for (; *bucket < nf_conntrack_htable_size; (*bucket)++) {
1054 list_for_each_entry(h, &nf_conntrack_hash[*bucket], list) { 875 hlist_for_each_entry(h, n, &nf_conntrack_hash[*bucket], hnode) {
1055 ct = nf_ct_tuplehash_to_ctrack(h); 876 ct = nf_ct_tuplehash_to_ctrack(h);
1056 if (iter(ct, data)) 877 if (iter(ct, data))
1057 goto found; 878 goto found;
1058 } 879 }
1059 } 880 }
1060 list_for_each_entry(h, &unconfirmed, list) { 881 hlist_for_each_entry(h, n, &unconfirmed, hnode) {
1061 ct = nf_ct_tuplehash_to_ctrack(h); 882 ct = nf_ct_tuplehash_to_ctrack(h);
1062 if (iter(ct, data)) 883 if (iter(ct, data))
1063 set_bit(IPS_DYING_BIT, &ct->status); 884 set_bit(IPS_DYING_BIT, &ct->status);
@@ -1092,14 +913,15 @@ static int kill_all(struct nf_conn *i, void *data)
1092 return 1; 913 return 1;
1093} 914}
1094 915
1095static void free_conntrack_hash(struct list_head *hash, int vmalloced, int size) 916void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced, int size)
1096{ 917{
1097 if (vmalloced) 918 if (vmalloced)
1098 vfree(hash); 919 vfree(hash);
1099 else 920 else
1100 free_pages((unsigned long)hash, 921 free_pages((unsigned long)hash,
1101 get_order(sizeof(struct list_head) * size)); 922 get_order(sizeof(struct hlist_head) * size));
1102} 923}
924EXPORT_SYMBOL_GPL(nf_ct_free_hashtable);
1103 925
1104void nf_conntrack_flush(void) 926void nf_conntrack_flush(void)
1105{ 927{
@@ -1111,8 +933,6 @@ EXPORT_SYMBOL_GPL(nf_conntrack_flush);
1111 supposed to kill the mall. */ 933 supposed to kill the mall. */
1112void nf_conntrack_cleanup(void) 934void nf_conntrack_cleanup(void)
1113{ 935{
1114 int i;
1115
1116 rcu_assign_pointer(ip_ct_attach, NULL); 936 rcu_assign_pointer(ip_ct_attach, NULL);
1117 937
1118 /* This makes sure all current packets have passed through 938 /* This makes sure all current packets have passed through
@@ -1133,49 +953,46 @@ void nf_conntrack_cleanup(void)
1133 953
1134 rcu_assign_pointer(nf_ct_destroy, NULL); 954 rcu_assign_pointer(nf_ct_destroy, NULL);
1135 955
1136 for (i = 0; i < NF_CT_F_NUM; i++) { 956 kmem_cache_destroy(nf_conntrack_cachep);
1137 if (nf_ct_cache[i].use == 0) 957 nf_ct_free_hashtable(nf_conntrack_hash, nf_conntrack_vmalloc,
1138 continue; 958 nf_conntrack_htable_size);
1139
1140 NF_CT_ASSERT(nf_ct_cache[i].use == 1);
1141 nf_ct_cache[i].use = 1;
1142 nf_conntrack_unregister_cache(i);
1143 }
1144 kmem_cache_destroy(nf_conntrack_expect_cachep);
1145 free_conntrack_hash(nf_conntrack_hash, nf_conntrack_vmalloc,
1146 nf_conntrack_htable_size);
1147 959
1148 nf_conntrack_proto_fini(); 960 nf_conntrack_proto_fini();
961 nf_conntrack_helper_fini();
962 nf_conntrack_expect_fini();
1149} 963}
1150 964
1151static struct list_head *alloc_hashtable(int size, int *vmalloced) 965struct hlist_head *nf_ct_alloc_hashtable(int *sizep, int *vmalloced)
1152{ 966{
1153 struct list_head *hash; 967 struct hlist_head *hash;
1154 unsigned int i; 968 unsigned int size, i;
1155 969
1156 *vmalloced = 0; 970 *vmalloced = 0;
971
972 size = *sizep = roundup(*sizep, PAGE_SIZE / sizeof(struct hlist_head));
1157 hash = (void*)__get_free_pages(GFP_KERNEL, 973 hash = (void*)__get_free_pages(GFP_KERNEL,
1158 get_order(sizeof(struct list_head) 974 get_order(sizeof(struct hlist_head)
1159 * size)); 975 * size));
1160 if (!hash) { 976 if (!hash) {
1161 *vmalloced = 1; 977 *vmalloced = 1;
1162 printk(KERN_WARNING "nf_conntrack: falling back to vmalloc.\n"); 978 printk(KERN_WARNING "nf_conntrack: falling back to vmalloc.\n");
1163 hash = vmalloc(sizeof(struct list_head) * size); 979 hash = vmalloc(sizeof(struct hlist_head) * size);
1164 } 980 }
1165 981
1166 if (hash) 982 if (hash)
1167 for (i = 0; i < size; i++) 983 for (i = 0; i < size; i++)
1168 INIT_LIST_HEAD(&hash[i]); 984 INIT_HLIST_HEAD(&hash[i]);
1169 985
1170 return hash; 986 return hash;
1171} 987}
988EXPORT_SYMBOL_GPL(nf_ct_alloc_hashtable);
1172 989
1173int set_hashsize(const char *val, struct kernel_param *kp) 990int set_hashsize(const char *val, struct kernel_param *kp)
1174{ 991{
1175 int i, bucket, hashsize, vmalloced; 992 int i, bucket, hashsize, vmalloced;
1176 int old_vmalloced, old_size; 993 int old_vmalloced, old_size;
1177 int rnd; 994 int rnd;
1178 struct list_head *hash, *old_hash; 995 struct hlist_head *hash, *old_hash;
1179 struct nf_conntrack_tuple_hash *h; 996 struct nf_conntrack_tuple_hash *h;
1180 997
1181 /* On boot, we can set this without any fancy locking. */ 998 /* On boot, we can set this without any fancy locking. */
@@ -1186,7 +1003,7 @@ int set_hashsize(const char *val, struct kernel_param *kp)
1186 if (!hashsize) 1003 if (!hashsize)
1187 return -EINVAL; 1004 return -EINVAL;
1188 1005
1189 hash = alloc_hashtable(hashsize, &vmalloced); 1006 hash = nf_ct_alloc_hashtable(&hashsize, &vmalloced);
1190 if (!hash) 1007 if (!hash)
1191 return -ENOMEM; 1008 return -ENOMEM;
1192 1009
@@ -1196,12 +1013,12 @@ int set_hashsize(const char *val, struct kernel_param *kp)
1196 1013
1197 write_lock_bh(&nf_conntrack_lock); 1014 write_lock_bh(&nf_conntrack_lock);
1198 for (i = 0; i < nf_conntrack_htable_size; i++) { 1015 for (i = 0; i < nf_conntrack_htable_size; i++) {
1199 while (!list_empty(&nf_conntrack_hash[i])) { 1016 while (!hlist_empty(&nf_conntrack_hash[i])) {
1200 h = list_entry(nf_conntrack_hash[i].next, 1017 h = hlist_entry(nf_conntrack_hash[i].first,
1201 struct nf_conntrack_tuple_hash, list); 1018 struct nf_conntrack_tuple_hash, hnode);
1202 list_del(&h->list); 1019 hlist_del(&h->hnode);
1203 bucket = __hash_conntrack(&h->tuple, hashsize, rnd); 1020 bucket = __hash_conntrack(&h->tuple, hashsize, rnd);
1204 list_add_tail(&h->list, &hash[bucket]); 1021 hlist_add_head(&h->hnode, &hash[bucket]);
1205 } 1022 }
1206 } 1023 }
1207 old_size = nf_conntrack_htable_size; 1024 old_size = nf_conntrack_htable_size;
@@ -1214,7 +1031,7 @@ int set_hashsize(const char *val, struct kernel_param *kp)
1214 nf_conntrack_hash_rnd = rnd; 1031 nf_conntrack_hash_rnd = rnd;
1215 write_unlock_bh(&nf_conntrack_lock); 1032 write_unlock_bh(&nf_conntrack_lock);
1216 1033
1217 free_conntrack_hash(old_hash, old_vmalloced, old_size); 1034 nf_ct_free_hashtable(old_hash, old_vmalloced, old_size);
1218 return 0; 1035 return 0;
1219} 1036}
1220 1037
@@ -1223,50 +1040,58 @@ module_param_call(hashsize, set_hashsize, param_get_uint,
1223 1040
1224int __init nf_conntrack_init(void) 1041int __init nf_conntrack_init(void)
1225{ 1042{
1043 int max_factor = 8;
1226 int ret; 1044 int ret;
1227 1045
1228 /* Idea from tcp.c: use 1/16384 of memory. On i386: 32MB 1046 /* Idea from tcp.c: use 1/16384 of memory. On i386: 32MB
1229 * machine has 256 buckets. >= 1GB machines have 8192 buckets. */ 1047 * machine has 512 buckets. >= 1GB machines have 16384 buckets. */
1230 if (!nf_conntrack_htable_size) { 1048 if (!nf_conntrack_htable_size) {
1231 nf_conntrack_htable_size 1049 nf_conntrack_htable_size
1232 = (((num_physpages << PAGE_SHIFT) / 16384) 1050 = (((num_physpages << PAGE_SHIFT) / 16384)
1233 / sizeof(struct list_head)); 1051 / sizeof(struct hlist_head));
1234 if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE)) 1052 if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))
1235 nf_conntrack_htable_size = 8192; 1053 nf_conntrack_htable_size = 16384;
1236 if (nf_conntrack_htable_size < 16) 1054 if (nf_conntrack_htable_size < 32)
1237 nf_conntrack_htable_size = 16; 1055 nf_conntrack_htable_size = 32;
1056
1057 /* Use a max. factor of four by default to get the same max as
1058 * with the old struct list_heads. When a table size is given
1059 * we use the old value of 8 to avoid reducing the max.
1060 * entries. */
1061 max_factor = 4;
1238 } 1062 }
1239 nf_conntrack_max = 8 * nf_conntrack_htable_size; 1063 nf_conntrack_hash = nf_ct_alloc_hashtable(&nf_conntrack_htable_size,
1240 1064 &nf_conntrack_vmalloc);
1241 printk("nf_conntrack version %s (%u buckets, %d max)\n",
1242 NF_CONNTRACK_VERSION, nf_conntrack_htable_size,
1243 nf_conntrack_max);
1244
1245 nf_conntrack_hash = alloc_hashtable(nf_conntrack_htable_size,
1246 &nf_conntrack_vmalloc);
1247 if (!nf_conntrack_hash) { 1065 if (!nf_conntrack_hash) {
1248 printk(KERN_ERR "Unable to create nf_conntrack_hash\n"); 1066 printk(KERN_ERR "Unable to create nf_conntrack_hash\n");
1249 goto err_out; 1067 goto err_out;
1250 } 1068 }
1251 1069
1252 ret = nf_conntrack_register_cache(NF_CT_F_BASIC, "nf_conntrack:basic", 1070 nf_conntrack_max = max_factor * nf_conntrack_htable_size;
1253 sizeof(struct nf_conn)); 1071
1254 if (ret < 0) { 1072 printk("nf_conntrack version %s (%u buckets, %d max)\n",
1073 NF_CONNTRACK_VERSION, nf_conntrack_htable_size,
1074 nf_conntrack_max);
1075
1076 nf_conntrack_cachep = kmem_cache_create("nf_conntrack",
1077 sizeof(struct nf_conn),
1078 0, 0, NULL, NULL);
1079 if (!nf_conntrack_cachep) {
1255 printk(KERN_ERR "Unable to create nf_conn slab cache\n"); 1080 printk(KERN_ERR "Unable to create nf_conn slab cache\n");
1256 goto err_free_hash; 1081 goto err_free_hash;
1257 } 1082 }
1258 1083
1259 nf_conntrack_expect_cachep = kmem_cache_create("nf_conntrack_expect", 1084 ret = nf_conntrack_proto_init();
1260 sizeof(struct nf_conntrack_expect), 1085 if (ret < 0)
1261 0, 0, NULL, NULL);
1262 if (!nf_conntrack_expect_cachep) {
1263 printk(KERN_ERR "Unable to create nf_expect slab cache\n");
1264 goto err_free_conntrack_slab; 1086 goto err_free_conntrack_slab;
1265 }
1266 1087
1267 ret = nf_conntrack_proto_init(); 1088 ret = nf_conntrack_expect_init();
1268 if (ret < 0) 1089 if (ret < 0)
1269 goto out_free_expect_slab; 1090 goto out_fini_proto;
1091
1092 ret = nf_conntrack_helper_init();
1093 if (ret < 0)
1094 goto out_fini_expect;
1270 1095
1271 /* For use by REJECT target */ 1096 /* For use by REJECT target */
1272 rcu_assign_pointer(ip_ct_attach, __nf_conntrack_attach); 1097 rcu_assign_pointer(ip_ct_attach, __nf_conntrack_attach);
@@ -1280,13 +1105,15 @@ int __init nf_conntrack_init(void)
1280 1105
1281 return ret; 1106 return ret;
1282 1107
1283out_free_expect_slab: 1108out_fini_expect:
1284 kmem_cache_destroy(nf_conntrack_expect_cachep); 1109 nf_conntrack_expect_fini();
1110out_fini_proto:
1111 nf_conntrack_proto_fini();
1285err_free_conntrack_slab: 1112err_free_conntrack_slab:
1286 nf_conntrack_unregister_cache(NF_CT_F_BASIC); 1113 kmem_cache_destroy(nf_conntrack_cachep);
1287err_free_hash: 1114err_free_hash:
1288 free_conntrack_hash(nf_conntrack_hash, nf_conntrack_vmalloc, 1115 nf_ct_free_hashtable(nf_conntrack_hash, nf_conntrack_vmalloc,
1289 nf_conntrack_htable_size); 1116 nf_conntrack_htable_size);
1290err_out: 1117err_out:
1291 return -ENOMEM; 1118 return -ENOMEM;
1292} 1119}
diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c
index 6bd421df2dbc..83c41ac3505b 100644
--- a/net/netfilter/nf_conntrack_ecache.c
+++ b/net/netfilter/nf_conntrack_ecache.c
@@ -26,8 +26,8 @@
26ATOMIC_NOTIFIER_HEAD(nf_conntrack_chain); 26ATOMIC_NOTIFIER_HEAD(nf_conntrack_chain);
27EXPORT_SYMBOL_GPL(nf_conntrack_chain); 27EXPORT_SYMBOL_GPL(nf_conntrack_chain);
28 28
29ATOMIC_NOTIFIER_HEAD(nf_conntrack_expect_chain); 29ATOMIC_NOTIFIER_HEAD(nf_ct_expect_chain);
30EXPORT_SYMBOL_GPL(nf_conntrack_expect_chain); 30EXPORT_SYMBOL_GPL(nf_ct_expect_chain);
31 31
32DEFINE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache); 32DEFINE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache);
33EXPORT_PER_CPU_SYMBOL_GPL(nf_conntrack_ecache); 33EXPORT_PER_CPU_SYMBOL_GPL(nf_conntrack_ecache);
@@ -103,14 +103,14 @@ int nf_conntrack_unregister_notifier(struct notifier_block *nb)
103} 103}
104EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier); 104EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
105 105
106int nf_conntrack_expect_register_notifier(struct notifier_block *nb) 106int nf_ct_expect_register_notifier(struct notifier_block *nb)
107{ 107{
108 return atomic_notifier_chain_register(&nf_conntrack_expect_chain, nb); 108 return atomic_notifier_chain_register(&nf_ct_expect_chain, nb);
109} 109}
110EXPORT_SYMBOL_GPL(nf_conntrack_expect_register_notifier); 110EXPORT_SYMBOL_GPL(nf_ct_expect_register_notifier);
111 111
112int nf_conntrack_expect_unregister_notifier(struct notifier_block *nb) 112int nf_ct_expect_unregister_notifier(struct notifier_block *nb)
113{ 113{
114 return atomic_notifier_chain_unregister(&nf_conntrack_expect_chain, nb); 114 return atomic_notifier_chain_unregister(&nf_ct_expect_chain, nb);
115} 115}
116EXPORT_SYMBOL_GPL(nf_conntrack_expect_unregister_notifier); 116EXPORT_SYMBOL_GPL(nf_ct_expect_unregister_notifier);
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index 504fb6c083f9..2191fe008f60 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -19,6 +19,7 @@
19#include <linux/err.h> 19#include <linux/err.h>
20#include <linux/percpu.h> 20#include <linux/percpu.h>
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/jhash.h>
22 23
23#include <net/netfilter/nf_conntrack.h> 24#include <net/netfilter/nf_conntrack.h>
24#include <net/netfilter/nf_conntrack_core.h> 25#include <net/netfilter/nf_conntrack_core.h>
@@ -26,11 +27,20 @@
26#include <net/netfilter/nf_conntrack_helper.h> 27#include <net/netfilter/nf_conntrack_helper.h>
27#include <net/netfilter/nf_conntrack_tuple.h> 28#include <net/netfilter/nf_conntrack_tuple.h>
28 29
29LIST_HEAD(nf_conntrack_expect_list); 30struct hlist_head *nf_ct_expect_hash __read_mostly;
30EXPORT_SYMBOL_GPL(nf_conntrack_expect_list); 31EXPORT_SYMBOL_GPL(nf_ct_expect_hash);
31 32
32struct kmem_cache *nf_conntrack_expect_cachep __read_mostly; 33unsigned int nf_ct_expect_hsize __read_mostly;
33static unsigned int nf_conntrack_expect_next_id; 34EXPORT_SYMBOL_GPL(nf_ct_expect_hsize);
35
36static unsigned int nf_ct_expect_hash_rnd __read_mostly;
37static unsigned int nf_ct_expect_count;
38unsigned int nf_ct_expect_max __read_mostly;
39static int nf_ct_expect_hash_rnd_initted __read_mostly;
40static int nf_ct_expect_vmalloc;
41
42static struct kmem_cache *nf_ct_expect_cachep __read_mostly;
43static unsigned int nf_ct_expect_next_id;
34 44
35/* nf_conntrack_expect helper functions */ 45/* nf_conntrack_expect helper functions */
36void nf_ct_unlink_expect(struct nf_conntrack_expect *exp) 46void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
@@ -40,60 +50,83 @@ void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
40 NF_CT_ASSERT(master_help); 50 NF_CT_ASSERT(master_help);
41 NF_CT_ASSERT(!timer_pending(&exp->timeout)); 51 NF_CT_ASSERT(!timer_pending(&exp->timeout));
42 52
43 list_del(&exp->list); 53 hlist_del(&exp->hnode);
44 NF_CT_STAT_INC(expect_delete); 54 nf_ct_expect_count--;
55
56 hlist_del(&exp->lnode);
45 master_help->expecting--; 57 master_help->expecting--;
46 nf_conntrack_expect_put(exp); 58 nf_ct_expect_put(exp);
59
60 NF_CT_STAT_INC(expect_delete);
47} 61}
48EXPORT_SYMBOL_GPL(nf_ct_unlink_expect); 62EXPORT_SYMBOL_GPL(nf_ct_unlink_expect);
49 63
50static void expectation_timed_out(unsigned long ul_expect) 64static void nf_ct_expectation_timed_out(unsigned long ul_expect)
51{ 65{
52 struct nf_conntrack_expect *exp = (void *)ul_expect; 66 struct nf_conntrack_expect *exp = (void *)ul_expect;
53 67
54 write_lock_bh(&nf_conntrack_lock); 68 write_lock_bh(&nf_conntrack_lock);
55 nf_ct_unlink_expect(exp); 69 nf_ct_unlink_expect(exp);
56 write_unlock_bh(&nf_conntrack_lock); 70 write_unlock_bh(&nf_conntrack_lock);
57 nf_conntrack_expect_put(exp); 71 nf_ct_expect_put(exp);
72}
73
74static unsigned int nf_ct_expect_dst_hash(const struct nf_conntrack_tuple *tuple)
75{
76 if (unlikely(!nf_ct_expect_hash_rnd_initted)) {
77 get_random_bytes(&nf_ct_expect_hash_rnd, 4);
78 nf_ct_expect_hash_rnd_initted = 1;
79 }
80
81 return jhash2(tuple->dst.u3.all, ARRAY_SIZE(tuple->dst.u3.all),
82 (((tuple->dst.protonum ^ tuple->src.l3num) << 16) |
83 tuple->dst.u.all) ^ nf_ct_expect_hash_rnd) %
84 nf_ct_expect_hsize;
58} 85}
59 86
60struct nf_conntrack_expect * 87struct nf_conntrack_expect *
61__nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple) 88__nf_ct_expect_find(const struct nf_conntrack_tuple *tuple)
62{ 89{
63 struct nf_conntrack_expect *i; 90 struct nf_conntrack_expect *i;
91 struct hlist_node *n;
92 unsigned int h;
93
94 if (!nf_ct_expect_count)
95 return NULL;
64 96
65 list_for_each_entry(i, &nf_conntrack_expect_list, list) { 97 h = nf_ct_expect_dst_hash(tuple);
98 hlist_for_each_entry(i, n, &nf_ct_expect_hash[h], hnode) {
66 if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) 99 if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask))
67 return i; 100 return i;
68 } 101 }
69 return NULL; 102 return NULL;
70} 103}
71EXPORT_SYMBOL_GPL(__nf_conntrack_expect_find); 104EXPORT_SYMBOL_GPL(__nf_ct_expect_find);
72 105
73/* Just find a expectation corresponding to a tuple. */ 106/* Just find a expectation corresponding to a tuple. */
74struct nf_conntrack_expect * 107struct nf_conntrack_expect *
75nf_conntrack_expect_find_get(const struct nf_conntrack_tuple *tuple) 108nf_ct_expect_find_get(const struct nf_conntrack_tuple *tuple)
76{ 109{
77 struct nf_conntrack_expect *i; 110 struct nf_conntrack_expect *i;
78 111
79 read_lock_bh(&nf_conntrack_lock); 112 read_lock_bh(&nf_conntrack_lock);
80 i = __nf_conntrack_expect_find(tuple); 113 i = __nf_ct_expect_find(tuple);
81 if (i) 114 if (i)
82 atomic_inc(&i->use); 115 atomic_inc(&i->use);
83 read_unlock_bh(&nf_conntrack_lock); 116 read_unlock_bh(&nf_conntrack_lock);
84 117
85 return i; 118 return i;
86} 119}
87EXPORT_SYMBOL_GPL(nf_conntrack_expect_find_get); 120EXPORT_SYMBOL_GPL(nf_ct_expect_find_get);
88 121
89/* If an expectation for this connection is found, it gets delete from 122/* If an expectation for this connection is found, it gets delete from
90 * global list then returned. */ 123 * global list then returned. */
91struct nf_conntrack_expect * 124struct nf_conntrack_expect *
92find_expectation(const struct nf_conntrack_tuple *tuple) 125nf_ct_find_expectation(const struct nf_conntrack_tuple *tuple)
93{ 126{
94 struct nf_conntrack_expect *exp; 127 struct nf_conntrack_expect *exp;
95 128
96 exp = __nf_conntrack_expect_find(tuple); 129 exp = __nf_ct_expect_find(tuple);
97 if (!exp) 130 if (!exp)
98 return NULL; 131 return NULL;
99 132
@@ -119,17 +152,18 @@ find_expectation(const struct nf_conntrack_tuple *tuple)
119/* delete all expectations for this conntrack */ 152/* delete all expectations for this conntrack */
120void nf_ct_remove_expectations(struct nf_conn *ct) 153void nf_ct_remove_expectations(struct nf_conn *ct)
121{ 154{
122 struct nf_conntrack_expect *i, *tmp;
123 struct nf_conn_help *help = nfct_help(ct); 155 struct nf_conn_help *help = nfct_help(ct);
156 struct nf_conntrack_expect *exp;
157 struct hlist_node *n, *next;
124 158
125 /* Optimization: most connection never expect any others. */ 159 /* Optimization: most connection never expect any others. */
126 if (!help || help->expecting == 0) 160 if (!help || help->expecting == 0)
127 return; 161 return;
128 162
129 list_for_each_entry_safe(i, tmp, &nf_conntrack_expect_list, list) { 163 hlist_for_each_entry_safe(exp, n, next, &help->expectations, lnode) {
130 if (i->master == ct && del_timer(&i->timeout)) { 164 if (del_timer(&exp->timeout)) {
131 nf_ct_unlink_expect(i); 165 nf_ct_unlink_expect(exp);
132 nf_conntrack_expect_put(i); 166 nf_ct_expect_put(exp);
133 } 167 }
134 } 168 }
135} 169}
@@ -141,25 +175,16 @@ static inline int expect_clash(const struct nf_conntrack_expect *a,
141{ 175{
142 /* Part covered by intersection of masks must be unequal, 176 /* Part covered by intersection of masks must be unequal,
143 otherwise they clash */ 177 otherwise they clash */
144 struct nf_conntrack_tuple intersect_mask; 178 struct nf_conntrack_tuple_mask intersect_mask;
145 int count; 179 int count;
146 180
147 intersect_mask.src.l3num = a->mask.src.l3num & b->mask.src.l3num;
148 intersect_mask.src.u.all = a->mask.src.u.all & b->mask.src.u.all; 181 intersect_mask.src.u.all = a->mask.src.u.all & b->mask.src.u.all;
149 intersect_mask.dst.u.all = a->mask.dst.u.all & b->mask.dst.u.all;
150 intersect_mask.dst.protonum = a->mask.dst.protonum
151 & b->mask.dst.protonum;
152 182
153 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){ 183 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
154 intersect_mask.src.u3.all[count] = 184 intersect_mask.src.u3.all[count] =
155 a->mask.src.u3.all[count] & b->mask.src.u3.all[count]; 185 a->mask.src.u3.all[count] & b->mask.src.u3.all[count];
156 } 186 }
157 187
158 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
159 intersect_mask.dst.u3.all[count] =
160 a->mask.dst.u3.all[count] & b->mask.dst.u3.all[count];
161 }
162
163 return nf_ct_tuple_mask_cmp(&a->tuple, &b->tuple, &intersect_mask); 188 return nf_ct_tuple_mask_cmp(&a->tuple, &b->tuple, &intersect_mask);
164} 189}
165 190
@@ -168,36 +193,29 @@ static inline int expect_matches(const struct nf_conntrack_expect *a,
168{ 193{
169 return a->master == b->master 194 return a->master == b->master
170 && nf_ct_tuple_equal(&a->tuple, &b->tuple) 195 && nf_ct_tuple_equal(&a->tuple, &b->tuple)
171 && nf_ct_tuple_equal(&a->mask, &b->mask); 196 && nf_ct_tuple_mask_equal(&a->mask, &b->mask);
172} 197}
173 198
174/* Generally a bad idea to call this: could have matched already. */ 199/* Generally a bad idea to call this: could have matched already. */
175void nf_conntrack_unexpect_related(struct nf_conntrack_expect *exp) 200void nf_ct_unexpect_related(struct nf_conntrack_expect *exp)
176{ 201{
177 struct nf_conntrack_expect *i;
178
179 write_lock_bh(&nf_conntrack_lock); 202 write_lock_bh(&nf_conntrack_lock);
180 /* choose the oldest expectation to evict */ 203 if (del_timer(&exp->timeout)) {
181 list_for_each_entry_reverse(i, &nf_conntrack_expect_list, list) { 204 nf_ct_unlink_expect(exp);
182 if (expect_matches(i, exp) && del_timer(&i->timeout)) { 205 nf_ct_expect_put(exp);
183 nf_ct_unlink_expect(i);
184 write_unlock_bh(&nf_conntrack_lock);
185 nf_conntrack_expect_put(i);
186 return;
187 }
188 } 206 }
189 write_unlock_bh(&nf_conntrack_lock); 207 write_unlock_bh(&nf_conntrack_lock);
190} 208}
191EXPORT_SYMBOL_GPL(nf_conntrack_unexpect_related); 209EXPORT_SYMBOL_GPL(nf_ct_unexpect_related);
192 210
193/* We don't increase the master conntrack refcount for non-fulfilled 211/* We don't increase the master conntrack refcount for non-fulfilled
194 * conntracks. During the conntrack destruction, the expectations are 212 * conntracks. During the conntrack destruction, the expectations are
195 * always killed before the conntrack itself */ 213 * always killed before the conntrack itself */
196struct nf_conntrack_expect *nf_conntrack_expect_alloc(struct nf_conn *me) 214struct nf_conntrack_expect *nf_ct_expect_alloc(struct nf_conn *me)
197{ 215{
198 struct nf_conntrack_expect *new; 216 struct nf_conntrack_expect *new;
199 217
200 new = kmem_cache_alloc(nf_conntrack_expect_cachep, GFP_ATOMIC); 218 new = kmem_cache_alloc(nf_ct_expect_cachep, GFP_ATOMIC);
201 if (!new) 219 if (!new)
202 return NULL; 220 return NULL;
203 221
@@ -205,12 +223,12 @@ struct nf_conntrack_expect *nf_conntrack_expect_alloc(struct nf_conn *me)
205 atomic_set(&new->use, 1); 223 atomic_set(&new->use, 1);
206 return new; 224 return new;
207} 225}
208EXPORT_SYMBOL_GPL(nf_conntrack_expect_alloc); 226EXPORT_SYMBOL_GPL(nf_ct_expect_alloc);
209 227
210void nf_conntrack_expect_init(struct nf_conntrack_expect *exp, int family, 228void nf_ct_expect_init(struct nf_conntrack_expect *exp, int family,
211 union nf_conntrack_address *saddr, 229 union nf_conntrack_address *saddr,
212 union nf_conntrack_address *daddr, 230 union nf_conntrack_address *daddr,
213 u_int8_t proto, __be16 *src, __be16 *dst) 231 u_int8_t proto, __be16 *src, __be16 *dst)
214{ 232{
215 int len; 233 int len;
216 234
@@ -224,8 +242,6 @@ void nf_conntrack_expect_init(struct nf_conntrack_expect *exp, int family,
224 exp->helper = NULL; 242 exp->helper = NULL;
225 exp->tuple.src.l3num = family; 243 exp->tuple.src.l3num = family;
226 exp->tuple.dst.protonum = proto; 244 exp->tuple.dst.protonum = proto;
227 exp->mask.src.l3num = 0xFFFF;
228 exp->mask.dst.protonum = 0xFF;
229 245
230 if (saddr) { 246 if (saddr) {
231 memcpy(&exp->tuple.src.u3, saddr, len); 247 memcpy(&exp->tuple.src.u3, saddr, len);
@@ -242,21 +258,6 @@ void nf_conntrack_expect_init(struct nf_conntrack_expect *exp, int family,
242 memset(&exp->mask.src.u3, 0x00, sizeof(exp->mask.src.u3)); 258 memset(&exp->mask.src.u3, 0x00, sizeof(exp->mask.src.u3));
243 } 259 }
244 260
245 if (daddr) {
246 memcpy(&exp->tuple.dst.u3, daddr, len);
247 if (sizeof(exp->tuple.dst.u3) > len)
248 /* address needs to be cleared for nf_ct_tuple_equal */
249 memset((void *)&exp->tuple.dst.u3 + len, 0x00,
250 sizeof(exp->tuple.dst.u3) - len);
251 memset(&exp->mask.dst.u3, 0xFF, len);
252 if (sizeof(exp->mask.dst.u3) > len)
253 memset((void *)&exp->mask.dst.u3 + len, 0x00,
254 sizeof(exp->mask.dst.u3) - len);
255 } else {
256 memset(&exp->tuple.dst.u3, 0x00, sizeof(exp->tuple.dst.u3));
257 memset(&exp->mask.dst.u3, 0x00, sizeof(exp->mask.dst.u3));
258 }
259
260 if (src) { 261 if (src) {
261 exp->tuple.src.u.all = (__force u16)*src; 262 exp->tuple.src.u.all = (__force u16)*src;
262 exp->mask.src.u.all = 0xFFFF; 263 exp->mask.src.u.all = 0xFFFF;
@@ -265,36 +266,42 @@ void nf_conntrack_expect_init(struct nf_conntrack_expect *exp, int family,
265 exp->mask.src.u.all = 0; 266 exp->mask.src.u.all = 0;
266 } 267 }
267 268
268 if (dst) { 269 memcpy(&exp->tuple.dst.u3, daddr, len);
269 exp->tuple.dst.u.all = (__force u16)*dst; 270 if (sizeof(exp->tuple.dst.u3) > len)
270 exp->mask.dst.u.all = 0xFFFF; 271 /* address needs to be cleared for nf_ct_tuple_equal */
271 } else { 272 memset((void *)&exp->tuple.dst.u3 + len, 0x00,
272 exp->tuple.dst.u.all = 0; 273 sizeof(exp->tuple.dst.u3) - len);
273 exp->mask.dst.u.all = 0; 274
274 } 275 exp->tuple.dst.u.all = (__force u16)*dst;
275} 276}
276EXPORT_SYMBOL_GPL(nf_conntrack_expect_init); 277EXPORT_SYMBOL_GPL(nf_ct_expect_init);
277 278
278void nf_conntrack_expect_put(struct nf_conntrack_expect *exp) 279void nf_ct_expect_put(struct nf_conntrack_expect *exp)
279{ 280{
280 if (atomic_dec_and_test(&exp->use)) 281 if (atomic_dec_and_test(&exp->use))
281 kmem_cache_free(nf_conntrack_expect_cachep, exp); 282 kmem_cache_free(nf_ct_expect_cachep, exp);
282} 283}
283EXPORT_SYMBOL_GPL(nf_conntrack_expect_put); 284EXPORT_SYMBOL_GPL(nf_ct_expect_put);
284 285
285static void nf_conntrack_expect_insert(struct nf_conntrack_expect *exp) 286static void nf_ct_expect_insert(struct nf_conntrack_expect *exp)
286{ 287{
287 struct nf_conn_help *master_help = nfct_help(exp->master); 288 struct nf_conn_help *master_help = nfct_help(exp->master);
289 unsigned int h = nf_ct_expect_dst_hash(&exp->tuple);
288 290
289 atomic_inc(&exp->use); 291 atomic_inc(&exp->use);
292
293 hlist_add_head(&exp->lnode, &master_help->expectations);
290 master_help->expecting++; 294 master_help->expecting++;
291 list_add(&exp->list, &nf_conntrack_expect_list);
292 295
293 setup_timer(&exp->timeout, expectation_timed_out, (unsigned long)exp); 296 hlist_add_head(&exp->hnode, &nf_ct_expect_hash[h]);
297 nf_ct_expect_count++;
298
299 setup_timer(&exp->timeout, nf_ct_expectation_timed_out,
300 (unsigned long)exp);
294 exp->timeout.expires = jiffies + master_help->helper->timeout * HZ; 301 exp->timeout.expires = jiffies + master_help->helper->timeout * HZ;
295 add_timer(&exp->timeout); 302 add_timer(&exp->timeout);
296 303
297 exp->id = ++nf_conntrack_expect_next_id; 304 exp->id = ++nf_ct_expect_next_id;
298 atomic_inc(&exp->use); 305 atomic_inc(&exp->use);
299 NF_CT_STAT_INC(expect_create); 306 NF_CT_STAT_INC(expect_create);
300} 307}
@@ -302,16 +309,16 @@ static void nf_conntrack_expect_insert(struct nf_conntrack_expect *exp)
302/* Race with expectations being used means we could have none to find; OK. */ 309/* Race with expectations being used means we could have none to find; OK. */
303static void evict_oldest_expect(struct nf_conn *master) 310static void evict_oldest_expect(struct nf_conn *master)
304{ 311{
305 struct nf_conntrack_expect *i; 312 struct nf_conn_help *master_help = nfct_help(master);
313 struct nf_conntrack_expect *exp = NULL;
314 struct hlist_node *n;
306 315
307 list_for_each_entry_reverse(i, &nf_conntrack_expect_list, list) { 316 hlist_for_each_entry(exp, n, &master_help->expectations, lnode)
308 if (i->master == master) { 317 ; /* nothing */
309 if (del_timer(&i->timeout)) { 318
310 nf_ct_unlink_expect(i); 319 if (exp && del_timer(&exp->timeout)) {
311 nf_conntrack_expect_put(i); 320 nf_ct_unlink_expect(exp);
312 } 321 nf_ct_expect_put(exp);
313 break;
314 }
315 } 322 }
316} 323}
317 324
@@ -327,11 +334,13 @@ static inline int refresh_timer(struct nf_conntrack_expect *i)
327 return 1; 334 return 1;
328} 335}
329 336
330int nf_conntrack_expect_related(struct nf_conntrack_expect *expect) 337int nf_ct_expect_related(struct nf_conntrack_expect *expect)
331{ 338{
332 struct nf_conntrack_expect *i; 339 struct nf_conntrack_expect *i;
333 struct nf_conn *master = expect->master; 340 struct nf_conn *master = expect->master;
334 struct nf_conn_help *master_help = nfct_help(master); 341 struct nf_conn_help *master_help = nfct_help(master);
342 struct hlist_node *n;
343 unsigned int h;
335 int ret; 344 int ret;
336 345
337 NF_CT_ASSERT(master_help); 346 NF_CT_ASSERT(master_help);
@@ -341,7 +350,8 @@ int nf_conntrack_expect_related(struct nf_conntrack_expect *expect)
341 ret = -ESHUTDOWN; 350 ret = -ESHUTDOWN;
342 goto out; 351 goto out;
343 } 352 }
344 list_for_each_entry(i, &nf_conntrack_expect_list, list) { 353 h = nf_ct_expect_dst_hash(&expect->tuple);
354 hlist_for_each_entry(i, n, &nf_ct_expect_hash[h], hnode) {
345 if (expect_matches(i, expect)) { 355 if (expect_matches(i, expect)) {
346 /* Refresh timer: if it's dying, ignore.. */ 356 /* Refresh timer: if it's dying, ignore.. */
347 if (refresh_timer(i)) { 357 if (refresh_timer(i)) {
@@ -358,57 +368,86 @@ int nf_conntrack_expect_related(struct nf_conntrack_expect *expect)
358 master_help->expecting >= master_help->helper->max_expected) 368 master_help->expecting >= master_help->helper->max_expected)
359 evict_oldest_expect(master); 369 evict_oldest_expect(master);
360 370
361 nf_conntrack_expect_insert(expect); 371 if (nf_ct_expect_count >= nf_ct_expect_max) {
362 nf_conntrack_expect_event(IPEXP_NEW, expect); 372 if (net_ratelimit())
373 printk(KERN_WARNING
374 "nf_conntrack: expectation table full");
375 ret = -EMFILE;
376 goto out;
377 }
378
379 nf_ct_expect_insert(expect);
380 nf_ct_expect_event(IPEXP_NEW, expect);
363 ret = 0; 381 ret = 0;
364out: 382out:
365 write_unlock_bh(&nf_conntrack_lock); 383 write_unlock_bh(&nf_conntrack_lock);
366 return ret; 384 return ret;
367} 385}
368EXPORT_SYMBOL_GPL(nf_conntrack_expect_related); 386EXPORT_SYMBOL_GPL(nf_ct_expect_related);
369 387
370#ifdef CONFIG_PROC_FS 388#ifdef CONFIG_PROC_FS
371static void *exp_seq_start(struct seq_file *s, loff_t *pos) 389struct ct_expect_iter_state {
390 unsigned int bucket;
391};
392
393static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
372{ 394{
373 struct list_head *e = &nf_conntrack_expect_list; 395 struct ct_expect_iter_state *st = seq->private;
374 loff_t i;
375 396
376 /* strange seq_file api calls stop even if we fail, 397 for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) {
377 * thus we need to grab lock since stop unlocks */ 398 if (!hlist_empty(&nf_ct_expect_hash[st->bucket]))
378 read_lock_bh(&nf_conntrack_lock); 399 return nf_ct_expect_hash[st->bucket].first;
400 }
401 return NULL;
402}
379 403
380 if (list_empty(e)) 404static struct hlist_node *ct_expect_get_next(struct seq_file *seq,
381 return NULL; 405 struct hlist_node *head)
406{
407 struct ct_expect_iter_state *st = seq->private;
382 408
383 for (i = 0; i <= *pos; i++) { 409 head = head->next;
384 e = e->next; 410 while (head == NULL) {
385 if (e == &nf_conntrack_expect_list) 411 if (++st->bucket >= nf_ct_expect_hsize)
386 return NULL; 412 return NULL;
413 head = nf_ct_expect_hash[st->bucket].first;
387 } 414 }
388 return e; 415 return head;
389} 416}
390 417
391static void *exp_seq_next(struct seq_file *s, void *v, loff_t *pos) 418static struct hlist_node *ct_expect_get_idx(struct seq_file *seq, loff_t pos)
392{ 419{
393 struct list_head *e = v; 420 struct hlist_node *head = ct_expect_get_first(seq);
394 421
395 ++*pos; 422 if (head)
396 e = e->next; 423 while (pos && (head = ct_expect_get_next(seq, head)))
424 pos--;
425 return pos ? NULL : head;
426}
397 427
398 if (e == &nf_conntrack_expect_list) 428static void *exp_seq_start(struct seq_file *seq, loff_t *pos)
399 return NULL; 429{
430 read_lock_bh(&nf_conntrack_lock);
431 return ct_expect_get_idx(seq, *pos);
432}
400 433
401 return e; 434static void *exp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
435{
436 (*pos)++;
437 return ct_expect_get_next(seq, v);
402} 438}
403 439
404static void exp_seq_stop(struct seq_file *s, void *v) 440static void exp_seq_stop(struct seq_file *seq, void *v)
405{ 441{
406 read_unlock_bh(&nf_conntrack_lock); 442 read_unlock_bh(&nf_conntrack_lock);
407} 443}
408 444
409static int exp_seq_show(struct seq_file *s, void *v) 445static int exp_seq_show(struct seq_file *s, void *v)
410{ 446{
411 struct nf_conntrack_expect *expect = v; 447 struct nf_conntrack_expect *expect;
448 struct hlist_node *n = v;
449
450 expect = hlist_entry(n, struct nf_conntrack_expect, hnode);
412 451
413 if (expect->timeout.function) 452 if (expect->timeout.function)
414 seq_printf(s, "%ld ", timer_pending(&expect->timeout) 453 seq_printf(s, "%ld ", timer_pending(&expect->timeout)
@@ -425,7 +464,7 @@ static int exp_seq_show(struct seq_file *s, void *v)
425 return seq_putc(s, '\n'); 464 return seq_putc(s, '\n');
426} 465}
427 466
428static struct seq_operations exp_seq_ops = { 467static const struct seq_operations exp_seq_ops = {
429 .start = exp_seq_start, 468 .start = exp_seq_start,
430 .next = exp_seq_next, 469 .next = exp_seq_next,
431 .stop = exp_seq_stop, 470 .stop = exp_seq_stop,
@@ -434,14 +473,96 @@ static struct seq_operations exp_seq_ops = {
434 473
435static int exp_open(struct inode *inode, struct file *file) 474static int exp_open(struct inode *inode, struct file *file)
436{ 475{
437 return seq_open(file, &exp_seq_ops); 476 struct seq_file *seq;
477 struct ct_expect_iter_state *st;
478 int ret;
479
480 st = kmalloc(sizeof(struct ct_expect_iter_state), GFP_KERNEL);
481 if (st == NULL)
482 return -ENOMEM;
483 ret = seq_open(file, &exp_seq_ops);
484 if (ret)
485 goto out_free;
486 seq = file->private_data;
487 seq->private = st;
488 memset(st, 0, sizeof(struct ct_expect_iter_state));
489 return ret;
490out_free:
491 kfree(st);
492 return ret;
438} 493}
439 494
440const struct file_operations exp_file_ops = { 495static const struct file_operations exp_file_ops = {
441 .owner = THIS_MODULE, 496 .owner = THIS_MODULE,
442 .open = exp_open, 497 .open = exp_open,
443 .read = seq_read, 498 .read = seq_read,
444 .llseek = seq_lseek, 499 .llseek = seq_lseek,
445 .release = seq_release 500 .release = seq_release_private,
446}; 501};
447#endif /* CONFIG_PROC_FS */ 502#endif /* CONFIG_PROC_FS */
503
504static int __init exp_proc_init(void)
505{
506#ifdef CONFIG_PROC_FS
507 struct proc_dir_entry *proc;
508
509 proc = proc_net_fops_create("nf_conntrack_expect", 0440, &exp_file_ops);
510 if (!proc)
511 return -ENOMEM;
512#endif /* CONFIG_PROC_FS */
513 return 0;
514}
515
516static void exp_proc_remove(void)
517{
518#ifdef CONFIG_PROC_FS
519 proc_net_remove("nf_conntrack_expect");
520#endif /* CONFIG_PROC_FS */
521}
522
523module_param_named(expect_hashsize, nf_ct_expect_hsize, uint, 0600);
524
525int __init nf_conntrack_expect_init(void)
526{
527 int err = -ENOMEM;
528
529 if (!nf_ct_expect_hsize) {
530 nf_ct_expect_hsize = nf_conntrack_htable_size / 256;
531 if (!nf_ct_expect_hsize)
532 nf_ct_expect_hsize = 1;
533 }
534 nf_ct_expect_max = nf_ct_expect_hsize * 4;
535
536 nf_ct_expect_hash = nf_ct_alloc_hashtable(&nf_ct_expect_hsize,
537 &nf_ct_expect_vmalloc);
538 if (nf_ct_expect_hash == NULL)
539 goto err1;
540
541 nf_ct_expect_cachep = kmem_cache_create("nf_conntrack_expect",
542 sizeof(struct nf_conntrack_expect),
543 0, 0, NULL, NULL);
544 if (!nf_ct_expect_cachep)
545 goto err2;
546
547 err = exp_proc_init();
548 if (err < 0)
549 goto err3;
550
551 return 0;
552
553err3:
554 nf_ct_free_hashtable(nf_ct_expect_hash, nf_ct_expect_vmalloc,
555 nf_ct_expect_hsize);
556err2:
557 kmem_cache_destroy(nf_ct_expect_cachep);
558err1:
559 return err;
560}
561
562void nf_conntrack_expect_fini(void)
563{
564 exp_proc_remove();
565 kmem_cache_destroy(nf_ct_expect_cachep);
566 nf_ct_free_hashtable(nf_ct_expect_hash, nf_ct_expect_vmalloc,
567 nf_ct_expect_hsize);
568}
diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c
new file mode 100644
index 000000000000..a1a65a1313b3
--- /dev/null
+++ b/net/netfilter/nf_conntrack_extend.c
@@ -0,0 +1,195 @@
1/* Structure dynamic extension infrastructure
2 * Copyright (C) 2004 Rusty Russell IBM Corporation
3 * Copyright (C) 2007 Netfilter Core Team <coreteam@netfilter.org>
4 * Copyright (C) 2007 USAGI/WIDE Project <http://www.linux-ipv6.org>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/mutex.h>
14#include <linux/rcupdate.h>
15#include <linux/slab.h>
16#include <linux/skbuff.h>
17#include <net/netfilter/nf_conntrack_extend.h>
18
19static struct nf_ct_ext_type *nf_ct_ext_types[NF_CT_EXT_NUM];
20static DEFINE_MUTEX(nf_ct_ext_type_mutex);
21
22/* Horrible trick to figure out smallest amount worth kmallocing. */
23#define CACHE(x) (x) + 0 *
24enum {
25 NF_CT_EXT_MIN_SIZE =
26#include <linux/kmalloc_sizes.h>
27 1 };
28#undef CACHE
29
30void __nf_ct_ext_destroy(struct nf_conn *ct)
31{
32 unsigned int i;
33 struct nf_ct_ext_type *t;
34
35 for (i = 0; i < NF_CT_EXT_NUM; i++) {
36 if (!nf_ct_ext_exist(ct, i))
37 continue;
38
39 rcu_read_lock();
40 t = rcu_dereference(nf_ct_ext_types[i]);
41
42 /* Here the nf_ct_ext_type might have been unregisterd.
43 * I.e., it has responsible to cleanup private
44 * area in all conntracks when it is unregisterd.
45 */
46 if (t && t->destroy)
47 t->destroy(ct);
48 rcu_read_unlock();
49 }
50}
51EXPORT_SYMBOL(__nf_ct_ext_destroy);
52
53static void *
54nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp)
55{
56 unsigned int off, len, real_len;
57 struct nf_ct_ext_type *t;
58
59 rcu_read_lock();
60 t = rcu_dereference(nf_ct_ext_types[id]);
61 BUG_ON(t == NULL);
62 off = ALIGN(sizeof(struct nf_ct_ext), t->align);
63 len = off + t->len;
64 real_len = t->alloc_size;
65 rcu_read_unlock();
66
67 *ext = kzalloc(real_len, gfp);
68 if (!*ext)
69 return NULL;
70
71 (*ext)->offset[id] = off;
72 (*ext)->len = len;
73 (*ext)->real_len = real_len;
74
75 return (void *)(*ext) + off;
76}
77
78void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)
79{
80 struct nf_ct_ext *new;
81 int i, newlen, newoff;
82 struct nf_ct_ext_type *t;
83
84 if (!ct->ext)
85 return nf_ct_ext_create(&ct->ext, id, gfp);
86
87 if (nf_ct_ext_exist(ct, id))
88 return NULL;
89
90 rcu_read_lock();
91 t = rcu_dereference(nf_ct_ext_types[id]);
92 BUG_ON(t == NULL);
93
94 newoff = ALIGN(ct->ext->len, t->align);
95 newlen = newoff + t->len;
96 rcu_read_unlock();
97
98 if (newlen >= ct->ext->real_len) {
99 new = kmalloc(newlen, gfp);
100 if (!new)
101 return NULL;
102
103 memcpy(new, ct->ext, ct->ext->len);
104
105 for (i = 0; i < NF_CT_EXT_NUM; i++) {
106 if (!nf_ct_ext_exist(ct, i))
107 continue;
108
109 rcu_read_lock();
110 t = rcu_dereference(nf_ct_ext_types[i]);
111 if (t && t->move)
112 t->move(ct, ct->ext + ct->ext->offset[id]);
113 rcu_read_unlock();
114 }
115 kfree(ct->ext);
116 new->real_len = newlen;
117 ct->ext = new;
118 }
119
120 ct->ext->offset[id] = newoff;
121 ct->ext->len = newlen;
122 memset((void *)ct->ext + newoff, 0, newlen - newoff);
123 return (void *)ct->ext + newoff;
124}
125EXPORT_SYMBOL(__nf_ct_ext_add);
126
127static void update_alloc_size(struct nf_ct_ext_type *type)
128{
129 int i, j;
130 struct nf_ct_ext_type *t1, *t2;
131 enum nf_ct_ext_id min = 0, max = NF_CT_EXT_NUM - 1;
132
133 /* unnecessary to update all types */
134 if ((type->flags & NF_CT_EXT_F_PREALLOC) == 0) {
135 min = type->id;
136 max = type->id;
137 }
138
139 /* This assumes that extended areas in conntrack for the types
140 whose NF_CT_EXT_F_PREALLOC bit set are allocated in order */
141 for (i = min; i <= max; i++) {
142 t1 = nf_ct_ext_types[i];
143 if (!t1)
144 continue;
145
146 t1->alloc_size = sizeof(struct nf_ct_ext)
147 + ALIGN(sizeof(struct nf_ct_ext), t1->align)
148 + t1->len;
149 for (j = 0; j < NF_CT_EXT_NUM; j++) {
150 t2 = nf_ct_ext_types[j];
151 if (t2 == NULL || t2 == t1 ||
152 (t2->flags & NF_CT_EXT_F_PREALLOC) == 0)
153 continue;
154
155 t1->alloc_size = ALIGN(t1->alloc_size, t2->align)
156 + t2->len;
157 }
158 if (t1->alloc_size < NF_CT_EXT_MIN_SIZE)
159 t1->alloc_size = NF_CT_EXT_MIN_SIZE;
160 }
161}
162
163/* This MUST be called in process context. */
164int nf_ct_extend_register(struct nf_ct_ext_type *type)
165{
166 int ret = 0;
167
168 mutex_lock(&nf_ct_ext_type_mutex);
169 if (nf_ct_ext_types[type->id]) {
170 ret = -EBUSY;
171 goto out;
172 }
173
174 /* This ensures that nf_ct_ext_create() can allocate enough area
175 before updating alloc_size */
176 type->alloc_size = ALIGN(sizeof(struct nf_ct_ext), type->align)
177 + type->len;
178 rcu_assign_pointer(nf_ct_ext_types[type->id], type);
179 update_alloc_size(type);
180out:
181 mutex_unlock(&nf_ct_ext_type_mutex);
182 return ret;
183}
184EXPORT_SYMBOL_GPL(nf_ct_extend_register);
185
186/* This MUST be called in process context. */
187void nf_ct_extend_unregister(struct nf_ct_ext_type *type)
188{
189 mutex_lock(&nf_ct_ext_type_mutex);
190 rcu_assign_pointer(nf_ct_ext_types[type->id], NULL);
191 update_alloc_size(type);
192 mutex_unlock(&nf_ct_ext_type_mutex);
193 synchronize_rcu();
194}
195EXPORT_SYMBOL_GPL(nf_ct_extend_unregister);
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index 82db2aa53bfc..c763ee74ea02 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -51,12 +51,6 @@ unsigned int (*nf_nat_ftp_hook)(struct sk_buff **pskb,
51 struct nf_conntrack_expect *exp); 51 struct nf_conntrack_expect *exp);
52EXPORT_SYMBOL_GPL(nf_nat_ftp_hook); 52EXPORT_SYMBOL_GPL(nf_nat_ftp_hook);
53 53
54#if 0
55#define DEBUGP printk
56#else
57#define DEBUGP(format, args...)
58#endif
59
60static int try_rfc959(const char *, size_t, struct nf_conntrack_man *, char); 54static int try_rfc959(const char *, size_t, struct nf_conntrack_man *, char);
61static int try_eprt(const char *, size_t, struct nf_conntrack_man *, char); 55static int try_eprt(const char *, size_t, struct nf_conntrack_man *, char);
62static int try_epsv_response(const char *, size_t, struct nf_conntrack_man *, 56static int try_epsv_response(const char *, size_t, struct nf_conntrack_man *,
@@ -138,13 +132,13 @@ static int try_number(const char *data, size_t dlen, u_int32_t array[],
138 if (*data == term && i == array_size - 1) 132 if (*data == term && i == array_size - 1)
139 return len; 133 return len;
140 134
141 DEBUGP("Char %u (got %u nums) `%u' unexpected\n", 135 pr_debug("Char %u (got %u nums) `%u' unexpected\n",
142 len, i, *data); 136 len, i, *data);
143 return 0; 137 return 0;
144 } 138 }
145 } 139 }
146 DEBUGP("Failed to fill %u numbers separated by %c\n", array_size, sep); 140 pr_debug("Failed to fill %u numbers separated by %c\n",
147 141 array_size, sep);
148 return 0; 142 return 0;
149} 143}
150 144
@@ -178,13 +172,13 @@ static int get_port(const char *data, int start, size_t dlen, char delim,
178 if (tmp_port == 0) 172 if (tmp_port == 0)
179 break; 173 break;
180 *port = htons(tmp_port); 174 *port = htons(tmp_port);
181 DEBUGP("get_port: return %d\n", tmp_port); 175 pr_debug("get_port: return %d\n", tmp_port);
182 return i + 1; 176 return i + 1;
183 } 177 }
184 else if (data[i] >= '0' && data[i] <= '9') 178 else if (data[i] >= '0' && data[i] <= '9')
185 tmp_port = tmp_port*10 + data[i] - '0'; 179 tmp_port = tmp_port*10 + data[i] - '0';
186 else { /* Some other crap */ 180 else { /* Some other crap */
187 DEBUGP("get_port: invalid char.\n"); 181 pr_debug("get_port: invalid char.\n");
188 break; 182 break;
189 } 183 }
190 } 184 }
@@ -201,22 +195,22 @@ static int try_eprt(const char *data, size_t dlen, struct nf_conntrack_man *cmd,
201 /* First character is delimiter, then "1" for IPv4 or "2" for IPv6, 195 /* First character is delimiter, then "1" for IPv4 or "2" for IPv6,
202 then delimiter again. */ 196 then delimiter again. */
203 if (dlen <= 3) { 197 if (dlen <= 3) {
204 DEBUGP("EPRT: too short\n"); 198 pr_debug("EPRT: too short\n");
205 return 0; 199 return 0;
206 } 200 }
207 delim = data[0]; 201 delim = data[0];
208 if (isdigit(delim) || delim < 33 || delim > 126 || data[2] != delim) { 202 if (isdigit(delim) || delim < 33 || delim > 126 || data[2] != delim) {
209 DEBUGP("try_eprt: invalid delimitter.\n"); 203 pr_debug("try_eprt: invalid delimitter.\n");
210 return 0; 204 return 0;
211 } 205 }
212 206
213 if ((cmd->l3num == PF_INET && data[1] != '1') || 207 if ((cmd->l3num == PF_INET && data[1] != '1') ||
214 (cmd->l3num == PF_INET6 && data[1] != '2')) { 208 (cmd->l3num == PF_INET6 && data[1] != '2')) {
215 DEBUGP("EPRT: invalid protocol number.\n"); 209 pr_debug("EPRT: invalid protocol number.\n");
216 return 0; 210 return 0;
217 } 211 }
218 212
219 DEBUGP("EPRT: Got %c%c%c\n", delim, data[1], delim); 213 pr_debug("EPRT: Got %c%c%c\n", delim, data[1], delim);
220 214
221 if (data[1] == '1') { 215 if (data[1] == '1') {
222 u_int32_t array[4]; 216 u_int32_t array[4];
@@ -234,7 +228,7 @@ static int try_eprt(const char *data, size_t dlen, struct nf_conntrack_man *cmd,
234 228
235 if (length == 0) 229 if (length == 0)
236 return 0; 230 return 0;
237 DEBUGP("EPRT: Got IP address!\n"); 231 pr_debug("EPRT: Got IP address!\n");
238 /* Start offset includes initial "|1|", and trailing delimiter */ 232 /* Start offset includes initial "|1|", and trailing delimiter */
239 return get_port(data, 3 + length + 1, dlen, delim, &cmd->u.tcp.port); 233 return get_port(data, 3 + length + 1, dlen, delim, &cmd->u.tcp.port);
240} 234}
@@ -267,7 +261,7 @@ static int find_pattern(const char *data, size_t dlen,
267{ 261{
268 size_t i; 262 size_t i;
269 263
270 DEBUGP("find_pattern `%s': dlen = %u\n", pattern, dlen); 264 pr_debug("find_pattern `%s': dlen = %Zu\n", pattern, dlen);
271 if (dlen == 0) 265 if (dlen == 0)
272 return 0; 266 return 0;
273 267
@@ -282,17 +276,17 @@ static int find_pattern(const char *data, size_t dlen,
282#if 0 276#if 0
283 size_t i; 277 size_t i;
284 278
285 DEBUGP("ftp: string mismatch\n"); 279 pr_debug("ftp: string mismatch\n");
286 for (i = 0; i < plen; i++) { 280 for (i = 0; i < plen; i++) {
287 DEBUGP("ftp:char %u `%c'(%u) vs `%c'(%u)\n", 281 pr_debug("ftp:char %u `%c'(%u) vs `%c'(%u)\n",
288 i, data[i], data[i], 282 i, data[i], data[i],
289 pattern[i], pattern[i]); 283 pattern[i], pattern[i]);
290 } 284 }
291#endif 285#endif
292 return 0; 286 return 0;
293 } 287 }
294 288
295 DEBUGP("Pattern matches!\n"); 289 pr_debug("Pattern matches!\n");
296 /* Now we've found the constant string, try to skip 290 /* Now we've found the constant string, try to skip
297 to the 'skip' character */ 291 to the 'skip' character */
298 for (i = plen; data[i] != skip; i++) 292 for (i = plen; data[i] != skip; i++)
@@ -301,14 +295,14 @@ static int find_pattern(const char *data, size_t dlen,
301 /* Skip over the last character */ 295 /* Skip over the last character */
302 i++; 296 i++;
303 297
304 DEBUGP("Skipped up to `%c'!\n", skip); 298 pr_debug("Skipped up to `%c'!\n", skip);
305 299
306 *numoff = i; 300 *numoff = i;
307 *numlen = getnum(data + i, dlen - i, cmd, term); 301 *numlen = getnum(data + i, dlen - i, cmd, term);
308 if (!*numlen) 302 if (!*numlen)
309 return -1; 303 return -1;
310 304
311 DEBUGP("Match succeeded!\n"); 305 pr_debug("Match succeeded!\n");
312 return 1; 306 return 1;
313} 307}
314 308
@@ -364,6 +358,7 @@ static int help(struct sk_buff **pskb,
364 unsigned int matchlen, matchoff; 358 unsigned int matchlen, matchoff;
365 struct nf_ct_ftp_master *ct_ftp_info = &nfct_help(ct)->help.ct_ftp_info; 359 struct nf_ct_ftp_master *ct_ftp_info = &nfct_help(ct)->help.ct_ftp_info;
366 struct nf_conntrack_expect *exp; 360 struct nf_conntrack_expect *exp;
361 union nf_conntrack_address *daddr;
367 struct nf_conntrack_man cmd = {}; 362 struct nf_conntrack_man cmd = {};
368 unsigned int i; 363 unsigned int i;
369 int found = 0, ends_in_nl; 364 int found = 0, ends_in_nl;
@@ -372,7 +367,7 @@ static int help(struct sk_buff **pskb,
372 /* Until there's been traffic both ways, don't look in packets. */ 367 /* Until there's been traffic both ways, don't look in packets. */
373 if (ctinfo != IP_CT_ESTABLISHED 368 if (ctinfo != IP_CT_ESTABLISHED
374 && ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY) { 369 && ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY) {
375 DEBUGP("ftp: Conntrackinfo = %u\n", ctinfo); 370 pr_debug("ftp: Conntrackinfo = %u\n", ctinfo);
376 return NF_ACCEPT; 371 return NF_ACCEPT;
377 } 372 }
378 373
@@ -383,8 +378,8 @@ static int help(struct sk_buff **pskb,
383 dataoff = protoff + th->doff * 4; 378 dataoff = protoff + th->doff * 4;
384 /* No data? */ 379 /* No data? */
385 if (dataoff >= (*pskb)->len) { 380 if (dataoff >= (*pskb)->len) {
386 DEBUGP("ftp: dataoff(%u) >= skblen(%u)\n", dataoff, 381 pr_debug("ftp: dataoff(%u) >= skblen(%u)\n", dataoff,
387 (*pskb)->len); 382 (*pskb)->len);
388 return NF_ACCEPT; 383 return NF_ACCEPT;
389 } 384 }
390 datalen = (*pskb)->len - dataoff; 385 datalen = (*pskb)->len - dataoff;
@@ -399,11 +394,11 @@ static int help(struct sk_buff **pskb,
399 /* Look up to see if we're just after a \n. */ 394 /* Look up to see if we're just after a \n. */
400 if (!find_nl_seq(ntohl(th->seq), ct_ftp_info, dir)) { 395 if (!find_nl_seq(ntohl(th->seq), ct_ftp_info, dir)) {
401 /* Now if this ends in \n, update ftp info. */ 396 /* Now if this ends in \n, update ftp info. */
402 DEBUGP("nf_conntrack_ftp_help: wrong seq pos %s(%u) or %s(%u)\n", 397 pr_debug("nf_conntrack_ftp: wrong seq pos %s(%u) or %s(%u)\n",
403 ct_ftp_info->seq_aft_nl_num[dir] > 0 ? "" : "(UNSET)", 398 ct_ftp_info->seq_aft_nl_num[dir] > 0 ? "" : "(UNSET)",
404 ct_ftp_info->seq_aft_nl[dir][0], 399 ct_ftp_info->seq_aft_nl[dir][0],
405 ct_ftp_info->seq_aft_nl_num[dir] > 1 ? "" : "(UNSET)", 400 ct_ftp_info->seq_aft_nl_num[dir] > 1 ? "" : "(UNSET)",
406 ct_ftp_info->seq_aft_nl[dir][1]); 401 ct_ftp_info->seq_aft_nl[dir][1]);
407 ret = NF_ACCEPT; 402 ret = NF_ACCEPT;
408 goto out_update_nl; 403 goto out_update_nl;
409 } 404 }
@@ -441,11 +436,11 @@ static int help(struct sk_buff **pskb,
441 goto out_update_nl; 436 goto out_update_nl;
442 } 437 }
443 438
444 DEBUGP("conntrack_ftp: match `%.*s' (%u bytes at %u)\n", 439 pr_debug("conntrack_ftp: match `%.*s' (%u bytes at %u)\n",
445 (int)matchlen, fb_ptr + matchoff, 440 matchlen, fb_ptr + matchoff,
446 matchlen, ntohl(th->seq) + matchoff); 441 matchlen, ntohl(th->seq) + matchoff);
447 442
448 exp = nf_conntrack_expect_alloc(ct); 443 exp = nf_ct_expect_alloc(ct);
449 if (exp == NULL) { 444 if (exp == NULL) {
450 ret = NF_DROP; 445 ret = NF_DROP;
451 goto out; 446 goto out;
@@ -454,7 +449,7 @@ static int help(struct sk_buff **pskb,
454 /* We refer to the reverse direction ("!dir") tuples here, 449 /* We refer to the reverse direction ("!dir") tuples here,
455 * because we're expecting something in the other direction. 450 * because we're expecting something in the other direction.
456 * Doesn't matter unless NAT is happening. */ 451 * Doesn't matter unless NAT is happening. */
457 exp->tuple.dst.u3 = ct->tuplehash[!dir].tuple.dst.u3; 452 daddr = &ct->tuplehash[!dir].tuple.dst.u3;
458 453
459 /* Update the ftp info */ 454 /* Update the ftp info */
460 if ((cmd.l3num == ct->tuplehash[dir].tuple.src.l3num) && 455 if ((cmd.l3num == ct->tuplehash[dir].tuple.src.l3num) &&
@@ -465,14 +460,16 @@ static int help(struct sk_buff **pskb,
465 different IP address. Simply don't record it for 460 different IP address. Simply don't record it for
466 NAT. */ 461 NAT. */
467 if (cmd.l3num == PF_INET) { 462 if (cmd.l3num == PF_INET) {
468 DEBUGP("conntrack_ftp: NOT RECORDING: " NIPQUAD_FMT " != " NIPQUAD_FMT "\n", 463 pr_debug("conntrack_ftp: NOT RECORDING: " NIPQUAD_FMT
469 NIPQUAD(cmd.u3.ip), 464 " != " NIPQUAD_FMT "\n",
470 NIPQUAD(ct->tuplehash[dir].tuple.src.u3.ip)); 465 NIPQUAD(cmd.u3.ip),
466 NIPQUAD(ct->tuplehash[dir].tuple.src.u3.ip));
471 } else { 467 } else {
472 DEBUGP("conntrack_ftp: NOT RECORDING: " NIP6_FMT " != " NIP6_FMT "\n", 468 pr_debug("conntrack_ftp: NOT RECORDING: " NIP6_FMT
473 NIP6(*((struct in6_addr *)cmd.u3.ip6)), 469 " != " NIP6_FMT "\n",
474 NIP6(*((struct in6_addr *)ct->tuplehash[dir] 470 NIP6(*((struct in6_addr *)cmd.u3.ip6)),
475 .tuple.src.u3.ip6))); 471 NIP6(*((struct in6_addr *)
472 ct->tuplehash[dir].tuple.src.u3.ip6)));
476 } 473 }
477 474
478 /* Thanks to Cristiano Lincoln Mattos 475 /* Thanks to Cristiano Lincoln Mattos
@@ -483,37 +480,12 @@ static int help(struct sk_buff **pskb,
483 ret = NF_ACCEPT; 480 ret = NF_ACCEPT;
484 goto out_put_expect; 481 goto out_put_expect;
485 } 482 }
486 memcpy(&exp->tuple.dst.u3, &cmd.u3.all, 483 daddr = &cmd.u3;
487 sizeof(exp->tuple.dst.u3));
488 }
489
490 exp->tuple.src.u3 = ct->tuplehash[!dir].tuple.src.u3;
491 exp->tuple.src.l3num = cmd.l3num;
492 exp->tuple.src.u.tcp.port = 0;
493 exp->tuple.dst.u.tcp.port = cmd.u.tcp.port;
494 exp->tuple.dst.protonum = IPPROTO_TCP;
495
496 exp->mask = (struct nf_conntrack_tuple)
497 { .src = { .l3num = 0xFFFF,
498 .u = { .tcp = { 0 }},
499 },
500 .dst = { .protonum = 0xFF,
501 .u = { .tcp = { __constant_htons(0xFFFF) }},
502 },
503 };
504 if (cmd.l3num == PF_INET) {
505 exp->mask.src.u3.ip = htonl(0xFFFFFFFF);
506 exp->mask.dst.u3.ip = htonl(0xFFFFFFFF);
507 } else {
508 memset(exp->mask.src.u3.ip6, 0xFF,
509 sizeof(exp->mask.src.u3.ip6));
510 memset(exp->mask.dst.u3.ip6, 0xFF,
511 sizeof(exp->mask.src.u3.ip6));
512 } 484 }
513 485
514 exp->expectfn = NULL; 486 nf_ct_expect_init(exp, cmd.l3num,
515 exp->helper = NULL; 487 &ct->tuplehash[!dir].tuple.src.u3, daddr,
516 exp->flags = 0; 488 IPPROTO_TCP, NULL, &cmd.u.tcp.port);
517 489
518 /* Now, NAT might want to mangle the packet, and register the 490 /* Now, NAT might want to mangle the packet, and register the
519 * (possibly changed) expectation itself. */ 491 * (possibly changed) expectation itself. */
@@ -523,14 +495,14 @@ static int help(struct sk_buff **pskb,
523 matchoff, matchlen, exp); 495 matchoff, matchlen, exp);
524 else { 496 else {
525 /* Can't expect this? Best to drop packet now. */ 497 /* Can't expect this? Best to drop packet now. */
526 if (nf_conntrack_expect_related(exp) != 0) 498 if (nf_ct_expect_related(exp) != 0)
527 ret = NF_DROP; 499 ret = NF_DROP;
528 else 500 else
529 ret = NF_ACCEPT; 501 ret = NF_ACCEPT;
530 } 502 }
531 503
532out_put_expect: 504out_put_expect:
533 nf_conntrack_expect_put(exp); 505 nf_ct_expect_put(exp);
534 506
535out_update_nl: 507out_update_nl:
536 /* Now if this ends in \n, update ftp info. Seq may have been 508 /* Now if this ends in \n, update ftp info. Seq may have been
@@ -542,8 +514,8 @@ out_update_nl:
542 return ret; 514 return ret;
543} 515}
544 516
545static struct nf_conntrack_helper ftp[MAX_PORTS][2]; 517static struct nf_conntrack_helper ftp[MAX_PORTS][2] __read_mostly;
546static char ftp_names[MAX_PORTS][2][sizeof("ftp-65535")]; 518static char ftp_names[MAX_PORTS][2][sizeof("ftp-65535")] __read_mostly;
547 519
548/* don't make this __exit, since it's called from __init ! */ 520/* don't make this __exit, since it's called from __init ! */
549static void nf_conntrack_ftp_fini(void) 521static void nf_conntrack_ftp_fini(void)
@@ -554,9 +526,9 @@ static void nf_conntrack_ftp_fini(void)
554 if (ftp[i][j].me == NULL) 526 if (ftp[i][j].me == NULL)
555 continue; 527 continue;
556 528
557 DEBUGP("nf_ct_ftp: unregistering helper for pf: %d " 529 pr_debug("nf_ct_ftp: unregistering helper for pf: %d "
558 "port: %d\n", 530 "port: %d\n",
559 ftp[i][j].tuple.src.l3num, ports[i]); 531 ftp[i][j].tuple.src.l3num, ports[i]);
560 nf_conntrack_helper_unregister(&ftp[i][j]); 532 nf_conntrack_helper_unregister(&ftp[i][j]);
561 } 533 }
562 } 534 }
@@ -584,9 +556,6 @@ static int __init nf_conntrack_ftp_init(void)
584 for (j = 0; j < 2; j++) { 556 for (j = 0; j < 2; j++) {
585 ftp[i][j].tuple.src.u.tcp.port = htons(ports[i]); 557 ftp[i][j].tuple.src.u.tcp.port = htons(ports[i]);
586 ftp[i][j].tuple.dst.protonum = IPPROTO_TCP; 558 ftp[i][j].tuple.dst.protonum = IPPROTO_TCP;
587 ftp[i][j].mask.src.l3num = 0xFFFF;
588 ftp[i][j].mask.src.u.tcp.port = htons(0xFFFF);
589 ftp[i][j].mask.dst.protonum = 0xFF;
590 ftp[i][j].max_expected = 1; 559 ftp[i][j].max_expected = 1;
591 ftp[i][j].timeout = 5 * 60; /* 5 Minutes */ 560 ftp[i][j].timeout = 5 * 60; /* 5 Minutes */
592 ftp[i][j].me = THIS_MODULE; 561 ftp[i][j].me = THIS_MODULE;
@@ -598,9 +567,9 @@ static int __init nf_conntrack_ftp_init(void)
598 sprintf(tmpname, "ftp-%d", ports[i]); 567 sprintf(tmpname, "ftp-%d", ports[i]);
599 ftp[i][j].name = tmpname; 568 ftp[i][j].name = tmpname;
600 569
601 DEBUGP("nf_ct_ftp: registering helper for pf: %d " 570 pr_debug("nf_ct_ftp: registering helper for pf: %d "
602 "port: %d\n", 571 "port: %d\n",
603 ftp[i][j].tuple.src.l3num, ports[i]); 572 ftp[i][j].tuple.src.l3num, ports[i]);
604 ret = nf_conntrack_helper_register(&ftp[i][j]); 573 ret = nf_conntrack_helper_register(&ftp[i][j]);
605 if (ret) { 574 if (ret) {
606 printk("nf_ct_ftp: failed to register helper " 575 printk("nf_ct_ftp: failed to register helper "
diff --git a/net/netfilter/nf_conntrack_h323_asn1.c b/net/netfilter/nf_conntrack_h323_asn1.c
index 6b7eaa019d4c..a869403b2294 100644
--- a/net/netfilter/nf_conntrack_h323_asn1.c
+++ b/net/netfilter/nf_conntrack_h323_asn1.c
@@ -555,15 +555,6 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level)
555 555
556 /* Decode the extension components */ 556 /* Decode the extension components */
557 for (opt = 0; opt < bmp2_len; opt++, i++, son++) { 557 for (opt = 0; opt < bmp2_len; opt++, i++, son++) {
558 if (i < f->ub && son->attr & STOP) {
559 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
560 son->name);
561 return H323_ERROR_STOP;
562 }
563
564 if (!((0x80000000 >> opt) & bmp2)) /* Not present */
565 continue;
566
567 /* Check Range */ 558 /* Check Range */
568 if (i >= f->ub) { /* Newer Version? */ 559 if (i >= f->ub) { /* Newer Version? */
569 CHECK_BOUND(bs, 2); 560 CHECK_BOUND(bs, 2);
@@ -573,6 +564,15 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level)
573 continue; 564 continue;
574 } 565 }
575 566
567 if (son->attr & STOP) {
568 PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
569 son->name);
570 return H323_ERROR_STOP;
571 }
572
573 if (!((0x80000000 >> opt) & bmp2)) /* Not present */
574 continue;
575
576 CHECK_BOUND(bs, 2); 576 CHECK_BOUND(bs, 2);
577 len = get_len(bs); 577 len = get_len(bs);
578 CHECK_BOUND(bs, len); 578 CHECK_BOUND(bs, len);
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index a1b95acad297..a8a9dfbe7a67 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -31,12 +31,6 @@
31#include <net/netfilter/nf_conntrack_helper.h> 31#include <net/netfilter/nf_conntrack_helper.h>
32#include <linux/netfilter/nf_conntrack_h323.h> 32#include <linux/netfilter/nf_conntrack_h323.h>
33 33
34#if 0
35#define DEBUGP printk
36#else
37#define DEBUGP(format, args...)
38#endif
39
40/* Parameters */ 34/* Parameters */
41static unsigned int default_rrq_ttl __read_mostly = 300; 35static unsigned int default_rrq_ttl __read_mostly = 300;
42module_param(default_rrq_ttl, uint, 0600); 36module_param(default_rrq_ttl, uint, 0600);
@@ -150,9 +144,9 @@ static int get_tpkt_data(struct sk_buff **pskb, unsigned int protoff,
150 if (tcpdatalen < 4 || tpkt[0] != 0x03 || tpkt[1] != 0) { 144 if (tcpdatalen < 4 || tpkt[0] != 0x03 || tpkt[1] != 0) {
151 /* Netmeeting sends TPKT header and data separately */ 145 /* Netmeeting sends TPKT header and data separately */
152 if (info->tpkt_len[dir] > 0) { 146 if (info->tpkt_len[dir] > 0) {
153 DEBUGP("nf_ct_h323: previous packet " 147 pr_debug("nf_ct_h323: previous packet "
154 "indicated separate TPKT data of %hu " 148 "indicated separate TPKT data of %hu "
155 "bytes\n", info->tpkt_len[dir]); 149 "bytes\n", info->tpkt_len[dir]);
156 if (info->tpkt_len[dir] <= tcpdatalen) { 150 if (info->tpkt_len[dir] <= tcpdatalen) {
157 /* Yes, there was a TPKT header 151 /* Yes, there was a TPKT header
158 * received */ 152 * received */
@@ -163,9 +157,7 @@ static int get_tpkt_data(struct sk_buff **pskb, unsigned int protoff,
163 } 157 }
164 158
165 /* Fragmented TPKT */ 159 /* Fragmented TPKT */
166 if (net_ratelimit()) 160 pr_debug("nf_ct_h323: fragmented TPKT\n");
167 printk("nf_ct_h323: "
168 "fragmented TPKT\n");
169 goto clear_out; 161 goto clear_out;
170 } 162 }
171 163
@@ -192,9 +184,9 @@ static int get_tpkt_data(struct sk_buff **pskb, unsigned int protoff,
192 if (tpktlen > tcpdatalen) { 184 if (tpktlen > tcpdatalen) {
193 if (tcpdatalen == 4) { /* Separate TPKT header */ 185 if (tcpdatalen == 4) { /* Separate TPKT header */
194 /* Netmeeting sends TPKT header and data separately */ 186 /* Netmeeting sends TPKT header and data separately */
195 DEBUGP("nf_ct_h323: separate TPKT header indicates " 187 pr_debug("nf_ct_h323: separate TPKT header indicates "
196 "there will be TPKT data of %hu bytes\n", 188 "there will be TPKT data of %hu bytes\n",
197 tpktlen - 4); 189 tpktlen - 4);
198 info->tpkt_len[dir] = tpktlen - 4; 190 info->tpkt_len[dir] = tpktlen - 4;
199 return 0; 191 return 0;
200 } 192 }
@@ -282,22 +274,22 @@ static int expect_rtp_rtcp(struct sk_buff **pskb, struct nf_conn *ct,
282 rtcp_port = htons(ntohs(port) + 1); 274 rtcp_port = htons(ntohs(port) + 1);
283 275
284 /* Create expect for RTP */ 276 /* Create expect for RTP */
285 if ((rtp_exp = nf_conntrack_expect_alloc(ct)) == NULL) 277 if ((rtp_exp = nf_ct_expect_alloc(ct)) == NULL)
286 return -1; 278 return -1;
287 nf_conntrack_expect_init(rtp_exp, ct->tuplehash[!dir].tuple.src.l3num, 279 nf_ct_expect_init(rtp_exp, ct->tuplehash[!dir].tuple.src.l3num,
288 &ct->tuplehash[!dir].tuple.src.u3, 280 &ct->tuplehash[!dir].tuple.src.u3,
289 &ct->tuplehash[!dir].tuple.dst.u3, 281 &ct->tuplehash[!dir].tuple.dst.u3,
290 IPPROTO_UDP, NULL, &rtp_port); 282 IPPROTO_UDP, NULL, &rtp_port);
291 283
292 /* Create expect for RTCP */ 284 /* Create expect for RTCP */
293 if ((rtcp_exp = nf_conntrack_expect_alloc(ct)) == NULL) { 285 if ((rtcp_exp = nf_ct_expect_alloc(ct)) == NULL) {
294 nf_conntrack_expect_put(rtp_exp); 286 nf_ct_expect_put(rtp_exp);
295 return -1; 287 return -1;
296 } 288 }
297 nf_conntrack_expect_init(rtcp_exp, ct->tuplehash[!dir].tuple.src.l3num, 289 nf_ct_expect_init(rtcp_exp, ct->tuplehash[!dir].tuple.src.l3num,
298 &ct->tuplehash[!dir].tuple.src.u3, 290 &ct->tuplehash[!dir].tuple.src.u3,
299 &ct->tuplehash[!dir].tuple.dst.u3, 291 &ct->tuplehash[!dir].tuple.dst.u3,
300 IPPROTO_UDP, NULL, &rtcp_port); 292 IPPROTO_UDP, NULL, &rtcp_port);
301 293
302 if (memcmp(&ct->tuplehash[dir].tuple.src.u3, 294 if (memcmp(&ct->tuplehash[dir].tuple.src.u3,
303 &ct->tuplehash[!dir].tuple.dst.u3, 295 &ct->tuplehash[!dir].tuple.dst.u3,
@@ -308,22 +300,22 @@ static int expect_rtp_rtcp(struct sk_buff **pskb, struct nf_conn *ct,
308 ret = nat_rtp_rtcp(pskb, ct, ctinfo, data, dataoff, 300 ret = nat_rtp_rtcp(pskb, ct, ctinfo, data, dataoff,
309 taddr, port, rtp_port, rtp_exp, rtcp_exp); 301 taddr, port, rtp_port, rtp_exp, rtcp_exp);
310 } else { /* Conntrack only */ 302 } else { /* Conntrack only */
311 if (nf_conntrack_expect_related(rtp_exp) == 0) { 303 if (nf_ct_expect_related(rtp_exp) == 0) {
312 if (nf_conntrack_expect_related(rtcp_exp) == 0) { 304 if (nf_ct_expect_related(rtcp_exp) == 0) {
313 DEBUGP("nf_ct_h323: expect RTP "); 305 pr_debug("nf_ct_h323: expect RTP ");
314 NF_CT_DUMP_TUPLE(&rtp_exp->tuple); 306 NF_CT_DUMP_TUPLE(&rtp_exp->tuple);
315 DEBUGP("nf_ct_h323: expect RTCP "); 307 pr_debug("nf_ct_h323: expect RTCP ");
316 NF_CT_DUMP_TUPLE(&rtcp_exp->tuple); 308 NF_CT_DUMP_TUPLE(&rtcp_exp->tuple);
317 } else { 309 } else {
318 nf_conntrack_unexpect_related(rtp_exp); 310 nf_ct_unexpect_related(rtp_exp);
319 ret = -1; 311 ret = -1;
320 } 312 }
321 } else 313 } else
322 ret = -1; 314 ret = -1;
323 } 315 }
324 316
325 nf_conntrack_expect_put(rtp_exp); 317 nf_ct_expect_put(rtp_exp);
326 nf_conntrack_expect_put(rtcp_exp); 318 nf_ct_expect_put(rtcp_exp);
327 319
328 return ret; 320 return ret;
329} 321}
@@ -349,12 +341,12 @@ static int expect_t120(struct sk_buff **pskb,
349 return 0; 341 return 0;
350 342
351 /* Create expect for T.120 connections */ 343 /* Create expect for T.120 connections */
352 if ((exp = nf_conntrack_expect_alloc(ct)) == NULL) 344 if ((exp = nf_ct_expect_alloc(ct)) == NULL)
353 return -1; 345 return -1;
354 nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num, 346 nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
355 &ct->tuplehash[!dir].tuple.src.u3, 347 &ct->tuplehash[!dir].tuple.src.u3,
356 &ct->tuplehash[!dir].tuple.dst.u3, 348 &ct->tuplehash[!dir].tuple.dst.u3,
357 IPPROTO_TCP, NULL, &port); 349 IPPROTO_TCP, NULL, &port);
358 exp->flags = NF_CT_EXPECT_PERMANENT; /* Accept multiple channels */ 350 exp->flags = NF_CT_EXPECT_PERMANENT; /* Accept multiple channels */
359 351
360 if (memcmp(&ct->tuplehash[dir].tuple.src.u3, 352 if (memcmp(&ct->tuplehash[dir].tuple.src.u3,
@@ -366,14 +358,14 @@ static int expect_t120(struct sk_buff **pskb,
366 ret = nat_t120(pskb, ct, ctinfo, data, dataoff, taddr, 358 ret = nat_t120(pskb, ct, ctinfo, data, dataoff, taddr,
367 port, exp); 359 port, exp);
368 } else { /* Conntrack only */ 360 } else { /* Conntrack only */
369 if (nf_conntrack_expect_related(exp) == 0) { 361 if (nf_ct_expect_related(exp) == 0) {
370 DEBUGP("nf_ct_h323: expect T.120 "); 362 pr_debug("nf_ct_h323: expect T.120 ");
371 NF_CT_DUMP_TUPLE(&exp->tuple); 363 NF_CT_DUMP_TUPLE(&exp->tuple);
372 } else 364 } else
373 ret = -1; 365 ret = -1;
374 } 366 }
375 367
376 nf_conntrack_expect_put(exp); 368 nf_ct_expect_put(exp);
377 369
378 return ret; 370 return ret;
379} 371}
@@ -415,7 +407,7 @@ static int process_olc(struct sk_buff **pskb, struct nf_conn *ct,
415{ 407{
416 int ret; 408 int ret;
417 409
418 DEBUGP("nf_ct_h323: OpenLogicalChannel\n"); 410 pr_debug("nf_ct_h323: OpenLogicalChannel\n");
419 411
420 if (olc->forwardLogicalChannelParameters.multiplexParameters.choice == 412 if (olc->forwardLogicalChannelParameters.multiplexParameters.choice ==
421 eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters) 413 eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)
@@ -475,7 +467,7 @@ static int process_olca(struct sk_buff **pskb, struct nf_conn *ct,
475 H2250LogicalChannelAckParameters *ack; 467 H2250LogicalChannelAckParameters *ack;
476 int ret; 468 int ret;
477 469
478 DEBUGP("nf_ct_h323: OpenLogicalChannelAck\n"); 470 pr_debug("nf_ct_h323: OpenLogicalChannelAck\n");
479 471
480 if ((olca->options & 472 if ((olca->options &
481 eOpenLogicalChannelAck_reverseLogicalChannelParameters) && 473 eOpenLogicalChannelAck_reverseLogicalChannelParameters) &&
@@ -546,8 +538,8 @@ static int process_h245(struct sk_buff **pskb, struct nf_conn *ct,
546 return process_olc(pskb, ct, ctinfo, data, dataoff, 538 return process_olc(pskb, ct, ctinfo, data, dataoff,
547 &mscm->request.openLogicalChannel); 539 &mscm->request.openLogicalChannel);
548 } 540 }
549 DEBUGP("nf_ct_h323: H.245 Request %d\n", 541 pr_debug("nf_ct_h323: H.245 Request %d\n",
550 mscm->request.choice); 542 mscm->request.choice);
551 break; 543 break;
552 case eMultimediaSystemControlMessage_response: 544 case eMultimediaSystemControlMessage_response:
553 if (mscm->response.choice == 545 if (mscm->response.choice ==
@@ -556,11 +548,11 @@ static int process_h245(struct sk_buff **pskb, struct nf_conn *ct,
556 &mscm->response. 548 &mscm->response.
557 openLogicalChannelAck); 549 openLogicalChannelAck);
558 } 550 }
559 DEBUGP("nf_ct_h323: H.245 Response %d\n", 551 pr_debug("nf_ct_h323: H.245 Response %d\n",
560 mscm->response.choice); 552 mscm->response.choice);
561 break; 553 break;
562 default: 554 default:
563 DEBUGP("nf_ct_h323: H.245 signal %d\n", mscm->choice); 555 pr_debug("nf_ct_h323: H.245 signal %d\n", mscm->choice);
564 break; 556 break;
565 } 557 }
566 558
@@ -582,24 +574,23 @@ static int h245_help(struct sk_buff **pskb, unsigned int protoff,
582 ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) { 574 ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
583 return NF_ACCEPT; 575 return NF_ACCEPT;
584 } 576 }
585 DEBUGP("nf_ct_h245: skblen = %u\n", (*pskb)->len); 577 pr_debug("nf_ct_h245: skblen = %u\n", (*pskb)->len);
586 578
587 spin_lock_bh(&nf_h323_lock); 579 spin_lock_bh(&nf_h323_lock);
588 580
589 /* Process each TPKT */ 581 /* Process each TPKT */
590 while (get_tpkt_data(pskb, protoff, ct, ctinfo, 582 while (get_tpkt_data(pskb, protoff, ct, ctinfo,
591 &data, &datalen, &dataoff)) { 583 &data, &datalen, &dataoff)) {
592 DEBUGP("nf_ct_h245: TPKT len=%d ", datalen); 584 pr_debug("nf_ct_h245: TPKT len=%d ", datalen);
593 NF_CT_DUMP_TUPLE(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple); 585 NF_CT_DUMP_TUPLE(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple);
594 586
595 /* Decode H.245 signal */ 587 /* Decode H.245 signal */
596 ret = DecodeMultimediaSystemControlMessage(data, datalen, 588 ret = DecodeMultimediaSystemControlMessage(data, datalen,
597 &mscm); 589 &mscm);
598 if (ret < 0) { 590 if (ret < 0) {
599 if (net_ratelimit()) 591 pr_debug("nf_ct_h245: decoding error: %s\n",
600 printk("nf_ct_h245: decoding error: %s\n", 592 ret == H323_ERROR_BOUND ?
601 ret == H323_ERROR_BOUND ? 593 "out of bound" : "out of range");
602 "out of bound" : "out of range");
603 /* We don't drop when decoding error */ 594 /* We don't drop when decoding error */
604 break; 595 break;
605 } 596 }
@@ -626,8 +617,6 @@ static struct nf_conntrack_helper nf_conntrack_helper_h245 __read_mostly = {
626 .max_expected = H323_RTP_CHANNEL_MAX * 4 + 2 /* T.120 */, 617 .max_expected = H323_RTP_CHANNEL_MAX * 4 + 2 /* T.120 */,
627 .timeout = 240, 618 .timeout = 240,
628 .tuple.dst.protonum = IPPROTO_UDP, 619 .tuple.dst.protonum = IPPROTO_UDP,
629 .mask.src.u.udp.port = __constant_htons(0xFFFF),
630 .mask.dst.protonum = 0xFF,
631 .help = h245_help 620 .help = h245_help
632}; 621};
633 622
@@ -684,12 +673,12 @@ static int expect_h245(struct sk_buff **pskb, struct nf_conn *ct,
684 return 0; 673 return 0;
685 674
686 /* Create expect for h245 connection */ 675 /* Create expect for h245 connection */
687 if ((exp = nf_conntrack_expect_alloc(ct)) == NULL) 676 if ((exp = nf_ct_expect_alloc(ct)) == NULL)
688 return -1; 677 return -1;
689 nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num, 678 nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
690 &ct->tuplehash[!dir].tuple.src.u3, 679 &ct->tuplehash[!dir].tuple.src.u3,
691 &ct->tuplehash[!dir].tuple.dst.u3, 680 &ct->tuplehash[!dir].tuple.dst.u3,
692 IPPROTO_TCP, NULL, &port); 681 IPPROTO_TCP, NULL, &port);
693 exp->helper = &nf_conntrack_helper_h245; 682 exp->helper = &nf_conntrack_helper_h245;
694 683
695 if (memcmp(&ct->tuplehash[dir].tuple.src.u3, 684 if (memcmp(&ct->tuplehash[dir].tuple.src.u3,
@@ -701,14 +690,14 @@ static int expect_h245(struct sk_buff **pskb, struct nf_conn *ct,
701 ret = nat_h245(pskb, ct, ctinfo, data, dataoff, taddr, 690 ret = nat_h245(pskb, ct, ctinfo, data, dataoff, taddr,
702 port, exp); 691 port, exp);
703 } else { /* Conntrack only */ 692 } else { /* Conntrack only */
704 if (nf_conntrack_expect_related(exp) == 0) { 693 if (nf_ct_expect_related(exp) == 0) {
705 DEBUGP("nf_ct_q931: expect H.245 "); 694 pr_debug("nf_ct_q931: expect H.245 ");
706 NF_CT_DUMP_TUPLE(&exp->tuple); 695 NF_CT_DUMP_TUPLE(&exp->tuple);
707 } else 696 } else
708 ret = -1; 697 ret = -1;
709 } 698 }
710 699
711 nf_conntrack_expect_put(exp); 700 nf_ct_expect_put(exp);
712 701
713 return ret; 702 return ret;
714} 703}
@@ -791,16 +780,16 @@ static int expect_callforwarding(struct sk_buff **pskb,
791 if (callforward_filter && 780 if (callforward_filter &&
792 callforward_do_filter(&addr, &ct->tuplehash[!dir].tuple.src.u3, 781 callforward_do_filter(&addr, &ct->tuplehash[!dir].tuple.src.u3,
793 ct->tuplehash[!dir].tuple.src.l3num)) { 782 ct->tuplehash[!dir].tuple.src.l3num)) {
794 DEBUGP("nf_ct_q931: Call Forwarding not tracked\n"); 783 pr_debug("nf_ct_q931: Call Forwarding not tracked\n");
795 return 0; 784 return 0;
796 } 785 }
797 786
798 /* Create expect for the second call leg */ 787 /* Create expect for the second call leg */
799 if ((exp = nf_conntrack_expect_alloc(ct)) == NULL) 788 if ((exp = nf_ct_expect_alloc(ct)) == NULL)
800 return -1; 789 return -1;
801 nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num, 790 nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
802 &ct->tuplehash[!dir].tuple.src.u3, &addr, 791 &ct->tuplehash[!dir].tuple.src.u3, &addr,
803 IPPROTO_TCP, NULL, &port); 792 IPPROTO_TCP, NULL, &port);
804 exp->helper = nf_conntrack_helper_q931; 793 exp->helper = nf_conntrack_helper_q931;
805 794
806 if (memcmp(&ct->tuplehash[dir].tuple.src.u3, 795 if (memcmp(&ct->tuplehash[dir].tuple.src.u3,
@@ -812,14 +801,14 @@ static int expect_callforwarding(struct sk_buff **pskb,
812 ret = nat_callforwarding(pskb, ct, ctinfo, data, dataoff, 801 ret = nat_callforwarding(pskb, ct, ctinfo, data, dataoff,
813 taddr, port, exp); 802 taddr, port, exp);
814 } else { /* Conntrack only */ 803 } else { /* Conntrack only */
815 if (nf_conntrack_expect_related(exp) == 0) { 804 if (nf_ct_expect_related(exp) == 0) {
816 DEBUGP("nf_ct_q931: expect Call Forwarding "); 805 pr_debug("nf_ct_q931: expect Call Forwarding ");
817 NF_CT_DUMP_TUPLE(&exp->tuple); 806 NF_CT_DUMP_TUPLE(&exp->tuple);
818 } else 807 } else
819 ret = -1; 808 ret = -1;
820 } 809 }
821 810
822 nf_conntrack_expect_put(exp); 811 nf_ct_expect_put(exp);
823 812
824 return ret; 813 return ret;
825} 814}
@@ -837,7 +826,7 @@ static int process_setup(struct sk_buff **pskb, struct nf_conn *ct,
837 union nf_conntrack_address addr; 826 union nf_conntrack_address addr;
838 typeof(set_h225_addr_hook) set_h225_addr; 827 typeof(set_h225_addr_hook) set_h225_addr;
839 828
840 DEBUGP("nf_ct_q931: Setup\n"); 829 pr_debug("nf_ct_q931: Setup\n");
841 830
842 if (setup->options & eSetup_UUIE_h245Address) { 831 if (setup->options & eSetup_UUIE_h245Address) {
843 ret = expect_h245(pskb, ct, ctinfo, data, dataoff, 832 ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
@@ -852,11 +841,11 @@ static int process_setup(struct sk_buff **pskb, struct nf_conn *ct,
852 get_h225_addr(ct, *data, &setup->destCallSignalAddress, 841 get_h225_addr(ct, *data, &setup->destCallSignalAddress,
853 &addr, &port) && 842 &addr, &port) &&
854 memcmp(&addr, &ct->tuplehash[!dir].tuple.src.u3, sizeof(addr))) { 843 memcmp(&addr, &ct->tuplehash[!dir].tuple.src.u3, sizeof(addr))) {
855 DEBUGP("nf_ct_q931: set destCallSignalAddress " 844 pr_debug("nf_ct_q931: set destCallSignalAddress "
856 NIP6_FMT ":%hu->" NIP6_FMT ":%hu\n", 845 NIP6_FMT ":%hu->" NIP6_FMT ":%hu\n",
857 NIP6(*(struct in6_addr *)&addr), ntohs(port), 846 NIP6(*(struct in6_addr *)&addr), ntohs(port),
858 NIP6(*(struct in6_addr *)&ct->tuplehash[!dir].tuple.src.u3), 847 NIP6(*(struct in6_addr *)&ct->tuplehash[!dir].tuple.src.u3),
859 ntohs(ct->tuplehash[!dir].tuple.src.u.tcp.port)); 848 ntohs(ct->tuplehash[!dir].tuple.src.u.tcp.port));
860 ret = set_h225_addr(pskb, data, dataoff, 849 ret = set_h225_addr(pskb, data, dataoff,
861 &setup->destCallSignalAddress, 850 &setup->destCallSignalAddress,
862 &ct->tuplehash[!dir].tuple.src.u3, 851 &ct->tuplehash[!dir].tuple.src.u3,
@@ -870,11 +859,11 @@ static int process_setup(struct sk_buff **pskb, struct nf_conn *ct,
870 get_h225_addr(ct, *data, &setup->sourceCallSignalAddress, 859 get_h225_addr(ct, *data, &setup->sourceCallSignalAddress,
871 &addr, &port) && 860 &addr, &port) &&
872 memcmp(&addr, &ct->tuplehash[!dir].tuple.dst.u3, sizeof(addr))) { 861 memcmp(&addr, &ct->tuplehash[!dir].tuple.dst.u3, sizeof(addr))) {
873 DEBUGP("nf_ct_q931: set sourceCallSignalAddress " 862 pr_debug("nf_ct_q931: set sourceCallSignalAddress "
874 NIP6_FMT ":%hu->" NIP6_FMT ":%hu\n", 863 NIP6_FMT ":%hu->" NIP6_FMT ":%hu\n",
875 NIP6(*(struct in6_addr *)&addr), ntohs(port), 864 NIP6(*(struct in6_addr *)&addr), ntohs(port),
876 NIP6(*(struct in6_addr *)&ct->tuplehash[!dir].tuple.dst.u3), 865 NIP6(*(struct in6_addr *)&ct->tuplehash[!dir].tuple.dst.u3),
877 ntohs(ct->tuplehash[!dir].tuple.dst.u.tcp.port)); 866 ntohs(ct->tuplehash[!dir].tuple.dst.u.tcp.port));
878 ret = set_h225_addr(pskb, data, dataoff, 867 ret = set_h225_addr(pskb, data, dataoff,
879 &setup->sourceCallSignalAddress, 868 &setup->sourceCallSignalAddress,
880 &ct->tuplehash[!dir].tuple.dst.u3, 869 &ct->tuplehash[!dir].tuple.dst.u3,
@@ -905,7 +894,7 @@ static int process_callproceeding(struct sk_buff **pskb,
905 int ret; 894 int ret;
906 int i; 895 int i;
907 896
908 DEBUGP("nf_ct_q931: CallProceeding\n"); 897 pr_debug("nf_ct_q931: CallProceeding\n");
909 898
910 if (callproc->options & eCallProceeding_UUIE_h245Address) { 899 if (callproc->options & eCallProceeding_UUIE_h245Address) {
911 ret = expect_h245(pskb, ct, ctinfo, data, dataoff, 900 ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
@@ -935,7 +924,7 @@ static int process_connect(struct sk_buff **pskb, struct nf_conn *ct,
935 int ret; 924 int ret;
936 int i; 925 int i;
937 926
938 DEBUGP("nf_ct_q931: Connect\n"); 927 pr_debug("nf_ct_q931: Connect\n");
939 928
940 if (connect->options & eConnect_UUIE_h245Address) { 929 if (connect->options & eConnect_UUIE_h245Address) {
941 ret = expect_h245(pskb, ct, ctinfo, data, dataoff, 930 ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
@@ -965,7 +954,7 @@ static int process_alerting(struct sk_buff **pskb, struct nf_conn *ct,
965 int ret; 954 int ret;
966 int i; 955 int i;
967 956
968 DEBUGP("nf_ct_q931: Alerting\n"); 957 pr_debug("nf_ct_q931: Alerting\n");
969 958
970 if (alert->options & eAlerting_UUIE_h245Address) { 959 if (alert->options & eAlerting_UUIE_h245Address) {
971 ret = expect_h245(pskb, ct, ctinfo, data, dataoff, 960 ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
@@ -995,7 +984,7 @@ static int process_facility(struct sk_buff **pskb, struct nf_conn *ct,
995 int ret; 984 int ret;
996 int i; 985 int i;
997 986
998 DEBUGP("nf_ct_q931: Facility\n"); 987 pr_debug("nf_ct_q931: Facility\n");
999 988
1000 if (facility->reason.choice == eFacilityReason_callForwarded) { 989 if (facility->reason.choice == eFacilityReason_callForwarded) {
1001 if (facility->options & eFacility_UUIE_alternativeAddress) 990 if (facility->options & eFacility_UUIE_alternativeAddress)
@@ -1034,7 +1023,7 @@ static int process_progress(struct sk_buff **pskb, struct nf_conn *ct,
1034 int ret; 1023 int ret;
1035 int i; 1024 int i;
1036 1025
1037 DEBUGP("nf_ct_q931: Progress\n"); 1026 pr_debug("nf_ct_q931: Progress\n");
1038 1027
1039 if (progress->options & eProgress_UUIE_h245Address) { 1028 if (progress->options & eProgress_UUIE_h245Address) {
1040 ret = expect_h245(pskb, ct, ctinfo, data, dataoff, 1029 ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
@@ -1091,8 +1080,8 @@ static int process_q931(struct sk_buff **pskb, struct nf_conn *ct,
1091 &pdu->h323_message_body.progress); 1080 &pdu->h323_message_body.progress);
1092 break; 1081 break;
1093 default: 1082 default:
1094 DEBUGP("nf_ct_q931: Q.931 signal %d\n", 1083 pr_debug("nf_ct_q931: Q.931 signal %d\n",
1095 pdu->h323_message_body.choice); 1084 pdu->h323_message_body.choice);
1096 break; 1085 break;
1097 } 1086 }
1098 1087
@@ -1126,23 +1115,22 @@ static int q931_help(struct sk_buff **pskb, unsigned int protoff,
1126 ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) { 1115 ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
1127 return NF_ACCEPT; 1116 return NF_ACCEPT;
1128 } 1117 }
1129 DEBUGP("nf_ct_q931: skblen = %u\n", (*pskb)->len); 1118 pr_debug("nf_ct_q931: skblen = %u\n", (*pskb)->len);
1130 1119
1131 spin_lock_bh(&nf_h323_lock); 1120 spin_lock_bh(&nf_h323_lock);
1132 1121
1133 /* Process each TPKT */ 1122 /* Process each TPKT */
1134 while (get_tpkt_data(pskb, protoff, ct, ctinfo, 1123 while (get_tpkt_data(pskb, protoff, ct, ctinfo,
1135 &data, &datalen, &dataoff)) { 1124 &data, &datalen, &dataoff)) {
1136 DEBUGP("nf_ct_q931: TPKT len=%d ", datalen); 1125 pr_debug("nf_ct_q931: TPKT len=%d ", datalen);
1137 NF_CT_DUMP_TUPLE(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple); 1126 NF_CT_DUMP_TUPLE(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple);
1138 1127
1139 /* Decode Q.931 signal */ 1128 /* Decode Q.931 signal */
1140 ret = DecodeQ931(data, datalen, &q931); 1129 ret = DecodeQ931(data, datalen, &q931);
1141 if (ret < 0) { 1130 if (ret < 0) {
1142 if (net_ratelimit()) 1131 pr_debug("nf_ct_q931: decoding error: %s\n",
1143 printk("nf_ct_q931: decoding error: %s\n", 1132 ret == H323_ERROR_BOUND ?
1144 ret == H323_ERROR_BOUND ? 1133 "out of bound" : "out of range");
1145 "out of bound" : "out of range");
1146 /* We don't drop when decoding error */ 1134 /* We don't drop when decoding error */
1147 break; 1135 break;
1148 } 1136 }
@@ -1173,9 +1161,6 @@ static struct nf_conntrack_helper nf_conntrack_helper_q931[] __read_mostly = {
1173 .tuple.src.l3num = AF_INET, 1161 .tuple.src.l3num = AF_INET,
1174 .tuple.src.u.tcp.port = __constant_htons(Q931_PORT), 1162 .tuple.src.u.tcp.port = __constant_htons(Q931_PORT),
1175 .tuple.dst.protonum = IPPROTO_TCP, 1163 .tuple.dst.protonum = IPPROTO_TCP,
1176 .mask.src.l3num = 0xFFFF,
1177 .mask.src.u.tcp.port = __constant_htons(0xFFFF),
1178 .mask.dst.protonum = 0xFF,
1179 .help = q931_help 1164 .help = q931_help
1180 }, 1165 },
1181 { 1166 {
@@ -1187,9 +1172,6 @@ static struct nf_conntrack_helper nf_conntrack_helper_q931[] __read_mostly = {
1187 .tuple.src.l3num = AF_INET6, 1172 .tuple.src.l3num = AF_INET6,
1188 .tuple.src.u.tcp.port = __constant_htons(Q931_PORT), 1173 .tuple.src.u.tcp.port = __constant_htons(Q931_PORT),
1189 .tuple.dst.protonum = IPPROTO_TCP, 1174 .tuple.dst.protonum = IPPROTO_TCP,
1190 .mask.src.l3num = 0xFFFF,
1191 .mask.src.u.tcp.port = __constant_htons(0xFFFF),
1192 .mask.dst.protonum = 0xFF,
1193 .help = q931_help 1175 .help = q931_help
1194 }, 1176 },
1195}; 1177};
@@ -1225,7 +1207,7 @@ static struct nf_conntrack_expect *find_expect(struct nf_conn *ct,
1225 tuple.dst.u.tcp.port = port; 1207 tuple.dst.u.tcp.port = port;
1226 tuple.dst.protonum = IPPROTO_TCP; 1208 tuple.dst.protonum = IPPROTO_TCP;
1227 1209
1228 exp = __nf_conntrack_expect_find(&tuple); 1210 exp = __nf_ct_expect_find(&tuple);
1229 if (exp && exp->master == ct) 1211 if (exp && exp->master == ct)
1230 return exp; 1212 return exp;
1231 return NULL; 1213 return NULL;
@@ -1271,14 +1253,13 @@ static int expect_q931(struct sk_buff **pskb, struct nf_conn *ct,
1271 return 0; 1253 return 0;
1272 1254
1273 /* Create expect for Q.931 */ 1255 /* Create expect for Q.931 */
1274 if ((exp = nf_conntrack_expect_alloc(ct)) == NULL) 1256 if ((exp = nf_ct_expect_alloc(ct)) == NULL)
1275 return -1; 1257 return -1;
1276 nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num, 1258 nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
1277 gkrouted_only ? /* only accept calls from GK? */ 1259 gkrouted_only ? /* only accept calls from GK? */
1278 &ct->tuplehash[!dir].tuple.src.u3 : 1260 &ct->tuplehash[!dir].tuple.src.u3 : NULL,
1279 NULL, 1261 &ct->tuplehash[!dir].tuple.dst.u3,
1280 &ct->tuplehash[!dir].tuple.dst.u3, 1262 IPPROTO_TCP, NULL, &port);
1281 IPPROTO_TCP, NULL, &port);
1282 exp->helper = nf_conntrack_helper_q931; 1263 exp->helper = nf_conntrack_helper_q931;
1283 exp->flags = NF_CT_EXPECT_PERMANENT; /* Accept multiple calls */ 1264 exp->flags = NF_CT_EXPECT_PERMANENT; /* Accept multiple calls */
1284 1265
@@ -1286,8 +1267,8 @@ static int expect_q931(struct sk_buff **pskb, struct nf_conn *ct,
1286 if (nat_q931 && ct->status & IPS_NAT_MASK) { /* Need NAT */ 1267 if (nat_q931 && ct->status & IPS_NAT_MASK) { /* Need NAT */
1287 ret = nat_q931(pskb, ct, ctinfo, data, taddr, i, port, exp); 1268 ret = nat_q931(pskb, ct, ctinfo, data, taddr, i, port, exp);
1288 } else { /* Conntrack only */ 1269 } else { /* Conntrack only */
1289 if (nf_conntrack_expect_related(exp) == 0) { 1270 if (nf_ct_expect_related(exp) == 0) {
1290 DEBUGP("nf_ct_ras: expect Q.931 "); 1271 pr_debug("nf_ct_ras: expect Q.931 ");
1291 NF_CT_DUMP_TUPLE(&exp->tuple); 1272 NF_CT_DUMP_TUPLE(&exp->tuple);
1292 1273
1293 /* Save port for looking up expect in processing RCF */ 1274 /* Save port for looking up expect in processing RCF */
@@ -1296,7 +1277,7 @@ static int expect_q931(struct sk_buff **pskb, struct nf_conn *ct,
1296 ret = -1; 1277 ret = -1;
1297 } 1278 }
1298 1279
1299 nf_conntrack_expect_put(exp); 1280 nf_ct_expect_put(exp);
1300 1281
1301 return ret; 1282 return ret;
1302} 1283}
@@ -1308,7 +1289,7 @@ static int process_grq(struct sk_buff **pskb, struct nf_conn *ct,
1308{ 1289{
1309 typeof(set_ras_addr_hook) set_ras_addr; 1290 typeof(set_ras_addr_hook) set_ras_addr;
1310 1291
1311 DEBUGP("nf_ct_ras: GRQ\n"); 1292 pr_debug("nf_ct_ras: GRQ\n");
1312 1293
1313 set_ras_addr = rcu_dereference(set_ras_addr_hook); 1294 set_ras_addr = rcu_dereference(set_ras_addr_hook);
1314 if (set_ras_addr && ct->status & IPS_NAT_MASK) /* NATed */ 1295 if (set_ras_addr && ct->status & IPS_NAT_MASK) /* NATed */
@@ -1328,7 +1309,7 @@ static int process_gcf(struct sk_buff **pskb, struct nf_conn *ct,
1328 union nf_conntrack_address addr; 1309 union nf_conntrack_address addr;
1329 struct nf_conntrack_expect *exp; 1310 struct nf_conntrack_expect *exp;
1330 1311
1331 DEBUGP("nf_ct_ras: GCF\n"); 1312 pr_debug("nf_ct_ras: GCF\n");
1332 1313
1333 if (!get_h225_addr(ct, *data, &gcf->rasAddress, &addr, &port)) 1314 if (!get_h225_addr(ct, *data, &gcf->rasAddress, &addr, &port))
1334 return 0; 1315 return 0;
@@ -1343,20 +1324,20 @@ static int process_gcf(struct sk_buff **pskb, struct nf_conn *ct,
1343 return 0; 1324 return 0;
1344 1325
1345 /* Need new expect */ 1326 /* Need new expect */
1346 if ((exp = nf_conntrack_expect_alloc(ct)) == NULL) 1327 if ((exp = nf_ct_expect_alloc(ct)) == NULL)
1347 return -1; 1328 return -1;
1348 nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num, 1329 nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
1349 &ct->tuplehash[!dir].tuple.src.u3, &addr, 1330 &ct->tuplehash[!dir].tuple.src.u3, &addr,
1350 IPPROTO_UDP, NULL, &port); 1331 IPPROTO_UDP, NULL, &port);
1351 exp->helper = nf_conntrack_helper_ras; 1332 exp->helper = nf_conntrack_helper_ras;
1352 1333
1353 if (nf_conntrack_expect_related(exp) == 0) { 1334 if (nf_ct_expect_related(exp) == 0) {
1354 DEBUGP("nf_ct_ras: expect RAS "); 1335 pr_debug("nf_ct_ras: expect RAS ");
1355 NF_CT_DUMP_TUPLE(&exp->tuple); 1336 NF_CT_DUMP_TUPLE(&exp->tuple);
1356 } else 1337 } else
1357 ret = -1; 1338 ret = -1;
1358 1339
1359 nf_conntrack_expect_put(exp); 1340 nf_ct_expect_put(exp);
1360 1341
1361 return ret; 1342 return ret;
1362} 1343}
@@ -1370,7 +1351,7 @@ static int process_rrq(struct sk_buff **pskb, struct nf_conn *ct,
1370 int ret; 1351 int ret;
1371 typeof(set_ras_addr_hook) set_ras_addr; 1352 typeof(set_ras_addr_hook) set_ras_addr;
1372 1353
1373 DEBUGP("nf_ct_ras: RRQ\n"); 1354 pr_debug("nf_ct_ras: RRQ\n");
1374 1355
1375 ret = expect_q931(pskb, ct, ctinfo, data, 1356 ret = expect_q931(pskb, ct, ctinfo, data,
1376 rrq->callSignalAddress.item, 1357 rrq->callSignalAddress.item,
@@ -1388,7 +1369,7 @@ static int process_rrq(struct sk_buff **pskb, struct nf_conn *ct,
1388 } 1369 }
1389 1370
1390 if (rrq->options & eRegistrationRequest_timeToLive) { 1371 if (rrq->options & eRegistrationRequest_timeToLive) {
1391 DEBUGP("nf_ct_ras: RRQ TTL = %u seconds\n", rrq->timeToLive); 1372 pr_debug("nf_ct_ras: RRQ TTL = %u seconds\n", rrq->timeToLive);
1392 info->timeout = rrq->timeToLive; 1373 info->timeout = rrq->timeToLive;
1393 } else 1374 } else
1394 info->timeout = default_rrq_ttl; 1375 info->timeout = default_rrq_ttl;
@@ -1407,7 +1388,7 @@ static int process_rcf(struct sk_buff **pskb, struct nf_conn *ct,
1407 struct nf_conntrack_expect *exp; 1388 struct nf_conntrack_expect *exp;
1408 typeof(set_sig_addr_hook) set_sig_addr; 1389 typeof(set_sig_addr_hook) set_sig_addr;
1409 1390
1410 DEBUGP("nf_ct_ras: RCF\n"); 1391 pr_debug("nf_ct_ras: RCF\n");
1411 1392
1412 set_sig_addr = rcu_dereference(set_sig_addr_hook); 1393 set_sig_addr = rcu_dereference(set_sig_addr_hook);
1413 if (set_sig_addr && ct->status & IPS_NAT_MASK) { 1394 if (set_sig_addr && ct->status & IPS_NAT_MASK) {
@@ -1419,14 +1400,13 @@ static int process_rcf(struct sk_buff **pskb, struct nf_conn *ct,
1419 } 1400 }
1420 1401
1421 if (rcf->options & eRegistrationConfirm_timeToLive) { 1402 if (rcf->options & eRegistrationConfirm_timeToLive) {
1422 DEBUGP("nf_ct_ras: RCF TTL = %u seconds\n", rcf->timeToLive); 1403 pr_debug("nf_ct_ras: RCF TTL = %u seconds\n", rcf->timeToLive);
1423 info->timeout = rcf->timeToLive; 1404 info->timeout = rcf->timeToLive;
1424 } 1405 }
1425 1406
1426 if (info->timeout > 0) { 1407 if (info->timeout > 0) {
1427 DEBUGP 1408 pr_debug("nf_ct_ras: set RAS connection timeout to "
1428 ("nf_ct_ras: set RAS connection timeout to %u seconds\n", 1409 "%u seconds\n", info->timeout);
1429 info->timeout);
1430 nf_ct_refresh(ct, *pskb, info->timeout * HZ); 1410 nf_ct_refresh(ct, *pskb, info->timeout * HZ);
1431 1411
1432 /* Set expect timeout */ 1412 /* Set expect timeout */
@@ -1434,9 +1414,9 @@ static int process_rcf(struct sk_buff **pskb, struct nf_conn *ct,
1434 exp = find_expect(ct, &ct->tuplehash[dir].tuple.dst.u3, 1414 exp = find_expect(ct, &ct->tuplehash[dir].tuple.dst.u3,
1435 info->sig_port[!dir]); 1415 info->sig_port[!dir]);
1436 if (exp) { 1416 if (exp) {
1437 DEBUGP("nf_ct_ras: set Q.931 expect " 1417 pr_debug("nf_ct_ras: set Q.931 expect "
1438 "timeout to %u seconds for", 1418 "timeout to %u seconds for",
1439 info->timeout); 1419 info->timeout);
1440 NF_CT_DUMP_TUPLE(&exp->tuple); 1420 NF_CT_DUMP_TUPLE(&exp->tuple);
1441 set_expect_timeout(exp, info->timeout); 1421 set_expect_timeout(exp, info->timeout);
1442 } 1422 }
@@ -1456,7 +1436,7 @@ static int process_urq(struct sk_buff **pskb, struct nf_conn *ct,
1456 int ret; 1436 int ret;
1457 typeof(set_sig_addr_hook) set_sig_addr; 1437 typeof(set_sig_addr_hook) set_sig_addr;
1458 1438
1459 DEBUGP("nf_ct_ras: URQ\n"); 1439 pr_debug("nf_ct_ras: URQ\n");
1460 1440
1461 set_sig_addr = rcu_dereference(set_sig_addr_hook); 1441 set_sig_addr = rcu_dereference(set_sig_addr_hook);
1462 if (set_sig_addr && ct->status & IPS_NAT_MASK) { 1442 if (set_sig_addr && ct->status & IPS_NAT_MASK) {
@@ -1489,7 +1469,7 @@ static int process_arq(struct sk_buff **pskb, struct nf_conn *ct,
1489 union nf_conntrack_address addr; 1469 union nf_conntrack_address addr;
1490 typeof(set_h225_addr_hook) set_h225_addr; 1470 typeof(set_h225_addr_hook) set_h225_addr;
1491 1471
1492 DEBUGP("nf_ct_ras: ARQ\n"); 1472 pr_debug("nf_ct_ras: ARQ\n");
1493 1473
1494 set_h225_addr = rcu_dereference(set_h225_addr_hook); 1474 set_h225_addr = rcu_dereference(set_h225_addr_hook);
1495 if ((arq->options & eAdmissionRequest_destCallSignalAddress) && 1475 if ((arq->options & eAdmissionRequest_destCallSignalAddress) &&
@@ -1532,7 +1512,7 @@ static int process_acf(struct sk_buff **pskb, struct nf_conn *ct,
1532 struct nf_conntrack_expect *exp; 1512 struct nf_conntrack_expect *exp;
1533 typeof(set_sig_addr_hook) set_sig_addr; 1513 typeof(set_sig_addr_hook) set_sig_addr;
1534 1514
1535 DEBUGP("nf_ct_ras: ACF\n"); 1515 pr_debug("nf_ct_ras: ACF\n");
1536 1516
1537 if (!get_h225_addr(ct, *data, &acf->destCallSignalAddress, 1517 if (!get_h225_addr(ct, *data, &acf->destCallSignalAddress,
1538 &addr, &port)) 1518 &addr, &port))
@@ -1548,21 +1528,21 @@ static int process_acf(struct sk_buff **pskb, struct nf_conn *ct,
1548 } 1528 }
1549 1529
1550 /* Need new expect */ 1530 /* Need new expect */
1551 if ((exp = nf_conntrack_expect_alloc(ct)) == NULL) 1531 if ((exp = nf_ct_expect_alloc(ct)) == NULL)
1552 return -1; 1532 return -1;
1553 nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num, 1533 nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
1554 &ct->tuplehash[!dir].tuple.src.u3, &addr, 1534 &ct->tuplehash[!dir].tuple.src.u3, &addr,
1555 IPPROTO_TCP, NULL, &port); 1535 IPPROTO_TCP, NULL, &port);
1556 exp->flags = NF_CT_EXPECT_PERMANENT; 1536 exp->flags = NF_CT_EXPECT_PERMANENT;
1557 exp->helper = nf_conntrack_helper_q931; 1537 exp->helper = nf_conntrack_helper_q931;
1558 1538
1559 if (nf_conntrack_expect_related(exp) == 0) { 1539 if (nf_ct_expect_related(exp) == 0) {
1560 DEBUGP("nf_ct_ras: expect Q.931 "); 1540 pr_debug("nf_ct_ras: expect Q.931 ");
1561 NF_CT_DUMP_TUPLE(&exp->tuple); 1541 NF_CT_DUMP_TUPLE(&exp->tuple);
1562 } else 1542 } else
1563 ret = -1; 1543 ret = -1;
1564 1544
1565 nf_conntrack_expect_put(exp); 1545 nf_ct_expect_put(exp);
1566 1546
1567 return ret; 1547 return ret;
1568} 1548}
@@ -1574,7 +1554,7 @@ static int process_lrq(struct sk_buff **pskb, struct nf_conn *ct,
1574{ 1554{
1575 typeof(set_ras_addr_hook) set_ras_addr; 1555 typeof(set_ras_addr_hook) set_ras_addr;
1576 1556
1577 DEBUGP("nf_ct_ras: LRQ\n"); 1557 pr_debug("nf_ct_ras: LRQ\n");
1578 1558
1579 set_ras_addr = rcu_dereference(set_ras_addr_hook); 1559 set_ras_addr = rcu_dereference(set_ras_addr_hook);
1580 if (set_ras_addr && ct->status & IPS_NAT_MASK) 1560 if (set_ras_addr && ct->status & IPS_NAT_MASK)
@@ -1594,28 +1574,28 @@ static int process_lcf(struct sk_buff **pskb, struct nf_conn *ct,
1594 union nf_conntrack_address addr; 1574 union nf_conntrack_address addr;
1595 struct nf_conntrack_expect *exp; 1575 struct nf_conntrack_expect *exp;
1596 1576
1597 DEBUGP("nf_ct_ras: LCF\n"); 1577 pr_debug("nf_ct_ras: LCF\n");
1598 1578
1599 if (!get_h225_addr(ct, *data, &lcf->callSignalAddress, 1579 if (!get_h225_addr(ct, *data, &lcf->callSignalAddress,
1600 &addr, &port)) 1580 &addr, &port))
1601 return 0; 1581 return 0;
1602 1582
1603 /* Need new expect for call signal */ 1583 /* Need new expect for call signal */
1604 if ((exp = nf_conntrack_expect_alloc(ct)) == NULL) 1584 if ((exp = nf_ct_expect_alloc(ct)) == NULL)
1605 return -1; 1585 return -1;
1606 nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num, 1586 nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
1607 &ct->tuplehash[!dir].tuple.src.u3, &addr, 1587 &ct->tuplehash[!dir].tuple.src.u3, &addr,
1608 IPPROTO_TCP, NULL, &port); 1588 IPPROTO_TCP, NULL, &port);
1609 exp->flags = NF_CT_EXPECT_PERMANENT; 1589 exp->flags = NF_CT_EXPECT_PERMANENT;
1610 exp->helper = nf_conntrack_helper_q931; 1590 exp->helper = nf_conntrack_helper_q931;
1611 1591
1612 if (nf_conntrack_expect_related(exp) == 0) { 1592 if (nf_ct_expect_related(exp) == 0) {
1613 DEBUGP("nf_ct_ras: expect Q.931 "); 1593 pr_debug("nf_ct_ras: expect Q.931 ");
1614 NF_CT_DUMP_TUPLE(&exp->tuple); 1594 NF_CT_DUMP_TUPLE(&exp->tuple);
1615 } else 1595 } else
1616 ret = -1; 1596 ret = -1;
1617 1597
1618 nf_conntrack_expect_put(exp); 1598 nf_ct_expect_put(exp);
1619 1599
1620 /* Ignore rasAddress */ 1600 /* Ignore rasAddress */
1621 1601
@@ -1631,7 +1611,7 @@ static int process_irr(struct sk_buff **pskb, struct nf_conn *ct,
1631 typeof(set_ras_addr_hook) set_ras_addr; 1611 typeof(set_ras_addr_hook) set_ras_addr;
1632 typeof(set_sig_addr_hook) set_sig_addr; 1612 typeof(set_sig_addr_hook) set_sig_addr;
1633 1613
1634 DEBUGP("nf_ct_ras: IRR\n"); 1614 pr_debug("nf_ct_ras: IRR\n");
1635 1615
1636 set_ras_addr = rcu_dereference(set_ras_addr_hook); 1616 set_ras_addr = rcu_dereference(set_ras_addr_hook);
1637 if (set_ras_addr && ct->status & IPS_NAT_MASK) { 1617 if (set_ras_addr && ct->status & IPS_NAT_MASK) {
@@ -1690,7 +1670,7 @@ static int process_ras(struct sk_buff **pskb, struct nf_conn *ct,
1690 return process_irr(pskb, ct, ctinfo, data, 1670 return process_irr(pskb, ct, ctinfo, data,
1691 &ras->infoRequestResponse); 1671 &ras->infoRequestResponse);
1692 default: 1672 default:
1693 DEBUGP("nf_ct_ras: RAS message %d\n", ras->choice); 1673 pr_debug("nf_ct_ras: RAS message %d\n", ras->choice);
1694 break; 1674 break;
1695 } 1675 }
1696 1676
@@ -1706,7 +1686,7 @@ static int ras_help(struct sk_buff **pskb, unsigned int protoff,
1706 int datalen = 0; 1686 int datalen = 0;
1707 int ret; 1687 int ret;
1708 1688
1709 DEBUGP("nf_ct_ras: skblen = %u\n", (*pskb)->len); 1689 pr_debug("nf_ct_ras: skblen = %u\n", (*pskb)->len);
1710 1690
1711 spin_lock_bh(&nf_h323_lock); 1691 spin_lock_bh(&nf_h323_lock);
1712 1692
@@ -1714,16 +1694,15 @@ static int ras_help(struct sk_buff **pskb, unsigned int protoff,
1714 data = get_udp_data(pskb, protoff, &datalen); 1694 data = get_udp_data(pskb, protoff, &datalen);
1715 if (data == NULL) 1695 if (data == NULL)
1716 goto accept; 1696 goto accept;
1717 DEBUGP("nf_ct_ras: RAS message len=%d ", datalen); 1697 pr_debug("nf_ct_ras: RAS message len=%d ", datalen);
1718 NF_CT_DUMP_TUPLE(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple); 1698 NF_CT_DUMP_TUPLE(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple);
1719 1699
1720 /* Decode RAS message */ 1700 /* Decode RAS message */
1721 ret = DecodeRasMessage(data, datalen, &ras); 1701 ret = DecodeRasMessage(data, datalen, &ras);
1722 if (ret < 0) { 1702 if (ret < 0) {
1723 if (net_ratelimit()) 1703 pr_debug("nf_ct_ras: decoding error: %s\n",
1724 printk("nf_ct_ras: decoding error: %s\n", 1704 ret == H323_ERROR_BOUND ?
1725 ret == H323_ERROR_BOUND ? 1705 "out of bound" : "out of range");
1726 "out of bound" : "out of range");
1727 goto accept; 1706 goto accept;
1728 } 1707 }
1729 1708
@@ -1752,9 +1731,6 @@ static struct nf_conntrack_helper nf_conntrack_helper_ras[] __read_mostly = {
1752 .tuple.src.l3num = AF_INET, 1731 .tuple.src.l3num = AF_INET,
1753 .tuple.src.u.udp.port = __constant_htons(RAS_PORT), 1732 .tuple.src.u.udp.port = __constant_htons(RAS_PORT),
1754 .tuple.dst.protonum = IPPROTO_UDP, 1733 .tuple.dst.protonum = IPPROTO_UDP,
1755 .mask.src.l3num = 0xFFFF,
1756 .mask.src.u.udp.port = __constant_htons(0xFFFF),
1757 .mask.dst.protonum = 0xFF,
1758 .help = ras_help, 1734 .help = ras_help,
1759 }, 1735 },
1760 { 1736 {
@@ -1765,9 +1741,6 @@ static struct nf_conntrack_helper nf_conntrack_helper_ras[] __read_mostly = {
1765 .tuple.src.l3num = AF_INET6, 1741 .tuple.src.l3num = AF_INET6,
1766 .tuple.src.u.udp.port = __constant_htons(RAS_PORT), 1742 .tuple.src.u.udp.port = __constant_htons(RAS_PORT),
1767 .tuple.dst.protonum = IPPROTO_UDP, 1743 .tuple.dst.protonum = IPPROTO_UDP,
1768 .mask.src.l3num = 0xFFFF,
1769 .mask.src.u.udp.port = __constant_htons(0xFFFF),
1770 .mask.dst.protonum = 0xFF,
1771 .help = ras_help, 1744 .help = ras_help,
1772 }, 1745 },
1773}; 1746};
@@ -1780,7 +1753,7 @@ static void __exit nf_conntrack_h323_fini(void)
1780 nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[1]); 1753 nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[1]);
1781 nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[0]); 1754 nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[0]);
1782 kfree(h323_buffer); 1755 kfree(h323_buffer);
1783 DEBUGP("nf_ct_h323: fini\n"); 1756 pr_debug("nf_ct_h323: fini\n");
1784} 1757}
1785 1758
1786/****************************************************************************/ 1759/****************************************************************************/
@@ -1803,7 +1776,7 @@ static int __init nf_conntrack_h323_init(void)
1803 ret = nf_conntrack_helper_register(&nf_conntrack_helper_ras[1]); 1776 ret = nf_conntrack_helper_register(&nf_conntrack_helper_ras[1]);
1804 if (ret < 0) 1777 if (ret < 0)
1805 goto err4; 1778 goto err4;
1806 DEBUGP("nf_ct_h323: init success\n"); 1779 pr_debug("nf_ct_h323: init success\n");
1807 return 0; 1780 return 0;
1808 1781
1809err4: 1782err4:
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index f868b7fbd9b4..b1179dd3d8c3 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -26,23 +26,43 @@
26#include <net/netfilter/nf_conntrack_l4proto.h> 26#include <net/netfilter/nf_conntrack_l4proto.h>
27#include <net/netfilter/nf_conntrack_helper.h> 27#include <net/netfilter/nf_conntrack_helper.h>
28#include <net/netfilter/nf_conntrack_core.h> 28#include <net/netfilter/nf_conntrack_core.h>
29#include <net/netfilter/nf_conntrack_extend.h>
29 30
30static __read_mostly LIST_HEAD(helpers); 31static struct hlist_head *nf_ct_helper_hash __read_mostly;
32static unsigned int nf_ct_helper_hsize __read_mostly;
33static unsigned int nf_ct_helper_count __read_mostly;
34static int nf_ct_helper_vmalloc;
35
36
37/* Stupid hash, but collision free for the default registrations of the
38 * helpers currently in the kernel. */
39static unsigned int helper_hash(const struct nf_conntrack_tuple *tuple)
40{
41 return (((tuple->src.l3num << 8) | tuple->dst.protonum) ^
42 tuple->src.u.all) % nf_ct_helper_hsize;
43}
31 44
32struct nf_conntrack_helper * 45struct nf_conntrack_helper *
33__nf_ct_helper_find(const struct nf_conntrack_tuple *tuple) 46__nf_ct_helper_find(const struct nf_conntrack_tuple *tuple)
34{ 47{
35 struct nf_conntrack_helper *h; 48 struct nf_conntrack_helper *helper;
49 struct nf_conntrack_tuple_mask mask = { .src.u.all = htons(0xFFFF) };
50 struct hlist_node *n;
51 unsigned int h;
52
53 if (!nf_ct_helper_count)
54 return NULL;
36 55
37 list_for_each_entry(h, &helpers, list) { 56 h = helper_hash(tuple);
38 if (nf_ct_tuple_mask_cmp(tuple, &h->tuple, &h->mask)) 57 hlist_for_each_entry(helper, n, &nf_ct_helper_hash[h], hnode) {
39 return h; 58 if (nf_ct_tuple_src_mask_cmp(tuple, &helper->tuple, &mask))
59 return helper;
40 } 60 }
41 return NULL; 61 return NULL;
42} 62}
43 63
44struct nf_conntrack_helper * 64struct nf_conntrack_helper *
45nf_ct_helper_find_get( const struct nf_conntrack_tuple *tuple) 65nf_ct_helper_find_get(const struct nf_conntrack_tuple *tuple)
46{ 66{
47 struct nf_conntrack_helper *helper; 67 struct nf_conntrack_helper *helper;
48 68
@@ -75,16 +95,32 @@ struct nf_conntrack_helper *
75__nf_conntrack_helper_find_byname(const char *name) 95__nf_conntrack_helper_find_byname(const char *name)
76{ 96{
77 struct nf_conntrack_helper *h; 97 struct nf_conntrack_helper *h;
98 struct hlist_node *n;
99 unsigned int i;
78 100
79 list_for_each_entry(h, &helpers, list) { 101 for (i = 0; i < nf_ct_helper_hsize; i++) {
80 if (!strcmp(h->name, name)) 102 hlist_for_each_entry(h, n, &nf_ct_helper_hash[i], hnode) {
81 return h; 103 if (!strcmp(h->name, name))
104 return h;
105 }
82 } 106 }
83
84 return NULL; 107 return NULL;
85} 108}
86EXPORT_SYMBOL_GPL(__nf_conntrack_helper_find_byname); 109EXPORT_SYMBOL_GPL(__nf_conntrack_helper_find_byname);
87 110
111struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp)
112{
113 struct nf_conn_help *help;
114
115 help = nf_ct_ext_add(ct, NF_CT_EXT_HELPER, gfp);
116 if (help)
117 INIT_HLIST_HEAD(&help->expectations);
118 else
119 pr_debug("failed to add helper extension area");
120 return help;
121}
122EXPORT_SYMBOL_GPL(nf_ct_helper_ext_add);
123
88static inline int unhelp(struct nf_conntrack_tuple_hash *i, 124static inline int unhelp(struct nf_conntrack_tuple_hash *i,
89 const struct nf_conntrack_helper *me) 125 const struct nf_conntrack_helper *me)
90{ 126{
@@ -100,20 +136,13 @@ static inline int unhelp(struct nf_conntrack_tuple_hash *i,
100 136
101int nf_conntrack_helper_register(struct nf_conntrack_helper *me) 137int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
102{ 138{
103 int size, ret; 139 unsigned int h = helper_hash(&me->tuple);
104 140
105 BUG_ON(me->timeout == 0); 141 BUG_ON(me->timeout == 0);
106 142
107 size = ALIGN(sizeof(struct nf_conn), __alignof__(struct nf_conn_help)) +
108 sizeof(struct nf_conn_help);
109 ret = nf_conntrack_register_cache(NF_CT_F_HELP, "nf_conntrack:help",
110 size);
111 if (ret < 0) {
112 printk(KERN_ERR "nf_conntrack_helper_register: Unable to create slab cache for conntracks\n");
113 return ret;
114 }
115 write_lock_bh(&nf_conntrack_lock); 143 write_lock_bh(&nf_conntrack_lock);
116 list_add(&me->list, &helpers); 144 hlist_add_head(&me->hnode, &nf_ct_helper_hash[h]);
145 nf_ct_helper_count++;
117 write_unlock_bh(&nf_conntrack_lock); 146 write_unlock_bh(&nf_conntrack_lock);
118 147
119 return 0; 148 return 0;
@@ -122,29 +151,34 @@ EXPORT_SYMBOL_GPL(nf_conntrack_helper_register);
122 151
123void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me) 152void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
124{ 153{
125 unsigned int i;
126 struct nf_conntrack_tuple_hash *h; 154 struct nf_conntrack_tuple_hash *h;
127 struct nf_conntrack_expect *exp, *tmp; 155 struct nf_conntrack_expect *exp;
156 struct hlist_node *n, *next;
157 unsigned int i;
128 158
129 /* Need write lock here, to delete helper. */ 159 /* Need write lock here, to delete helper. */
130 write_lock_bh(&nf_conntrack_lock); 160 write_lock_bh(&nf_conntrack_lock);
131 list_del(&me->list); 161 hlist_del(&me->hnode);
162 nf_ct_helper_count--;
132 163
133 /* Get rid of expectations */ 164 /* Get rid of expectations */
134 list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list, list) { 165 for (i = 0; i < nf_ct_expect_hsize; i++) {
135 struct nf_conn_help *help = nfct_help(exp->master); 166 hlist_for_each_entry_safe(exp, n, next,
136 if ((help->helper == me || exp->helper == me) && 167 &nf_ct_expect_hash[i], hnode) {
137 del_timer(&exp->timeout)) { 168 struct nf_conn_help *help = nfct_help(exp->master);
138 nf_ct_unlink_expect(exp); 169 if ((help->helper == me || exp->helper == me) &&
139 nf_conntrack_expect_put(exp); 170 del_timer(&exp->timeout)) {
171 nf_ct_unlink_expect(exp);
172 nf_ct_expect_put(exp);
173 }
140 } 174 }
141 } 175 }
142 176
143 /* Get rid of expecteds, set helpers to NULL. */ 177 /* Get rid of expecteds, set helpers to NULL. */
144 list_for_each_entry(h, &unconfirmed, list) 178 hlist_for_each_entry(h, n, &unconfirmed, hnode)
145 unhelp(h, me); 179 unhelp(h, me);
146 for (i = 0; i < nf_conntrack_htable_size; i++) { 180 for (i = 0; i < nf_conntrack_htable_size; i++) {
147 list_for_each_entry(h, &nf_conntrack_hash[i], list) 181 hlist_for_each_entry(h, n, &nf_conntrack_hash[i], hnode)
148 unhelp(h, me); 182 unhelp(h, me);
149 } 183 }
150 write_unlock_bh(&nf_conntrack_lock); 184 write_unlock_bh(&nf_conntrack_lock);
@@ -153,3 +187,38 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
153 synchronize_net(); 187 synchronize_net();
154} 188}
155EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister); 189EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister);
190
191static struct nf_ct_ext_type helper_extend __read_mostly = {
192 .len = sizeof(struct nf_conn_help),
193 .align = __alignof__(struct nf_conn_help),
194 .id = NF_CT_EXT_HELPER,
195};
196
197int nf_conntrack_helper_init()
198{
199 int err;
200
201 nf_ct_helper_hsize = 1; /* gets rounded up to use one page */
202 nf_ct_helper_hash = nf_ct_alloc_hashtable(&nf_ct_helper_hsize,
203 &nf_ct_helper_vmalloc);
204 if (!nf_ct_helper_hash)
205 return -ENOMEM;
206
207 err = nf_ct_extend_register(&helper_extend);
208 if (err < 0)
209 goto err1;
210
211 return 0;
212
213err1:
214 nf_ct_free_hashtable(nf_ct_helper_hash, nf_ct_helper_vmalloc,
215 nf_ct_helper_hsize);
216 return err;
217}
218
219void nf_conntrack_helper_fini()
220{
221 nf_ct_extend_unregister(&helper_extend);
222 nf_ct_free_hashtable(nf_ct_helper_hash, nf_ct_helper_vmalloc,
223 nf_ct_helper_hsize);
224}
diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c
index 43ccd0e2e8ae..1562ca97a349 100644
--- a/net/netfilter/nf_conntrack_irc.c
+++ b/net/netfilter/nf_conntrack_irc.c
@@ -12,6 +12,7 @@
12#include <linux/moduleparam.h> 12#include <linux/moduleparam.h>
13#include <linux/skbuff.h> 13#include <linux/skbuff.h>
14#include <linux/in.h> 14#include <linux/in.h>
15#include <linux/ip.h>
15#include <linux/tcp.h> 16#include <linux/tcp.h>
16#include <linux/netfilter.h> 17#include <linux/netfilter.h>
17 18
@@ -55,13 +56,6 @@ static const char *dccprotos[] = {
55 56
56#define MINMATCHLEN 5 57#define MINMATCHLEN 5
57 58
58#if 0
59#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s:" format, \
60 __FILE__, __FUNCTION__ , ## args)
61#else
62#define DEBUGP(format, args...)
63#endif
64
65/* tries to get the ip_addr and port out of a dcc command 59/* tries to get the ip_addr and port out of a dcc command
66 * return value: -1 on failure, 0 on success 60 * return value: -1 on failure, 0 on success
67 * data pointer to first byte of DCC command data 61 * data pointer to first byte of DCC command data
@@ -99,6 +93,7 @@ static int help(struct sk_buff **pskb, unsigned int protoff,
99 struct nf_conn *ct, enum ip_conntrack_info ctinfo) 93 struct nf_conn *ct, enum ip_conntrack_info ctinfo)
100{ 94{
101 unsigned int dataoff; 95 unsigned int dataoff;
96 struct iphdr *iph;
102 struct tcphdr _tcph, *th; 97 struct tcphdr _tcph, *th;
103 char *data, *data_limit, *ib_ptr; 98 char *data, *data_limit, *ib_ptr;
104 int dir = CTINFO2DIR(ctinfo); 99 int dir = CTINFO2DIR(ctinfo);
@@ -148,9 +143,10 @@ static int help(struct sk_buff **pskb, unsigned int protoff,
148 data += 5; 143 data += 5;
149 /* we have at least (19+MINMATCHLEN)-5 bytes valid data left */ 144 /* we have at least (19+MINMATCHLEN)-5 bytes valid data left */
150 145
151 DEBUGP("DCC found in master %u.%u.%u.%u:%u %u.%u.%u.%u:%u...\n", 146 iph = ip_hdr(*pskb);
152 NIPQUAD(iph->saddr), ntohs(th->source), 147 pr_debug("DCC found in master %u.%u.%u.%u:%u %u.%u.%u.%u:%u\n",
153 NIPQUAD(iph->daddr), ntohs(th->dest)); 148 NIPQUAD(iph->saddr), ntohs(th->source),
149 NIPQUAD(iph->daddr), ntohs(th->dest));
154 150
155 for (i = 0; i < ARRAY_SIZE(dccprotos); i++) { 151 for (i = 0; i < ARRAY_SIZE(dccprotos); i++) {
156 if (memcmp(data, dccprotos[i], strlen(dccprotos[i]))) { 152 if (memcmp(data, dccprotos[i], strlen(dccprotos[i]))) {
@@ -158,18 +154,18 @@ static int help(struct sk_buff **pskb, unsigned int protoff,
158 continue; 154 continue;
159 } 155 }
160 data += strlen(dccprotos[i]); 156 data += strlen(dccprotos[i]);
161 DEBUGP("DCC %s detected\n", dccprotos[i]); 157 pr_debug("DCC %s detected\n", dccprotos[i]);
162 158
163 /* we have at least 159 /* we have at least
164 * (19+MINMATCHLEN)-5-dccprotos[i].matchlen bytes valid 160 * (19+MINMATCHLEN)-5-dccprotos[i].matchlen bytes valid
165 * data left (== 14/13 bytes) */ 161 * data left (== 14/13 bytes) */
166 if (parse_dcc((char *)data, data_limit, &dcc_ip, 162 if (parse_dcc((char *)data, data_limit, &dcc_ip,
167 &dcc_port, &addr_beg_p, &addr_end_p)) { 163 &dcc_port, &addr_beg_p, &addr_end_p)) {
168 DEBUGP("unable to parse dcc command\n"); 164 pr_debug("unable to parse dcc command\n");
169 continue; 165 continue;
170 } 166 }
171 DEBUGP("DCC bound ip/port: %u.%u.%u.%u:%u\n", 167 pr_debug("DCC bound ip/port: %u.%u.%u.%u:%u\n",
172 HIPQUAD(dcc_ip), dcc_port); 168 HIPQUAD(dcc_ip), dcc_port);
173 169
174 /* dcc_ip can be the internal OR external (NAT'ed) IP */ 170 /* dcc_ip can be the internal OR external (NAT'ed) IP */
175 tuple = &ct->tuplehash[dir].tuple; 171 tuple = &ct->tuplehash[dir].tuple;
@@ -184,16 +180,16 @@ static int help(struct sk_buff **pskb, unsigned int protoff,
184 continue; 180 continue;
185 } 181 }
186 182
187 exp = nf_conntrack_expect_alloc(ct); 183 exp = nf_ct_expect_alloc(ct);
188 if (exp == NULL) { 184 if (exp == NULL) {
189 ret = NF_DROP; 185 ret = NF_DROP;
190 goto out; 186 goto out;
191 } 187 }
192 tuple = &ct->tuplehash[!dir].tuple; 188 tuple = &ct->tuplehash[!dir].tuple;
193 port = htons(dcc_port); 189 port = htons(dcc_port);
194 nf_conntrack_expect_init(exp, tuple->src.l3num, 190 nf_ct_expect_init(exp, tuple->src.l3num,
195 NULL, &tuple->dst.u3, 191 NULL, &tuple->dst.u3,
196 IPPROTO_TCP, NULL, &port); 192 IPPROTO_TCP, NULL, &port);
197 193
198 nf_nat_irc = rcu_dereference(nf_nat_irc_hook); 194 nf_nat_irc = rcu_dereference(nf_nat_irc_hook);
199 if (nf_nat_irc && ct->status & IPS_NAT_MASK) 195 if (nf_nat_irc && ct->status & IPS_NAT_MASK)
@@ -201,9 +197,9 @@ static int help(struct sk_buff **pskb, unsigned int protoff,
201 addr_beg_p - ib_ptr, 197 addr_beg_p - ib_ptr,
202 addr_end_p - addr_beg_p, 198 addr_end_p - addr_beg_p,
203 exp); 199 exp);
204 else if (nf_conntrack_expect_related(exp) != 0) 200 else if (nf_ct_expect_related(exp) != 0)
205 ret = NF_DROP; 201 ret = NF_DROP;
206 nf_conntrack_expect_put(exp); 202 nf_ct_expect_put(exp);
207 goto out; 203 goto out;
208 } 204 }
209 } 205 }
@@ -239,9 +235,6 @@ static int __init nf_conntrack_irc_init(void)
239 irc[i].tuple.src.l3num = AF_INET; 235 irc[i].tuple.src.l3num = AF_INET;
240 irc[i].tuple.src.u.tcp.port = htons(ports[i]); 236 irc[i].tuple.src.u.tcp.port = htons(ports[i]);
241 irc[i].tuple.dst.protonum = IPPROTO_TCP; 237 irc[i].tuple.dst.protonum = IPPROTO_TCP;
242 irc[i].mask.src.l3num = 0xFFFF;
243 irc[i].mask.src.u.tcp.port = htons(0xFFFF);
244 irc[i].mask.dst.protonum = 0xFF;
245 irc[i].max_expected = max_dcc_channels; 238 irc[i].max_expected = max_dcc_channels;
246 irc[i].timeout = dcc_timeout; 239 irc[i].timeout = dcc_timeout;
247 irc[i].me = THIS_MODULE; 240 irc[i].me = THIS_MODULE;
diff --git a/net/netfilter/nf_conntrack_l3proto_generic.c b/net/netfilter/nf_conntrack_l3proto_generic.c
index cbd96f3c1b89..b1bfa207a850 100644
--- a/net/netfilter/nf_conntrack_l3proto_generic.c
+++ b/net/netfilter/nf_conntrack_l3proto_generic.c
@@ -31,12 +31,6 @@
31#include <net/netfilter/nf_conntrack_core.h> 31#include <net/netfilter/nf_conntrack_core.h>
32#include <net/netfilter/ipv4/nf_conntrack_ipv4.h> 32#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
33 33
34#if 0
35#define DEBUGP printk
36#else
37#define DEBUGP(format, args...)
38#endif
39
40static int generic_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, 34static int generic_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
41 struct nf_conntrack_tuple *tuple) 35 struct nf_conntrack_tuple *tuple)
42{ 36{
@@ -76,12 +70,6 @@ generic_prepare(struct sk_buff **pskb, unsigned int hooknum,
76} 70}
77 71
78 72
79static u_int32_t generic_get_features(const struct nf_conntrack_tuple *tuple)
80
81{
82 return NF_CT_F_BASIC;
83}
84
85struct nf_conntrack_l3proto nf_conntrack_l3proto_generic = { 73struct nf_conntrack_l3proto nf_conntrack_l3proto_generic = {
86 .l3proto = PF_UNSPEC, 74 .l3proto = PF_UNSPEC,
87 .name = "unknown", 75 .name = "unknown",
@@ -90,6 +78,5 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_generic = {
90 .print_tuple = generic_print_tuple, 78 .print_tuple = generic_print_tuple,
91 .print_conntrack = generic_print_conntrack, 79 .print_conntrack = generic_print_conntrack,
92 .prepare = generic_prepare, 80 .prepare = generic_prepare,
93 .get_features = generic_get_features,
94}; 81};
95EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_generic); 82EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_generic);
diff --git a/net/netfilter/nf_conntrack_netbios_ns.c b/net/netfilter/nf_conntrack_netbios_ns.c
index 1093478cc007..1d59fabeb5f7 100644
--- a/net/netfilter/nf_conntrack_netbios_ns.c
+++ b/net/netfilter/nf_conntrack_netbios_ns.c
@@ -74,7 +74,7 @@ static int help(struct sk_buff **pskb, unsigned int protoff,
74 if (mask == 0) 74 if (mask == 0)
75 goto out; 75 goto out;
76 76
77 exp = nf_conntrack_expect_alloc(ct); 77 exp = nf_ct_expect_alloc(ct);
78 if (exp == NULL) 78 if (exp == NULL)
79 goto out; 79 goto out;
80 80
@@ -83,16 +83,13 @@ static int help(struct sk_buff **pskb, unsigned int protoff,
83 83
84 exp->mask.src.u3.ip = mask; 84 exp->mask.src.u3.ip = mask;
85 exp->mask.src.u.udp.port = htons(0xFFFF); 85 exp->mask.src.u.udp.port = htons(0xFFFF);
86 exp->mask.dst.u3.ip = htonl(0xFFFFFFFF);
87 exp->mask.dst.u.udp.port = htons(0xFFFF);
88 exp->mask.dst.protonum = 0xFF;
89 86
90 exp->expectfn = NULL; 87 exp->expectfn = NULL;
91 exp->flags = NF_CT_EXPECT_PERMANENT; 88 exp->flags = NF_CT_EXPECT_PERMANENT;
92 exp->helper = NULL; 89 exp->helper = NULL;
93 90
94 nf_conntrack_expect_related(exp); 91 nf_ct_expect_related(exp);
95 nf_conntrack_expect_put(exp); 92 nf_ct_expect_put(exp);
96 93
97 nf_ct_refresh(ct, *pskb, timeout * HZ); 94 nf_ct_refresh(ct, *pskb, timeout * HZ);
98out: 95out:
@@ -104,9 +101,6 @@ static struct nf_conntrack_helper helper __read_mostly = {
104 .tuple.src.l3num = AF_INET, 101 .tuple.src.l3num = AF_INET,
105 .tuple.src.u.udp.port = __constant_htons(NMBD_PORT), 102 .tuple.src.u.udp.port = __constant_htons(NMBD_PORT),
106 .tuple.dst.protonum = IPPROTO_UDP, 103 .tuple.dst.protonum = IPPROTO_UDP,
107 .mask.src.l3num = 0xFFFF,
108 .mask.src.u.udp.port = __constant_htons(0xFFFF),
109 .mask.dst.protonum = 0xFF,
110 .max_expected = 1, 104 .max_expected = 1,
111 .me = THIS_MODULE, 105 .me = THIS_MODULE,
112 .help = help, 106 .help = help,
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index d0fe3d769828..6f89b105a205 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -428,7 +428,7 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
428{ 428{
429 struct nf_conn *ct, *last; 429 struct nf_conn *ct, *last;
430 struct nf_conntrack_tuple_hash *h; 430 struct nf_conntrack_tuple_hash *h;
431 struct list_head *i; 431 struct hlist_node *n;
432 struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh); 432 struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
433 u_int8_t l3proto = nfmsg->nfgen_family; 433 u_int8_t l3proto = nfmsg->nfgen_family;
434 434
@@ -436,8 +436,8 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
436 last = (struct nf_conn *)cb->args[1]; 436 last = (struct nf_conn *)cb->args[1];
437 for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) { 437 for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) {
438restart: 438restart:
439 list_for_each_prev(i, &nf_conntrack_hash[cb->args[0]]) { 439 hlist_for_each_entry(h, n, &nf_conntrack_hash[cb->args[0]],
440 h = (struct nf_conntrack_tuple_hash *) i; 440 hnode) {
441 if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL) 441 if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL)
442 continue; 442 continue;
443 ct = nf_ct_tuplehash_to_ctrack(h); 443 ct = nf_ct_tuplehash_to_ctrack(h);
@@ -689,7 +689,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
689 if (err < 0) 689 if (err < 0)
690 return err; 690 return err;
691 691
692 h = nf_conntrack_find_get(&tuple, NULL); 692 h = nf_conntrack_find_get(&tuple);
693 if (!h) 693 if (!h)
694 return -ENOENT; 694 return -ENOENT;
695 695
@@ -744,7 +744,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
744 if (err < 0) 744 if (err < 0)
745 return err; 745 return err;
746 746
747 h = nf_conntrack_find_get(&tuple, NULL); 747 h = nf_conntrack_find_get(&tuple);
748 if (!h) 748 if (!h)
749 return -ENOENT; 749 return -ENOENT;
750 750
@@ -856,23 +856,23 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
856 return 0; 856 return 0;
857 } 857 }
858 858
859 if (!help) {
860 /* FIXME: we need to reallocate and rehash */
861 return -EBUSY;
862 }
863
864 helper = __nf_conntrack_helper_find_byname(helpname); 859 helper = __nf_conntrack_helper_find_byname(helpname);
865 if (helper == NULL) 860 if (helper == NULL)
866 return -EINVAL; 861 return -EINVAL;
867 862
868 if (help->helper == helper) 863 if (help) {
869 return 0; 864 if (help->helper == helper)
870 865 return 0;
871 if (help->helper) 866 if (help->helper)
872 return -EBUSY; 867 return -EBUSY;
868 /* need to zero data of old helper */
869 memset(&help->help, 0, sizeof(help->help));
870 } else {
871 help = nf_ct_helper_ext_add(ct, GFP_KERNEL);
872 if (help == NULL)
873 return -ENOMEM;
874 }
873 875
874 /* need to zero data of old helper */
875 memset(&help->help, 0, sizeof(help->help));
876 rcu_assign_pointer(help->helper, helper); 876 rcu_assign_pointer(help->helper, helper);
877 877
878 return 0; 878 return 0;
@@ -957,7 +957,7 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
957 struct nf_conn *ct; 957 struct nf_conn *ct;
958 int err = -EINVAL; 958 int err = -EINVAL;
959 struct nf_conn_help *help; 959 struct nf_conn_help *help;
960 struct nf_conntrack_helper *helper = NULL; 960 struct nf_conntrack_helper *helper;
961 961
962 ct = nf_conntrack_alloc(otuple, rtuple); 962 ct = nf_conntrack_alloc(otuple, rtuple);
963 if (ct == NULL || IS_ERR(ct)) 963 if (ct == NULL || IS_ERR(ct))
@@ -987,9 +987,14 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
987 ct->mark = ntohl(*(__be32 *)NFA_DATA(cda[CTA_MARK-1])); 987 ct->mark = ntohl(*(__be32 *)NFA_DATA(cda[CTA_MARK-1]));
988#endif 988#endif
989 989
990 help = nfct_help(ct); 990 helper = nf_ct_helper_find_get(rtuple);
991 if (help) { 991 if (helper) {
992 helper = nf_ct_helper_find_get(rtuple); 992 help = nf_ct_helper_ext_add(ct, GFP_KERNEL);
993 if (help == NULL) {
994 nf_ct_helper_put(helper);
995 err = -ENOMEM;
996 goto err;
997 }
993 /* not in hash table yet so not strictly necessary */ 998 /* not in hash table yet so not strictly necessary */
994 rcu_assign_pointer(help->helper, helper); 999 rcu_assign_pointer(help->helper, helper);
995 } 1000 }
@@ -1089,22 +1094,29 @@ nfattr_failure:
1089static inline int 1094static inline int
1090ctnetlink_exp_dump_mask(struct sk_buff *skb, 1095ctnetlink_exp_dump_mask(struct sk_buff *skb,
1091 const struct nf_conntrack_tuple *tuple, 1096 const struct nf_conntrack_tuple *tuple,
1092 const struct nf_conntrack_tuple *mask) 1097 const struct nf_conntrack_tuple_mask *mask)
1093{ 1098{
1094 int ret; 1099 int ret;
1095 struct nf_conntrack_l3proto *l3proto; 1100 struct nf_conntrack_l3proto *l3proto;
1096 struct nf_conntrack_l4proto *l4proto; 1101 struct nf_conntrack_l4proto *l4proto;
1097 struct nfattr *nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK); 1102 struct nf_conntrack_tuple m;
1103 struct nfattr *nest_parms;
1104
1105 memset(&m, 0xFF, sizeof(m));
1106 m.src.u.all = mask->src.u.all;
1107 memcpy(&m.src.u3, &mask->src.u3, sizeof(m.src.u3));
1108
1109 nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK);
1098 1110
1099 l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); 1111 l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
1100 ret = ctnetlink_dump_tuples_ip(skb, mask, l3proto); 1112 ret = ctnetlink_dump_tuples_ip(skb, &m, l3proto);
1101 nf_ct_l3proto_put(l3proto); 1113 nf_ct_l3proto_put(l3proto);
1102 1114
1103 if (unlikely(ret < 0)) 1115 if (unlikely(ret < 0))
1104 goto nfattr_failure; 1116 goto nfattr_failure;
1105 1117
1106 l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum); 1118 l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum);
1107 ret = ctnetlink_dump_tuples_proto(skb, mask, l4proto); 1119 ret = ctnetlink_dump_tuples_proto(skb, &m, l4proto);
1108 nf_ct_l4proto_put(l4proto); 1120 nf_ct_l4proto_put(l4proto);
1109 if (unlikely(ret < 0)) 1121 if (unlikely(ret < 0))
1110 goto nfattr_failure; 1122 goto nfattr_failure;
@@ -1223,32 +1235,52 @@ nfattr_failure:
1223 return NOTIFY_DONE; 1235 return NOTIFY_DONE;
1224} 1236}
1225#endif 1237#endif
1238static int ctnetlink_exp_done(struct netlink_callback *cb)
1239{
1240 if (cb->args[1])
1241 nf_ct_expect_put((struct nf_conntrack_expect *)cb->args[1]);
1242 return 0;
1243}
1226 1244
1227static int 1245static int
1228ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb) 1246ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
1229{ 1247{
1230 struct nf_conntrack_expect *exp = NULL; 1248 struct nf_conntrack_expect *exp, *last;
1231 struct list_head *i;
1232 u_int32_t *id = (u_int32_t *) &cb->args[0];
1233 struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh); 1249 struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
1250 struct hlist_node *n;
1234 u_int8_t l3proto = nfmsg->nfgen_family; 1251 u_int8_t l3proto = nfmsg->nfgen_family;
1235 1252
1236 read_lock_bh(&nf_conntrack_lock); 1253 read_lock_bh(&nf_conntrack_lock);
1237 list_for_each_prev(i, &nf_conntrack_expect_list) { 1254 last = (struct nf_conntrack_expect *)cb->args[1];
1238 exp = (struct nf_conntrack_expect *) i; 1255 for (; cb->args[0] < nf_ct_expect_hsize; cb->args[0]++) {
1239 if (l3proto && exp->tuple.src.l3num != l3proto) 1256restart:
1240 continue; 1257 hlist_for_each_entry(exp, n, &nf_ct_expect_hash[cb->args[0]],
1241 if (exp->id <= *id) 1258 hnode) {
1242 continue; 1259 if (l3proto && exp->tuple.src.l3num != l3proto)
1243 if (ctnetlink_exp_fill_info(skb, NETLINK_CB(cb->skb).pid, 1260 continue;
1244 cb->nlh->nlmsg_seq, 1261 if (cb->args[1]) {
1245 IPCTNL_MSG_EXP_NEW, 1262 if (exp != last)
1246 1, exp) < 0) 1263 continue;
1247 goto out; 1264 cb->args[1] = 0;
1248 *id = exp->id; 1265 }
1266 if (ctnetlink_exp_fill_info(skb, NETLINK_CB(cb->skb).pid,
1267 cb->nlh->nlmsg_seq,
1268 IPCTNL_MSG_EXP_NEW,
1269 1, exp) < 0) {
1270 atomic_inc(&exp->use);
1271 cb->args[1] = (unsigned long)exp;
1272 goto out;
1273 }
1274 }
1275 if (cb->args[1]) {
1276 cb->args[1] = 0;
1277 goto restart;
1278 }
1249 } 1279 }
1250out: 1280out:
1251 read_unlock_bh(&nf_conntrack_lock); 1281 read_unlock_bh(&nf_conntrack_lock);
1282 if (last)
1283 nf_ct_expect_put(last);
1252 1284
1253 return skb->len; 1285 return skb->len;
1254} 1286}
@@ -1275,7 +1307,7 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
1275 if (nlh->nlmsg_flags & NLM_F_DUMP) { 1307 if (nlh->nlmsg_flags & NLM_F_DUMP) {
1276 return netlink_dump_start(ctnl, skb, nlh, 1308 return netlink_dump_start(ctnl, skb, nlh,
1277 ctnetlink_exp_dump_table, 1309 ctnetlink_exp_dump_table,
1278 ctnetlink_done); 1310 ctnetlink_exp_done);
1279 } 1311 }
1280 1312
1281 if (cda[CTA_EXPECT_MASTER-1]) 1313 if (cda[CTA_EXPECT_MASTER-1])
@@ -1286,14 +1318,14 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
1286 if (err < 0) 1318 if (err < 0)
1287 return err; 1319 return err;
1288 1320
1289 exp = nf_conntrack_expect_find_get(&tuple); 1321 exp = nf_ct_expect_find_get(&tuple);
1290 if (!exp) 1322 if (!exp)
1291 return -ENOENT; 1323 return -ENOENT;
1292 1324
1293 if (cda[CTA_EXPECT_ID-1]) { 1325 if (cda[CTA_EXPECT_ID-1]) {
1294 __be32 id = *(__be32 *)NFA_DATA(cda[CTA_EXPECT_ID-1]); 1326 __be32 id = *(__be32 *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
1295 if (exp->id != ntohl(id)) { 1327 if (exp->id != ntohl(id)) {
1296 nf_conntrack_expect_put(exp); 1328 nf_ct_expect_put(exp);
1297 return -ENOENT; 1329 return -ENOENT;
1298 } 1330 }
1299 } 1331 }
@@ -1309,14 +1341,14 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
1309 if (err <= 0) 1341 if (err <= 0)
1310 goto free; 1342 goto free;
1311 1343
1312 nf_conntrack_expect_put(exp); 1344 nf_ct_expect_put(exp);
1313 1345
1314 return netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT); 1346 return netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
1315 1347
1316free: 1348free:
1317 kfree_skb(skb2); 1349 kfree_skb(skb2);
1318out: 1350out:
1319 nf_conntrack_expect_put(exp); 1351 nf_ct_expect_put(exp);
1320 return err; 1352 return err;
1321} 1353}
1322 1354
@@ -1324,11 +1356,13 @@ static int
1324ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, 1356ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1325 struct nlmsghdr *nlh, struct nfattr *cda[]) 1357 struct nlmsghdr *nlh, struct nfattr *cda[])
1326{ 1358{
1327 struct nf_conntrack_expect *exp, *tmp; 1359 struct nf_conntrack_expect *exp;
1328 struct nf_conntrack_tuple tuple; 1360 struct nf_conntrack_tuple tuple;
1329 struct nf_conntrack_helper *h; 1361 struct nf_conntrack_helper *h;
1330 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); 1362 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
1363 struct hlist_node *n, *next;
1331 u_int8_t u3 = nfmsg->nfgen_family; 1364 u_int8_t u3 = nfmsg->nfgen_family;
1365 unsigned int i;
1332 int err; 1366 int err;
1333 1367
1334 if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp)) 1368 if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
@@ -1341,25 +1375,26 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1341 return err; 1375 return err;
1342 1376
1343 /* bump usage count to 2 */ 1377 /* bump usage count to 2 */
1344 exp = nf_conntrack_expect_find_get(&tuple); 1378 exp = nf_ct_expect_find_get(&tuple);
1345 if (!exp) 1379 if (!exp)
1346 return -ENOENT; 1380 return -ENOENT;
1347 1381
1348 if (cda[CTA_EXPECT_ID-1]) { 1382 if (cda[CTA_EXPECT_ID-1]) {
1349 __be32 id = *(__be32 *)NFA_DATA(cda[CTA_EXPECT_ID-1]); 1383 __be32 id = *(__be32 *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
1350 if (exp->id != ntohl(id)) { 1384 if (exp->id != ntohl(id)) {
1351 nf_conntrack_expect_put(exp); 1385 nf_ct_expect_put(exp);
1352 return -ENOENT; 1386 return -ENOENT;
1353 } 1387 }
1354 } 1388 }
1355 1389
1356 /* after list removal, usage count == 1 */ 1390 /* after list removal, usage count == 1 */
1357 nf_conntrack_unexpect_related(exp); 1391 nf_ct_unexpect_related(exp);
1358 /* have to put what we 'get' above. 1392 /* have to put what we 'get' above.
1359 * after this line usage count == 0 */ 1393 * after this line usage count == 0 */
1360 nf_conntrack_expect_put(exp); 1394 nf_ct_expect_put(exp);
1361 } else if (cda[CTA_EXPECT_HELP_NAME-1]) { 1395 } else if (cda[CTA_EXPECT_HELP_NAME-1]) {
1362 char *name = NFA_DATA(cda[CTA_EXPECT_HELP_NAME-1]); 1396 char *name = NFA_DATA(cda[CTA_EXPECT_HELP_NAME-1]);
1397 struct nf_conn_help *m_help;
1363 1398
1364 /* delete all expectations for this helper */ 1399 /* delete all expectations for this helper */
1365 write_lock_bh(&nf_conntrack_lock); 1400 write_lock_bh(&nf_conntrack_lock);
@@ -1368,24 +1403,30 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1368 write_unlock_bh(&nf_conntrack_lock); 1403 write_unlock_bh(&nf_conntrack_lock);
1369 return -EINVAL; 1404 return -EINVAL;
1370 } 1405 }
1371 list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list, 1406 for (i = 0; i < nf_ct_expect_hsize; i++) {
1372 list) { 1407 hlist_for_each_entry_safe(exp, n, next,
1373 struct nf_conn_help *m_help = nfct_help(exp->master); 1408 &nf_ct_expect_hash[i],
1374 if (m_help->helper == h 1409 hnode) {
1375 && del_timer(&exp->timeout)) { 1410 m_help = nfct_help(exp->master);
1376 nf_ct_unlink_expect(exp); 1411 if (m_help->helper == h
1377 nf_conntrack_expect_put(exp); 1412 && del_timer(&exp->timeout)) {
1413 nf_ct_unlink_expect(exp);
1414 nf_ct_expect_put(exp);
1415 }
1378 } 1416 }
1379 } 1417 }
1380 write_unlock_bh(&nf_conntrack_lock); 1418 write_unlock_bh(&nf_conntrack_lock);
1381 } else { 1419 } else {
1382 /* This basically means we have to flush everything*/ 1420 /* This basically means we have to flush everything*/
1383 write_lock_bh(&nf_conntrack_lock); 1421 write_lock_bh(&nf_conntrack_lock);
1384 list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list, 1422 for (i = 0; i < nf_ct_expect_hsize; i++) {
1385 list) { 1423 hlist_for_each_entry_safe(exp, n, next,
1386 if (del_timer(&exp->timeout)) { 1424 &nf_ct_expect_hash[i],
1387 nf_ct_unlink_expect(exp); 1425 hnode) {
1388 nf_conntrack_expect_put(exp); 1426 if (del_timer(&exp->timeout)) {
1427 nf_ct_unlink_expect(exp);
1428 nf_ct_expect_put(exp);
1429 }
1389 } 1430 }
1390 } 1431 }
1391 write_unlock_bh(&nf_conntrack_lock); 1432 write_unlock_bh(&nf_conntrack_lock);
@@ -1421,7 +1462,7 @@ ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3)
1421 return err; 1462 return err;
1422 1463
1423 /* Look for master conntrack of this expectation */ 1464 /* Look for master conntrack of this expectation */
1424 h = nf_conntrack_find_get(&master_tuple, NULL); 1465 h = nf_conntrack_find_get(&master_tuple);
1425 if (!h) 1466 if (!h)
1426 return -ENOENT; 1467 return -ENOENT;
1427 ct = nf_ct_tuplehash_to_ctrack(h); 1468 ct = nf_ct_tuplehash_to_ctrack(h);
@@ -1433,7 +1474,7 @@ ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3)
1433 goto out; 1474 goto out;
1434 } 1475 }
1435 1476
1436 exp = nf_conntrack_expect_alloc(ct); 1477 exp = nf_ct_expect_alloc(ct);
1437 if (!exp) { 1478 if (!exp) {
1438 err = -ENOMEM; 1479 err = -ENOMEM;
1439 goto out; 1480 goto out;
@@ -1444,10 +1485,11 @@ ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3)
1444 exp->master = ct; 1485 exp->master = ct;
1445 exp->helper = NULL; 1486 exp->helper = NULL;
1446 memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple)); 1487 memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple));
1447 memcpy(&exp->mask, &mask, sizeof(struct nf_conntrack_tuple)); 1488 memcpy(&exp->mask.src.u3, &mask.src.u3, sizeof(exp->mask.src.u3));
1489 exp->mask.src.u.all = mask.src.u.all;
1448 1490
1449 err = nf_conntrack_expect_related(exp); 1491 err = nf_ct_expect_related(exp);
1450 nf_conntrack_expect_put(exp); 1492 nf_ct_expect_put(exp);
1451 1493
1452out: 1494out:
1453 nf_ct_put(nf_ct_tuplehash_to_ctrack(h)); 1495 nf_ct_put(nf_ct_tuplehash_to_ctrack(h));
@@ -1477,7 +1519,7 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
1477 return err; 1519 return err;
1478 1520
1479 write_lock_bh(&nf_conntrack_lock); 1521 write_lock_bh(&nf_conntrack_lock);
1480 exp = __nf_conntrack_expect_find(&tuple); 1522 exp = __nf_ct_expect_find(&tuple);
1481 1523
1482 if (!exp) { 1524 if (!exp) {
1483 write_unlock_bh(&nf_conntrack_lock); 1525 write_unlock_bh(&nf_conntrack_lock);
@@ -1567,7 +1609,7 @@ static int __init ctnetlink_init(void)
1567 goto err_unreg_exp_subsys; 1609 goto err_unreg_exp_subsys;
1568 } 1610 }
1569 1611
1570 ret = nf_conntrack_expect_register_notifier(&ctnl_notifier_exp); 1612 ret = nf_ct_expect_register_notifier(&ctnl_notifier_exp);
1571 if (ret < 0) { 1613 if (ret < 0) {
1572 printk("ctnetlink_init: cannot expect register notifier.\n"); 1614 printk("ctnetlink_init: cannot expect register notifier.\n");
1573 goto err_unreg_notifier; 1615 goto err_unreg_notifier;
@@ -1593,7 +1635,7 @@ static void __exit ctnetlink_exit(void)
1593 printk("ctnetlink: unregistering from nfnetlink.\n"); 1635 printk("ctnetlink: unregistering from nfnetlink.\n");
1594 1636
1595#ifdef CONFIG_NF_CONNTRACK_EVENTS 1637#ifdef CONFIG_NF_CONNTRACK_EVENTS
1596 nf_conntrack_expect_unregister_notifier(&ctnl_notifier_exp); 1638 nf_ct_expect_unregister_notifier(&ctnl_notifier_exp);
1597 nf_conntrack_unregister_notifier(&ctnl_notifier); 1639 nf_conntrack_unregister_notifier(&ctnl_notifier);
1598#endif 1640#endif
1599 1641
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c
index 115bcb5d5a7c..b0804199ab59 100644
--- a/net/netfilter/nf_conntrack_pptp.c
+++ b/net/netfilter/nf_conntrack_pptp.c
@@ -65,7 +65,7 @@ void
65 struct nf_conntrack_expect *exp) __read_mostly; 65 struct nf_conntrack_expect *exp) __read_mostly;
66EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_expectfn); 66EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_expectfn);
67 67
68#if 0 68#ifdef DEBUG
69/* PptpControlMessageType names */ 69/* PptpControlMessageType names */
70const char *pptp_msg_name[] = { 70const char *pptp_msg_name[] = {
71 "UNKNOWN_MESSAGE", 71 "UNKNOWN_MESSAGE",
@@ -86,9 +86,6 @@ const char *pptp_msg_name[] = {
86 "SET_LINK_INFO" 86 "SET_LINK_INFO"
87}; 87};
88EXPORT_SYMBOL(pptp_msg_name); 88EXPORT_SYMBOL(pptp_msg_name);
89#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, __FUNCTION__, ## args)
90#else
91#define DEBUGP(format, args...)
92#endif 89#endif
93 90
94#define SECS *HZ 91#define SECS *HZ
@@ -102,7 +99,7 @@ static void pptp_expectfn(struct nf_conn *ct,
102 struct nf_conntrack_expect *exp) 99 struct nf_conntrack_expect *exp)
103{ 100{
104 typeof(nf_nat_pptp_hook_expectfn) nf_nat_pptp_expectfn; 101 typeof(nf_nat_pptp_hook_expectfn) nf_nat_pptp_expectfn;
105 DEBUGP("increasing timeouts\n"); 102 pr_debug("increasing timeouts\n");
106 103
107 /* increase timeout of GRE data channel conntrack entry */ 104 /* increase timeout of GRE data channel conntrack entry */
108 ct->proto.gre.timeout = PPTP_GRE_TIMEOUT; 105 ct->proto.gre.timeout = PPTP_GRE_TIMEOUT;
@@ -121,17 +118,17 @@ static void pptp_expectfn(struct nf_conn *ct,
121 118
122 /* obviously this tuple inversion only works until you do NAT */ 119 /* obviously this tuple inversion only works until you do NAT */
123 nf_ct_invert_tuplepr(&inv_t, &exp->tuple); 120 nf_ct_invert_tuplepr(&inv_t, &exp->tuple);
124 DEBUGP("trying to unexpect other dir: "); 121 pr_debug("trying to unexpect other dir: ");
125 NF_CT_DUMP_TUPLE(&inv_t); 122 NF_CT_DUMP_TUPLE(&inv_t);
126 123
127 exp_other = nf_conntrack_expect_find_get(&inv_t); 124 exp_other = nf_ct_expect_find_get(&inv_t);
128 if (exp_other) { 125 if (exp_other) {
129 /* delete other expectation. */ 126 /* delete other expectation. */
130 DEBUGP("found\n"); 127 pr_debug("found\n");
131 nf_conntrack_unexpect_related(exp_other); 128 nf_ct_unexpect_related(exp_other);
132 nf_conntrack_expect_put(exp_other); 129 nf_ct_expect_put(exp_other);
133 } else { 130 } else {
134 DEBUGP("not found\n"); 131 pr_debug("not found\n");
135 } 132 }
136 } 133 }
137 rcu_read_unlock(); 134 rcu_read_unlock();
@@ -143,13 +140,13 @@ static int destroy_sibling_or_exp(const struct nf_conntrack_tuple *t)
143 struct nf_conntrack_expect *exp; 140 struct nf_conntrack_expect *exp;
144 struct nf_conn *sibling; 141 struct nf_conn *sibling;
145 142
146 DEBUGP("trying to timeout ct or exp for tuple "); 143 pr_debug("trying to timeout ct or exp for tuple ");
147 NF_CT_DUMP_TUPLE(t); 144 NF_CT_DUMP_TUPLE(t);
148 145
149 h = nf_conntrack_find_get(t, NULL); 146 h = nf_conntrack_find_get(t);
150 if (h) { 147 if (h) {
151 sibling = nf_ct_tuplehash_to_ctrack(h); 148 sibling = nf_ct_tuplehash_to_ctrack(h);
152 DEBUGP("setting timeout of conntrack %p to 0\n", sibling); 149 pr_debug("setting timeout of conntrack %p to 0\n", sibling);
153 sibling->proto.gre.timeout = 0; 150 sibling->proto.gre.timeout = 0;
154 sibling->proto.gre.stream_timeout = 0; 151 sibling->proto.gre.stream_timeout = 0;
155 if (del_timer(&sibling->timeout)) 152 if (del_timer(&sibling->timeout))
@@ -157,11 +154,11 @@ static int destroy_sibling_or_exp(const struct nf_conntrack_tuple *t)
157 nf_ct_put(sibling); 154 nf_ct_put(sibling);
158 return 1; 155 return 1;
159 } else { 156 } else {
160 exp = nf_conntrack_expect_find_get(t); 157 exp = nf_ct_expect_find_get(t);
161 if (exp) { 158 if (exp) {
162 DEBUGP("unexpect_related of expect %p\n", exp); 159 pr_debug("unexpect_related of expect %p\n", exp);
163 nf_conntrack_unexpect_related(exp); 160 nf_ct_unexpect_related(exp);
164 nf_conntrack_expect_put(exp); 161 nf_ct_expect_put(exp);
165 return 1; 162 return 1;
166 } 163 }
167 } 164 }
@@ -182,7 +179,7 @@ static void pptp_destroy_siblings(struct nf_conn *ct)
182 t.src.u.gre.key = help->help.ct_pptp_info.pns_call_id; 179 t.src.u.gre.key = help->help.ct_pptp_info.pns_call_id;
183 t.dst.u.gre.key = help->help.ct_pptp_info.pac_call_id; 180 t.dst.u.gre.key = help->help.ct_pptp_info.pac_call_id;
184 if (!destroy_sibling_or_exp(&t)) 181 if (!destroy_sibling_or_exp(&t))
185 DEBUGP("failed to timeout original pns->pac ct/exp\n"); 182 pr_debug("failed to timeout original pns->pac ct/exp\n");
186 183
187 /* try reply (pac->pns) tuple */ 184 /* try reply (pac->pns) tuple */
188 memcpy(&t, &ct->tuplehash[IP_CT_DIR_REPLY].tuple, sizeof(t)); 185 memcpy(&t, &ct->tuplehash[IP_CT_DIR_REPLY].tuple, sizeof(t));
@@ -190,7 +187,7 @@ static void pptp_destroy_siblings(struct nf_conn *ct)
190 t.src.u.gre.key = help->help.ct_pptp_info.pac_call_id; 187 t.src.u.gre.key = help->help.ct_pptp_info.pac_call_id;
191 t.dst.u.gre.key = help->help.ct_pptp_info.pns_call_id; 188 t.dst.u.gre.key = help->help.ct_pptp_info.pns_call_id;
192 if (!destroy_sibling_or_exp(&t)) 189 if (!destroy_sibling_or_exp(&t))
193 DEBUGP("failed to timeout reply pac->pns ct/exp\n"); 190 pr_debug("failed to timeout reply pac->pns ct/exp\n");
194} 191}
195 192
196/* expect GRE connections (PNS->PAC and PAC->PNS direction) */ 193/* expect GRE connections (PNS->PAC and PAC->PNS direction) */
@@ -201,36 +198,36 @@ static int exp_gre(struct nf_conn *ct, __be16 callid, __be16 peer_callid)
201 int ret = 1; 198 int ret = 1;
202 typeof(nf_nat_pptp_hook_exp_gre) nf_nat_pptp_exp_gre; 199 typeof(nf_nat_pptp_hook_exp_gre) nf_nat_pptp_exp_gre;
203 200
204 exp_orig = nf_conntrack_expect_alloc(ct); 201 exp_orig = nf_ct_expect_alloc(ct);
205 if (exp_orig == NULL) 202 if (exp_orig == NULL)
206 goto out; 203 goto out;
207 204
208 exp_reply = nf_conntrack_expect_alloc(ct); 205 exp_reply = nf_ct_expect_alloc(ct);
209 if (exp_reply == NULL) 206 if (exp_reply == NULL)
210 goto out_put_orig; 207 goto out_put_orig;
211 208
212 /* original direction, PNS->PAC */ 209 /* original direction, PNS->PAC */
213 dir = IP_CT_DIR_ORIGINAL; 210 dir = IP_CT_DIR_ORIGINAL;
214 nf_conntrack_expect_init(exp_orig, ct->tuplehash[dir].tuple.src.l3num, 211 nf_ct_expect_init(exp_orig, ct->tuplehash[dir].tuple.src.l3num,
215 &ct->tuplehash[dir].tuple.src.u3, 212 &ct->tuplehash[dir].tuple.src.u3,
216 &ct->tuplehash[dir].tuple.dst.u3, 213 &ct->tuplehash[dir].tuple.dst.u3,
217 IPPROTO_GRE, &peer_callid, &callid); 214 IPPROTO_GRE, &peer_callid, &callid);
218 exp_orig->expectfn = pptp_expectfn; 215 exp_orig->expectfn = pptp_expectfn;
219 216
220 /* reply direction, PAC->PNS */ 217 /* reply direction, PAC->PNS */
221 dir = IP_CT_DIR_REPLY; 218 dir = IP_CT_DIR_REPLY;
222 nf_conntrack_expect_init(exp_reply, ct->tuplehash[dir].tuple.src.l3num, 219 nf_ct_expect_init(exp_reply, ct->tuplehash[dir].tuple.src.l3num,
223 &ct->tuplehash[dir].tuple.src.u3, 220 &ct->tuplehash[dir].tuple.src.u3,
224 &ct->tuplehash[dir].tuple.dst.u3, 221 &ct->tuplehash[dir].tuple.dst.u3,
225 IPPROTO_GRE, &callid, &peer_callid); 222 IPPROTO_GRE, &callid, &peer_callid);
226 exp_reply->expectfn = pptp_expectfn; 223 exp_reply->expectfn = pptp_expectfn;
227 224
228 nf_nat_pptp_exp_gre = rcu_dereference(nf_nat_pptp_hook_exp_gre); 225 nf_nat_pptp_exp_gre = rcu_dereference(nf_nat_pptp_hook_exp_gre);
229 if (nf_nat_pptp_exp_gre && ct->status & IPS_NAT_MASK) 226 if (nf_nat_pptp_exp_gre && ct->status & IPS_NAT_MASK)
230 nf_nat_pptp_exp_gre(exp_orig, exp_reply); 227 nf_nat_pptp_exp_gre(exp_orig, exp_reply);
231 if (nf_conntrack_expect_related(exp_orig) != 0) 228 if (nf_ct_expect_related(exp_orig) != 0)
232 goto out_put_both; 229 goto out_put_both;
233 if (nf_conntrack_expect_related(exp_reply) != 0) 230 if (nf_ct_expect_related(exp_reply) != 0)
234 goto out_unexpect_orig; 231 goto out_unexpect_orig;
235 232
236 /* Add GRE keymap entries */ 233 /* Add GRE keymap entries */
@@ -243,16 +240,16 @@ static int exp_gre(struct nf_conn *ct, __be16 callid, __be16 peer_callid)
243 ret = 0; 240 ret = 0;
244 241
245out_put_both: 242out_put_both:
246 nf_conntrack_expect_put(exp_reply); 243 nf_ct_expect_put(exp_reply);
247out_put_orig: 244out_put_orig:
248 nf_conntrack_expect_put(exp_orig); 245 nf_ct_expect_put(exp_orig);
249out: 246out:
250 return ret; 247 return ret;
251 248
252out_unexpect_both: 249out_unexpect_both:
253 nf_conntrack_unexpect_related(exp_reply); 250 nf_ct_unexpect_related(exp_reply);
254out_unexpect_orig: 251out_unexpect_orig:
255 nf_conntrack_unexpect_related(exp_orig); 252 nf_ct_unexpect_related(exp_orig);
256 goto out_put_both; 253 goto out_put_both;
257} 254}
258 255
@@ -270,7 +267,7 @@ pptp_inbound_pkt(struct sk_buff **pskb,
270 typeof(nf_nat_pptp_hook_inbound) nf_nat_pptp_inbound; 267 typeof(nf_nat_pptp_hook_inbound) nf_nat_pptp_inbound;
271 268
272 msg = ntohs(ctlh->messageType); 269 msg = ntohs(ctlh->messageType);
273 DEBUGP("inbound control message %s\n", pptp_msg_name[msg]); 270 pr_debug("inbound control message %s\n", pptp_msg_name[msg]);
274 271
275 switch (msg) { 272 switch (msg) {
276 case PPTP_START_SESSION_REPLY: 273 case PPTP_START_SESSION_REPLY:
@@ -305,8 +302,8 @@ pptp_inbound_pkt(struct sk_buff **pskb,
305 pcid = pptpReq->ocack.peersCallID; 302 pcid = pptpReq->ocack.peersCallID;
306 if (info->pns_call_id != pcid) 303 if (info->pns_call_id != pcid)
307 goto invalid; 304 goto invalid;
308 DEBUGP("%s, CID=%X, PCID=%X\n", pptp_msg_name[msg], 305 pr_debug("%s, CID=%X, PCID=%X\n", pptp_msg_name[msg],
309 ntohs(cid), ntohs(pcid)); 306 ntohs(cid), ntohs(pcid));
310 307
311 if (pptpReq->ocack.resultCode == PPTP_OUTCALL_CONNECT) { 308 if (pptpReq->ocack.resultCode == PPTP_OUTCALL_CONNECT) {
312 info->cstate = PPTP_CALL_OUT_CONF; 309 info->cstate = PPTP_CALL_OUT_CONF;
@@ -322,7 +319,7 @@ pptp_inbound_pkt(struct sk_buff **pskb,
322 goto invalid; 319 goto invalid;
323 320
324 cid = pptpReq->icreq.callID; 321 cid = pptpReq->icreq.callID;
325 DEBUGP("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid)); 322 pr_debug("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid));
326 info->cstate = PPTP_CALL_IN_REQ; 323 info->cstate = PPTP_CALL_IN_REQ;
327 info->pac_call_id = cid; 324 info->pac_call_id = cid;
328 break; 325 break;
@@ -341,7 +338,7 @@ pptp_inbound_pkt(struct sk_buff **pskb,
341 if (info->pns_call_id != pcid) 338 if (info->pns_call_id != pcid)
342 goto invalid; 339 goto invalid;
343 340
344 DEBUGP("%s, PCID=%X\n", pptp_msg_name[msg], ntohs(pcid)); 341 pr_debug("%s, PCID=%X\n", pptp_msg_name[msg], ntohs(pcid));
345 info->cstate = PPTP_CALL_IN_CONF; 342 info->cstate = PPTP_CALL_IN_CONF;
346 343
347 /* we expect a GRE connection from PAC to PNS */ 344 /* we expect a GRE connection from PAC to PNS */
@@ -351,7 +348,7 @@ pptp_inbound_pkt(struct sk_buff **pskb,
351 case PPTP_CALL_DISCONNECT_NOTIFY: 348 case PPTP_CALL_DISCONNECT_NOTIFY:
352 /* server confirms disconnect */ 349 /* server confirms disconnect */
353 cid = pptpReq->disc.callID; 350 cid = pptpReq->disc.callID;
354 DEBUGP("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid)); 351 pr_debug("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid));
355 info->cstate = PPTP_CALL_NONE; 352 info->cstate = PPTP_CALL_NONE;
356 353
357 /* untrack this call id, unexpect GRE packets */ 354 /* untrack this call id, unexpect GRE packets */
@@ -374,11 +371,11 @@ pptp_inbound_pkt(struct sk_buff **pskb,
374 return NF_ACCEPT; 371 return NF_ACCEPT;
375 372
376invalid: 373invalid:
377 DEBUGP("invalid %s: type=%d cid=%u pcid=%u " 374 pr_debug("invalid %s: type=%d cid=%u pcid=%u "
378 "cstate=%d sstate=%d pns_cid=%u pac_cid=%u\n", 375 "cstate=%d sstate=%d pns_cid=%u pac_cid=%u\n",
379 msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : pptp_msg_name[0], 376 msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : pptp_msg_name[0],
380 msg, ntohs(cid), ntohs(pcid), info->cstate, info->sstate, 377 msg, ntohs(cid), ntohs(pcid), info->cstate, info->sstate,
381 ntohs(info->pns_call_id), ntohs(info->pac_call_id)); 378 ntohs(info->pns_call_id), ntohs(info->pac_call_id));
382 return NF_ACCEPT; 379 return NF_ACCEPT;
383} 380}
384 381
@@ -396,7 +393,7 @@ pptp_outbound_pkt(struct sk_buff **pskb,
396 typeof(nf_nat_pptp_hook_outbound) nf_nat_pptp_outbound; 393 typeof(nf_nat_pptp_hook_outbound) nf_nat_pptp_outbound;
397 394
398 msg = ntohs(ctlh->messageType); 395 msg = ntohs(ctlh->messageType);
399 DEBUGP("outbound control message %s\n", pptp_msg_name[msg]); 396 pr_debug("outbound control message %s\n", pptp_msg_name[msg]);
400 397
401 switch (msg) { 398 switch (msg) {
402 case PPTP_START_SESSION_REQUEST: 399 case PPTP_START_SESSION_REQUEST:
@@ -418,7 +415,7 @@ pptp_outbound_pkt(struct sk_buff **pskb,
418 info->cstate = PPTP_CALL_OUT_REQ; 415 info->cstate = PPTP_CALL_OUT_REQ;
419 /* track PNS call id */ 416 /* track PNS call id */
420 cid = pptpReq->ocreq.callID; 417 cid = pptpReq->ocreq.callID;
421 DEBUGP("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid)); 418 pr_debug("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid));
422 info->pns_call_id = cid; 419 info->pns_call_id = cid;
423 break; 420 break;
424 421
@@ -432,8 +429,8 @@ pptp_outbound_pkt(struct sk_buff **pskb,
432 pcid = pptpReq->icack.peersCallID; 429 pcid = pptpReq->icack.peersCallID;
433 if (info->pac_call_id != pcid) 430 if (info->pac_call_id != pcid)
434 goto invalid; 431 goto invalid;
435 DEBUGP("%s, CID=%X PCID=%X\n", pptp_msg_name[msg], 432 pr_debug("%s, CID=%X PCID=%X\n", pptp_msg_name[msg],
436 ntohs(cid), ntohs(pcid)); 433 ntohs(cid), ntohs(pcid));
437 434
438 if (pptpReq->icack.resultCode == PPTP_INCALL_ACCEPT) { 435 if (pptpReq->icack.resultCode == PPTP_INCALL_ACCEPT) {
439 /* part two of the three-way handshake */ 436 /* part two of the three-way handshake */
@@ -469,11 +466,11 @@ pptp_outbound_pkt(struct sk_buff **pskb,
469 return NF_ACCEPT; 466 return NF_ACCEPT;
470 467
471invalid: 468invalid:
472 DEBUGP("invalid %s: type=%d cid=%u pcid=%u " 469 pr_debug("invalid %s: type=%d cid=%u pcid=%u "
473 "cstate=%d sstate=%d pns_cid=%u pac_cid=%u\n", 470 "cstate=%d sstate=%d pns_cid=%u pac_cid=%u\n",
474 msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : pptp_msg_name[0], 471 msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : pptp_msg_name[0],
475 msg, ntohs(cid), ntohs(pcid), info->cstate, info->sstate, 472 msg, ntohs(cid), ntohs(pcid), info->cstate, info->sstate,
476 ntohs(info->pns_call_id), ntohs(info->pac_call_id)); 473 ntohs(info->pns_call_id), ntohs(info->pac_call_id));
477 return NF_ACCEPT; 474 return NF_ACCEPT;
478} 475}
479 476
@@ -524,7 +521,7 @@ conntrack_pptp_help(struct sk_buff **pskb, unsigned int protoff,
524 521
525 pptph = skb_header_pointer(*pskb, nexthdr_off, sizeof(_pptph), &_pptph); 522 pptph = skb_header_pointer(*pskb, nexthdr_off, sizeof(_pptph), &_pptph);
526 if (!pptph) { 523 if (!pptph) {
527 DEBUGP("no full PPTP header, can't track\n"); 524 pr_debug("no full PPTP header, can't track\n");
528 return NF_ACCEPT; 525 return NF_ACCEPT;
529 } 526 }
530 nexthdr_off += sizeof(_pptph); 527 nexthdr_off += sizeof(_pptph);
@@ -533,7 +530,7 @@ conntrack_pptp_help(struct sk_buff **pskb, unsigned int protoff,
533 /* if it's not a control message we can't do anything with it */ 530 /* if it's not a control message we can't do anything with it */
534 if (ntohs(pptph->packetType) != PPTP_PACKET_CONTROL || 531 if (ntohs(pptph->packetType) != PPTP_PACKET_CONTROL ||
535 ntohl(pptph->magicCookie) != PPTP_MAGIC_COOKIE) { 532 ntohl(pptph->magicCookie) != PPTP_MAGIC_COOKIE) {
536 DEBUGP("not a control packet\n"); 533 pr_debug("not a control packet\n");
537 return NF_ACCEPT; 534 return NF_ACCEPT;
538 } 535 }
539 536
@@ -569,8 +566,8 @@ conntrack_pptp_help(struct sk_buff **pskb, unsigned int protoff,
569 /* server -> client (PAC -> PNS) */ 566 /* server -> client (PAC -> PNS) */
570 ret = pptp_inbound_pkt(pskb, ctlh, pptpReq, reqlen, ct, 567 ret = pptp_inbound_pkt(pskb, ctlh, pptpReq, reqlen, ct,
571 ctinfo); 568 ctinfo);
572 DEBUGP("sstate: %d->%d, cstate: %d->%d\n", 569 pr_debug("sstate: %d->%d, cstate: %d->%d\n",
573 oldsstate, info->sstate, oldcstate, info->cstate); 570 oldsstate, info->sstate, oldcstate, info->cstate);
574 spin_unlock_bh(&nf_pptp_lock); 571 spin_unlock_bh(&nf_pptp_lock);
575 572
576 return ret; 573 return ret;
@@ -585,9 +582,6 @@ static struct nf_conntrack_helper pptp __read_mostly = {
585 .tuple.src.l3num = AF_INET, 582 .tuple.src.l3num = AF_INET,
586 .tuple.src.u.tcp.port = __constant_htons(PPTP_CONTROL_PORT), 583 .tuple.src.u.tcp.port = __constant_htons(PPTP_CONTROL_PORT),
587 .tuple.dst.protonum = IPPROTO_TCP, 584 .tuple.dst.protonum = IPPROTO_TCP,
588 .mask.src.l3num = 0xffff,
589 .mask.src.u.tcp.port = __constant_htons(0xffff),
590 .mask.dst.protonum = 0xff,
591 .help = conntrack_pptp_help, 585 .help = conntrack_pptp_help,
592 .destroy = pptp_destroy_siblings, 586 .destroy = pptp_destroy_siblings,
593}; 587};
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index 339c397d1b5f..771c4c29936e 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -40,12 +40,6 @@
40#define GRE_TIMEOUT (30 * HZ) 40#define GRE_TIMEOUT (30 * HZ)
41#define GRE_STREAM_TIMEOUT (180 * HZ) 41#define GRE_STREAM_TIMEOUT (180 * HZ)
42 42
43#if 0
44#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, __FUNCTION__, ## args)
45#else
46#define DEBUGP(x, args...)
47#endif
48
49static DEFINE_RWLOCK(nf_ct_gre_lock); 43static DEFINE_RWLOCK(nf_ct_gre_lock);
50static LIST_HEAD(gre_keymap_list); 44static LIST_HEAD(gre_keymap_list);
51 45
@@ -87,7 +81,7 @@ static __be16 gre_keymap_lookup(struct nf_conntrack_tuple *t)
87 } 81 }
88 read_unlock_bh(&nf_ct_gre_lock); 82 read_unlock_bh(&nf_ct_gre_lock);
89 83
90 DEBUGP("lookup src key 0x%x for ", key); 84 pr_debug("lookup src key 0x%x for ", key);
91 NF_CT_DUMP_TUPLE(t); 85 NF_CT_DUMP_TUPLE(t);
92 86
93 return key; 87 return key;
@@ -107,8 +101,8 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
107 if (gre_key_cmpfn(km, t) && km == *kmp) 101 if (gre_key_cmpfn(km, t) && km == *kmp)
108 return 0; 102 return 0;
109 } 103 }
110 DEBUGP("trying to override keymap_%s for ct %p\n", 104 pr_debug("trying to override keymap_%s for ct %p\n",
111 dir == IP_CT_DIR_REPLY ? "reply" : "orig", ct); 105 dir == IP_CT_DIR_REPLY ? "reply" : "orig", ct);
112 return -EEXIST; 106 return -EEXIST;
113 } 107 }
114 108
@@ -118,7 +112,7 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
118 memcpy(&km->tuple, t, sizeof(*t)); 112 memcpy(&km->tuple, t, sizeof(*t));
119 *kmp = km; 113 *kmp = km;
120 114
121 DEBUGP("adding new entry %p: ", km); 115 pr_debug("adding new entry %p: ", km);
122 NF_CT_DUMP_TUPLE(&km->tuple); 116 NF_CT_DUMP_TUPLE(&km->tuple);
123 117
124 write_lock_bh(&nf_ct_gre_lock); 118 write_lock_bh(&nf_ct_gre_lock);
@@ -135,13 +129,13 @@ void nf_ct_gre_keymap_destroy(struct nf_conn *ct)
135 struct nf_conn_help *help = nfct_help(ct); 129 struct nf_conn_help *help = nfct_help(ct);
136 enum ip_conntrack_dir dir; 130 enum ip_conntrack_dir dir;
137 131
138 DEBUGP("entering for ct %p\n", ct); 132 pr_debug("entering for ct %p\n", ct);
139 133
140 write_lock_bh(&nf_ct_gre_lock); 134 write_lock_bh(&nf_ct_gre_lock);
141 for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) { 135 for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) {
142 if (help->help.ct_pptp_info.keymap[dir]) { 136 if (help->help.ct_pptp_info.keymap[dir]) {
143 DEBUGP("removing %p from list\n", 137 pr_debug("removing %p from list\n",
144 help->help.ct_pptp_info.keymap[dir]); 138 help->help.ct_pptp_info.keymap[dir]);
145 list_del(&help->help.ct_pptp_info.keymap[dir]->list); 139 list_del(&help->help.ct_pptp_info.keymap[dir]->list);
146 kfree(help->help.ct_pptp_info.keymap[dir]); 140 kfree(help->help.ct_pptp_info.keymap[dir]);
147 help->help.ct_pptp_info.keymap[dir] = NULL; 141 help->help.ct_pptp_info.keymap[dir] = NULL;
@@ -186,7 +180,7 @@ static int gre_pkt_to_tuple(const struct sk_buff *skb,
186 return 1; 180 return 1;
187 181
188 if (ntohs(grehdr->protocol) != GRE_PROTOCOL_PPTP) { 182 if (ntohs(grehdr->protocol) != GRE_PROTOCOL_PPTP) {
189 DEBUGP("GRE_VERSION_PPTP but unknown proto\n"); 183 pr_debug("GRE_VERSION_PPTP but unknown proto\n");
190 return 0; 184 return 0;
191 } 185 }
192 186
@@ -242,7 +236,7 @@ static int gre_packet(struct nf_conn *ct,
242static int gre_new(struct nf_conn *ct, const struct sk_buff *skb, 236static int gre_new(struct nf_conn *ct, const struct sk_buff *skb,
243 unsigned int dataoff) 237 unsigned int dataoff)
244{ 238{
245 DEBUGP(": "); 239 pr_debug(": ");
246 NF_CT_DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); 240 NF_CT_DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
247 241
248 /* initialize to sane value. Ideally a conntrack helper 242 /* initialize to sane value. Ideally a conntrack helper
@@ -258,10 +252,10 @@ static int gre_new(struct nf_conn *ct, const struct sk_buff *skb,
258static void gre_destroy(struct nf_conn *ct) 252static void gre_destroy(struct nf_conn *ct)
259{ 253{
260 struct nf_conn *master = ct->master; 254 struct nf_conn *master = ct->master;
261 DEBUGP(" entering\n"); 255 pr_debug(" entering\n");
262 256
263 if (!master) 257 if (!master)
264 DEBUGP("no master !?!\n"); 258 pr_debug("no master !?!\n");
265 else 259 else
266 nf_ct_gre_keymap_destroy(master); 260 nf_ct_gre_keymap_destroy(master);
267} 261}
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index 0d3254b974c5..debfe61378a1 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -25,12 +25,6 @@
25#include <net/netfilter/nf_conntrack_l4proto.h> 25#include <net/netfilter/nf_conntrack_l4proto.h>
26#include <net/netfilter/nf_conntrack_ecache.h> 26#include <net/netfilter/nf_conntrack_ecache.h>
27 27
28#if 0
29#define DEBUGP(format, ...) printk(format, ## __VA_ARGS__)
30#else
31#define DEBUGP(format, args...)
32#endif
33
34/* Protects conntrack->proto.sctp */ 28/* Protects conntrack->proto.sctp */
35static DEFINE_RWLOCK(sctp_lock); 29static DEFINE_RWLOCK(sctp_lock);
36 30
@@ -151,9 +145,6 @@ static int sctp_pkt_to_tuple(const struct sk_buff *skb,
151{ 145{
152 sctp_sctphdr_t _hdr, *hp; 146 sctp_sctphdr_t _hdr, *hp;
153 147
154 DEBUGP(__FUNCTION__);
155 DEBUGP("\n");
156
157 /* Actually only need first 8 bytes. */ 148 /* Actually only need first 8 bytes. */
158 hp = skb_header_pointer(skb, dataoff, 8, &_hdr); 149 hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
159 if (hp == NULL) 150 if (hp == NULL)
@@ -167,9 +158,6 @@ static int sctp_pkt_to_tuple(const struct sk_buff *skb,
167static int sctp_invert_tuple(struct nf_conntrack_tuple *tuple, 158static int sctp_invert_tuple(struct nf_conntrack_tuple *tuple,
168 const struct nf_conntrack_tuple *orig) 159 const struct nf_conntrack_tuple *orig)
169{ 160{
170 DEBUGP(__FUNCTION__);
171 DEBUGP("\n");
172
173 tuple->src.u.sctp.port = orig->dst.u.sctp.port; 161 tuple->src.u.sctp.port = orig->dst.u.sctp.port;
174 tuple->dst.u.sctp.port = orig->src.u.sctp.port; 162 tuple->dst.u.sctp.port = orig->src.u.sctp.port;
175 return 1; 163 return 1;
@@ -179,9 +167,6 @@ static int sctp_invert_tuple(struct nf_conntrack_tuple *tuple,
179static int sctp_print_tuple(struct seq_file *s, 167static int sctp_print_tuple(struct seq_file *s,
180 const struct nf_conntrack_tuple *tuple) 168 const struct nf_conntrack_tuple *tuple)
181{ 169{
182 DEBUGP(__FUNCTION__);
183 DEBUGP("\n");
184
185 return seq_printf(s, "sport=%hu dport=%hu ", 170 return seq_printf(s, "sport=%hu dport=%hu ",
186 ntohs(tuple->src.u.sctp.port), 171 ntohs(tuple->src.u.sctp.port),
187 ntohs(tuple->dst.u.sctp.port)); 172 ntohs(tuple->dst.u.sctp.port));
@@ -193,9 +178,6 @@ static int sctp_print_conntrack(struct seq_file *s,
193{ 178{
194 enum sctp_conntrack state; 179 enum sctp_conntrack state;
195 180
196 DEBUGP(__FUNCTION__);
197 DEBUGP("\n");
198
199 read_lock_bh(&sctp_lock); 181 read_lock_bh(&sctp_lock);
200 state = conntrack->proto.sctp.state; 182 state = conntrack->proto.sctp.state;
201 read_unlock_bh(&sctp_lock); 183 read_unlock_bh(&sctp_lock);
@@ -219,13 +201,10 @@ static int do_basic_checks(struct nf_conn *conntrack,
219 sctp_chunkhdr_t _sch, *sch; 201 sctp_chunkhdr_t _sch, *sch;
220 int flag; 202 int flag;
221 203
222 DEBUGP(__FUNCTION__);
223 DEBUGP("\n");
224
225 flag = 0; 204 flag = 0;
226 205
227 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) { 206 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
228 DEBUGP("Chunk Num: %d Type: %d\n", count, sch->type); 207 pr_debug("Chunk Num: %d Type: %d\n", count, sch->type);
229 208
230 if (sch->type == SCTP_CID_INIT 209 if (sch->type == SCTP_CID_INIT
231 || sch->type == SCTP_CID_INIT_ACK 210 || sch->type == SCTP_CID_INIT_ACK
@@ -242,7 +221,7 @@ static int do_basic_checks(struct nf_conn *conntrack,
242 || sch->type == SCTP_CID_COOKIE_ECHO 221 || sch->type == SCTP_CID_COOKIE_ECHO
243 || flag) 222 || flag)
244 && count !=0) || !sch->length) { 223 && count !=0) || !sch->length) {
245 DEBUGP("Basic checks failed\n"); 224 pr_debug("Basic checks failed\n");
246 return 1; 225 return 1;
247 } 226 }
248 227
@@ -251,7 +230,7 @@ static int do_basic_checks(struct nf_conn *conntrack,
251 } 230 }
252 } 231 }
253 232
254 DEBUGP("Basic checks passed\n"); 233 pr_debug("Basic checks passed\n");
255 return count == 0; 234 return count == 0;
256} 235}
257 236
@@ -261,50 +240,47 @@ static int new_state(enum ip_conntrack_dir dir,
261{ 240{
262 int i; 241 int i;
263 242
264 DEBUGP(__FUNCTION__); 243 pr_debug("Chunk type: %d\n", chunk_type);
265 DEBUGP("\n");
266
267 DEBUGP("Chunk type: %d\n", chunk_type);
268 244
269 switch (chunk_type) { 245 switch (chunk_type) {
270 case SCTP_CID_INIT: 246 case SCTP_CID_INIT:
271 DEBUGP("SCTP_CID_INIT\n"); 247 pr_debug("SCTP_CID_INIT\n");
272 i = 0; break; 248 i = 0; break;
273 case SCTP_CID_INIT_ACK: 249 case SCTP_CID_INIT_ACK:
274 DEBUGP("SCTP_CID_INIT_ACK\n"); 250 pr_debug("SCTP_CID_INIT_ACK\n");
275 i = 1; break; 251 i = 1; break;
276 case SCTP_CID_ABORT: 252 case SCTP_CID_ABORT:
277 DEBUGP("SCTP_CID_ABORT\n"); 253 pr_debug("SCTP_CID_ABORT\n");
278 i = 2; break; 254 i = 2; break;
279 case SCTP_CID_SHUTDOWN: 255 case SCTP_CID_SHUTDOWN:
280 DEBUGP("SCTP_CID_SHUTDOWN\n"); 256 pr_debug("SCTP_CID_SHUTDOWN\n");
281 i = 3; break; 257 i = 3; break;
282 case SCTP_CID_SHUTDOWN_ACK: 258 case SCTP_CID_SHUTDOWN_ACK:
283 DEBUGP("SCTP_CID_SHUTDOWN_ACK\n"); 259 pr_debug("SCTP_CID_SHUTDOWN_ACK\n");
284 i = 4; break; 260 i = 4; break;
285 case SCTP_CID_ERROR: 261 case SCTP_CID_ERROR:
286 DEBUGP("SCTP_CID_ERROR\n"); 262 pr_debug("SCTP_CID_ERROR\n");
287 i = 5; break; 263 i = 5; break;
288 case SCTP_CID_COOKIE_ECHO: 264 case SCTP_CID_COOKIE_ECHO:
289 DEBUGP("SCTP_CID_COOKIE_ECHO\n"); 265 pr_debug("SCTP_CID_COOKIE_ECHO\n");
290 i = 6; break; 266 i = 6; break;
291 case SCTP_CID_COOKIE_ACK: 267 case SCTP_CID_COOKIE_ACK:
292 DEBUGP("SCTP_CID_COOKIE_ACK\n"); 268 pr_debug("SCTP_CID_COOKIE_ACK\n");
293 i = 7; break; 269 i = 7; break;
294 case SCTP_CID_SHUTDOWN_COMPLETE: 270 case SCTP_CID_SHUTDOWN_COMPLETE:
295 DEBUGP("SCTP_CID_SHUTDOWN_COMPLETE\n"); 271 pr_debug("SCTP_CID_SHUTDOWN_COMPLETE\n");
296 i = 8; break; 272 i = 8; break;
297 default: 273 default:
298 /* Other chunks like DATA, SACK, HEARTBEAT and 274 /* Other chunks like DATA, SACK, HEARTBEAT and
299 its ACK do not cause a change in state */ 275 its ACK do not cause a change in state */
300 DEBUGP("Unknown chunk type, Will stay in %s\n", 276 pr_debug("Unknown chunk type, Will stay in %s\n",
301 sctp_conntrack_names[cur_state]); 277 sctp_conntrack_names[cur_state]);
302 return cur_state; 278 return cur_state;
303 } 279 }
304 280
305 DEBUGP("dir: %d cur_state: %s chunk_type: %d new_state: %s\n", 281 pr_debug("dir: %d cur_state: %s chunk_type: %d new_state: %s\n",
306 dir, sctp_conntrack_names[cur_state], chunk_type, 282 dir, sctp_conntrack_names[cur_state], chunk_type,
307 sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]); 283 sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]);
308 284
309 return sctp_conntracks[dir][i][cur_state]; 285 return sctp_conntracks[dir][i][cur_state];
310} 286}
@@ -323,9 +299,6 @@ static int sctp_packet(struct nf_conn *conntrack,
323 u_int32_t offset, count; 299 u_int32_t offset, count;
324 char map[256 / sizeof (char)] = {0}; 300 char map[256 / sizeof (char)] = {0};
325 301
326 DEBUGP(__FUNCTION__);
327 DEBUGP("\n");
328
329 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph); 302 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
330 if (sh == NULL) 303 if (sh == NULL)
331 return -1; 304 return -1;
@@ -340,7 +313,7 @@ static int sctp_packet(struct nf_conn *conntrack,
340 && !test_bit(SCTP_CID_ABORT, (void *)map) 313 && !test_bit(SCTP_CID_ABORT, (void *)map)
341 && !test_bit(SCTP_CID_SHUTDOWN_ACK, (void *)map) 314 && !test_bit(SCTP_CID_SHUTDOWN_ACK, (void *)map)
342 && (sh->vtag != conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) { 315 && (sh->vtag != conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) {
343 DEBUGP("Verification tag check failed\n"); 316 pr_debug("Verification tag check failed\n");
344 return -1; 317 return -1;
345 } 318 }
346 319
@@ -385,8 +358,9 @@ static int sctp_packet(struct nf_conn *conntrack,
385 358
386 /* Invalid */ 359 /* Invalid */
387 if (newconntrack == SCTP_CONNTRACK_MAX) { 360 if (newconntrack == SCTP_CONNTRACK_MAX) {
388 DEBUGP("nf_conntrack_sctp: Invalid dir=%i ctype=%u conntrack=%u\n", 361 pr_debug("nf_conntrack_sctp: Invalid dir=%i ctype=%u "
389 CTINFO2DIR(ctinfo), sch->type, oldsctpstate); 362 "conntrack=%u\n",
363 CTINFO2DIR(ctinfo), sch->type, oldsctpstate);
390 write_unlock_bh(&sctp_lock); 364 write_unlock_bh(&sctp_lock);
391 return -1; 365 return -1;
392 } 366 }
@@ -402,8 +376,8 @@ static int sctp_packet(struct nf_conn *conntrack,
402 write_unlock_bh(&sctp_lock); 376 write_unlock_bh(&sctp_lock);
403 return -1; 377 return -1;
404 } 378 }
405 DEBUGP("Setting vtag %x for dir %d\n", 379 pr_debug("Setting vtag %x for dir %d\n",
406 ih->init_tag, !CTINFO2DIR(ctinfo)); 380 ih->init_tag, !CTINFO2DIR(ctinfo));
407 conntrack->proto.sctp.vtag[!CTINFO2DIR(ctinfo)] = ih->init_tag; 381 conntrack->proto.sctp.vtag[!CTINFO2DIR(ctinfo)] = ih->init_tag;
408 } 382 }
409 383
@@ -418,7 +392,7 @@ static int sctp_packet(struct nf_conn *conntrack,
418 if (oldsctpstate == SCTP_CONNTRACK_COOKIE_ECHOED 392 if (oldsctpstate == SCTP_CONNTRACK_COOKIE_ECHOED
419 && CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY 393 && CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY
420 && newconntrack == SCTP_CONNTRACK_ESTABLISHED) { 394 && newconntrack == SCTP_CONNTRACK_ESTABLISHED) {
421 DEBUGP("Setting assured bit\n"); 395 pr_debug("Setting assured bit\n");
422 set_bit(IPS_ASSURED_BIT, &conntrack->status); 396 set_bit(IPS_ASSURED_BIT, &conntrack->status);
423 nf_conntrack_event_cache(IPCT_STATUS, skb); 397 nf_conntrack_event_cache(IPCT_STATUS, skb);
424 } 398 }
@@ -436,9 +410,6 @@ static int sctp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
436 u_int32_t offset, count; 410 u_int32_t offset, count;
437 char map[256 / sizeof (char)] = {0}; 411 char map[256 / sizeof (char)] = {0};
438 412
439 DEBUGP(__FUNCTION__);
440 DEBUGP("\n");
441
442 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph); 413 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
443 if (sh == NULL) 414 if (sh == NULL)
444 return 0; 415 return 0;
@@ -460,8 +431,9 @@ static int sctp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
460 SCTP_CONNTRACK_NONE, sch->type); 431 SCTP_CONNTRACK_NONE, sch->type);
461 432
462 /* Invalid: delete conntrack */ 433 /* Invalid: delete conntrack */
463 if (newconntrack == SCTP_CONNTRACK_MAX) { 434 if (newconntrack == SCTP_CONNTRACK_NONE ||
464 DEBUGP("nf_conntrack_sctp: invalid new deleting.\n"); 435 newconntrack == SCTP_CONNTRACK_MAX) {
436 pr_debug("nf_conntrack_sctp: invalid new deleting.\n");
465 return 0; 437 return 0;
466 } 438 }
467 439
@@ -475,8 +447,8 @@ static int sctp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
475 if (ih == NULL) 447 if (ih == NULL)
476 return 0; 448 return 0;
477 449
478 DEBUGP("Setting vtag %x for new conn\n", 450 pr_debug("Setting vtag %x for new conn\n",
479 ih->init_tag); 451 ih->init_tag);
480 452
481 conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] = 453 conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] =
482 ih->init_tag; 454 ih->init_tag;
@@ -488,8 +460,8 @@ static int sctp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
488 /* If it is a shutdown ack OOTB packet, we expect a return 460 /* If it is a shutdown ack OOTB packet, we expect a return
489 shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */ 461 shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */
490 else { 462 else {
491 DEBUGP("Setting vtag %x for new conn OOTB\n", 463 pr_debug("Setting vtag %x for new conn OOTB\n",
492 sh->vtag); 464 sh->vtag);
493 conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag; 465 conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag;
494 } 466 }
495 467
@@ -688,8 +660,6 @@ int __init nf_conntrack_proto_sctp_init(void)
688 cleanup_sctp4: 660 cleanup_sctp4:
689 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4); 661 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
690 out: 662 out:
691 DEBUGP("SCTP conntrack module loading %s\n",
692 ret ? "failed": "succeeded");
693 return ret; 663 return ret;
694} 664}
695 665
@@ -697,7 +667,6 @@ void __exit nf_conntrack_proto_sctp_fini(void)
697{ 667{
698 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp6); 668 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
699 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4); 669 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
700 DEBUGP("SCTP conntrack module unloaded\n");
701} 670}
702 671
703module_init(nf_conntrack_proto_sctp_init); 672module_init(nf_conntrack_proto_sctp_init);
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index ccdd5d231e0d..1c8206e6560a 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -26,13 +26,6 @@
26#include <net/netfilter/nf_conntrack_l4proto.h> 26#include <net/netfilter/nf_conntrack_l4proto.h>
27#include <net/netfilter/nf_conntrack_ecache.h> 27#include <net/netfilter/nf_conntrack_ecache.h>
28 28
29#if 0
30#define DEBUGP printk
31#define DEBUGP_VARS
32#else
33#define DEBUGP(format, args...)
34#endif
35
36/* Protects conntrack->proto.tcp */ 29/* Protects conntrack->proto.tcp */
37static DEFINE_RWLOCK(tcp_lock); 30static DEFINE_RWLOCK(tcp_lock);
38 31
@@ -496,7 +489,8 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
496 } 489 }
497} 490}
498 491
499static int tcp_in_window(struct ip_ct_tcp *state, 492static int tcp_in_window(struct nf_conn *ct,
493 struct ip_ct_tcp *state,
500 enum ip_conntrack_dir dir, 494 enum ip_conntrack_dir dir,
501 unsigned int index, 495 unsigned int index,
502 const struct sk_buff *skb, 496 const struct sk_buff *skb,
@@ -506,6 +500,7 @@ static int tcp_in_window(struct ip_ct_tcp *state,
506{ 500{
507 struct ip_ct_tcp_state *sender = &state->seen[dir]; 501 struct ip_ct_tcp_state *sender = &state->seen[dir];
508 struct ip_ct_tcp_state *receiver = &state->seen[!dir]; 502 struct ip_ct_tcp_state *receiver = &state->seen[!dir];
503 struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
509 __u32 seq, ack, sack, end, win, swin; 504 __u32 seq, ack, sack, end, win, swin;
510 int res; 505 int res;
511 506
@@ -520,18 +515,17 @@ static int tcp_in_window(struct ip_ct_tcp *state,
520 if (receiver->flags & IP_CT_TCP_FLAG_SACK_PERM) 515 if (receiver->flags & IP_CT_TCP_FLAG_SACK_PERM)
521 tcp_sack(skb, dataoff, tcph, &sack); 516 tcp_sack(skb, dataoff, tcph, &sack);
522 517
523 DEBUGP("tcp_in_window: START\n"); 518 pr_debug("tcp_in_window: START\n");
524 DEBUGP("tcp_in_window: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu " 519 pr_debug("tcp_in_window: ");
525 "seq=%u ack=%u sack=%u win=%u end=%u\n", 520 NF_CT_DUMP_TUPLE(tuple);
526 NIPQUAD(iph->saddr), ntohs(tcph->source), 521 pr_debug("seq=%u ack=%u sack=%u win=%u end=%u\n",
527 NIPQUAD(iph->daddr), ntohs(tcph->dest), 522 seq, ack, sack, win, end);
528 seq, ack, sack, win, end); 523 pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
529 DEBUGP("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i " 524 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
530 "receiver end=%u maxend=%u maxwin=%u scale=%i\n", 525 sender->td_end, sender->td_maxend, sender->td_maxwin,
531 sender->td_end, sender->td_maxend, sender->td_maxwin, 526 sender->td_scale,
532 sender->td_scale, 527 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
533 receiver->td_end, receiver->td_maxend, receiver->td_maxwin, 528 receiver->td_scale);
534 receiver->td_scale);
535 529
536 if (sender->td_end == 0) { 530 if (sender->td_end == 0) {
537 /* 531 /*
@@ -609,23 +603,22 @@ static int tcp_in_window(struct ip_ct_tcp *state,
609 */ 603 */
610 seq = end = sender->td_end; 604 seq = end = sender->td_end;
611 605
612 DEBUGP("tcp_in_window: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu " 606 pr_debug("tcp_in_window: ");
613 "seq=%u ack=%u sack =%u win=%u end=%u\n", 607 NF_CT_DUMP_TUPLE(tuple);
614 NIPQUAD(iph->saddr), ntohs(tcph->source), 608 pr_debug("seq=%u ack=%u sack =%u win=%u end=%u\n",
615 NIPQUAD(iph->daddr), ntohs(tcph->dest), 609 seq, ack, sack, win, end);
616 seq, ack, sack, win, end); 610 pr_debug("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i "
617 DEBUGP("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i " 611 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
618 "receiver end=%u maxend=%u maxwin=%u scale=%i\n", 612 sender->td_end, sender->td_maxend, sender->td_maxwin,
619 sender->td_end, sender->td_maxend, sender->td_maxwin, 613 sender->td_scale,
620 sender->td_scale, 614 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
621 receiver->td_end, receiver->td_maxend, receiver->td_maxwin, 615 receiver->td_scale);
622 receiver->td_scale); 616
623 617 pr_debug("tcp_in_window: I=%i II=%i III=%i IV=%i\n",
624 DEBUGP("tcp_in_window: I=%i II=%i III=%i IV=%i\n", 618 before(seq, sender->td_maxend + 1),
625 before(seq, sender->td_maxend + 1), 619 after(end, sender->td_end - receiver->td_maxwin - 1),
626 after(end, sender->td_end - receiver->td_maxwin - 1), 620 before(sack, receiver->td_end + 1),
627 before(sack, receiver->td_end + 1), 621 after(ack, receiver->td_end - MAXACKWINDOW(sender)));
628 after(ack, receiver->td_end - MAXACKWINDOW(sender)));
629 622
630 if (before(seq, sender->td_maxend + 1) && 623 if (before(seq, sender->td_maxend + 1) &&
631 after(end, sender->td_end - receiver->td_maxwin - 1) && 624 after(end, sender->td_end - receiver->td_maxwin - 1) &&
@@ -694,10 +687,10 @@ static int tcp_in_window(struct ip_ct_tcp *state,
694 : "SEQ is over the upper bound (over the window of the receiver)"); 687 : "SEQ is over the upper bound (over the window of the receiver)");
695 } 688 }
696 689
697 DEBUGP("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u " 690 pr_debug("tcp_in_window: res=%i sender end=%u maxend=%u maxwin=%u "
698 "receiver end=%u maxend=%u maxwin=%u\n", 691 "receiver end=%u maxend=%u maxwin=%u\n",
699 res, sender->td_end, sender->td_maxend, sender->td_maxwin, 692 res, sender->td_end, sender->td_maxend, sender->td_maxwin,
700 receiver->td_end, receiver->td_maxend, receiver->td_maxwin); 693 receiver->td_end, receiver->td_maxend, receiver->td_maxwin);
701 694
702 return res; 695 return res;
703} 696}
@@ -711,11 +704,9 @@ void nf_conntrack_tcp_update(struct sk_buff *skb,
711 int dir) 704 int dir)
712{ 705{
713 struct tcphdr *tcph = (void *)skb->data + dataoff; 706 struct tcphdr *tcph = (void *)skb->data + dataoff;
714 __u32 end;
715#ifdef DEBUGP_VARS
716 struct ip_ct_tcp_state *sender = &conntrack->proto.tcp.seen[dir]; 707 struct ip_ct_tcp_state *sender = &conntrack->proto.tcp.seen[dir];
717 struct ip_ct_tcp_state *receiver = &conntrack->proto.tcp.seen[!dir]; 708 struct ip_ct_tcp_state *receiver = &conntrack->proto.tcp.seen[!dir];
718#endif 709 __u32 end;
719 710
720 end = segment_seq_plus_len(ntohl(tcph->seq), skb->len, dataoff, tcph); 711 end = segment_seq_plus_len(ntohl(tcph->seq), skb->len, dataoff, tcph);
721 712
@@ -727,12 +718,12 @@ void nf_conntrack_tcp_update(struct sk_buff *skb,
727 conntrack->proto.tcp.seen[dir].td_end = end; 718 conntrack->proto.tcp.seen[dir].td_end = end;
728 conntrack->proto.tcp.last_end = end; 719 conntrack->proto.tcp.last_end = end;
729 write_unlock_bh(&tcp_lock); 720 write_unlock_bh(&tcp_lock);
730 DEBUGP("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i " 721 pr_debug("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i "
731 "receiver end=%u maxend=%u maxwin=%u scale=%i\n", 722 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
732 sender->td_end, sender->td_maxend, sender->td_maxwin, 723 sender->td_end, sender->td_maxend, sender->td_maxwin,
733 sender->td_scale, 724 sender->td_scale,
734 receiver->td_end, receiver->td_maxend, receiver->td_maxwin, 725 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
735 receiver->td_scale); 726 receiver->td_scale);
736} 727}
737EXPORT_SYMBOL_GPL(nf_conntrack_tcp_update); 728EXPORT_SYMBOL_GPL(nf_conntrack_tcp_update);
738#endif 729#endif
@@ -823,6 +814,7 @@ static int tcp_packet(struct nf_conn *conntrack,
823 int pf, 814 int pf,
824 unsigned int hooknum) 815 unsigned int hooknum)
825{ 816{
817 struct nf_conntrack_tuple *tuple;
826 enum tcp_conntrack new_state, old_state; 818 enum tcp_conntrack new_state, old_state;
827 enum ip_conntrack_dir dir; 819 enum ip_conntrack_dir dir;
828 struct tcphdr *th, _tcph; 820 struct tcphdr *th, _tcph;
@@ -837,6 +829,7 @@ static int tcp_packet(struct nf_conn *conntrack,
837 dir = CTINFO2DIR(ctinfo); 829 dir = CTINFO2DIR(ctinfo);
838 index = get_conntrack_index(th); 830 index = get_conntrack_index(th);
839 new_state = tcp_conntracks[dir][index][old_state]; 831 new_state = tcp_conntracks[dir][index][old_state];
832 tuple = &conntrack->tuplehash[dir].tuple;
840 833
841 switch (new_state) { 834 switch (new_state) {
842 case TCP_CONNTRACK_IGNORE: 835 case TCP_CONNTRACK_IGNORE:
@@ -880,9 +873,8 @@ static int tcp_packet(struct nf_conn *conntrack,
880 return NF_ACCEPT; 873 return NF_ACCEPT;
881 case TCP_CONNTRACK_MAX: 874 case TCP_CONNTRACK_MAX:
882 /* Invalid packet */ 875 /* Invalid packet */
883 DEBUGP("nf_ct_tcp: Invalid dir=%i index=%u ostate=%u\n", 876 pr_debug("nf_ct_tcp: Invalid dir=%i index=%u ostate=%u\n",
884 dir, get_conntrack_index(th), 877 dir, get_conntrack_index(th), old_state);
885 old_state);
886 write_unlock_bh(&tcp_lock); 878 write_unlock_bh(&tcp_lock);
887 if (LOG_INVALID(IPPROTO_TCP)) 879 if (LOG_INVALID(IPPROTO_TCP))
888 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 880 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
@@ -933,7 +925,7 @@ static int tcp_packet(struct nf_conn *conntrack,
933 break; 925 break;
934 } 926 }
935 927
936 if (!tcp_in_window(&conntrack->proto.tcp, dir, index, 928 if (!tcp_in_window(conntrack, &conntrack->proto.tcp, dir, index,
937 skb, dataoff, th, pf)) { 929 skb, dataoff, th, pf)) {
938 write_unlock_bh(&tcp_lock); 930 write_unlock_bh(&tcp_lock);
939 return -NF_ACCEPT; 931 return -NF_ACCEPT;
@@ -942,13 +934,12 @@ static int tcp_packet(struct nf_conn *conntrack,
942 /* From now on we have got in-window packets */ 934 /* From now on we have got in-window packets */
943 conntrack->proto.tcp.last_index = index; 935 conntrack->proto.tcp.last_index = index;
944 936
945 DEBUGP("tcp_conntracks: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu " 937 pr_debug("tcp_conntracks: ");
946 "syn=%i ack=%i fin=%i rst=%i old=%i new=%i\n", 938 NF_CT_DUMP_TUPLE(tuple);
947 NIPQUAD(iph->saddr), ntohs(th->source), 939 pr_debug("syn=%i ack=%i fin=%i rst=%i old=%i new=%i\n",
948 NIPQUAD(iph->daddr), ntohs(th->dest), 940 (th->syn ? 1 : 0), (th->ack ? 1 : 0),
949 (th->syn ? 1 : 0), (th->ack ? 1 : 0), 941 (th->fin ? 1 : 0), (th->rst ? 1 : 0),
950 (th->fin ? 1 : 0), (th->rst ? 1 : 0), 942 old_state, new_state);
951 old_state, new_state);
952 943
953 conntrack->proto.tcp.state = new_state; 944 conntrack->proto.tcp.state = new_state;
954 if (old_state != new_state 945 if (old_state != new_state
@@ -997,10 +988,8 @@ static int tcp_new(struct nf_conn *conntrack,
997{ 988{
998 enum tcp_conntrack new_state; 989 enum tcp_conntrack new_state;
999 struct tcphdr *th, _tcph; 990 struct tcphdr *th, _tcph;
1000#ifdef DEBUGP_VARS
1001 struct ip_ct_tcp_state *sender = &conntrack->proto.tcp.seen[0]; 991 struct ip_ct_tcp_state *sender = &conntrack->proto.tcp.seen[0];
1002 struct ip_ct_tcp_state *receiver = &conntrack->proto.tcp.seen[1]; 992 struct ip_ct_tcp_state *receiver = &conntrack->proto.tcp.seen[1];
1003#endif
1004 993
1005 th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph); 994 th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
1006 BUG_ON(th == NULL); 995 BUG_ON(th == NULL);
@@ -1012,7 +1001,7 @@ static int tcp_new(struct nf_conn *conntrack,
1012 1001
1013 /* Invalid: delete conntrack */ 1002 /* Invalid: delete conntrack */
1014 if (new_state >= TCP_CONNTRACK_MAX) { 1003 if (new_state >= TCP_CONNTRACK_MAX) {
1015 DEBUGP("nf_ct_tcp: invalid new deleting.\n"); 1004 pr_debug("nf_ct_tcp: invalid new deleting.\n");
1016 return 0; 1005 return 0;
1017 } 1006 }
1018 1007
@@ -1065,12 +1054,12 @@ static int tcp_new(struct nf_conn *conntrack,
1065 conntrack->proto.tcp.state = TCP_CONNTRACK_NONE; 1054 conntrack->proto.tcp.state = TCP_CONNTRACK_NONE;
1066 conntrack->proto.tcp.last_index = TCP_NONE_SET; 1055 conntrack->proto.tcp.last_index = TCP_NONE_SET;
1067 1056
1068 DEBUGP("tcp_new: sender end=%u maxend=%u maxwin=%u scale=%i " 1057 pr_debug("tcp_new: sender end=%u maxend=%u maxwin=%u scale=%i "
1069 "receiver end=%u maxend=%u maxwin=%u scale=%i\n", 1058 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
1070 sender->td_end, sender->td_maxend, sender->td_maxwin, 1059 sender->td_end, sender->td_maxend, sender->td_maxwin,
1071 sender->td_scale, 1060 sender->td_scale,
1072 receiver->td_end, receiver->td_maxend, receiver->td_maxwin, 1061 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
1073 receiver->td_scale); 1062 receiver->td_scale);
1074 return 1; 1063 return 1;
1075} 1064}
1076 1065
diff --git a/net/netfilter/nf_conntrack_sane.c b/net/netfilter/nf_conntrack_sane.c
index eb2d1dc46d45..355d371bac93 100644
--- a/net/netfilter/nf_conntrack_sane.c
+++ b/net/netfilter/nf_conntrack_sane.c
@@ -40,12 +40,6 @@ static u_int16_t ports[MAX_PORTS];
40static unsigned int ports_c; 40static unsigned int ports_c;
41module_param_array(ports, ushort, &ports_c, 0400); 41module_param_array(ports, ushort, &ports_c, 0400);
42 42
43#if 0
44#define DEBUGP printk
45#else
46#define DEBUGP(format, args...)
47#endif
48
49struct sane_request { 43struct sane_request {
50 __be32 RPC_code; 44 __be32 RPC_code;
51#define SANE_NET_START 7 /* RPC code */ 45#define SANE_NET_START 7 /* RPC code */
@@ -125,15 +119,15 @@ static int help(struct sk_buff **pskb,
125 ct_sane_info->state = SANE_STATE_NORMAL; 119 ct_sane_info->state = SANE_STATE_NORMAL;
126 120
127 if (datalen < sizeof(struct sane_reply_net_start)) { 121 if (datalen < sizeof(struct sane_reply_net_start)) {
128 DEBUGP("nf_ct_sane: NET_START reply too short\n"); 122 pr_debug("nf_ct_sane: NET_START reply too short\n");
129 goto out; 123 goto out;
130 } 124 }
131 125
132 reply = (struct sane_reply_net_start *)sb_ptr; 126 reply = (struct sane_reply_net_start *)sb_ptr;
133 if (reply->status != htonl(SANE_STATUS_SUCCESS)) { 127 if (reply->status != htonl(SANE_STATUS_SUCCESS)) {
134 /* saned refused the command */ 128 /* saned refused the command */
135 DEBUGP("nf_ct_sane: unsuccessful SANE_STATUS = %u\n", 129 pr_debug("nf_ct_sane: unsuccessful SANE_STATUS = %u\n",
136 ntohl(reply->status)); 130 ntohl(reply->status));
137 goto out; 131 goto out;
138 } 132 }
139 133
@@ -141,35 +135,32 @@ static int help(struct sk_buff **pskb,
141 if (reply->zero != 0) 135 if (reply->zero != 0)
142 goto out; 136 goto out;
143 137
144 exp = nf_conntrack_expect_alloc(ct); 138 exp = nf_ct_expect_alloc(ct);
145 if (exp == NULL) { 139 if (exp == NULL) {
146 ret = NF_DROP; 140 ret = NF_DROP;
147 goto out; 141 goto out;
148 } 142 }
149 143
150 tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; 144 tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
151 nf_conntrack_expect_init(exp, family, 145 nf_ct_expect_init(exp, family, &tuple->src.u3, &tuple->dst.u3,
152 &tuple->src.u3, &tuple->dst.u3, 146 IPPROTO_TCP, NULL, &reply->port);
153 IPPROTO_TCP,
154 NULL, &reply->port);
155 147
156 DEBUGP("nf_ct_sane: expect: "); 148 pr_debug("nf_ct_sane: expect: ");
157 NF_CT_DUMP_TUPLE(&exp->tuple); 149 NF_CT_DUMP_TUPLE(&exp->tuple);
158 NF_CT_DUMP_TUPLE(&exp->mask);
159 150
160 /* Can't expect this? Best to drop packet now. */ 151 /* Can't expect this? Best to drop packet now. */
161 if (nf_conntrack_expect_related(exp) != 0) 152 if (nf_ct_expect_related(exp) != 0)
162 ret = NF_DROP; 153 ret = NF_DROP;
163 154
164 nf_conntrack_expect_put(exp); 155 nf_ct_expect_put(exp);
165 156
166out: 157out:
167 spin_unlock_bh(&nf_sane_lock); 158 spin_unlock_bh(&nf_sane_lock);
168 return ret; 159 return ret;
169} 160}
170 161
171static struct nf_conntrack_helper sane[MAX_PORTS][2]; 162static struct nf_conntrack_helper sane[MAX_PORTS][2] __read_mostly;
172static char sane_names[MAX_PORTS][2][sizeof("sane-65535")]; 163static char sane_names[MAX_PORTS][2][sizeof("sane-65535")] __read_mostly;
173 164
174/* don't make this __exit, since it's called from __init ! */ 165/* don't make this __exit, since it's called from __init ! */
175static void nf_conntrack_sane_fini(void) 166static void nf_conntrack_sane_fini(void)
@@ -178,9 +169,9 @@ static void nf_conntrack_sane_fini(void)
178 169
179 for (i = 0; i < ports_c; i++) { 170 for (i = 0; i < ports_c; i++) {
180 for (j = 0; j < 2; j++) { 171 for (j = 0; j < 2; j++) {
181 DEBUGP("nf_ct_sane: unregistering helper for pf: %d " 172 pr_debug("nf_ct_sane: unregistering helper for pf: %d "
182 "port: %d\n", 173 "port: %d\n",
183 sane[i][j].tuple.src.l3num, ports[i]); 174 sane[i][j].tuple.src.l3num, ports[i]);
184 nf_conntrack_helper_unregister(&sane[i][j]); 175 nf_conntrack_helper_unregister(&sane[i][j]);
185 } 176 }
186 } 177 }
@@ -208,8 +199,6 @@ static int __init nf_conntrack_sane_init(void)
208 for (j = 0; j < 2; j++) { 199 for (j = 0; j < 2; j++) {
209 sane[i][j].tuple.src.u.tcp.port = htons(ports[i]); 200 sane[i][j].tuple.src.u.tcp.port = htons(ports[i]);
210 sane[i][j].tuple.dst.protonum = IPPROTO_TCP; 201 sane[i][j].tuple.dst.protonum = IPPROTO_TCP;
211 sane[i][j].mask.src.u.tcp.port = 0xFFFF;
212 sane[i][j].mask.dst.protonum = 0xFF;
213 sane[i][j].max_expected = 1; 202 sane[i][j].max_expected = 1;
214 sane[i][j].timeout = 5 * 60; /* 5 Minutes */ 203 sane[i][j].timeout = 5 * 60; /* 5 Minutes */
215 sane[i][j].me = THIS_MODULE; 204 sane[i][j].me = THIS_MODULE;
@@ -221,9 +210,9 @@ static int __init nf_conntrack_sane_init(void)
221 sprintf(tmpname, "sane-%d", ports[i]); 210 sprintf(tmpname, "sane-%d", ports[i]);
222 sane[i][j].name = tmpname; 211 sane[i][j].name = tmpname;
223 212
224 DEBUGP("nf_ct_sane: registering helper for pf: %d " 213 pr_debug("nf_ct_sane: registering helper for pf: %d "
225 "port: %d\n", 214 "port: %d\n",
226 sane[i][j].tuple.src.l3num, ports[i]); 215 sane[i][j].tuple.src.l3num, ports[i]);
227 ret = nf_conntrack_helper_register(&sane[i][j]); 216 ret = nf_conntrack_helper_register(&sane[i][j]);
228 if (ret) { 217 if (ret) {
229 printk(KERN_ERR "nf_ct_sane: failed to " 218 printk(KERN_ERR "nf_ct_sane: failed to "
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 1b5c6c1055f7..1276a442f10c 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -21,12 +21,6 @@
21#include <net/netfilter/nf_conntrack_helper.h> 21#include <net/netfilter/nf_conntrack_helper.h>
22#include <linux/netfilter/nf_conntrack_sip.h> 22#include <linux/netfilter/nf_conntrack_sip.h>
23 23
24#if 0
25#define DEBUGP printk
26#else
27#define DEBUGP(format, args...)
28#endif
29
30MODULE_LICENSE("GPL"); 24MODULE_LICENSE("GPL");
31MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com.ar>"); 25MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com.ar>");
32MODULE_DESCRIPTION("SIP connection tracking helper"); 26MODULE_DESCRIPTION("SIP connection tracking helper");
@@ -285,7 +279,7 @@ static int epaddr_len(struct nf_conn *ct, const char *dptr,
285 const char *aux = dptr; 279 const char *aux = dptr;
286 280
287 if (!parse_addr(ct, dptr, &dptr, &addr, limit)) { 281 if (!parse_addr(ct, dptr, &dptr, &addr, limit)) {
288 DEBUGP("ip: %s parse failed.!\n", dptr); 282 pr_debug("ip: %s parse failed.!\n", dptr);
289 return 0; 283 return 0;
290 } 284 }
291 285
@@ -344,8 +338,8 @@ int ct_sip_get_info(struct nf_conn *ct,
344 ct_sip_lnlen(dptr, limit), 338 ct_sip_lnlen(dptr, limit),
345 hnfo->case_sensitive); 339 hnfo->case_sensitive);
346 if (!aux) { 340 if (!aux) {
347 DEBUGP("'%s' not found in '%s'.\n", hnfo->ln_str, 341 pr_debug("'%s' not found in '%s'.\n", hnfo->ln_str,
348 hnfo->lname); 342 hnfo->lname);
349 return -1; 343 return -1;
350 } 344 }
351 aux += hnfo->ln_strlen; 345 aux += hnfo->ln_strlen;
@@ -356,11 +350,11 @@ int ct_sip_get_info(struct nf_conn *ct,
356 350
357 *matchoff = (aux - k) + shift; 351 *matchoff = (aux - k) + shift;
358 352
359 DEBUGP("%s match succeeded! - len: %u\n", hnfo->lname, 353 pr_debug("%s match succeeded! - len: %u\n", hnfo->lname,
360 *matchlen); 354 *matchlen);
361 return 1; 355 return 1;
362 } 356 }
363 DEBUGP("%s header not found.\n", hnfo->lname); 357 pr_debug("%s header not found.\n", hnfo->lname);
364 return 0; 358 return 0;
365} 359}
366EXPORT_SYMBOL_GPL(ct_sip_get_info); 360EXPORT_SYMBOL_GPL(ct_sip_get_info);
@@ -378,23 +372,23 @@ static int set_expected_rtp(struct sk_buff **pskb,
378 int ret; 372 int ret;
379 typeof(nf_nat_sdp_hook) nf_nat_sdp; 373 typeof(nf_nat_sdp_hook) nf_nat_sdp;
380 374
381 exp = nf_conntrack_expect_alloc(ct); 375 exp = nf_ct_expect_alloc(ct);
382 if (exp == NULL) 376 if (exp == NULL)
383 return NF_DROP; 377 return NF_DROP;
384 nf_conntrack_expect_init(exp, family, 378 nf_ct_expect_init(exp, family,
385 &ct->tuplehash[!dir].tuple.src.u3, addr, 379 &ct->tuplehash[!dir].tuple.src.u3, addr,
386 IPPROTO_UDP, NULL, &port); 380 IPPROTO_UDP, NULL, &port);
387 381
388 nf_nat_sdp = rcu_dereference(nf_nat_sdp_hook); 382 nf_nat_sdp = rcu_dereference(nf_nat_sdp_hook);
389 if (nf_nat_sdp && ct->status & IPS_NAT_MASK) 383 if (nf_nat_sdp && ct->status & IPS_NAT_MASK)
390 ret = nf_nat_sdp(pskb, ctinfo, exp, dptr); 384 ret = nf_nat_sdp(pskb, ctinfo, exp, dptr);
391 else { 385 else {
392 if (nf_conntrack_expect_related(exp) != 0) 386 if (nf_ct_expect_related(exp) != 0)
393 ret = NF_DROP; 387 ret = NF_DROP;
394 else 388 else
395 ret = NF_ACCEPT; 389 ret = NF_ACCEPT;
396 } 390 }
397 nf_conntrack_expect_put(exp); 391 nf_ct_expect_put(exp);
398 392
399 return ret; 393 return ret;
400} 394}
@@ -424,7 +418,7 @@ static int sip_help(struct sk_buff **pskb,
424 if (!skb_is_nonlinear(*pskb)) 418 if (!skb_is_nonlinear(*pskb))
425 dptr = (*pskb)->data + dataoff; 419 dptr = (*pskb)->data + dataoff;
426 else { 420 else {
427 DEBUGP("Copy of skbuff not supported yet.\n"); 421 pr_debug("Copy of skbuff not supported yet.\n");
428 goto out; 422 goto out;
429 } 423 }
430 424
@@ -506,9 +500,6 @@ static int __init nf_conntrack_sip_init(void)
506 for (j = 0; j < 2; j++) { 500 for (j = 0; j < 2; j++) {
507 sip[i][j].tuple.dst.protonum = IPPROTO_UDP; 501 sip[i][j].tuple.dst.protonum = IPPROTO_UDP;
508 sip[i][j].tuple.src.u.udp.port = htons(ports[i]); 502 sip[i][j].tuple.src.u.udp.port = htons(ports[i]);
509 sip[i][j].mask.src.l3num = 0xFFFF;
510 sip[i][j].mask.src.u.udp.port = htons(0xFFFF);
511 sip[i][j].mask.dst.protonum = 0xFF;
512 sip[i][j].max_expected = 2; 503 sip[i][j].max_expected = 2;
513 sip[i][j].timeout = 3 * 60; /* 3 minutes */ 504 sip[i][j].timeout = 3 * 60; /* 3 minutes */
514 sip[i][j].me = THIS_MODULE; 505 sip[i][j].me = THIS_MODULE;
@@ -521,7 +512,7 @@ static int __init nf_conntrack_sip_init(void)
521 sprintf(tmpname, "sip-%u", i); 512 sprintf(tmpname, "sip-%u", i);
522 sip[i][j].name = tmpname; 513 sip[i][j].name = tmpname;
523 514
524 DEBUGP("port #%u: %u\n", i, ports[i]); 515 pr_debug("port #%u: %u\n", i, ports[i]);
525 516
526 ret = nf_conntrack_helper_register(&sip[i][j]); 517 ret = nf_conntrack_helper_register(&sip[i][j]);
527 if (ret) { 518 if (ret) {
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 45baeb0e30f9..ffb6ff8c3528 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -25,12 +25,6 @@
25#include <net/netfilter/nf_conntrack_expect.h> 25#include <net/netfilter/nf_conntrack_expect.h>
26#include <net/netfilter/nf_conntrack_helper.h> 26#include <net/netfilter/nf_conntrack_helper.h>
27 27
28#if 0
29#define DEBUGP printk
30#else
31#define DEBUGP(format, args...)
32#endif
33
34MODULE_LICENSE("GPL"); 28MODULE_LICENSE("GPL");
35 29
36#ifdef CONFIG_PROC_FS 30#ifdef CONFIG_PROC_FS
@@ -60,35 +54,36 @@ struct ct_iter_state {
60 unsigned int bucket; 54 unsigned int bucket;
61}; 55};
62 56
63static struct list_head *ct_get_first(struct seq_file *seq) 57static struct hlist_node *ct_get_first(struct seq_file *seq)
64{ 58{
65 struct ct_iter_state *st = seq->private; 59 struct ct_iter_state *st = seq->private;
66 60
67 for (st->bucket = 0; 61 for (st->bucket = 0;
68 st->bucket < nf_conntrack_htable_size; 62 st->bucket < nf_conntrack_htable_size;
69 st->bucket++) { 63 st->bucket++) {
70 if (!list_empty(&nf_conntrack_hash[st->bucket])) 64 if (!hlist_empty(&nf_conntrack_hash[st->bucket]))
71 return nf_conntrack_hash[st->bucket].next; 65 return nf_conntrack_hash[st->bucket].first;
72 } 66 }
73 return NULL; 67 return NULL;
74} 68}
75 69
76static struct list_head *ct_get_next(struct seq_file *seq, struct list_head *head) 70static struct hlist_node *ct_get_next(struct seq_file *seq,
71 struct hlist_node *head)
77{ 72{
78 struct ct_iter_state *st = seq->private; 73 struct ct_iter_state *st = seq->private;
79 74
80 head = head->next; 75 head = head->next;
81 while (head == &nf_conntrack_hash[st->bucket]) { 76 while (head == NULL) {
82 if (++st->bucket >= nf_conntrack_htable_size) 77 if (++st->bucket >= nf_conntrack_htable_size)
83 return NULL; 78 return NULL;
84 head = nf_conntrack_hash[st->bucket].next; 79 head = nf_conntrack_hash[st->bucket].first;
85 } 80 }
86 return head; 81 return head;
87} 82}
88 83
89static struct list_head *ct_get_idx(struct seq_file *seq, loff_t pos) 84static struct hlist_node *ct_get_idx(struct seq_file *seq, loff_t pos)
90{ 85{
91 struct list_head *head = ct_get_first(seq); 86 struct hlist_node *head = ct_get_first(seq);
92 87
93 if (head) 88 if (head)
94 while (pos && (head = ct_get_next(seq, head))) 89 while (pos && (head = ct_get_next(seq, head)))
@@ -190,7 +185,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
190 return 0; 185 return 0;
191} 186}
192 187
193static struct seq_operations ct_seq_ops = { 188static const struct seq_operations ct_seq_ops = {
194 .start = ct_seq_start, 189 .start = ct_seq_start,
195 .next = ct_seq_next, 190 .next = ct_seq_next,
196 .stop = ct_seq_stop, 191 .stop = ct_seq_stop,
@@ -294,7 +289,7 @@ static int ct_cpu_seq_show(struct seq_file *seq, void *v)
294 return 0; 289 return 0;
295} 290}
296 291
297static struct seq_operations ct_cpu_seq_ops = { 292static const struct seq_operations ct_cpu_seq_ops = {
298 .start = ct_cpu_seq_start, 293 .start = ct_cpu_seq_start,
299 .next = ct_cpu_seq_next, 294 .next = ct_cpu_seq_next,
300 .stop = ct_cpu_seq_stop, 295 .stop = ct_cpu_seq_stop,
@@ -371,7 +366,14 @@ static ctl_table nf_ct_sysctl_table[] = {
371 .extra1 = &log_invalid_proto_min, 366 .extra1 = &log_invalid_proto_min,
372 .extra2 = &log_invalid_proto_max, 367 .extra2 = &log_invalid_proto_max,
373 }, 368 },
374 369 {
370 .ctl_name = CTL_UNNUMBERED,
371 .procname = "nf_conntrack_expect_max",
372 .data = &nf_ct_expect_max,
373 .maxlen = sizeof(int),
374 .mode = 0644,
375 .proc_handler = &proc_dointvec,
376 },
375 { .ctl_name = 0 } 377 { .ctl_name = 0 }
376}; 378};
377 379
@@ -410,7 +412,7 @@ EXPORT_SYMBOL_GPL(nf_ct_log_invalid);
410static int __init nf_conntrack_standalone_init(void) 412static int __init nf_conntrack_standalone_init(void)
411{ 413{
412#ifdef CONFIG_PROC_FS 414#ifdef CONFIG_PROC_FS
413 struct proc_dir_entry *proc, *proc_exp, *proc_stat; 415 struct proc_dir_entry *proc, *proc_stat;
414#endif 416#endif
415 int ret = 0; 417 int ret = 0;
416 418
@@ -422,13 +424,9 @@ static int __init nf_conntrack_standalone_init(void)
422 proc = proc_net_fops_create("nf_conntrack", 0440, &ct_file_ops); 424 proc = proc_net_fops_create("nf_conntrack", 0440, &ct_file_ops);
423 if (!proc) goto cleanup_init; 425 if (!proc) goto cleanup_init;
424 426
425 proc_exp = proc_net_fops_create("nf_conntrack_expect", 0440,
426 &exp_file_ops);
427 if (!proc_exp) goto cleanup_proc;
428
429 proc_stat = create_proc_entry("nf_conntrack", S_IRUGO, proc_net_stat); 427 proc_stat = create_proc_entry("nf_conntrack", S_IRUGO, proc_net_stat);
430 if (!proc_stat) 428 if (!proc_stat)
431 goto cleanup_proc_exp; 429 goto cleanup_proc;
432 430
433 proc_stat->proc_fops = &ct_cpu_seq_fops; 431 proc_stat->proc_fops = &ct_cpu_seq_fops;
434 proc_stat->owner = THIS_MODULE; 432 proc_stat->owner = THIS_MODULE;
@@ -448,8 +446,6 @@ static int __init nf_conntrack_standalone_init(void)
448#endif 446#endif
449#ifdef CONFIG_PROC_FS 447#ifdef CONFIG_PROC_FS
450 remove_proc_entry("nf_conntrack", proc_net_stat); 448 remove_proc_entry("nf_conntrack", proc_net_stat);
451 cleanup_proc_exp:
452 proc_net_remove("nf_conntrack_expect");
453 cleanup_proc: 449 cleanup_proc:
454 proc_net_remove("nf_conntrack"); 450 proc_net_remove("nf_conntrack");
455 cleanup_init: 451 cleanup_init:
@@ -465,7 +461,6 @@ static void __exit nf_conntrack_standalone_fini(void)
465#endif 461#endif
466#ifdef CONFIG_PROC_FS 462#ifdef CONFIG_PROC_FS
467 remove_proc_entry("nf_conntrack", proc_net_stat); 463 remove_proc_entry("nf_conntrack", proc_net_stat);
468 proc_net_remove("nf_conntrack_expect");
469 proc_net_remove("nf_conntrack"); 464 proc_net_remove("nf_conntrack");
470#endif /* CNFIG_PROC_FS */ 465#endif /* CNFIG_PROC_FS */
471 nf_conntrack_cleanup(); 466 nf_conntrack_cleanup();
diff --git a/net/netfilter/nf_conntrack_tftp.c b/net/netfilter/nf_conntrack_tftp.c
index 37c4542e3112..cc19506cf2f8 100644
--- a/net/netfilter/nf_conntrack_tftp.c
+++ b/net/netfilter/nf_conntrack_tftp.c
@@ -29,13 +29,6 @@ static int ports_c;
29module_param_array(ports, ushort, &ports_c, 0400); 29module_param_array(ports, ushort, &ports_c, 0400);
30MODULE_PARM_DESC(ports, "Port numbers of TFTP servers"); 30MODULE_PARM_DESC(ports, "Port numbers of TFTP servers");
31 31
32#if 0
33#define DEBUGP(format, args...) printk("%s:%s:" format, \
34 __FILE__, __FUNCTION__ , ## args)
35#else
36#define DEBUGP(format, args...)
37#endif
38
39unsigned int (*nf_nat_tftp_hook)(struct sk_buff **pskb, 32unsigned int (*nf_nat_tftp_hook)(struct sk_buff **pskb,
40 enum ip_conntrack_info ctinfo, 33 enum ip_conntrack_info ctinfo,
41 struct nf_conntrack_expect *exp) __read_mostly; 34 struct nf_conntrack_expect *exp) __read_mostly;
@@ -62,39 +55,35 @@ static int tftp_help(struct sk_buff **pskb,
62 case TFTP_OPCODE_READ: 55 case TFTP_OPCODE_READ:
63 case TFTP_OPCODE_WRITE: 56 case TFTP_OPCODE_WRITE:
64 /* RRQ and WRQ works the same way */ 57 /* RRQ and WRQ works the same way */
65 DEBUGP("");
66 NF_CT_DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); 58 NF_CT_DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
67 NF_CT_DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); 59 NF_CT_DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
68 60
69 exp = nf_conntrack_expect_alloc(ct); 61 exp = nf_ct_expect_alloc(ct);
70 if (exp == NULL) 62 if (exp == NULL)
71 return NF_DROP; 63 return NF_DROP;
72 tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple; 64 tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
73 nf_conntrack_expect_init(exp, family, 65 nf_ct_expect_init(exp, family, &tuple->src.u3, &tuple->dst.u3,
74 &tuple->src.u3, &tuple->dst.u3, 66 IPPROTO_UDP, NULL, &tuple->dst.u.udp.port);
75 IPPROTO_UDP,
76 NULL, &tuple->dst.u.udp.port);
77 67
78 DEBUGP("expect: "); 68 pr_debug("expect: ");
79 NF_CT_DUMP_TUPLE(&exp->tuple); 69 NF_CT_DUMP_TUPLE(&exp->tuple);
80 NF_CT_DUMP_TUPLE(&exp->mask);
81 70
82 nf_nat_tftp = rcu_dereference(nf_nat_tftp_hook); 71 nf_nat_tftp = rcu_dereference(nf_nat_tftp_hook);
83 if (nf_nat_tftp && ct->status & IPS_NAT_MASK) 72 if (nf_nat_tftp && ct->status & IPS_NAT_MASK)
84 ret = nf_nat_tftp(pskb, ctinfo, exp); 73 ret = nf_nat_tftp(pskb, ctinfo, exp);
85 else if (nf_conntrack_expect_related(exp) != 0) 74 else if (nf_ct_expect_related(exp) != 0)
86 ret = NF_DROP; 75 ret = NF_DROP;
87 nf_conntrack_expect_put(exp); 76 nf_ct_expect_put(exp);
88 break; 77 break;
89 case TFTP_OPCODE_DATA: 78 case TFTP_OPCODE_DATA:
90 case TFTP_OPCODE_ACK: 79 case TFTP_OPCODE_ACK:
91 DEBUGP("Data/ACK opcode\n"); 80 pr_debug("Data/ACK opcode\n");
92 break; 81 break;
93 case TFTP_OPCODE_ERROR: 82 case TFTP_OPCODE_ERROR:
94 DEBUGP("Error opcode\n"); 83 pr_debug("Error opcode\n");
95 break; 84 break;
96 default: 85 default:
97 DEBUGP("Unknown opcode\n"); 86 pr_debug("Unknown opcode\n");
98 } 87 }
99 return ret; 88 return ret;
100} 89}
@@ -128,9 +117,6 @@ static int __init nf_conntrack_tftp_init(void)
128 for (j = 0; j < 2; j++) { 117 for (j = 0; j < 2; j++) {
129 tftp[i][j].tuple.dst.protonum = IPPROTO_UDP; 118 tftp[i][j].tuple.dst.protonum = IPPROTO_UDP;
130 tftp[i][j].tuple.src.u.udp.port = htons(ports[i]); 119 tftp[i][j].tuple.src.u.udp.port = htons(ports[i]);
131 tftp[i][j].mask.src.l3num = 0xFFFF;
132 tftp[i][j].mask.dst.protonum = 0xFF;
133 tftp[i][j].mask.src.u.udp.port = htons(0xFFFF);
134 tftp[i][j].max_expected = 1; 120 tftp[i][j].max_expected = 1;
135 tftp[i][j].timeout = 5 * 60; /* 5 minutes */ 121 tftp[i][j].timeout = 5 * 60; /* 5 minutes */
136 tftp[i][j].me = THIS_MODULE; 122 tftp[i][j].me = THIS_MODULE;
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index 91b220cf5a1f..94985792b79a 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -140,7 +140,7 @@ static int seq_show(struct seq_file *s, void *v)
140 return seq_printf(s, "%2lld %s\n", *pos, logger->name); 140 return seq_printf(s, "%2lld %s\n", *pos, logger->name);
141} 141}
142 142
143static struct seq_operations nflog_seq_ops = { 143static const struct seq_operations nflog_seq_ops = {
144 .start = seq_start, 144 .start = seq_start,
145 .next = seq_next, 145 .next = seq_next,
146 .stop = seq_stop, 146 .stop = seq_stop,
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index b1f2ace96f6d..a481a349f7bf 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -17,7 +17,7 @@
17 */ 17 */
18static struct nf_queue_handler *queue_handler[NPROTO]; 18static struct nf_queue_handler *queue_handler[NPROTO];
19 19
20static DEFINE_RWLOCK(queue_handler_lock); 20static DEFINE_MUTEX(queue_handler_mutex);
21 21
22/* return EBUSY when somebody else is registered, return EEXIST if the 22/* return EBUSY when somebody else is registered, return EEXIST if the
23 * same handler is registered, return 0 in case of success. */ 23 * same handler is registered, return 0 in case of success. */
@@ -28,30 +28,37 @@ int nf_register_queue_handler(int pf, struct nf_queue_handler *qh)
28 if (pf >= NPROTO) 28 if (pf >= NPROTO)
29 return -EINVAL; 29 return -EINVAL;
30 30
31 write_lock_bh(&queue_handler_lock); 31 mutex_lock(&queue_handler_mutex);
32 if (queue_handler[pf] == qh) 32 if (queue_handler[pf] == qh)
33 ret = -EEXIST; 33 ret = -EEXIST;
34 else if (queue_handler[pf]) 34 else if (queue_handler[pf])
35 ret = -EBUSY; 35 ret = -EBUSY;
36 else { 36 else {
37 queue_handler[pf] = qh; 37 rcu_assign_pointer(queue_handler[pf], qh);
38 ret = 0; 38 ret = 0;
39 } 39 }
40 write_unlock_bh(&queue_handler_lock); 40 mutex_unlock(&queue_handler_mutex);
41 41
42 return ret; 42 return ret;
43} 43}
44EXPORT_SYMBOL(nf_register_queue_handler); 44EXPORT_SYMBOL(nf_register_queue_handler);
45 45
46/* The caller must flush their queue before this */ 46/* The caller must flush their queue before this */
47int nf_unregister_queue_handler(int pf) 47int nf_unregister_queue_handler(int pf, struct nf_queue_handler *qh)
48{ 48{
49 if (pf >= NPROTO) 49 if (pf >= NPROTO)
50 return -EINVAL; 50 return -EINVAL;
51 51
52 write_lock_bh(&queue_handler_lock); 52 mutex_lock(&queue_handler_mutex);
53 queue_handler[pf] = NULL; 53 if (queue_handler[pf] != qh) {
54 write_unlock_bh(&queue_handler_lock); 54 mutex_unlock(&queue_handler_mutex);
55 return -EINVAL;
56 }
57
58 rcu_assign_pointer(queue_handler[pf], NULL);
59 mutex_unlock(&queue_handler_mutex);
60
61 synchronize_rcu();
55 62
56 return 0; 63 return 0;
57} 64}
@@ -61,12 +68,14 @@ void nf_unregister_queue_handlers(struct nf_queue_handler *qh)
61{ 68{
62 int pf; 69 int pf;
63 70
64 write_lock_bh(&queue_handler_lock); 71 mutex_lock(&queue_handler_mutex);
65 for (pf = 0; pf < NPROTO; pf++) { 72 for (pf = 0; pf < NPROTO; pf++) {
66 if (queue_handler[pf] == qh) 73 if (queue_handler[pf] == qh)
67 queue_handler[pf] = NULL; 74 rcu_assign_pointer(queue_handler[pf], NULL);
68 } 75 }
69 write_unlock_bh(&queue_handler_lock); 76 mutex_unlock(&queue_handler_mutex);
77
78 synchronize_rcu();
70} 79}
71EXPORT_SYMBOL_GPL(nf_unregister_queue_handlers); 80EXPORT_SYMBOL_GPL(nf_unregister_queue_handlers);
72 81
@@ -89,18 +98,21 @@ static int __nf_queue(struct sk_buff *skb,
89 struct net_device *physoutdev = NULL; 98 struct net_device *physoutdev = NULL;
90#endif 99#endif
91 struct nf_afinfo *afinfo; 100 struct nf_afinfo *afinfo;
101 struct nf_queue_handler *qh;
92 102
93 /* QUEUE == DROP if noone is waiting, to be safe. */ 103 /* QUEUE == DROP if noone is waiting, to be safe. */
94 read_lock(&queue_handler_lock); 104 rcu_read_lock();
95 if (!queue_handler[pf]) { 105
96 read_unlock(&queue_handler_lock); 106 qh = rcu_dereference(queue_handler[pf]);
107 if (!qh) {
108 rcu_read_unlock();
97 kfree_skb(skb); 109 kfree_skb(skb);
98 return 1; 110 return 1;
99 } 111 }
100 112
101 afinfo = nf_get_afinfo(pf); 113 afinfo = nf_get_afinfo(pf);
102 if (!afinfo) { 114 if (!afinfo) {
103 read_unlock(&queue_handler_lock); 115 rcu_read_unlock();
104 kfree_skb(skb); 116 kfree_skb(skb);
105 return 1; 117 return 1;
106 } 118 }
@@ -110,7 +122,7 @@ static int __nf_queue(struct sk_buff *skb,
110 if (net_ratelimit()) 122 if (net_ratelimit())
111 printk(KERN_ERR "OOM queueing packet %p\n", 123 printk(KERN_ERR "OOM queueing packet %p\n",
112 skb); 124 skb);
113 read_unlock(&queue_handler_lock); 125 rcu_read_unlock();
114 kfree_skb(skb); 126 kfree_skb(skb);
115 return 1; 127 return 1;
116 } 128 }
@@ -120,7 +132,7 @@ static int __nf_queue(struct sk_buff *skb,
120 132
121 /* If it's going away, ignore hook. */ 133 /* If it's going away, ignore hook. */
122 if (!try_module_get(info->elem->owner)) { 134 if (!try_module_get(info->elem->owner)) {
123 read_unlock(&queue_handler_lock); 135 rcu_read_unlock();
124 kfree(info); 136 kfree(info);
125 return 0; 137 return 0;
126 } 138 }
@@ -138,10 +150,9 @@ static int __nf_queue(struct sk_buff *skb,
138 } 150 }
139#endif 151#endif
140 afinfo->saveroute(skb, info); 152 afinfo->saveroute(skb, info);
141 status = queue_handler[pf]->outfn(skb, info, queuenum, 153 status = qh->outfn(skb, info, queuenum, qh->data);
142 queue_handler[pf]->data);
143 154
144 read_unlock(&queue_handler_lock); 155 rcu_read_unlock();
145 156
146 if (status < 0) { 157 if (status < 0) {
147 /* James M doesn't say fuck enough. */ 158 /* James M doesn't say fuck enough. */
@@ -308,18 +319,18 @@ static int seq_show(struct seq_file *s, void *v)
308 loff_t *pos = v; 319 loff_t *pos = v;
309 struct nf_queue_handler *qh; 320 struct nf_queue_handler *qh;
310 321
311 read_lock_bh(&queue_handler_lock); 322 rcu_read_lock();
312 qh = queue_handler[*pos]; 323 qh = rcu_dereference(queue_handler[*pos]);
313 if (!qh) 324 if (!qh)
314 ret = seq_printf(s, "%2lld NONE\n", *pos); 325 ret = seq_printf(s, "%2lld NONE\n", *pos);
315 else 326 else
316 ret = seq_printf(s, "%2lld %s\n", *pos, qh->name); 327 ret = seq_printf(s, "%2lld %s\n", *pos, qh->name);
317 read_unlock_bh(&queue_handler_lock); 328 rcu_read_unlock();
318 329
319 return ret; 330 return ret;
320} 331}
321 332
322static struct seq_operations nfqueue_seq_ops = { 333static const struct seq_operations nfqueue_seq_ops = {
323 .start = seq_start, 334 .start = seq_start,
324 .next = seq_next, 335 .next = seq_next,
325 .stop = seq_stop, 336 .stop = seq_stop,
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index e32e30e7a17c..e185a5b55913 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -962,7 +962,7 @@ static int seq_show(struct seq_file *s, void *v)
962 inst->flushtimeout, atomic_read(&inst->use)); 962 inst->flushtimeout, atomic_read(&inst->use));
963} 963}
964 964
965static struct seq_operations nful_seq_ops = { 965static const struct seq_operations nful_seq_ops = {
966 .start = seq_start, 966 .start = seq_start,
967 .next = seq_next, 967 .next = seq_next,
968 .stop = seq_stop, 968 .stop = seq_stop,
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 7a97bec67729..bb65a38c816c 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -913,9 +913,7 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
913 case NFQNL_CFG_CMD_PF_UNBIND: 913 case NFQNL_CFG_CMD_PF_UNBIND:
914 QDEBUG("unregistering queue handler for pf=%u\n", 914 QDEBUG("unregistering queue handler for pf=%u\n",
915 ntohs(cmd->pf)); 915 ntohs(cmd->pf));
916 /* This is a bug and a feature. We can unregister 916 ret = nf_unregister_queue_handler(ntohs(cmd->pf), &nfqh);
917 * other handlers(!) */
918 ret = nf_unregister_queue_handler(ntohs(cmd->pf));
919 break; 917 break;
920 default: 918 default:
921 ret = -EINVAL; 919 ret = -EINVAL;
@@ -1050,7 +1048,7 @@ static int seq_show(struct seq_file *s, void *v)
1050 atomic_read(&inst->use)); 1048 atomic_read(&inst->use));
1051} 1049}
1052 1050
1053static struct seq_operations nfqnl_seq_ops = { 1051static const struct seq_operations nfqnl_seq_ops = {
1054 .start = seq_start, 1052 .start = seq_start,
1055 .next = seq_next, 1053 .next = seq_next,
1056 .stop = seq_stop, 1054 .stop = seq_stop,
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 0eb2504b89b5..cc2baa6d5a7a 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -320,8 +320,8 @@ int xt_check_match(const struct xt_match *match, unsigned short family,
320 return -EINVAL; 320 return -EINVAL;
321 } 321 }
322 if (match->hooks && (hook_mask & ~match->hooks) != 0) { 322 if (match->hooks && (hook_mask & ~match->hooks) != 0) {
323 printk("%s_tables: %s match: bad hook_mask %u\n", 323 printk("%s_tables: %s match: bad hook_mask %u/%u\n",
324 xt_prefix[family], match->name, hook_mask); 324 xt_prefix[family], match->name, hook_mask, match->hooks);
325 return -EINVAL; 325 return -EINVAL;
326 } 326 }
327 if (match->proto && (match->proto != proto || inv_proto)) { 327 if (match->proto && (match->proto != proto || inv_proto)) {
@@ -410,8 +410,9 @@ int xt_check_target(const struct xt_target *target, unsigned short family,
410 return -EINVAL; 410 return -EINVAL;
411 } 411 }
412 if (target->hooks && (hook_mask & ~target->hooks) != 0) { 412 if (target->hooks && (hook_mask & ~target->hooks) != 0) {
413 printk("%s_tables: %s target: bad hook_mask %u\n", 413 printk("%s_tables: %s target: bad hook_mask %u/%u\n",
414 xt_prefix[family], target->name, hook_mask); 414 xt_prefix[family], target->name, hook_mask,
415 target->hooks);
415 return -EINVAL; 416 return -EINVAL;
416 } 417 }
417 if (target->proto && (target->proto != proto || inv_proto)) { 418 if (target->proto && (target->proto != proto || inv_proto)) {
@@ -744,7 +745,7 @@ static int xt_name_seq_show(struct seq_file *seq, void *v)
744 return 0; 745 return 0;
745} 746}
746 747
747static struct seq_operations xt_tgt_seq_ops = { 748static const struct seq_operations xt_tgt_seq_ops = {
748 .start = xt_tgt_seq_start, 749 .start = xt_tgt_seq_start,
749 .next = xt_tgt_seq_next, 750 .next = xt_tgt_seq_next,
750 .stop = xt_tgt_seq_stop, 751 .stop = xt_tgt_seq_stop,
diff --git a/net/netfilter/xt_CLASSIFY.c b/net/netfilter/xt_CLASSIFY.c
index 30884833e665..519428566829 100644
--- a/net/netfilter/xt_CLASSIFY.c
+++ b/net/netfilter/xt_CLASSIFY.c
@@ -39,7 +39,7 @@ target(struct sk_buff **pskb,
39 return XT_CONTINUE; 39 return XT_CONTINUE;
40} 40}
41 41
42static struct xt_target xt_classify_target[] = { 42static struct xt_target xt_classify_target[] __read_mostly = {
43 { 43 {
44 .family = AF_INET, 44 .family = AF_INET,
45 .name = "CLASSIFY", 45 .name = "CLASSIFY",
diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c
index b03ce009d0bf..5a00c5444334 100644
--- a/net/netfilter/xt_CONNMARK.c
+++ b/net/netfilter/xt_CONNMARK.c
@@ -76,33 +76,33 @@ target(struct sk_buff **pskb,
76 return XT_CONTINUE; 76 return XT_CONTINUE;
77} 77}
78 78
79static int 79static bool
80checkentry(const char *tablename, 80checkentry(const char *tablename,
81 const void *entry, 81 const void *entry,
82 const struct xt_target *target, 82 const struct xt_target *target,
83 void *targinfo, 83 void *targinfo,
84 unsigned int hook_mask) 84 unsigned int hook_mask)
85{ 85{
86 struct xt_connmark_target_info *matchinfo = targinfo; 86 const struct xt_connmark_target_info *matchinfo = targinfo;
87 87
88 if (nf_ct_l3proto_try_module_get(target->family) < 0) { 88 if (nf_ct_l3proto_try_module_get(target->family) < 0) {
89 printk(KERN_WARNING "can't load conntrack support for " 89 printk(KERN_WARNING "can't load conntrack support for "
90 "proto=%d\n", target->family); 90 "proto=%d\n", target->family);
91 return 0; 91 return false;
92 } 92 }
93 if (matchinfo->mode == XT_CONNMARK_RESTORE) { 93 if (matchinfo->mode == XT_CONNMARK_RESTORE) {
94 if (strcmp(tablename, "mangle") != 0) { 94 if (strcmp(tablename, "mangle") != 0) {
95 printk(KERN_WARNING "CONNMARK: restore can only be " 95 printk(KERN_WARNING "CONNMARK: restore can only be "
96 "called from \"mangle\" table, not \"%s\"\n", 96 "called from \"mangle\" table, not \"%s\"\n",
97 tablename); 97 tablename);
98 return 0; 98 return false;
99 } 99 }
100 } 100 }
101 if (matchinfo->mark > 0xffffffff || matchinfo->mask > 0xffffffff) { 101 if (matchinfo->mark > 0xffffffff || matchinfo->mask > 0xffffffff) {
102 printk(KERN_WARNING "CONNMARK: Only supports 32bit mark\n"); 102 printk(KERN_WARNING "CONNMARK: Only supports 32bit mark\n");
103 return 0; 103 return false;
104 } 104 }
105 return 1; 105 return true;
106} 106}
107 107
108static void 108static void
@@ -121,7 +121,7 @@ struct compat_xt_connmark_target_info {
121 121
122static void compat_from_user(void *dst, void *src) 122static void compat_from_user(void *dst, void *src)
123{ 123{
124 struct compat_xt_connmark_target_info *cm = src; 124 const struct compat_xt_connmark_target_info *cm = src;
125 struct xt_connmark_target_info m = { 125 struct xt_connmark_target_info m = {
126 .mark = cm->mark, 126 .mark = cm->mark,
127 .mask = cm->mask, 127 .mask = cm->mask,
@@ -132,7 +132,7 @@ static void compat_from_user(void *dst, void *src)
132 132
133static int compat_to_user(void __user *dst, void *src) 133static int compat_to_user(void __user *dst, void *src)
134{ 134{
135 struct xt_connmark_target_info *m = src; 135 const struct xt_connmark_target_info *m = src;
136 struct compat_xt_connmark_target_info cm = { 136 struct compat_xt_connmark_target_info cm = {
137 .mark = m->mark, 137 .mark = m->mark,
138 .mask = m->mask, 138 .mask = m->mask,
@@ -142,7 +142,7 @@ static int compat_to_user(void __user *dst, void *src)
142} 142}
143#endif /* CONFIG_COMPAT */ 143#endif /* CONFIG_COMPAT */
144 144
145static struct xt_target xt_connmark_target[] = { 145static struct xt_target xt_connmark_target[] __read_mostly = {
146 { 146 {
147 .name = "CONNMARK", 147 .name = "CONNMARK",
148 .family = AF_INET, 148 .family = AF_INET,
diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c
index 81c0c58bab47..63d73138c1b9 100644
--- a/net/netfilter/xt_CONNSECMARK.c
+++ b/net/netfilter/xt_CONNSECMARK.c
@@ -33,7 +33,7 @@ MODULE_ALIAS("ip6t_CONNSECMARK");
33 * If the packet has a security mark and the connection does not, copy 33 * If the packet has a security mark and the connection does not, copy
34 * the security mark from the packet to the connection. 34 * the security mark from the packet to the connection.
35 */ 35 */
36static void secmark_save(struct sk_buff *skb) 36static void secmark_save(const struct sk_buff *skb)
37{ 37{
38 if (skb->secmark) { 38 if (skb->secmark) {
39 struct nf_conn *ct; 39 struct nf_conn *ct;
@@ -85,16 +85,16 @@ static unsigned int target(struct sk_buff **pskb, const struct net_device *in,
85 return XT_CONTINUE; 85 return XT_CONTINUE;
86} 86}
87 87
88static int checkentry(const char *tablename, const void *entry, 88static bool checkentry(const char *tablename, const void *entry,
89 const struct xt_target *target, void *targinfo, 89 const struct xt_target *target, void *targinfo,
90 unsigned int hook_mask) 90 unsigned int hook_mask)
91{ 91{
92 struct xt_connsecmark_target_info *info = targinfo; 92 const struct xt_connsecmark_target_info *info = targinfo;
93 93
94 if (nf_ct_l3proto_try_module_get(target->family) < 0) { 94 if (nf_ct_l3proto_try_module_get(target->family) < 0) {
95 printk(KERN_WARNING "can't load conntrack support for " 95 printk(KERN_WARNING "can't load conntrack support for "
96 "proto=%d\n", target->family); 96 "proto=%d\n", target->family);
97 return 0; 97 return false;
98 } 98 }
99 switch (info->mode) { 99 switch (info->mode) {
100 case CONNSECMARK_SAVE: 100 case CONNSECMARK_SAVE:
@@ -103,10 +103,10 @@ static int checkentry(const char *tablename, const void *entry,
103 103
104 default: 104 default:
105 printk(KERN_INFO PFX "invalid mode: %hu\n", info->mode); 105 printk(KERN_INFO PFX "invalid mode: %hu\n", info->mode);
106 return 0; 106 return false;
107 } 107 }
108 108
109 return 1; 109 return true;
110} 110}
111 111
112static void 112static void
@@ -115,7 +115,7 @@ destroy(const struct xt_target *target, void *targinfo)
115 nf_ct_l3proto_module_put(target->family); 115 nf_ct_l3proto_module_put(target->family);
116} 116}
117 117
118static struct xt_target xt_connsecmark_target[] = { 118static struct xt_target xt_connsecmark_target[] __read_mostly = {
119 { 119 {
120 .name = "CONNSECMARK", 120 .name = "CONNSECMARK",
121 .family = AF_INET, 121 .family = AF_INET,
diff --git a/net/netfilter/xt_DSCP.c b/net/netfilter/xt_DSCP.c
index 9f2f2201f6ae..798ab731009d 100644
--- a/net/netfilter/xt_DSCP.c
+++ b/net/netfilter/xt_DSCP.c
@@ -66,22 +66,22 @@ static unsigned int target6(struct sk_buff **pskb,
66 return XT_CONTINUE; 66 return XT_CONTINUE;
67} 67}
68 68
69static int checkentry(const char *tablename, 69static bool checkentry(const char *tablename,
70 const void *e_void, 70 const void *e_void,
71 const struct xt_target *target, 71 const struct xt_target *target,
72 void *targinfo, 72 void *targinfo,
73 unsigned int hook_mask) 73 unsigned int hook_mask)
74{ 74{
75 const u_int8_t dscp = ((struct xt_DSCP_info *)targinfo)->dscp; 75 const u_int8_t dscp = ((struct xt_DSCP_info *)targinfo)->dscp;
76 76
77 if ((dscp > XT_DSCP_MAX)) { 77 if (dscp > XT_DSCP_MAX) {
78 printk(KERN_WARNING "DSCP: dscp %x out of range\n", dscp); 78 printk(KERN_WARNING "DSCP: dscp %x out of range\n", dscp);
79 return 0; 79 return false;
80 } 80 }
81 return 1; 81 return true;
82} 82}
83 83
84static struct xt_target xt_dscp_target[] = { 84static struct xt_target xt_dscp_target[] __read_mostly = {
85 { 85 {
86 .name = "DSCP", 86 .name = "DSCP",
87 .family = AF_INET, 87 .family = AF_INET,
diff --git a/net/netfilter/xt_MARK.c b/net/netfilter/xt_MARK.c
index 43817808d865..f30fe0baf7de 100644
--- a/net/netfilter/xt_MARK.c
+++ b/net/netfilter/xt_MARK.c
@@ -65,43 +65,43 @@ target_v1(struct sk_buff **pskb,
65} 65}
66 66
67 67
68static int 68static bool
69checkentry_v0(const char *tablename, 69checkentry_v0(const char *tablename,
70 const void *entry, 70 const void *entry,
71 const struct xt_target *target, 71 const struct xt_target *target,
72 void *targinfo, 72 void *targinfo,
73 unsigned int hook_mask) 73 unsigned int hook_mask)
74{ 74{
75 struct xt_mark_target_info *markinfo = targinfo; 75 const struct xt_mark_target_info *markinfo = targinfo;
76 76
77 if (markinfo->mark > 0xffffffff) { 77 if (markinfo->mark > 0xffffffff) {
78 printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n"); 78 printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n");
79 return 0; 79 return false;
80 } 80 }
81 return 1; 81 return true;
82} 82}
83 83
84static int 84static bool
85checkentry_v1(const char *tablename, 85checkentry_v1(const char *tablename,
86 const void *entry, 86 const void *entry,
87 const struct xt_target *target, 87 const struct xt_target *target,
88 void *targinfo, 88 void *targinfo,
89 unsigned int hook_mask) 89 unsigned int hook_mask)
90{ 90{
91 struct xt_mark_target_info_v1 *markinfo = targinfo; 91 const struct xt_mark_target_info_v1 *markinfo = targinfo;
92 92
93 if (markinfo->mode != XT_MARK_SET 93 if (markinfo->mode != XT_MARK_SET
94 && markinfo->mode != XT_MARK_AND 94 && markinfo->mode != XT_MARK_AND
95 && markinfo->mode != XT_MARK_OR) { 95 && markinfo->mode != XT_MARK_OR) {
96 printk(KERN_WARNING "MARK: unknown mode %u\n", 96 printk(KERN_WARNING "MARK: unknown mode %u\n",
97 markinfo->mode); 97 markinfo->mode);
98 return 0; 98 return false;
99 } 99 }
100 if (markinfo->mark > 0xffffffff) { 100 if (markinfo->mark > 0xffffffff) {
101 printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n"); 101 printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n");
102 return 0; 102 return false;
103 } 103 }
104 return 1; 104 return true;
105} 105}
106 106
107#ifdef CONFIG_COMPAT 107#ifdef CONFIG_COMPAT
@@ -114,7 +114,7 @@ struct compat_xt_mark_target_info_v1 {
114 114
115static void compat_from_user_v1(void *dst, void *src) 115static void compat_from_user_v1(void *dst, void *src)
116{ 116{
117 struct compat_xt_mark_target_info_v1 *cm = src; 117 const struct compat_xt_mark_target_info_v1 *cm = src;
118 struct xt_mark_target_info_v1 m = { 118 struct xt_mark_target_info_v1 m = {
119 .mark = cm->mark, 119 .mark = cm->mark,
120 .mode = cm->mode, 120 .mode = cm->mode,
@@ -124,7 +124,7 @@ static void compat_from_user_v1(void *dst, void *src)
124 124
125static int compat_to_user_v1(void __user *dst, void *src) 125static int compat_to_user_v1(void __user *dst, void *src)
126{ 126{
127 struct xt_mark_target_info_v1 *m = src; 127 const struct xt_mark_target_info_v1 *m = src;
128 struct compat_xt_mark_target_info_v1 cm = { 128 struct compat_xt_mark_target_info_v1 cm = {
129 .mark = m->mark, 129 .mark = m->mark,
130 .mode = m->mode, 130 .mode = m->mode,
@@ -133,7 +133,7 @@ static int compat_to_user_v1(void __user *dst, void *src)
133} 133}
134#endif /* CONFIG_COMPAT */ 134#endif /* CONFIG_COMPAT */
135 135
136static struct xt_target xt_mark_target[] = { 136static struct xt_target xt_mark_target[] __read_mostly = {
137 { 137 {
138 .name = "MARK", 138 .name = "MARK",
139 .family = AF_INET, 139 .family = AF_INET,
diff --git a/net/netfilter/xt_NFLOG.c b/net/netfilter/xt_NFLOG.c
index 901ed7abaa1b..d3594c7ccb26 100644
--- a/net/netfilter/xt_NFLOG.c
+++ b/net/netfilter/xt_NFLOG.c
@@ -38,21 +38,21 @@ nflog_target(struct sk_buff **pskb,
38 return XT_CONTINUE; 38 return XT_CONTINUE;
39} 39}
40 40
41static int 41static bool
42nflog_checkentry(const char *tablename, const void *entry, 42nflog_checkentry(const char *tablename, const void *entry,
43 const struct xt_target *target, void *targetinfo, 43 const struct xt_target *target, void *targetinfo,
44 unsigned int hookmask) 44 unsigned int hookmask)
45{ 45{
46 struct xt_nflog_info *info = targetinfo; 46 const struct xt_nflog_info *info = targetinfo;
47 47
48 if (info->flags & ~XT_NFLOG_MASK) 48 if (info->flags & ~XT_NFLOG_MASK)
49 return 0; 49 return false;
50 if (info->prefix[sizeof(info->prefix) - 1] != '\0') 50 if (info->prefix[sizeof(info->prefix) - 1] != '\0')
51 return 0; 51 return false;
52 return 1; 52 return true;
53} 53}
54 54
55static struct xt_target xt_nflog_target[] = { 55static struct xt_target xt_nflog_target[] __read_mostly = {
56 { 56 {
57 .name = "NFLOG", 57 .name = "NFLOG",
58 .family = AF_INET, 58 .family = AF_INET,
diff --git a/net/netfilter/xt_NFQUEUE.c b/net/netfilter/xt_NFQUEUE.c
index 201155b316e0..13f59f3e8c38 100644
--- a/net/netfilter/xt_NFQUEUE.c
+++ b/net/netfilter/xt_NFQUEUE.c
@@ -36,7 +36,7 @@ target(struct sk_buff **pskb,
36 return NF_QUEUE_NR(tinfo->queuenum); 36 return NF_QUEUE_NR(tinfo->queuenum);
37} 37}
38 38
39static struct xt_target xt_nfqueue_target[] = { 39static struct xt_target xt_nfqueue_target[] __read_mostly = {
40 { 40 {
41 .name = "NFQUEUE", 41 .name = "NFQUEUE",
42 .family = AF_INET, 42 .family = AF_INET,
diff --git a/net/netfilter/xt_NOTRACK.c b/net/netfilter/xt_NOTRACK.c
index 5085fb3d1e2d..b7d6312fccc7 100644
--- a/net/netfilter/xt_NOTRACK.c
+++ b/net/netfilter/xt_NOTRACK.c
@@ -33,7 +33,7 @@ target(struct sk_buff **pskb,
33 return XT_CONTINUE; 33 return XT_CONTINUE;
34} 34}
35 35
36static struct xt_target xt_notrack_target[] = { 36static struct xt_target xt_notrack_target[] __read_mostly = {
37 { 37 {
38 .name = "NOTRACK", 38 .name = "NOTRACK",
39 .family = AF_INET, 39 .family = AF_INET,
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
index 705f0e830a79..c83779a941a1 100644
--- a/net/netfilter/xt_SECMARK.c
+++ b/net/netfilter/xt_SECMARK.c
@@ -51,7 +51,7 @@ static unsigned int target(struct sk_buff **pskb, const struct net_device *in,
51 return XT_CONTINUE; 51 return XT_CONTINUE;
52} 52}
53 53
54static int checkentry_selinux(struct xt_secmark_target_info *info) 54static bool checkentry_selinux(struct xt_secmark_target_info *info)
55{ 55{
56 int err; 56 int err;
57 struct xt_secmark_target_selinux_info *sel = &info->u.sel; 57 struct xt_secmark_target_selinux_info *sel = &info->u.sel;
@@ -63,53 +63,53 @@ static int checkentry_selinux(struct xt_secmark_target_info *info)
63 if (err == -EINVAL) 63 if (err == -EINVAL)
64 printk(KERN_INFO PFX "invalid SELinux context \'%s\'\n", 64 printk(KERN_INFO PFX "invalid SELinux context \'%s\'\n",
65 sel->selctx); 65 sel->selctx);
66 return 0; 66 return false;
67 } 67 }
68 68
69 if (!sel->selsid) { 69 if (!sel->selsid) {
70 printk(KERN_INFO PFX "unable to map SELinux context \'%s\'\n", 70 printk(KERN_INFO PFX "unable to map SELinux context \'%s\'\n",
71 sel->selctx); 71 sel->selctx);
72 return 0; 72 return false;
73 } 73 }
74 74
75 err = selinux_relabel_packet_permission(sel->selsid); 75 err = selinux_relabel_packet_permission(sel->selsid);
76 if (err) { 76 if (err) {
77 printk(KERN_INFO PFX "unable to obtain relabeling permission\n"); 77 printk(KERN_INFO PFX "unable to obtain relabeling permission\n");
78 return 0; 78 return false;
79 } 79 }
80 80
81 return 1; 81 return true;
82} 82}
83 83
84static int checkentry(const char *tablename, const void *entry, 84static bool checkentry(const char *tablename, const void *entry,
85 const struct xt_target *target, void *targinfo, 85 const struct xt_target *target, void *targinfo,
86 unsigned int hook_mask) 86 unsigned int hook_mask)
87{ 87{
88 struct xt_secmark_target_info *info = targinfo; 88 struct xt_secmark_target_info *info = targinfo;
89 89
90 if (mode && mode != info->mode) { 90 if (mode && mode != info->mode) {
91 printk(KERN_INFO PFX "mode already set to %hu cannot mix with " 91 printk(KERN_INFO PFX "mode already set to %hu cannot mix with "
92 "rules for mode %hu\n", mode, info->mode); 92 "rules for mode %hu\n", mode, info->mode);
93 return 0; 93 return false;
94 } 94 }
95 95
96 switch (info->mode) { 96 switch (info->mode) {
97 case SECMARK_MODE_SEL: 97 case SECMARK_MODE_SEL:
98 if (!checkentry_selinux(info)) 98 if (!checkentry_selinux(info))
99 return 0; 99 return false;
100 break; 100 break;
101 101
102 default: 102 default:
103 printk(KERN_INFO PFX "invalid mode: %hu\n", info->mode); 103 printk(KERN_INFO PFX "invalid mode: %hu\n", info->mode);
104 return 0; 104 return false;
105 } 105 }
106 106
107 if (!mode) 107 if (!mode)
108 mode = info->mode; 108 mode = info->mode;
109 return 1; 109 return true;
110} 110}
111 111
112static struct xt_target xt_secmark_target[] = { 112static struct xt_target xt_secmark_target[] __read_mostly = {
113 { 113 {
114 .name = "SECMARK", 114 .name = "SECMARK",
115 .family = AF_INET, 115 .family = AF_INET,
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c
index 15fe8f649510..d40f7e4b1289 100644
--- a/net/netfilter/xt_TCPMSS.c
+++ b/net/netfilter/xt_TCPMSS.c
@@ -93,7 +93,7 @@ tcpmss_mangle_packet(struct sk_buff **pskb,
93 return 0; 93 return 0;
94 94
95 opt[i+2] = (newmss & 0xff00) >> 8; 95 opt[i+2] = (newmss & 0xff00) >> 8;
96 opt[i+3] = (newmss & 0x00ff); 96 opt[i+3] = newmss & 0x00ff;
97 97
98 nf_proto_csum_replace2(&tcph->check, *pskb, 98 nf_proto_csum_replace2(&tcph->check, *pskb,
99 htons(oldmss), htons(newmss), 0); 99 htons(oldmss), htons(newmss), 0);
@@ -126,7 +126,7 @@ tcpmss_mangle_packet(struct sk_buff **pskb,
126 opt[0] = TCPOPT_MSS; 126 opt[0] = TCPOPT_MSS;
127 opt[1] = TCPOLEN_MSS; 127 opt[1] = TCPOLEN_MSS;
128 opt[2] = (newmss & 0xff00) >> 8; 128 opt[2] = (newmss & 0xff00) >> 8;
129 opt[3] = (newmss & 0x00ff); 129 opt[3] = newmss & 0x00ff;
130 130
131 nf_proto_csum_replace4(&tcph->check, *pskb, 0, *((__be32 *)opt), 0); 131 nf_proto_csum_replace4(&tcph->check, *pskb, 0, *((__be32 *)opt), 0);
132 132
@@ -197,19 +197,19 @@ xt_tcpmss_target6(struct sk_buff **pskb,
197#define TH_SYN 0x02 197#define TH_SYN 0x02
198 198
199/* Must specify -p tcp --syn */ 199/* Must specify -p tcp --syn */
200static inline int find_syn_match(const struct xt_entry_match *m) 200static inline bool find_syn_match(const struct xt_entry_match *m)
201{ 201{
202 const struct xt_tcp *tcpinfo = (const struct xt_tcp *)m->data; 202 const struct xt_tcp *tcpinfo = (const struct xt_tcp *)m->data;
203 203
204 if (strcmp(m->u.kernel.match->name, "tcp") == 0 && 204 if (strcmp(m->u.kernel.match->name, "tcp") == 0 &&
205 tcpinfo->flg_cmp & TH_SYN && 205 tcpinfo->flg_cmp & TH_SYN &&
206 !(tcpinfo->invflags & XT_TCP_INV_FLAGS)) 206 !(tcpinfo->invflags & XT_TCP_INV_FLAGS))
207 return 1; 207 return true;
208 208
209 return 0; 209 return false;
210} 210}
211 211
212static int 212static bool
213xt_tcpmss_checkentry4(const char *tablename, 213xt_tcpmss_checkentry4(const char *tablename,
214 const void *entry, 214 const void *entry,
215 const struct xt_target *target, 215 const struct xt_target *target,
@@ -225,16 +225,16 @@ xt_tcpmss_checkentry4(const char *tablename,
225 (1 << NF_IP_POST_ROUTING))) != 0) { 225 (1 << NF_IP_POST_ROUTING))) != 0) {
226 printk("xt_TCPMSS: path-MTU clamping only supported in " 226 printk("xt_TCPMSS: path-MTU clamping only supported in "
227 "FORWARD, OUTPUT and POSTROUTING hooks\n"); 227 "FORWARD, OUTPUT and POSTROUTING hooks\n");
228 return 0; 228 return false;
229 } 229 }
230 if (IPT_MATCH_ITERATE(e, find_syn_match)) 230 if (IPT_MATCH_ITERATE(e, find_syn_match))
231 return 1; 231 return true;
232 printk("xt_TCPMSS: Only works on TCP SYN packets\n"); 232 printk("xt_TCPMSS: Only works on TCP SYN packets\n");
233 return 0; 233 return false;
234} 234}
235 235
236#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) 236#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
237static int 237static bool
238xt_tcpmss_checkentry6(const char *tablename, 238xt_tcpmss_checkentry6(const char *tablename,
239 const void *entry, 239 const void *entry,
240 const struct xt_target *target, 240 const struct xt_target *target,
@@ -250,16 +250,16 @@ xt_tcpmss_checkentry6(const char *tablename,
250 (1 << NF_IP6_POST_ROUTING))) != 0) { 250 (1 << NF_IP6_POST_ROUTING))) != 0) {
251 printk("xt_TCPMSS: path-MTU clamping only supported in " 251 printk("xt_TCPMSS: path-MTU clamping only supported in "
252 "FORWARD, OUTPUT and POSTROUTING hooks\n"); 252 "FORWARD, OUTPUT and POSTROUTING hooks\n");
253 return 0; 253 return false;
254 } 254 }
255 if (IP6T_MATCH_ITERATE(e, find_syn_match)) 255 if (IP6T_MATCH_ITERATE(e, find_syn_match))
256 return 1; 256 return true;
257 printk("xt_TCPMSS: Only works on TCP SYN packets\n"); 257 printk("xt_TCPMSS: Only works on TCP SYN packets\n");
258 return 0; 258 return false;
259} 259}
260#endif 260#endif
261 261
262static struct xt_target xt_tcpmss_reg[] = { 262static struct xt_target xt_tcpmss_reg[] __read_mostly = {
263 { 263 {
264 .family = AF_INET, 264 .family = AF_INET,
265 .name = "TCPMSS", 265 .name = "TCPMSS",
diff --git a/net/netfilter/xt_TRACE.c b/net/netfilter/xt_TRACE.c
new file mode 100644
index 000000000000..4df2dedcc0b5
--- /dev/null
+++ b/net/netfilter/xt_TRACE.c
@@ -0,0 +1,53 @@
1/* This is a module which is used to mark packets for tracing.
2 */
3#include <linux/module.h>
4#include <linux/skbuff.h>
5
6#include <linux/netfilter/x_tables.h>
7
8MODULE_LICENSE("GPL");
9MODULE_ALIAS("ipt_TRACE");
10MODULE_ALIAS("ip6t_TRACE");
11
12static unsigned int
13target(struct sk_buff **pskb,
14 const struct net_device *in,
15 const struct net_device *out,
16 unsigned int hooknum,
17 const struct xt_target *target,
18 const void *targinfo)
19{
20 (*pskb)->nf_trace = 1;
21 return XT_CONTINUE;
22}
23
24static struct xt_target xt_trace_target[] __read_mostly = {
25 {
26 .name = "TRACE",
27 .family = AF_INET,
28 .target = target,
29 .table = "raw",
30 .me = THIS_MODULE,
31 },
32 {
33 .name = "TRACE",
34 .family = AF_INET6,
35 .target = target,
36 .table = "raw",
37 .me = THIS_MODULE,
38 },
39};
40
41static int __init xt_trace_init(void)
42{
43 return xt_register_targets(xt_trace_target,
44 ARRAY_SIZE(xt_trace_target));
45}
46
47static void __exit xt_trace_fini(void)
48{
49 xt_unregister_targets(xt_trace_target, ARRAY_SIZE(xt_trace_target));
50}
51
52module_init(xt_trace_init);
53module_exit(xt_trace_fini);
diff --git a/net/netfilter/xt_comment.c b/net/netfilter/xt_comment.c
index 7db492d65220..64bcdb0fe1e6 100644
--- a/net/netfilter/xt_comment.c
+++ b/net/netfilter/xt_comment.c
@@ -15,7 +15,7 @@ MODULE_LICENSE("GPL");
15MODULE_ALIAS("ipt_comment"); 15MODULE_ALIAS("ipt_comment");
16MODULE_ALIAS("ip6t_comment"); 16MODULE_ALIAS("ip6t_comment");
17 17
18static int 18static bool
19match(const struct sk_buff *skb, 19match(const struct sk_buff *skb,
20 const struct net_device *in, 20 const struct net_device *in,
21 const struct net_device *out, 21 const struct net_device *out,
@@ -23,13 +23,13 @@ match(const struct sk_buff *skb,
23 const void *matchinfo, 23 const void *matchinfo,
24 int offset, 24 int offset,
25 unsigned int protooff, 25 unsigned int protooff,
26 int *hotdrop) 26 bool *hotdrop)
27{ 27{
28 /* We always match */ 28 /* We always match */
29 return 1; 29 return true;
30} 30}
31 31
32static struct xt_match xt_comment_match[] = { 32static struct xt_match xt_comment_match[] __read_mostly = {
33 { 33 {
34 .name = "comment", 34 .name = "comment",
35 .family = AF_INET, 35 .family = AF_INET,
diff --git a/net/netfilter/xt_connbytes.c b/net/netfilter/xt_connbytes.c
index 804afe55e141..dd4d79b8fc9d 100644
--- a/net/netfilter/xt_connbytes.c
+++ b/net/netfilter/xt_connbytes.c
@@ -15,7 +15,7 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
15MODULE_DESCRIPTION("iptables match for matching number of pkts/bytes per connection"); 15MODULE_DESCRIPTION("iptables match for matching number of pkts/bytes per connection");
16MODULE_ALIAS("ipt_connbytes"); 16MODULE_ALIAS("ipt_connbytes");
17 17
18static int 18static bool
19match(const struct sk_buff *skb, 19match(const struct sk_buff *skb,
20 const struct net_device *in, 20 const struct net_device *in,
21 const struct net_device *out, 21 const struct net_device *out,
@@ -23,10 +23,10 @@ match(const struct sk_buff *skb,
23 const void *matchinfo, 23 const void *matchinfo,
24 int offset, 24 int offset,
25 unsigned int protoff, 25 unsigned int protoff,
26 int *hotdrop) 26 bool *hotdrop)
27{ 27{
28 const struct xt_connbytes_info *sinfo = matchinfo; 28 const struct xt_connbytes_info *sinfo = matchinfo;
29 struct nf_conn *ct; 29 const struct nf_conn *ct;
30 enum ip_conntrack_info ctinfo; 30 enum ip_conntrack_info ctinfo;
31 u_int64_t what = 0; /* initialize to make gcc happy */ 31 u_int64_t what = 0; /* initialize to make gcc happy */
32 u_int64_t bytes = 0; 32 u_int64_t bytes = 0;
@@ -35,7 +35,7 @@ match(const struct sk_buff *skb,
35 35
36 ct = nf_ct_get(skb, &ctinfo); 36 ct = nf_ct_get(skb, &ctinfo);
37 if (!ct) 37 if (!ct)
38 return 0; 38 return false;
39 counters = ct->counters; 39 counters = ct->counters;
40 40
41 switch (sinfo->what) { 41 switch (sinfo->what) {
@@ -90,36 +90,36 @@ match(const struct sk_buff *skb,
90 } 90 }
91 91
92 if (sinfo->count.to) 92 if (sinfo->count.to)
93 return (what <= sinfo->count.to && what >= sinfo->count.from); 93 return what <= sinfo->count.to && what >= sinfo->count.from;
94 else 94 else
95 return (what >= sinfo->count.from); 95 return what >= sinfo->count.from;
96} 96}
97 97
98static int check(const char *tablename, 98static bool check(const char *tablename,
99 const void *ip, 99 const void *ip,
100 const struct xt_match *match, 100 const struct xt_match *match,
101 void *matchinfo, 101 void *matchinfo,
102 unsigned int hook_mask) 102 unsigned int hook_mask)
103{ 103{
104 const struct xt_connbytes_info *sinfo = matchinfo; 104 const struct xt_connbytes_info *sinfo = matchinfo;
105 105
106 if (sinfo->what != XT_CONNBYTES_PKTS && 106 if (sinfo->what != XT_CONNBYTES_PKTS &&
107 sinfo->what != XT_CONNBYTES_BYTES && 107 sinfo->what != XT_CONNBYTES_BYTES &&
108 sinfo->what != XT_CONNBYTES_AVGPKT) 108 sinfo->what != XT_CONNBYTES_AVGPKT)
109 return 0; 109 return false;
110 110
111 if (sinfo->direction != XT_CONNBYTES_DIR_ORIGINAL && 111 if (sinfo->direction != XT_CONNBYTES_DIR_ORIGINAL &&
112 sinfo->direction != XT_CONNBYTES_DIR_REPLY && 112 sinfo->direction != XT_CONNBYTES_DIR_REPLY &&
113 sinfo->direction != XT_CONNBYTES_DIR_BOTH) 113 sinfo->direction != XT_CONNBYTES_DIR_BOTH)
114 return 0; 114 return false;
115 115
116 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 116 if (nf_ct_l3proto_try_module_get(match->family) < 0) {
117 printk(KERN_WARNING "can't load conntrack support for " 117 printk(KERN_WARNING "can't load conntrack support for "
118 "proto=%d\n", match->family); 118 "proto=%d\n", match->family);
119 return 0; 119 return false;
120 } 120 }
121 121
122 return 1; 122 return true;
123} 123}
124 124
125static void 125static void
@@ -128,7 +128,7 @@ destroy(const struct xt_match *match, void *matchinfo)
128 nf_ct_l3proto_module_put(match->family); 128 nf_ct_l3proto_module_put(match->family);
129} 129}
130 130
131static struct xt_match xt_connbytes_match[] = { 131static struct xt_match xt_connbytes_match[] __read_mostly = {
132 { 132 {
133 .name = "connbytes", 133 .name = "connbytes",
134 .family = AF_INET, 134 .family = AF_INET,
diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c
index e1803256c792..e73fa9b46cf7 100644
--- a/net/netfilter/xt_connmark.c
+++ b/net/netfilter/xt_connmark.c
@@ -30,7 +30,7 @@ MODULE_DESCRIPTION("IP tables connmark match module");
30MODULE_LICENSE("GPL"); 30MODULE_LICENSE("GPL");
31MODULE_ALIAS("ipt_connmark"); 31MODULE_ALIAS("ipt_connmark");
32 32
33static int 33static bool
34match(const struct sk_buff *skb, 34match(const struct sk_buff *skb,
35 const struct net_device *in, 35 const struct net_device *in,
36 const struct net_device *out, 36 const struct net_device *out,
@@ -38,38 +38,38 @@ match(const struct sk_buff *skb,
38 const void *matchinfo, 38 const void *matchinfo,
39 int offset, 39 int offset,
40 unsigned int protoff, 40 unsigned int protoff,
41 int *hotdrop) 41 bool *hotdrop)
42{ 42{
43 const struct xt_connmark_info *info = matchinfo; 43 const struct xt_connmark_info *info = matchinfo;
44 struct nf_conn *ct; 44 const struct nf_conn *ct;
45 enum ip_conntrack_info ctinfo; 45 enum ip_conntrack_info ctinfo;
46 46
47 ct = nf_ct_get(skb, &ctinfo); 47 ct = nf_ct_get(skb, &ctinfo);
48 if (!ct) 48 if (!ct)
49 return 0; 49 return false;
50 50
51 return (((ct->mark) & info->mask) == info->mark) ^ info->invert; 51 return ((ct->mark & info->mask) == info->mark) ^ info->invert;
52} 52}
53 53
54static int 54static bool
55checkentry(const char *tablename, 55checkentry(const char *tablename,
56 const void *ip, 56 const void *ip,
57 const struct xt_match *match, 57 const struct xt_match *match,
58 void *matchinfo, 58 void *matchinfo,
59 unsigned int hook_mask) 59 unsigned int hook_mask)
60{ 60{
61 struct xt_connmark_info *cm = matchinfo; 61 const struct xt_connmark_info *cm = matchinfo;
62 62
63 if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) { 63 if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) {
64 printk(KERN_WARNING "connmark: only support 32bit mark\n"); 64 printk(KERN_WARNING "connmark: only support 32bit mark\n");
65 return 0; 65 return false;
66 } 66 }
67 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 67 if (nf_ct_l3proto_try_module_get(match->family) < 0) {
68 printk(KERN_WARNING "can't load conntrack support for " 68 printk(KERN_WARNING "can't load conntrack support for "
69 "proto=%d\n", match->family); 69 "proto=%d\n", match->family);
70 return 0; 70 return false;
71 } 71 }
72 return 1; 72 return true;
73} 73}
74 74
75static void 75static void
@@ -88,7 +88,7 @@ struct compat_xt_connmark_info {
88 88
89static void compat_from_user(void *dst, void *src) 89static void compat_from_user(void *dst, void *src)
90{ 90{
91 struct compat_xt_connmark_info *cm = src; 91 const struct compat_xt_connmark_info *cm = src;
92 struct xt_connmark_info m = { 92 struct xt_connmark_info m = {
93 .mark = cm->mark, 93 .mark = cm->mark,
94 .mask = cm->mask, 94 .mask = cm->mask,
@@ -99,7 +99,7 @@ static void compat_from_user(void *dst, void *src)
99 99
100static int compat_to_user(void __user *dst, void *src) 100static int compat_to_user(void __user *dst, void *src)
101{ 101{
102 struct xt_connmark_info *m = src; 102 const struct xt_connmark_info *m = src;
103 struct compat_xt_connmark_info cm = { 103 struct compat_xt_connmark_info cm = {
104 .mark = m->mark, 104 .mark = m->mark,
105 .mask = m->mask, 105 .mask = m->mask,
@@ -109,7 +109,7 @@ static int compat_to_user(void __user *dst, void *src)
109} 109}
110#endif /* CONFIG_COMPAT */ 110#endif /* CONFIG_COMPAT */
111 111
112static struct xt_match xt_connmark_match[] = { 112static struct xt_match xt_connmark_match[] __read_mostly = {
113 { 113 {
114 .name = "connmark", 114 .name = "connmark",
115 .family = AF_INET, 115 .family = AF_INET,
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index 189ded5f378b..ca4b69f020a8 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -19,7 +19,7 @@ MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
19MODULE_DESCRIPTION("iptables connection tracking match module"); 19MODULE_DESCRIPTION("iptables connection tracking match module");
20MODULE_ALIAS("ipt_conntrack"); 20MODULE_ALIAS("ipt_conntrack");
21 21
22static int 22static bool
23match(const struct sk_buff *skb, 23match(const struct sk_buff *skb,
24 const struct net_device *in, 24 const struct net_device *in,
25 const struct net_device *out, 25 const struct net_device *out,
@@ -27,14 +27,14 @@ match(const struct sk_buff *skb,
27 const void *matchinfo, 27 const void *matchinfo,
28 int offset, 28 int offset,
29 unsigned int protoff, 29 unsigned int protoff,
30 int *hotdrop) 30 bool *hotdrop)
31{ 31{
32 const struct xt_conntrack_info *sinfo = matchinfo; 32 const struct xt_conntrack_info *sinfo = matchinfo;
33 struct nf_conn *ct; 33 const struct nf_conn *ct;
34 enum ip_conntrack_info ctinfo; 34 enum ip_conntrack_info ctinfo;
35 unsigned int statebit; 35 unsigned int statebit;
36 36
37 ct = nf_ct_get((struct sk_buff *)skb, &ctinfo); 37 ct = nf_ct_get(skb, &ctinfo);
38 38
39#define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg)) 39#define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg))
40 40
@@ -54,53 +54,53 @@ match(const struct sk_buff *skb,
54 } 54 }
55 if (FWINV((statebit & sinfo->statemask) == 0, 55 if (FWINV((statebit & sinfo->statemask) == 0,
56 XT_CONNTRACK_STATE)) 56 XT_CONNTRACK_STATE))
57 return 0; 57 return false;
58 } 58 }
59 59
60 if (ct == NULL) { 60 if (ct == NULL) {
61 if (sinfo->flags & ~XT_CONNTRACK_STATE) 61 if (sinfo->flags & ~XT_CONNTRACK_STATE)
62 return 0; 62 return false;
63 return 1; 63 return true;
64 } 64 }
65 65
66 if (sinfo->flags & XT_CONNTRACK_PROTO && 66 if (sinfo->flags & XT_CONNTRACK_PROTO &&
67 FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != 67 FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum !=
68 sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, 68 sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum,
69 XT_CONNTRACK_PROTO)) 69 XT_CONNTRACK_PROTO))
70 return 0; 70 return false;
71 71
72 if (sinfo->flags & XT_CONNTRACK_ORIGSRC && 72 if (sinfo->flags & XT_CONNTRACK_ORIGSRC &&
73 FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip & 73 FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip &
74 sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != 74 sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) !=
75 sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, 75 sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip,
76 XT_CONNTRACK_ORIGSRC)) 76 XT_CONNTRACK_ORIGSRC))
77 return 0; 77 return false;
78 78
79 if (sinfo->flags & XT_CONNTRACK_ORIGDST && 79 if (sinfo->flags & XT_CONNTRACK_ORIGDST &&
80 FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip & 80 FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip &
81 sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != 81 sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) !=
82 sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, 82 sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip,
83 XT_CONNTRACK_ORIGDST)) 83 XT_CONNTRACK_ORIGDST))
84 return 0; 84 return false;
85 85
86 if (sinfo->flags & XT_CONNTRACK_REPLSRC && 86 if (sinfo->flags & XT_CONNTRACK_REPLSRC &&
87 FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip & 87 FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip &
88 sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != 88 sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) !=
89 sinfo->tuple[IP_CT_DIR_REPLY].src.ip, 89 sinfo->tuple[IP_CT_DIR_REPLY].src.ip,
90 XT_CONNTRACK_REPLSRC)) 90 XT_CONNTRACK_REPLSRC))
91 return 0; 91 return false;
92 92
93 if (sinfo->flags & XT_CONNTRACK_REPLDST && 93 if (sinfo->flags & XT_CONNTRACK_REPLDST &&
94 FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip & 94 FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip &
95 sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != 95 sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) !=
96 sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, 96 sinfo->tuple[IP_CT_DIR_REPLY].dst.ip,
97 XT_CONNTRACK_REPLDST)) 97 XT_CONNTRACK_REPLDST))
98 return 0; 98 return false;
99 99
100 if (sinfo->flags & XT_CONNTRACK_STATUS && 100 if (sinfo->flags & XT_CONNTRACK_STATUS &&
101 FWINV((ct->status & sinfo->statusmask) == 0, 101 FWINV((ct->status & sinfo->statusmask) == 0,
102 XT_CONNTRACK_STATUS)) 102 XT_CONNTRACK_STATUS))
103 return 0; 103 return false;
104 104
105 if(sinfo->flags & XT_CONNTRACK_EXPIRES) { 105 if(sinfo->flags & XT_CONNTRACK_EXPIRES) {
106 unsigned long expires = timer_pending(&ct->timeout) ? 106 unsigned long expires = timer_pending(&ct->timeout) ?
@@ -109,12 +109,12 @@ match(const struct sk_buff *skb,
109 if (FWINV(!(expires >= sinfo->expires_min && 109 if (FWINV(!(expires >= sinfo->expires_min &&
110 expires <= sinfo->expires_max), 110 expires <= sinfo->expires_max),
111 XT_CONNTRACK_EXPIRES)) 111 XT_CONNTRACK_EXPIRES))
112 return 0; 112 return false;
113 } 113 }
114 return 1; 114 return true;
115} 115}
116 116
117static int 117static bool
118checkentry(const char *tablename, 118checkentry(const char *tablename,
119 const void *ip, 119 const void *ip,
120 const struct xt_match *match, 120 const struct xt_match *match,
@@ -124,9 +124,9 @@ checkentry(const char *tablename,
124 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 124 if (nf_ct_l3proto_try_module_get(match->family) < 0) {
125 printk(KERN_WARNING "can't load conntrack support for " 125 printk(KERN_WARNING "can't load conntrack support for "
126 "proto=%d\n", match->family); 126 "proto=%d\n", match->family);
127 return 0; 127 return false;
128 } 128 }
129 return 1; 129 return true;
130} 130}
131 131
132static void destroy(const struct xt_match *match, void *matchinfo) 132static void destroy(const struct xt_match *match, void *matchinfo)
@@ -150,7 +150,7 @@ struct compat_xt_conntrack_info
150 150
151static void compat_from_user(void *dst, void *src) 151static void compat_from_user(void *dst, void *src)
152{ 152{
153 struct compat_xt_conntrack_info *cm = src; 153 const struct compat_xt_conntrack_info *cm = src;
154 struct xt_conntrack_info m = { 154 struct xt_conntrack_info m = {
155 .statemask = cm->statemask, 155 .statemask = cm->statemask,
156 .statusmask = cm->statusmask, 156 .statusmask = cm->statusmask,
@@ -167,7 +167,7 @@ static void compat_from_user(void *dst, void *src)
167 167
168static int compat_to_user(void __user *dst, void *src) 168static int compat_to_user(void __user *dst, void *src)
169{ 169{
170 struct xt_conntrack_info *m = src; 170 const struct xt_conntrack_info *m = src;
171 struct compat_xt_conntrack_info cm = { 171 struct compat_xt_conntrack_info cm = {
172 .statemask = m->statemask, 172 .statemask = m->statemask,
173 .statusmask = m->statusmask, 173 .statusmask = m->statusmask,
@@ -183,7 +183,7 @@ static int compat_to_user(void __user *dst, void *src)
183} 183}
184#endif 184#endif
185 185
186static struct xt_match conntrack_match = { 186static struct xt_match conntrack_match __read_mostly = {
187 .name = "conntrack", 187 .name = "conntrack",
188 .match = match, 188 .match = match,
189 .checkentry = checkentry, 189 .checkentry = checkentry,
diff --git a/net/netfilter/xt_dccp.c b/net/netfilter/xt_dccp.c
index 2c9c0dee8aaf..83224ec89cc0 100644
--- a/net/netfilter/xt_dccp.c
+++ b/net/netfilter/xt_dccp.c
@@ -31,40 +31,40 @@ MODULE_ALIAS("ipt_dccp");
31static unsigned char *dccp_optbuf; 31static unsigned char *dccp_optbuf;
32static DEFINE_SPINLOCK(dccp_buflock); 32static DEFINE_SPINLOCK(dccp_buflock);
33 33
34static inline int 34static inline bool
35dccp_find_option(u_int8_t option, 35dccp_find_option(u_int8_t option,
36 const struct sk_buff *skb, 36 const struct sk_buff *skb,
37 unsigned int protoff, 37 unsigned int protoff,
38 const struct dccp_hdr *dh, 38 const struct dccp_hdr *dh,
39 int *hotdrop) 39 bool *hotdrop)
40{ 40{
41 /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ 41 /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */
42 unsigned char *op; 42 const unsigned char *op;
43 unsigned int optoff = __dccp_hdr_len(dh); 43 unsigned int optoff = __dccp_hdr_len(dh);
44 unsigned int optlen = dh->dccph_doff*4 - __dccp_hdr_len(dh); 44 unsigned int optlen = dh->dccph_doff*4 - __dccp_hdr_len(dh);
45 unsigned int i; 45 unsigned int i;
46 46
47 if (dh->dccph_doff * 4 < __dccp_hdr_len(dh)) { 47 if (dh->dccph_doff * 4 < __dccp_hdr_len(dh)) {
48 *hotdrop = 1; 48 *hotdrop = true;
49 return 0; 49 return false;
50 } 50 }
51 51
52 if (!optlen) 52 if (!optlen)
53 return 0; 53 return false;
54 54
55 spin_lock_bh(&dccp_buflock); 55 spin_lock_bh(&dccp_buflock);
56 op = skb_header_pointer(skb, protoff + optoff, optlen, dccp_optbuf); 56 op = skb_header_pointer(skb, protoff + optoff, optlen, dccp_optbuf);
57 if (op == NULL) { 57 if (op == NULL) {
58 /* If we don't have the whole header, drop packet. */ 58 /* If we don't have the whole header, drop packet. */
59 spin_unlock_bh(&dccp_buflock); 59 spin_unlock_bh(&dccp_buflock);
60 *hotdrop = 1; 60 *hotdrop = true;
61 return 0; 61 return false;
62 } 62 }
63 63
64 for (i = 0; i < optlen; ) { 64 for (i = 0; i < optlen; ) {
65 if (op[i] == option) { 65 if (op[i] == option) {
66 spin_unlock_bh(&dccp_buflock); 66 spin_unlock_bh(&dccp_buflock);
67 return 1; 67 return true;
68 } 68 }
69 69
70 if (op[i] < 2) 70 if (op[i] < 2)
@@ -74,24 +74,24 @@ dccp_find_option(u_int8_t option,
74 } 74 }
75 75
76 spin_unlock_bh(&dccp_buflock); 76 spin_unlock_bh(&dccp_buflock);
77 return 0; 77 return false;
78} 78}
79 79
80 80
81static inline int 81static inline bool
82match_types(const struct dccp_hdr *dh, u_int16_t typemask) 82match_types(const struct dccp_hdr *dh, u_int16_t typemask)
83{ 83{
84 return (typemask & (1 << dh->dccph_type)); 84 return typemask & (1 << dh->dccph_type);
85} 85}
86 86
87static inline int 87static inline bool
88match_option(u_int8_t option, const struct sk_buff *skb, unsigned int protoff, 88match_option(u_int8_t option, const struct sk_buff *skb, unsigned int protoff,
89 const struct dccp_hdr *dh, int *hotdrop) 89 const struct dccp_hdr *dh, bool *hotdrop)
90{ 90{
91 return dccp_find_option(option, skb, protoff, dh, hotdrop); 91 return dccp_find_option(option, skb, protoff, dh, hotdrop);
92} 92}
93 93
94static int 94static bool
95match(const struct sk_buff *skb, 95match(const struct sk_buff *skb,
96 const struct net_device *in, 96 const struct net_device *in,
97 const struct net_device *out, 97 const struct net_device *out,
@@ -99,25 +99,25 @@ match(const struct sk_buff *skb,
99 const void *matchinfo, 99 const void *matchinfo,
100 int offset, 100 int offset,
101 unsigned int protoff, 101 unsigned int protoff,
102 int *hotdrop) 102 bool *hotdrop)
103{ 103{
104 const struct xt_dccp_info *info = matchinfo; 104 const struct xt_dccp_info *info = matchinfo;
105 struct dccp_hdr _dh, *dh; 105 struct dccp_hdr _dh, *dh;
106 106
107 if (offset) 107 if (offset)
108 return 0; 108 return false;
109 109
110 dh = skb_header_pointer(skb, protoff, sizeof(_dh), &_dh); 110 dh = skb_header_pointer(skb, protoff, sizeof(_dh), &_dh);
111 if (dh == NULL) { 111 if (dh == NULL) {
112 *hotdrop = 1; 112 *hotdrop = true;
113 return 0; 113 return false;
114 } 114 }
115 115
116 return DCCHECK(((ntohs(dh->dccph_sport) >= info->spts[0]) 116 return DCCHECK(ntohs(dh->dccph_sport) >= info->spts[0]
117 && (ntohs(dh->dccph_sport) <= info->spts[1])), 117 && ntohs(dh->dccph_sport) <= info->spts[1],
118 XT_DCCP_SRC_PORTS, info->flags, info->invflags) 118 XT_DCCP_SRC_PORTS, info->flags, info->invflags)
119 && DCCHECK(((ntohs(dh->dccph_dport) >= info->dpts[0]) 119 && DCCHECK(ntohs(dh->dccph_dport) >= info->dpts[0]
120 && (ntohs(dh->dccph_dport) <= info->dpts[1])), 120 && ntohs(dh->dccph_dport) <= info->dpts[1],
121 XT_DCCP_DEST_PORTS, info->flags, info->invflags) 121 XT_DCCP_DEST_PORTS, info->flags, info->invflags)
122 && DCCHECK(match_types(dh, info->typemask), 122 && DCCHECK(match_types(dh, info->typemask),
123 XT_DCCP_TYPE, info->flags, info->invflags) 123 XT_DCCP_TYPE, info->flags, info->invflags)
@@ -126,7 +126,7 @@ match(const struct sk_buff *skb,
126 XT_DCCP_OPTION, info->flags, info->invflags); 126 XT_DCCP_OPTION, info->flags, info->invflags);
127} 127}
128 128
129static int 129static bool
130checkentry(const char *tablename, 130checkentry(const char *tablename,
131 const void *inf, 131 const void *inf,
132 const struct xt_match *match, 132 const struct xt_match *match,
@@ -140,7 +140,7 @@ checkentry(const char *tablename,
140 && !(info->invflags & ~info->flags); 140 && !(info->invflags & ~info->flags);
141} 141}
142 142
143static struct xt_match xt_dccp_match[] = { 143static struct xt_match xt_dccp_match[] __read_mostly = {
144 { 144 {
145 .name = "dccp", 145 .name = "dccp",
146 .family = AF_INET, 146 .family = AF_INET,
diff --git a/net/netfilter/xt_dscp.c b/net/netfilter/xt_dscp.c
index 56b247ecc283..dde6d66e0d33 100644
--- a/net/netfilter/xt_dscp.c
+++ b/net/netfilter/xt_dscp.c
@@ -22,14 +22,14 @@ MODULE_LICENSE("GPL");
22MODULE_ALIAS("ipt_dscp"); 22MODULE_ALIAS("ipt_dscp");
23MODULE_ALIAS("ip6t_dscp"); 23MODULE_ALIAS("ip6t_dscp");
24 24
25static int match(const struct sk_buff *skb, 25static bool match(const struct sk_buff *skb,
26 const struct net_device *in, 26 const struct net_device *in,
27 const struct net_device *out, 27 const struct net_device *out,
28 const struct xt_match *match, 28 const struct xt_match *match,
29 const void *matchinfo, 29 const void *matchinfo,
30 int offset, 30 int offset,
31 unsigned int protoff, 31 unsigned int protoff,
32 int *hotdrop) 32 bool *hotdrop)
33{ 33{
34 const struct xt_dscp_info *info = matchinfo; 34 const struct xt_dscp_info *info = matchinfo;
35 u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT; 35 u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT;
@@ -37,14 +37,14 @@ static int match(const struct sk_buff *skb,
37 return (dscp == info->dscp) ^ !!info->invert; 37 return (dscp == info->dscp) ^ !!info->invert;
38} 38}
39 39
40static int match6(const struct sk_buff *skb, 40static bool match6(const struct sk_buff *skb,
41 const struct net_device *in, 41 const struct net_device *in,
42 const struct net_device *out, 42 const struct net_device *out,
43 const struct xt_match *match, 43 const struct xt_match *match,
44 const void *matchinfo, 44 const void *matchinfo,
45 int offset, 45 int offset,
46 unsigned int protoff, 46 unsigned int protoff,
47 int *hotdrop) 47 bool *hotdrop)
48{ 48{
49 const struct xt_dscp_info *info = matchinfo; 49 const struct xt_dscp_info *info = matchinfo;
50 u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT; 50 u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT;
@@ -52,23 +52,23 @@ static int match6(const struct sk_buff *skb,
52 return (dscp == info->dscp) ^ !!info->invert; 52 return (dscp == info->dscp) ^ !!info->invert;
53} 53}
54 54
55static int checkentry(const char *tablename, 55static bool checkentry(const char *tablename,
56 const void *info, 56 const void *info,
57 const struct xt_match *match, 57 const struct xt_match *match,
58 void *matchinfo, 58 void *matchinfo,
59 unsigned int hook_mask) 59 unsigned int hook_mask)
60{ 60{
61 const u_int8_t dscp = ((struct xt_dscp_info *)matchinfo)->dscp; 61 const u_int8_t dscp = ((struct xt_dscp_info *)matchinfo)->dscp;
62 62
63 if (dscp > XT_DSCP_MAX) { 63 if (dscp > XT_DSCP_MAX) {
64 printk(KERN_ERR "xt_dscp: dscp %x out of range\n", dscp); 64 printk(KERN_ERR "xt_dscp: dscp %x out of range\n", dscp);
65 return 0; 65 return false;
66 } 66 }
67 67
68 return 1; 68 return true;
69} 69}
70 70
71static struct xt_match xt_dscp_match[] = { 71static struct xt_match xt_dscp_match[] __read_mostly = {
72 { 72 {
73 .name = "dscp", 73 .name = "dscp",
74 .family = AF_INET, 74 .family = AF_INET,
diff --git a/net/netfilter/xt_esp.c b/net/netfilter/xt_esp.c
index 7c95f149d942..b11378e001b6 100644
--- a/net/netfilter/xt_esp.c
+++ b/net/netfilter/xt_esp.c
@@ -31,10 +31,10 @@ MODULE_ALIAS("ip6t_esp");
31#endif 31#endif
32 32
33/* Returns 1 if the spi is matched by the range, 0 otherwise */ 33/* Returns 1 if the spi is matched by the range, 0 otherwise */
34static inline int 34static inline bool
35spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert) 35spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
36{ 36{
37 int r = 0; 37 bool r;
38 duprintf("esp spi_match:%c 0x%x <= 0x%x <= 0x%x", invert ? '!' : ' ', 38 duprintf("esp spi_match:%c 0x%x <= 0x%x <= 0x%x", invert ? '!' : ' ',
39 min, spi, max); 39 min, spi, max);
40 r = (spi >= min && spi <= max) ^ invert; 40 r = (spi >= min && spi <= max) ^ invert;
@@ -42,7 +42,7 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert)
42 return r; 42 return r;
43} 43}
44 44
45static int 45static bool
46match(const struct sk_buff *skb, 46match(const struct sk_buff *skb,
47 const struct net_device *in, 47 const struct net_device *in,
48 const struct net_device *out, 48 const struct net_device *out,
@@ -50,14 +50,14 @@ match(const struct sk_buff *skb,
50 const void *matchinfo, 50 const void *matchinfo,
51 int offset, 51 int offset,
52 unsigned int protoff, 52 unsigned int protoff,
53 int *hotdrop) 53 bool *hotdrop)
54{ 54{
55 struct ip_esp_hdr _esp, *eh; 55 struct ip_esp_hdr _esp, *eh;
56 const struct xt_esp *espinfo = matchinfo; 56 const struct xt_esp *espinfo = matchinfo;
57 57
58 /* Must not be a fragment. */ 58 /* Must not be a fragment. */
59 if (offset) 59 if (offset)
60 return 0; 60 return false;
61 61
62 eh = skb_header_pointer(skb, protoff, sizeof(_esp), &_esp); 62 eh = skb_header_pointer(skb, protoff, sizeof(_esp), &_esp);
63 if (eh == NULL) { 63 if (eh == NULL) {
@@ -65,8 +65,8 @@ match(const struct sk_buff *skb,
65 * can't. Hence, no choice but to drop. 65 * can't. Hence, no choice but to drop.
66 */ 66 */
67 duprintf("Dropping evil ESP tinygram.\n"); 67 duprintf("Dropping evil ESP tinygram.\n");
68 *hotdrop = 1; 68 *hotdrop = true;
69 return 0; 69 return false;
70 } 70 }
71 71
72 return spi_match(espinfo->spis[0], espinfo->spis[1], ntohl(eh->spi), 72 return spi_match(espinfo->spis[0], espinfo->spis[1], ntohl(eh->spi),
@@ -74,7 +74,7 @@ match(const struct sk_buff *skb,
74} 74}
75 75
76/* Called when user tries to insert an entry of this type. */ 76/* Called when user tries to insert an entry of this type. */
77static int 77static bool
78checkentry(const char *tablename, 78checkentry(const char *tablename,
79 const void *ip_void, 79 const void *ip_void,
80 const struct xt_match *match, 80 const struct xt_match *match,
@@ -85,13 +85,13 @@ checkentry(const char *tablename,
85 85
86 if (espinfo->invflags & ~XT_ESP_INV_MASK) { 86 if (espinfo->invflags & ~XT_ESP_INV_MASK) {
87 duprintf("xt_esp: unknown flags %X\n", espinfo->invflags); 87 duprintf("xt_esp: unknown flags %X\n", espinfo->invflags);
88 return 0; 88 return false;
89 } 89 }
90 90
91 return 1; 91 return true;
92} 92}
93 93
94static struct xt_match xt_esp_match[] = { 94static struct xt_match xt_esp_match[] __read_mostly = {
95 { 95 {
96 .name = "esp", 96 .name = "esp",
97 .family = AF_INET, 97 .family = AF_INET,
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index d3043fa32ebc..d6b3d01975b6 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -94,7 +94,8 @@ static DEFINE_MUTEX(hlimit_mutex); /* additional checkentry protection */
94static HLIST_HEAD(hashlimit_htables); 94static HLIST_HEAD(hashlimit_htables);
95static struct kmem_cache *hashlimit_cachep __read_mostly; 95static struct kmem_cache *hashlimit_cachep __read_mostly;
96 96
97static inline int dst_cmp(const struct dsthash_ent *ent, struct dsthash_dst *b) 97static inline bool dst_cmp(const struct dsthash_ent *ent,
98 const struct dsthash_dst *b)
98{ 99{
99 return !memcmp(&ent->dst, b, sizeof(ent->dst)); 100 return !memcmp(&ent->dst, b, sizeof(ent->dst));
100} 101}
@@ -106,7 +107,8 @@ hash_dst(const struct xt_hashlimit_htable *ht, const struct dsthash_dst *dst)
106} 107}
107 108
108static struct dsthash_ent * 109static struct dsthash_ent *
109dsthash_find(const struct xt_hashlimit_htable *ht, struct dsthash_dst *dst) 110dsthash_find(const struct xt_hashlimit_htable *ht,
111 const struct dsthash_dst *dst)
110{ 112{
111 struct dsthash_ent *ent; 113 struct dsthash_ent *ent;
112 struct hlist_node *pos; 114 struct hlist_node *pos;
@@ -122,7 +124,8 @@ dsthash_find(const struct xt_hashlimit_htable *ht, struct dsthash_dst *dst)
122 124
123/* allocate dsthash_ent, initialize dst, put in htable and lock it */ 125/* allocate dsthash_ent, initialize dst, put in htable and lock it */
124static struct dsthash_ent * 126static struct dsthash_ent *
125dsthash_alloc_init(struct xt_hashlimit_htable *ht, struct dsthash_dst *dst) 127dsthash_alloc_init(struct xt_hashlimit_htable *ht,
128 const struct dsthash_dst *dst)
126{ 129{
127 struct dsthash_ent *ent; 130 struct dsthash_ent *ent;
128 131
@@ -227,19 +230,21 @@ static int htable_create(struct xt_hashlimit_info *minfo, int family)
227 return 0; 230 return 0;
228} 231}
229 232
230static int select_all(struct xt_hashlimit_htable *ht, struct dsthash_ent *he) 233static bool select_all(const struct xt_hashlimit_htable *ht,
234 const struct dsthash_ent *he)
231{ 235{
232 return 1; 236 return 1;
233} 237}
234 238
235static int select_gc(struct xt_hashlimit_htable *ht, struct dsthash_ent *he) 239static bool select_gc(const struct xt_hashlimit_htable *ht,
240 const struct dsthash_ent *he)
236{ 241{
237 return (jiffies >= he->expires); 242 return jiffies >= he->expires;
238} 243}
239 244
240static void htable_selective_cleanup(struct xt_hashlimit_htable *ht, 245static void htable_selective_cleanup(struct xt_hashlimit_htable *ht,
241 int (*select)(struct xt_hashlimit_htable *ht, 246 bool (*select)(const struct xt_hashlimit_htable *ht,
242 struct dsthash_ent *he)) 247 const struct dsthash_ent *he))
243{ 248{
244 unsigned int i; 249 unsigned int i;
245 250
@@ -282,7 +287,8 @@ static void htable_destroy(struct xt_hashlimit_htable *hinfo)
282 vfree(hinfo); 287 vfree(hinfo);
283} 288}
284 289
285static struct xt_hashlimit_htable *htable_find_get(char *name, int family) 290static struct xt_hashlimit_htable *htable_find_get(const char *name,
291 int family)
286{ 292{
287 struct xt_hashlimit_htable *hinfo; 293 struct xt_hashlimit_htable *hinfo;
288 struct hlist_node *pos; 294 struct hlist_node *pos;
@@ -367,7 +373,8 @@ static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now)
367} 373}
368 374
369static int 375static int
370hashlimit_init_dst(struct xt_hashlimit_htable *hinfo, struct dsthash_dst *dst, 376hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
377 struct dsthash_dst *dst,
371 const struct sk_buff *skb, unsigned int protoff) 378 const struct sk_buff *skb, unsigned int protoff)
372{ 379{
373 __be16 _ports[2], *ports; 380 __be16 _ports[2], *ports;
@@ -432,7 +439,7 @@ hashlimit_init_dst(struct xt_hashlimit_htable *hinfo, struct dsthash_dst *dst,
432 return 0; 439 return 0;
433} 440}
434 441
435static int 442static bool
436hashlimit_match(const struct sk_buff *skb, 443hashlimit_match(const struct sk_buff *skb,
437 const struct net_device *in, 444 const struct net_device *in,
438 const struct net_device *out, 445 const struct net_device *out,
@@ -440,10 +447,10 @@ hashlimit_match(const struct sk_buff *skb,
440 const void *matchinfo, 447 const void *matchinfo,
441 int offset, 448 int offset,
442 unsigned int protoff, 449 unsigned int protoff,
443 int *hotdrop) 450 bool *hotdrop)
444{ 451{
445 struct xt_hashlimit_info *r = 452 const struct xt_hashlimit_info *r =
446 ((struct xt_hashlimit_info *)matchinfo)->u.master; 453 ((const struct xt_hashlimit_info *)matchinfo)->u.master;
447 struct xt_hashlimit_htable *hinfo = r->hinfo; 454 struct xt_hashlimit_htable *hinfo = r->hinfo;
448 unsigned long now = jiffies; 455 unsigned long now = jiffies;
449 struct dsthash_ent *dh; 456 struct dsthash_ent *dh;
@@ -478,20 +485,20 @@ hashlimit_match(const struct sk_buff *skb,
478 /* We're underlimit. */ 485 /* We're underlimit. */
479 dh->rateinfo.credit -= dh->rateinfo.cost; 486 dh->rateinfo.credit -= dh->rateinfo.cost;
480 spin_unlock_bh(&hinfo->lock); 487 spin_unlock_bh(&hinfo->lock);
481 return 1; 488 return true;
482 } 489 }
483 490
484 spin_unlock_bh(&hinfo->lock); 491 spin_unlock_bh(&hinfo->lock);
485 492
486 /* default case: we're overlimit, thus don't match */ 493 /* default case: we're overlimit, thus don't match */
487 return 0; 494 return false;
488 495
489hotdrop: 496hotdrop:
490 *hotdrop = 1; 497 *hotdrop = true;
491 return 0; 498 return false;
492} 499}
493 500
494static int 501static bool
495hashlimit_checkentry(const char *tablename, 502hashlimit_checkentry(const char *tablename,
496 const void *inf, 503 const void *inf,
497 const struct xt_match *match, 504 const struct xt_match *match,
@@ -505,20 +512,20 @@ hashlimit_checkentry(const char *tablename,
505 user2credits(r->cfg.avg * r->cfg.burst) < user2credits(r->cfg.avg)) { 512 user2credits(r->cfg.avg * r->cfg.burst) < user2credits(r->cfg.avg)) {
506 printk(KERN_ERR "xt_hashlimit: overflow, try lower: %u/%u\n", 513 printk(KERN_ERR "xt_hashlimit: overflow, try lower: %u/%u\n",
507 r->cfg.avg, r->cfg.burst); 514 r->cfg.avg, r->cfg.burst);
508 return 0; 515 return false;
509 } 516 }
510 if (r->cfg.mode == 0 || 517 if (r->cfg.mode == 0 ||
511 r->cfg.mode > (XT_HASHLIMIT_HASH_DPT | 518 r->cfg.mode > (XT_HASHLIMIT_HASH_DPT |
512 XT_HASHLIMIT_HASH_DIP | 519 XT_HASHLIMIT_HASH_DIP |
513 XT_HASHLIMIT_HASH_SIP | 520 XT_HASHLIMIT_HASH_SIP |
514 XT_HASHLIMIT_HASH_SPT)) 521 XT_HASHLIMIT_HASH_SPT))
515 return 0; 522 return false;
516 if (!r->cfg.gc_interval) 523 if (!r->cfg.gc_interval)
517 return 0; 524 return false;
518 if (!r->cfg.expire) 525 if (!r->cfg.expire)
519 return 0; 526 return false;
520 if (r->name[sizeof(r->name) - 1] != '\0') 527 if (r->name[sizeof(r->name) - 1] != '\0')
521 return 0; 528 return false;
522 529
523 /* This is the best we've got: We cannot release and re-grab lock, 530 /* This is the best we've got: We cannot release and re-grab lock,
524 * since checkentry() is called before x_tables.c grabs xt_mutex. 531 * since checkentry() is called before x_tables.c grabs xt_mutex.
@@ -530,19 +537,19 @@ hashlimit_checkentry(const char *tablename,
530 r->hinfo = htable_find_get(r->name, match->family); 537 r->hinfo = htable_find_get(r->name, match->family);
531 if (!r->hinfo && htable_create(r, match->family) != 0) { 538 if (!r->hinfo && htable_create(r, match->family) != 0) {
532 mutex_unlock(&hlimit_mutex); 539 mutex_unlock(&hlimit_mutex);
533 return 0; 540 return false;
534 } 541 }
535 mutex_unlock(&hlimit_mutex); 542 mutex_unlock(&hlimit_mutex);
536 543
537 /* Ugly hack: For SMP, we only want to use one set */ 544 /* Ugly hack: For SMP, we only want to use one set */
538 r->u.master = r; 545 r->u.master = r;
539 return 1; 546 return true;
540} 547}
541 548
542static void 549static void
543hashlimit_destroy(const struct xt_match *match, void *matchinfo) 550hashlimit_destroy(const struct xt_match *match, void *matchinfo)
544{ 551{
545 struct xt_hashlimit_info *r = matchinfo; 552 const struct xt_hashlimit_info *r = matchinfo;
546 553
547 htable_put(r->hinfo); 554 htable_put(r->hinfo);
548} 555}
@@ -571,7 +578,7 @@ static int compat_to_user(void __user *dst, void *src)
571} 578}
572#endif 579#endif
573 580
574static struct xt_match xt_hashlimit[] = { 581static struct xt_match xt_hashlimit[] __read_mostly = {
575 { 582 {
576 .name = "hashlimit", 583 .name = "hashlimit",
577 .family = AF_INET, 584 .family = AF_INET,
@@ -694,7 +701,7 @@ static int dl_seq_show(struct seq_file *s, void *v)
694 return 0; 701 return 0;
695} 702}
696 703
697static struct seq_operations dl_seq_ops = { 704static const struct seq_operations dl_seq_ops = {
698 .start = dl_seq_start, 705 .start = dl_seq_start,
699 .next = dl_seq_next, 706 .next = dl_seq_next,
700 .stop = dl_seq_stop, 707 .stop = dl_seq_stop,
diff --git a/net/netfilter/xt_helper.c b/net/netfilter/xt_helper.c
index c139b2f43a10..0a1f4c6bcdef 100644
--- a/net/netfilter/xt_helper.c
+++ b/net/netfilter/xt_helper.c
@@ -22,13 +22,8 @@ MODULE_DESCRIPTION("iptables helper match module");
22MODULE_ALIAS("ipt_helper"); 22MODULE_ALIAS("ipt_helper");
23MODULE_ALIAS("ip6t_helper"); 23MODULE_ALIAS("ip6t_helper");
24 24
25#if 0
26#define DEBUGP printk
27#else
28#define DEBUGP(format, args...)
29#endif
30 25
31static int 26static bool
32match(const struct sk_buff *skb, 27match(const struct sk_buff *skb,
33 const struct net_device *in, 28 const struct net_device *in,
34 const struct net_device *out, 29 const struct net_device *out,
@@ -36,61 +31,51 @@ match(const struct sk_buff *skb,
36 const void *matchinfo, 31 const void *matchinfo,
37 int offset, 32 int offset,
38 unsigned int protoff, 33 unsigned int protoff,
39 int *hotdrop) 34 bool *hotdrop)
40{ 35{
41 const struct xt_helper_info *info = matchinfo; 36 const struct xt_helper_info *info = matchinfo;
42 struct nf_conn *ct; 37 const struct nf_conn *ct;
43 struct nf_conn_help *master_help; 38 const struct nf_conn_help *master_help;
39 const struct nf_conntrack_helper *helper;
44 enum ip_conntrack_info ctinfo; 40 enum ip_conntrack_info ctinfo;
45 int ret = info->invert; 41 bool ret = info->invert;
46 42
47 ct = nf_ct_get((struct sk_buff *)skb, &ctinfo); 43 ct = nf_ct_get(skb, &ctinfo);
48 if (!ct) { 44 if (!ct || !ct->master)
49 DEBUGP("xt_helper: Eek! invalid conntrack?\n");
50 return ret; 45 return ret;
51 }
52
53 if (!ct->master) {
54 DEBUGP("xt_helper: conntrack %p has no master\n", ct);
55 return ret;
56 }
57 46
58 read_lock_bh(&nf_conntrack_lock);
59 master_help = nfct_help(ct->master); 47 master_help = nfct_help(ct->master);
60 if (!master_help || !master_help->helper) { 48 if (!master_help)
61 DEBUGP("xt_helper: master ct %p has no helper\n", 49 return ret;
62 exp->expectant);
63 goto out_unlock;
64 }
65 50
66 DEBUGP("master's name = %s , info->name = %s\n", 51 /* rcu_read_lock()ed by nf_hook_slow */
67 ct->master->helper->name, info->name); 52 helper = rcu_dereference(master_help->helper);
53 if (!helper)
54 return ret;
68 55
69 if (info->name[0] == '\0') 56 if (info->name[0] == '\0')
70 ret ^= 1; 57 ret = !ret;
71 else 58 else
72 ret ^= !strncmp(master_help->helper->name, info->name, 59 ret ^= !strncmp(master_help->helper->name, info->name,
73 strlen(master_help->helper->name)); 60 strlen(master_help->helper->name));
74out_unlock:
75 read_unlock_bh(&nf_conntrack_lock);
76 return ret; 61 return ret;
77} 62}
78 63
79static int check(const char *tablename, 64static bool check(const char *tablename,
80 const void *inf, 65 const void *inf,
81 const struct xt_match *match, 66 const struct xt_match *match,
82 void *matchinfo, 67 void *matchinfo,
83 unsigned int hook_mask) 68 unsigned int hook_mask)
84{ 69{
85 struct xt_helper_info *info = matchinfo; 70 struct xt_helper_info *info = matchinfo;
86 71
87 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 72 if (nf_ct_l3proto_try_module_get(match->family) < 0) {
88 printk(KERN_WARNING "can't load conntrack support for " 73 printk(KERN_WARNING "can't load conntrack support for "
89 "proto=%d\n", match->family); 74 "proto=%d\n", match->family);
90 return 0; 75 return false;
91 } 76 }
92 info->name[29] = '\0'; 77 info->name[29] = '\0';
93 return 1; 78 return true;
94} 79}
95 80
96static void 81static void
@@ -99,7 +84,7 @@ destroy(const struct xt_match *match, void *matchinfo)
99 nf_ct_l3proto_module_put(match->family); 84 nf_ct_l3proto_module_put(match->family);
100} 85}
101 86
102static struct xt_match xt_helper_match[] = { 87static struct xt_match xt_helper_match[] __read_mostly = {
103 { 88 {
104 .name = "helper", 89 .name = "helper",
105 .family = AF_INET, 90 .family = AF_INET,
diff --git a/net/netfilter/xt_length.c b/net/netfilter/xt_length.c
index 77288c5ada78..3dad173d9735 100644
--- a/net/netfilter/xt_length.c
+++ b/net/netfilter/xt_length.c
@@ -20,7 +20,7 @@ MODULE_LICENSE("GPL");
20MODULE_ALIAS("ipt_length"); 20MODULE_ALIAS("ipt_length");
21MODULE_ALIAS("ip6t_length"); 21MODULE_ALIAS("ip6t_length");
22 22
23static int 23static bool
24match(const struct sk_buff *skb, 24match(const struct sk_buff *skb,
25 const struct net_device *in, 25 const struct net_device *in,
26 const struct net_device *out, 26 const struct net_device *out,
@@ -28,7 +28,7 @@ match(const struct sk_buff *skb,
28 const void *matchinfo, 28 const void *matchinfo,
29 int offset, 29 int offset,
30 unsigned int protoff, 30 unsigned int protoff,
31 int *hotdrop) 31 bool *hotdrop)
32{ 32{
33 const struct xt_length_info *info = matchinfo; 33 const struct xt_length_info *info = matchinfo;
34 u_int16_t pktlen = ntohs(ip_hdr(skb)->tot_len); 34 u_int16_t pktlen = ntohs(ip_hdr(skb)->tot_len);
@@ -36,7 +36,7 @@ match(const struct sk_buff *skb,
36 return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; 36 return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
37} 37}
38 38
39static int 39static bool
40match6(const struct sk_buff *skb, 40match6(const struct sk_buff *skb,
41 const struct net_device *in, 41 const struct net_device *in,
42 const struct net_device *out, 42 const struct net_device *out,
@@ -44,16 +44,16 @@ match6(const struct sk_buff *skb,
44 const void *matchinfo, 44 const void *matchinfo,
45 int offset, 45 int offset,
46 unsigned int protoff, 46 unsigned int protoff,
47 int *hotdrop) 47 bool *hotdrop)
48{ 48{
49 const struct xt_length_info *info = matchinfo; 49 const struct xt_length_info *info = matchinfo;
50 const u_int16_t pktlen = (ntohs(ipv6_hdr(skb)->payload_len) + 50 const u_int16_t pktlen = ntohs(ipv6_hdr(skb)->payload_len) +
51 sizeof(struct ipv6hdr)); 51 sizeof(struct ipv6hdr);
52 52
53 return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; 53 return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
54} 54}
55 55
56static struct xt_match xt_length_match[] = { 56static struct xt_match xt_length_match[] __read_mostly = {
57 { 57 {
58 .name = "length", 58 .name = "length",
59 .family = AF_INET, 59 .family = AF_INET,
diff --git a/net/netfilter/xt_limit.c b/net/netfilter/xt_limit.c
index 571a72ab89ad..4fcca797150f 100644
--- a/net/netfilter/xt_limit.c
+++ b/net/netfilter/xt_limit.c
@@ -57,7 +57,7 @@ static DEFINE_SPINLOCK(limit_lock);
57 57
58#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ) 58#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
59 59
60static int 60static bool
61ipt_limit_match(const struct sk_buff *skb, 61ipt_limit_match(const struct sk_buff *skb,
62 const struct net_device *in, 62 const struct net_device *in,
63 const struct net_device *out, 63 const struct net_device *out,
@@ -65,9 +65,10 @@ ipt_limit_match(const struct sk_buff *skb,
65 const void *matchinfo, 65 const void *matchinfo,
66 int offset, 66 int offset,
67 unsigned int protoff, 67 unsigned int protoff,
68 int *hotdrop) 68 bool *hotdrop)
69{ 69{
70 struct xt_rateinfo *r = ((struct xt_rateinfo *)matchinfo)->master; 70 struct xt_rateinfo *r =
71 ((const struct xt_rateinfo *)matchinfo)->master;
71 unsigned long now = jiffies; 72 unsigned long now = jiffies;
72 73
73 spin_lock_bh(&limit_lock); 74 spin_lock_bh(&limit_lock);
@@ -79,11 +80,11 @@ ipt_limit_match(const struct sk_buff *skb,
79 /* We're not limited. */ 80 /* We're not limited. */
80 r->credit -= r->cost; 81 r->credit -= r->cost;
81 spin_unlock_bh(&limit_lock); 82 spin_unlock_bh(&limit_lock);
82 return 1; 83 return true;
83 } 84 }
84 85
85 spin_unlock_bh(&limit_lock); 86 spin_unlock_bh(&limit_lock);
86 return 0; 87 return false;
87} 88}
88 89
89/* Precision saver. */ 90/* Precision saver. */
@@ -98,7 +99,7 @@ user2credits(u_int32_t user)
98 return (user * HZ * CREDITS_PER_JIFFY) / XT_LIMIT_SCALE; 99 return (user * HZ * CREDITS_PER_JIFFY) / XT_LIMIT_SCALE;
99} 100}
100 101
101static int 102static bool
102ipt_limit_checkentry(const char *tablename, 103ipt_limit_checkentry(const char *tablename,
103 const void *inf, 104 const void *inf,
104 const struct xt_match *match, 105 const struct xt_match *match,
@@ -112,7 +113,7 @@ ipt_limit_checkentry(const char *tablename,
112 || user2credits(r->avg * r->burst) < user2credits(r->avg)) { 113 || user2credits(r->avg * r->burst) < user2credits(r->avg)) {
113 printk("Overflow in xt_limit, try lower: %u/%u\n", 114 printk("Overflow in xt_limit, try lower: %u/%u\n",
114 r->avg, r->burst); 115 r->avg, r->burst);
115 return 0; 116 return false;
116 } 117 }
117 118
118 /* For SMP, we only want to use one set of counters. */ 119 /* For SMP, we only want to use one set of counters. */
@@ -125,7 +126,7 @@ ipt_limit_checkentry(const char *tablename,
125 r->credit_cap = user2credits(r->avg * r->burst); /* Credits full. */ 126 r->credit_cap = user2credits(r->avg * r->burst); /* Credits full. */
126 r->cost = user2credits(r->avg); 127 r->cost = user2credits(r->avg);
127 } 128 }
128 return 1; 129 return true;
129} 130}
130 131
131#ifdef CONFIG_COMPAT 132#ifdef CONFIG_COMPAT
@@ -144,7 +145,7 @@ struct compat_xt_rateinfo {
144 * master pointer, which does not need to be preserved. */ 145 * master pointer, which does not need to be preserved. */
145static void compat_from_user(void *dst, void *src) 146static void compat_from_user(void *dst, void *src)
146{ 147{
147 struct compat_xt_rateinfo *cm = src; 148 const struct compat_xt_rateinfo *cm = src;
148 struct xt_rateinfo m = { 149 struct xt_rateinfo m = {
149 .avg = cm->avg, 150 .avg = cm->avg,
150 .burst = cm->burst, 151 .burst = cm->burst,
@@ -158,7 +159,7 @@ static void compat_from_user(void *dst, void *src)
158 159
159static int compat_to_user(void __user *dst, void *src) 160static int compat_to_user(void __user *dst, void *src)
160{ 161{
161 struct xt_rateinfo *m = src; 162 const struct xt_rateinfo *m = src;
162 struct compat_xt_rateinfo cm = { 163 struct compat_xt_rateinfo cm = {
163 .avg = m->avg, 164 .avg = m->avg,
164 .burst = m->burst, 165 .burst = m->burst,
@@ -172,7 +173,7 @@ static int compat_to_user(void __user *dst, void *src)
172} 173}
173#endif /* CONFIG_COMPAT */ 174#endif /* CONFIG_COMPAT */
174 175
175static struct xt_match xt_limit_match[] = { 176static struct xt_match xt_limit_match[] __read_mostly = {
176 { 177 {
177 .name = "limit", 178 .name = "limit",
178 .family = AF_INET, 179 .family = AF_INET,
diff --git a/net/netfilter/xt_mac.c b/net/netfilter/xt_mac.c
index 1d3a1d98b885..00490d777a0f 100644
--- a/net/netfilter/xt_mac.c
+++ b/net/netfilter/xt_mac.c
@@ -24,7 +24,7 @@ MODULE_DESCRIPTION("iptables mac matching module");
24MODULE_ALIAS("ipt_mac"); 24MODULE_ALIAS("ipt_mac");
25MODULE_ALIAS("ip6t_mac"); 25MODULE_ALIAS("ip6t_mac");
26 26
27static int 27static bool
28match(const struct sk_buff *skb, 28match(const struct sk_buff *skb,
29 const struct net_device *in, 29 const struct net_device *in,
30 const struct net_device *out, 30 const struct net_device *out,
@@ -32,19 +32,19 @@ match(const struct sk_buff *skb,
32 const void *matchinfo, 32 const void *matchinfo,
33 int offset, 33 int offset,
34 unsigned int protoff, 34 unsigned int protoff,
35 int *hotdrop) 35 bool *hotdrop)
36{ 36{
37 const struct xt_mac_info *info = matchinfo; 37 const struct xt_mac_info *info = matchinfo;
38 38
39 /* Is mac pointer valid? */ 39 /* Is mac pointer valid? */
40 return (skb_mac_header(skb) >= skb->head && 40 return skb_mac_header(skb) >= skb->head &&
41 (skb_mac_header(skb) + ETH_HLEN) <= skb->data 41 skb_mac_header(skb) + ETH_HLEN <= skb->data
42 /* If so, compare... */ 42 /* If so, compare... */
43 && ((!compare_ether_addr(eth_hdr(skb)->h_source, info->srcaddr)) 43 && ((!compare_ether_addr(eth_hdr(skb)->h_source, info->srcaddr))
44 ^ info->invert)); 44 ^ info->invert);
45} 45}
46 46
47static struct xt_match xt_mac_match[] = { 47static struct xt_match xt_mac_match[] __read_mostly = {
48 { 48 {
49 .name = "mac", 49 .name = "mac",
50 .family = AF_INET, 50 .family = AF_INET,
diff --git a/net/netfilter/xt_mark.c b/net/netfilter/xt_mark.c
index 39911dddb011..c02a7f8f3925 100644
--- a/net/netfilter/xt_mark.c
+++ b/net/netfilter/xt_mark.c
@@ -19,7 +19,7 @@ MODULE_DESCRIPTION("iptables mark matching module");
19MODULE_ALIAS("ipt_mark"); 19MODULE_ALIAS("ipt_mark");
20MODULE_ALIAS("ip6t_mark"); 20MODULE_ALIAS("ip6t_mark");
21 21
22static int 22static bool
23match(const struct sk_buff *skb, 23match(const struct sk_buff *skb,
24 const struct net_device *in, 24 const struct net_device *in,
25 const struct net_device *out, 25 const struct net_device *out,
@@ -27,14 +27,14 @@ match(const struct sk_buff *skb,
27 const void *matchinfo, 27 const void *matchinfo,
28 int offset, 28 int offset,
29 unsigned int protoff, 29 unsigned int protoff,
30 int *hotdrop) 30 bool *hotdrop)
31{ 31{
32 const struct xt_mark_info *info = matchinfo; 32 const struct xt_mark_info *info = matchinfo;
33 33
34 return ((skb->mark & info->mask) == info->mark) ^ info->invert; 34 return ((skb->mark & info->mask) == info->mark) ^ info->invert;
35} 35}
36 36
37static int 37static bool
38checkentry(const char *tablename, 38checkentry(const char *tablename,
39 const void *entry, 39 const void *entry,
40 const struct xt_match *match, 40 const struct xt_match *match,
@@ -45,9 +45,9 @@ checkentry(const char *tablename,
45 45
46 if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) { 46 if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) {
47 printk(KERN_WARNING "mark: only supports 32bit mark\n"); 47 printk(KERN_WARNING "mark: only supports 32bit mark\n");
48 return 0; 48 return false;
49 } 49 }
50 return 1; 50 return true;
51} 51}
52 52
53#ifdef CONFIG_COMPAT 53#ifdef CONFIG_COMPAT
@@ -60,7 +60,7 @@ struct compat_xt_mark_info {
60 60
61static void compat_from_user(void *dst, void *src) 61static void compat_from_user(void *dst, void *src)
62{ 62{
63 struct compat_xt_mark_info *cm = src; 63 const struct compat_xt_mark_info *cm = src;
64 struct xt_mark_info m = { 64 struct xt_mark_info m = {
65 .mark = cm->mark, 65 .mark = cm->mark,
66 .mask = cm->mask, 66 .mask = cm->mask,
@@ -71,7 +71,7 @@ static void compat_from_user(void *dst, void *src)
71 71
72static int compat_to_user(void __user *dst, void *src) 72static int compat_to_user(void __user *dst, void *src)
73{ 73{
74 struct xt_mark_info *m = src; 74 const struct xt_mark_info *m = src;
75 struct compat_xt_mark_info cm = { 75 struct compat_xt_mark_info cm = {
76 .mark = m->mark, 76 .mark = m->mark,
77 .mask = m->mask, 77 .mask = m->mask,
@@ -81,7 +81,7 @@ static int compat_to_user(void __user *dst, void *src)
81} 81}
82#endif /* CONFIG_COMPAT */ 82#endif /* CONFIG_COMPAT */
83 83
84static struct xt_match xt_mark_match[] = { 84static struct xt_match xt_mark_match[] __read_mostly = {
85 { 85 {
86 .name = "mark", 86 .name = "mark",
87 .family = AF_INET, 87 .family = AF_INET,
diff --git a/net/netfilter/xt_multiport.c b/net/netfilter/xt_multiport.c
index 4dce2a81702a..e8ae10284acd 100644
--- a/net/netfilter/xt_multiport.c
+++ b/net/netfilter/xt_multiport.c
@@ -33,24 +33,24 @@ MODULE_ALIAS("ip6t_multiport");
33#endif 33#endif
34 34
35/* Returns 1 if the port is matched by the test, 0 otherwise. */ 35/* Returns 1 if the port is matched by the test, 0 otherwise. */
36static inline int 36static inline bool
37ports_match(const u_int16_t *portlist, enum xt_multiport_flags flags, 37ports_match(const u_int16_t *portlist, enum xt_multiport_flags flags,
38 u_int8_t count, u_int16_t src, u_int16_t dst) 38 u_int8_t count, u_int16_t src, u_int16_t dst)
39{ 39{
40 unsigned int i; 40 unsigned int i;
41 for (i = 0; i < count; i++) { 41 for (i = 0; i < count; i++) {
42 if (flags != XT_MULTIPORT_DESTINATION && portlist[i] == src) 42 if (flags != XT_MULTIPORT_DESTINATION && portlist[i] == src)
43 return 1; 43 return true;
44 44
45 if (flags != XT_MULTIPORT_SOURCE && portlist[i] == dst) 45 if (flags != XT_MULTIPORT_SOURCE && portlist[i] == dst)
46 return 1; 46 return true;
47 } 47 }
48 48
49 return 0; 49 return false;
50} 50}
51 51
52/* Returns 1 if the port is matched by the test, 0 otherwise. */ 52/* Returns 1 if the port is matched by the test, 0 otherwise. */
53static inline int 53static inline bool
54ports_match_v1(const struct xt_multiport_v1 *minfo, 54ports_match_v1(const struct xt_multiport_v1 *minfo,
55 u_int16_t src, u_int16_t dst) 55 u_int16_t src, u_int16_t dst)
56{ 56{
@@ -67,34 +67,34 @@ ports_match_v1(const struct xt_multiport_v1 *minfo,
67 67
68 if (minfo->flags == XT_MULTIPORT_SOURCE 68 if (minfo->flags == XT_MULTIPORT_SOURCE
69 && src >= s && src <= e) 69 && src >= s && src <= e)
70 return 1 ^ minfo->invert; 70 return true ^ minfo->invert;
71 if (minfo->flags == XT_MULTIPORT_DESTINATION 71 if (minfo->flags == XT_MULTIPORT_DESTINATION
72 && dst >= s && dst <= e) 72 && dst >= s && dst <= e)
73 return 1 ^ minfo->invert; 73 return true ^ minfo->invert;
74 if (minfo->flags == XT_MULTIPORT_EITHER 74 if (minfo->flags == XT_MULTIPORT_EITHER
75 && ((dst >= s && dst <= e) 75 && ((dst >= s && dst <= e)
76 || (src >= s && src <= e))) 76 || (src >= s && src <= e)))
77 return 1 ^ minfo->invert; 77 return true ^ minfo->invert;
78 } else { 78 } else {
79 /* exact port matching */ 79 /* exact port matching */
80 duprintf("src or dst matches with %d?\n", s); 80 duprintf("src or dst matches with %d?\n", s);
81 81
82 if (minfo->flags == XT_MULTIPORT_SOURCE 82 if (minfo->flags == XT_MULTIPORT_SOURCE
83 && src == s) 83 && src == s)
84 return 1 ^ minfo->invert; 84 return true ^ minfo->invert;
85 if (minfo->flags == XT_MULTIPORT_DESTINATION 85 if (minfo->flags == XT_MULTIPORT_DESTINATION
86 && dst == s) 86 && dst == s)
87 return 1 ^ minfo->invert; 87 return true ^ minfo->invert;
88 if (minfo->flags == XT_MULTIPORT_EITHER 88 if (minfo->flags == XT_MULTIPORT_EITHER
89 && (src == s || dst == s)) 89 && (src == s || dst == s))
90 return 1 ^ minfo->invert; 90 return true ^ minfo->invert;
91 } 91 }
92 } 92 }
93 93
94 return minfo->invert; 94 return minfo->invert;
95} 95}
96 96
97static int 97static bool
98match(const struct sk_buff *skb, 98match(const struct sk_buff *skb,
99 const struct net_device *in, 99 const struct net_device *in,
100 const struct net_device *out, 100 const struct net_device *out,
@@ -102,13 +102,13 @@ match(const struct sk_buff *skb,
102 const void *matchinfo, 102 const void *matchinfo,
103 int offset, 103 int offset,
104 unsigned int protoff, 104 unsigned int protoff,
105 int *hotdrop) 105 bool *hotdrop)
106{ 106{
107 __be16 _ports[2], *pptr; 107 __be16 _ports[2], *pptr;
108 const struct xt_multiport *multiinfo = matchinfo; 108 const struct xt_multiport *multiinfo = matchinfo;
109 109
110 if (offset) 110 if (offset)
111 return 0; 111 return false;
112 112
113 pptr = skb_header_pointer(skb, protoff, sizeof(_ports), _ports); 113 pptr = skb_header_pointer(skb, protoff, sizeof(_ports), _ports);
114 if (pptr == NULL) { 114 if (pptr == NULL) {
@@ -116,8 +116,8 @@ match(const struct sk_buff *skb,
116 * can't. Hence, no choice but to drop. 116 * can't. Hence, no choice but to drop.
117 */ 117 */
118 duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n"); 118 duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n");
119 *hotdrop = 1; 119 *hotdrop = true;
120 return 0; 120 return false;
121 } 121 }
122 122
123 return ports_match(multiinfo->ports, 123 return ports_match(multiinfo->ports,
@@ -125,7 +125,7 @@ match(const struct sk_buff *skb,
125 ntohs(pptr[0]), ntohs(pptr[1])); 125 ntohs(pptr[0]), ntohs(pptr[1]));
126} 126}
127 127
128static int 128static bool
129match_v1(const struct sk_buff *skb, 129match_v1(const struct sk_buff *skb,
130 const struct net_device *in, 130 const struct net_device *in,
131 const struct net_device *out, 131 const struct net_device *out,
@@ -133,13 +133,13 @@ match_v1(const struct sk_buff *skb,
133 const void *matchinfo, 133 const void *matchinfo,
134 int offset, 134 int offset,
135 unsigned int protoff, 135 unsigned int protoff,
136 int *hotdrop) 136 bool *hotdrop)
137{ 137{
138 __be16 _ports[2], *pptr; 138 __be16 _ports[2], *pptr;
139 const struct xt_multiport_v1 *multiinfo = matchinfo; 139 const struct xt_multiport_v1 *multiinfo = matchinfo;
140 140
141 if (offset) 141 if (offset)
142 return 0; 142 return false;
143 143
144 pptr = skb_header_pointer(skb, protoff, sizeof(_ports), _ports); 144 pptr = skb_header_pointer(skb, protoff, sizeof(_ports), _ports);
145 if (pptr == NULL) { 145 if (pptr == NULL) {
@@ -147,14 +147,14 @@ match_v1(const struct sk_buff *skb,
147 * can't. Hence, no choice but to drop. 147 * can't. Hence, no choice but to drop.
148 */ 148 */
149 duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n"); 149 duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n");
150 *hotdrop = 1; 150 *hotdrop = true;
151 return 0; 151 return false;
152 } 152 }
153 153
154 return ports_match_v1(multiinfo, ntohs(pptr[0]), ntohs(pptr[1])); 154 return ports_match_v1(multiinfo, ntohs(pptr[0]), ntohs(pptr[1]));
155} 155}
156 156
157static inline int 157static inline bool
158check(u_int16_t proto, 158check(u_int16_t proto,
159 u_int8_t ip_invflags, 159 u_int8_t ip_invflags,
160 u_int8_t match_flags, 160 u_int8_t match_flags,
@@ -172,7 +172,7 @@ check(u_int16_t proto,
172} 172}
173 173
174/* Called when user tries to insert an entry of this type. */ 174/* Called when user tries to insert an entry of this type. */
175static int 175static bool
176checkentry(const char *tablename, 176checkentry(const char *tablename,
177 const void *info, 177 const void *info,
178 const struct xt_match *match, 178 const struct xt_match *match,
@@ -186,7 +186,7 @@ checkentry(const char *tablename,
186 multiinfo->count); 186 multiinfo->count);
187} 187}
188 188
189static int 189static bool
190checkentry_v1(const char *tablename, 190checkentry_v1(const char *tablename,
191 const void *info, 191 const void *info,
192 const struct xt_match *match, 192 const struct xt_match *match,
@@ -200,7 +200,7 @@ checkentry_v1(const char *tablename,
200 multiinfo->count); 200 multiinfo->count);
201} 201}
202 202
203static int 203static bool
204checkentry6(const char *tablename, 204checkentry6(const char *tablename,
205 const void *info, 205 const void *info,
206 const struct xt_match *match, 206 const struct xt_match *match,
@@ -214,7 +214,7 @@ checkentry6(const char *tablename,
214 multiinfo->count); 214 multiinfo->count);
215} 215}
216 216
217static int 217static bool
218checkentry6_v1(const char *tablename, 218checkentry6_v1(const char *tablename,
219 const void *info, 219 const void *info,
220 const struct xt_match *match, 220 const struct xt_match *match,
@@ -228,7 +228,7 @@ checkentry6_v1(const char *tablename,
228 multiinfo->count); 228 multiinfo->count);
229} 229}
230 230
231static struct xt_match xt_multiport_match[] = { 231static struct xt_match xt_multiport_match[] __read_mostly = {
232 { 232 {
233 .name = "multiport", 233 .name = "multiport",
234 .family = AF_INET, 234 .family = AF_INET,
diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c
index 35a0fe200c39..f47cab7a696d 100644
--- a/net/netfilter/xt_physdev.c
+++ b/net/netfilter/xt_physdev.c
@@ -14,8 +14,6 @@
14#include <linux/netfilter/xt_physdev.h> 14#include <linux/netfilter/xt_physdev.h>
15#include <linux/netfilter/x_tables.h> 15#include <linux/netfilter/x_tables.h>
16#include <linux/netfilter_bridge.h> 16#include <linux/netfilter_bridge.h>
17#define MATCH 1
18#define NOMATCH 0
19 17
20MODULE_LICENSE("GPL"); 18MODULE_LICENSE("GPL");
21MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>"); 19MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
@@ -23,7 +21,7 @@ MODULE_DESCRIPTION("iptables bridge physical device match module");
23MODULE_ALIAS("ipt_physdev"); 21MODULE_ALIAS("ipt_physdev");
24MODULE_ALIAS("ip6t_physdev"); 22MODULE_ALIAS("ip6t_physdev");
25 23
26static int 24static bool
27match(const struct sk_buff *skb, 25match(const struct sk_buff *skb,
28 const struct net_device *in, 26 const struct net_device *in,
29 const struct net_device *out, 27 const struct net_device *out,
@@ -31,14 +29,14 @@ match(const struct sk_buff *skb,
31 const void *matchinfo, 29 const void *matchinfo,
32 int offset, 30 int offset,
33 unsigned int protoff, 31 unsigned int protoff,
34 int *hotdrop) 32 bool *hotdrop)
35{ 33{
36 int i; 34 int i;
37 static const char nulldevname[IFNAMSIZ]; 35 static const char nulldevname[IFNAMSIZ];
38 const struct xt_physdev_info *info = matchinfo; 36 const struct xt_physdev_info *info = matchinfo;
39 unsigned int ret; 37 bool ret;
40 const char *indev, *outdev; 38 const char *indev, *outdev;
41 struct nf_bridge_info *nf_bridge; 39 const struct nf_bridge_info *nf_bridge;
42 40
43 /* Not a bridged IP packet or no info available yet: 41 /* Not a bridged IP packet or no info available yet:
44 * LOCAL_OUT/mangle and LOCAL_OUT/nat don't know if 42 * LOCAL_OUT/mangle and LOCAL_OUT/nat don't know if
@@ -47,61 +45,61 @@ match(const struct sk_buff *skb,
47 /* Return MATCH if the invert flags of the used options are on */ 45 /* Return MATCH if the invert flags of the used options are on */
48 if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) && 46 if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) &&
49 !(info->invert & XT_PHYSDEV_OP_BRIDGED)) 47 !(info->invert & XT_PHYSDEV_OP_BRIDGED))
50 return NOMATCH; 48 return false;
51 if ((info->bitmask & XT_PHYSDEV_OP_ISIN) && 49 if ((info->bitmask & XT_PHYSDEV_OP_ISIN) &&
52 !(info->invert & XT_PHYSDEV_OP_ISIN)) 50 !(info->invert & XT_PHYSDEV_OP_ISIN))
53 return NOMATCH; 51 return false;
54 if ((info->bitmask & XT_PHYSDEV_OP_ISOUT) && 52 if ((info->bitmask & XT_PHYSDEV_OP_ISOUT) &&
55 !(info->invert & XT_PHYSDEV_OP_ISOUT)) 53 !(info->invert & XT_PHYSDEV_OP_ISOUT))
56 return NOMATCH; 54 return false;
57 if ((info->bitmask & XT_PHYSDEV_OP_IN) && 55 if ((info->bitmask & XT_PHYSDEV_OP_IN) &&
58 !(info->invert & XT_PHYSDEV_OP_IN)) 56 !(info->invert & XT_PHYSDEV_OP_IN))
59 return NOMATCH; 57 return false;
60 if ((info->bitmask & XT_PHYSDEV_OP_OUT) && 58 if ((info->bitmask & XT_PHYSDEV_OP_OUT) &&
61 !(info->invert & XT_PHYSDEV_OP_OUT)) 59 !(info->invert & XT_PHYSDEV_OP_OUT))
62 return NOMATCH; 60 return false;
63 return MATCH; 61 return true;
64 } 62 }
65 63
66 /* This only makes sense in the FORWARD and POSTROUTING chains */ 64 /* This only makes sense in the FORWARD and POSTROUTING chains */
67 if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) && 65 if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) &&
68 (!!(nf_bridge->mask & BRNF_BRIDGED) ^ 66 (!!(nf_bridge->mask & BRNF_BRIDGED) ^
69 !(info->invert & XT_PHYSDEV_OP_BRIDGED))) 67 !(info->invert & XT_PHYSDEV_OP_BRIDGED)))
70 return NOMATCH; 68 return false;
71 69
72 if ((info->bitmask & XT_PHYSDEV_OP_ISIN && 70 if ((info->bitmask & XT_PHYSDEV_OP_ISIN &&
73 (!nf_bridge->physindev ^ !!(info->invert & XT_PHYSDEV_OP_ISIN))) || 71 (!nf_bridge->physindev ^ !!(info->invert & XT_PHYSDEV_OP_ISIN))) ||
74 (info->bitmask & XT_PHYSDEV_OP_ISOUT && 72 (info->bitmask & XT_PHYSDEV_OP_ISOUT &&
75 (!nf_bridge->physoutdev ^ !!(info->invert & XT_PHYSDEV_OP_ISOUT)))) 73 (!nf_bridge->physoutdev ^ !!(info->invert & XT_PHYSDEV_OP_ISOUT))))
76 return NOMATCH; 74 return false;
77 75
78 if (!(info->bitmask & XT_PHYSDEV_OP_IN)) 76 if (!(info->bitmask & XT_PHYSDEV_OP_IN))
79 goto match_outdev; 77 goto match_outdev;
80 indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname; 78 indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname;
81 for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) { 79 for (i = 0, ret = false; i < IFNAMSIZ/sizeof(unsigned int); i++) {
82 ret |= (((const unsigned int *)indev)[i] 80 ret |= (((const unsigned int *)indev)[i]
83 ^ ((const unsigned int *)info->physindev)[i]) 81 ^ ((const unsigned int *)info->physindev)[i])
84 & ((const unsigned int *)info->in_mask)[i]; 82 & ((const unsigned int *)info->in_mask)[i];
85 } 83 }
86 84
87 if ((ret == 0) ^ !(info->invert & XT_PHYSDEV_OP_IN)) 85 if (!ret ^ !(info->invert & XT_PHYSDEV_OP_IN))
88 return NOMATCH; 86 return false;
89 87
90match_outdev: 88match_outdev:
91 if (!(info->bitmask & XT_PHYSDEV_OP_OUT)) 89 if (!(info->bitmask & XT_PHYSDEV_OP_OUT))
92 return MATCH; 90 return true;
93 outdev = nf_bridge->physoutdev ? 91 outdev = nf_bridge->physoutdev ?
94 nf_bridge->physoutdev->name : nulldevname; 92 nf_bridge->physoutdev->name : nulldevname;
95 for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) { 93 for (i = 0, ret = false; i < IFNAMSIZ/sizeof(unsigned int); i++) {
96 ret |= (((const unsigned int *)outdev)[i] 94 ret |= (((const unsigned int *)outdev)[i]
97 ^ ((const unsigned int *)info->physoutdev)[i]) 95 ^ ((const unsigned int *)info->physoutdev)[i])
98 & ((const unsigned int *)info->out_mask)[i]; 96 & ((const unsigned int *)info->out_mask)[i];
99 } 97 }
100 98
101 return (ret != 0) ^ !(info->invert & XT_PHYSDEV_OP_OUT); 99 return ret ^ !(info->invert & XT_PHYSDEV_OP_OUT);
102} 100}
103 101
104static int 102static bool
105checkentry(const char *tablename, 103checkentry(const char *tablename,
106 const void *ip, 104 const void *ip,
107 const struct xt_match *match, 105 const struct xt_match *match,
@@ -112,7 +110,7 @@ checkentry(const char *tablename,
112 110
113 if (!(info->bitmask & XT_PHYSDEV_OP_MASK) || 111 if (!(info->bitmask & XT_PHYSDEV_OP_MASK) ||
114 info->bitmask & ~XT_PHYSDEV_OP_MASK) 112 info->bitmask & ~XT_PHYSDEV_OP_MASK)
115 return 0; 113 return false;
116 if (info->bitmask & XT_PHYSDEV_OP_OUT && 114 if (info->bitmask & XT_PHYSDEV_OP_OUT &&
117 (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) || 115 (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) ||
118 info->invert & XT_PHYSDEV_OP_BRIDGED) && 116 info->invert & XT_PHYSDEV_OP_BRIDGED) &&
@@ -122,12 +120,12 @@ checkentry(const char *tablename,
122 "OUTPUT, FORWARD and POSTROUTING chains for non-bridged " 120 "OUTPUT, FORWARD and POSTROUTING chains for non-bridged "
123 "traffic is not supported anymore.\n"); 121 "traffic is not supported anymore.\n");
124 if (hook_mask & (1 << NF_IP_LOCAL_OUT)) 122 if (hook_mask & (1 << NF_IP_LOCAL_OUT))
125 return 0; 123 return false;
126 } 124 }
127 return 1; 125 return true;
128} 126}
129 127
130static struct xt_match xt_physdev_match[] = { 128static struct xt_match xt_physdev_match[] __read_mostly = {
131 { 129 {
132 .name = "physdev", 130 .name = "physdev",
133 .family = AF_INET, 131 .family = AF_INET,
diff --git a/net/netfilter/xt_pkttype.c b/net/netfilter/xt_pkttype.c
index e1409fc5c288..a52925f12f35 100644
--- a/net/netfilter/xt_pkttype.c
+++ b/net/netfilter/xt_pkttype.c
@@ -21,29 +21,29 @@ MODULE_DESCRIPTION("IP tables match to match on linklayer packet type");
21MODULE_ALIAS("ipt_pkttype"); 21MODULE_ALIAS("ipt_pkttype");
22MODULE_ALIAS("ip6t_pkttype"); 22MODULE_ALIAS("ip6t_pkttype");
23 23
24static int match(const struct sk_buff *skb, 24static bool match(const struct sk_buff *skb,
25 const struct net_device *in, 25 const struct net_device *in,
26 const struct net_device *out, 26 const struct net_device *out,
27 const struct xt_match *match, 27 const struct xt_match *match,
28 const void *matchinfo, 28 const void *matchinfo,
29 int offset, 29 int offset,
30 unsigned int protoff, 30 unsigned int protoff,
31 int *hotdrop) 31 bool *hotdrop)
32{ 32{
33 u_int8_t type; 33 u_int8_t type;
34 const struct xt_pkttype_info *info = matchinfo; 34 const struct xt_pkttype_info *info = matchinfo;
35 35
36 if (skb->pkt_type == PACKET_LOOPBACK) 36 if (skb->pkt_type == PACKET_LOOPBACK)
37 type = (MULTICAST(ip_hdr(skb)->daddr) 37 type = MULTICAST(ip_hdr(skb)->daddr)
38 ? PACKET_MULTICAST 38 ? PACKET_MULTICAST
39 : PACKET_BROADCAST); 39 : PACKET_BROADCAST;
40 else 40 else
41 type = skb->pkt_type; 41 type = skb->pkt_type;
42 42
43 return (type == info->pkttype) ^ info->invert; 43 return (type == info->pkttype) ^ info->invert;
44} 44}
45 45
46static struct xt_match xt_pkttype_match[] = { 46static struct xt_match xt_pkttype_match[] __read_mostly = {
47 { 47 {
48 .name = "pkttype", 48 .name = "pkttype",
49 .family = AF_INET, 49 .family = AF_INET,
diff --git a/net/netfilter/xt_policy.c b/net/netfilter/xt_policy.c
index 15b45a95ec13..6d6d3b7fcbb5 100644
--- a/net/netfilter/xt_policy.c
+++ b/net/netfilter/xt_policy.c
@@ -20,7 +20,7 @@ MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
20MODULE_DESCRIPTION("Xtables IPsec policy matching module"); 20MODULE_DESCRIPTION("Xtables IPsec policy matching module");
21MODULE_LICENSE("GPL"); 21MODULE_LICENSE("GPL");
22 22
23static inline int 23static inline bool
24xt_addr_cmp(const union xt_policy_addr *a1, const union xt_policy_addr *m, 24xt_addr_cmp(const union xt_policy_addr *a1, const union xt_policy_addr *m,
25 const union xt_policy_addr *a2, unsigned short family) 25 const union xt_policy_addr *a2, unsigned short family)
26{ 26{
@@ -30,11 +30,11 @@ xt_addr_cmp(const union xt_policy_addr *a1, const union xt_policy_addr *m,
30 case AF_INET6: 30 case AF_INET6:
31 return !ipv6_masked_addr_cmp(&a1->a6, &m->a6, &a2->a6); 31 return !ipv6_masked_addr_cmp(&a1->a6, &m->a6, &a2->a6);
32 } 32 }
33 return 0; 33 return false;
34} 34}
35 35
36static inline int 36static inline bool
37match_xfrm_state(struct xfrm_state *x, const struct xt_policy_elem *e, 37match_xfrm_state(const struct xfrm_state *x, const struct xt_policy_elem *e,
38 unsigned short family) 38 unsigned short family)
39{ 39{
40#define MATCH_ADDR(x,y,z) (!e->match.x || \ 40#define MATCH_ADDR(x,y,z) (!e->match.x || \
@@ -55,7 +55,7 @@ match_policy_in(const struct sk_buff *skb, const struct xt_policy_info *info,
55 unsigned short family) 55 unsigned short family)
56{ 56{
57 const struct xt_policy_elem *e; 57 const struct xt_policy_elem *e;
58 struct sec_path *sp = skb->sp; 58 const struct sec_path *sp = skb->sp;
59 int strict = info->flags & XT_POLICY_MATCH_STRICT; 59 int strict = info->flags & XT_POLICY_MATCH_STRICT;
60 int i, pos; 60 int i, pos;
61 61
@@ -85,7 +85,7 @@ match_policy_out(const struct sk_buff *skb, const struct xt_policy_info *info,
85 unsigned short family) 85 unsigned short family)
86{ 86{
87 const struct xt_policy_elem *e; 87 const struct xt_policy_elem *e;
88 struct dst_entry *dst = skb->dst; 88 const struct dst_entry *dst = skb->dst;
89 int strict = info->flags & XT_POLICY_MATCH_STRICT; 89 int strict = info->flags & XT_POLICY_MATCH_STRICT;
90 int i, pos; 90 int i, pos;
91 91
@@ -108,14 +108,14 @@ match_policy_out(const struct sk_buff *skb, const struct xt_policy_info *info,
108 return strict ? i == info->len : 0; 108 return strict ? i == info->len : 0;
109} 109}
110 110
111static int match(const struct sk_buff *skb, 111static bool match(const struct sk_buff *skb,
112 const struct net_device *in, 112 const struct net_device *in,
113 const struct net_device *out, 113 const struct net_device *out,
114 const struct xt_match *match, 114 const struct xt_match *match,
115 const void *matchinfo, 115 const void *matchinfo,
116 int offset, 116 int offset,
117 unsigned int protoff, 117 unsigned int protoff,
118 int *hotdrop) 118 bool *hotdrop)
119{ 119{
120 const struct xt_policy_info *info = matchinfo; 120 const struct xt_policy_info *info = matchinfo;
121 int ret; 121 int ret;
@@ -126,45 +126,45 @@ static int match(const struct sk_buff *skb,
126 ret = match_policy_out(skb, info, match->family); 126 ret = match_policy_out(skb, info, match->family);
127 127
128 if (ret < 0) 128 if (ret < 0)
129 ret = info->flags & XT_POLICY_MATCH_NONE ? 1 : 0; 129 ret = info->flags & XT_POLICY_MATCH_NONE ? true : false;
130 else if (info->flags & XT_POLICY_MATCH_NONE) 130 else if (info->flags & XT_POLICY_MATCH_NONE)
131 ret = 0; 131 ret = false;
132 132
133 return ret; 133 return ret;
134} 134}
135 135
136static int checkentry(const char *tablename, const void *ip_void, 136static bool checkentry(const char *tablename, const void *ip_void,
137 const struct xt_match *match, 137 const struct xt_match *match,
138 void *matchinfo, unsigned int hook_mask) 138 void *matchinfo, unsigned int hook_mask)
139{ 139{
140 struct xt_policy_info *info = matchinfo; 140 struct xt_policy_info *info = matchinfo;
141 141
142 if (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT))) { 142 if (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT))) {
143 printk(KERN_ERR "xt_policy: neither incoming nor " 143 printk(KERN_ERR "xt_policy: neither incoming nor "
144 "outgoing policy selected\n"); 144 "outgoing policy selected\n");
145 return 0; 145 return false;
146 } 146 }
147 /* hook values are equal for IPv4 and IPv6 */ 147 /* hook values are equal for IPv4 and IPv6 */
148 if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN) 148 if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN)
149 && info->flags & XT_POLICY_MATCH_OUT) { 149 && info->flags & XT_POLICY_MATCH_OUT) {
150 printk(KERN_ERR "xt_policy: output policy not valid in " 150 printk(KERN_ERR "xt_policy: output policy not valid in "
151 "PRE_ROUTING and INPUT\n"); 151 "PRE_ROUTING and INPUT\n");
152 return 0; 152 return false;
153 } 153 }
154 if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT) 154 if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT)
155 && info->flags & XT_POLICY_MATCH_IN) { 155 && info->flags & XT_POLICY_MATCH_IN) {
156 printk(KERN_ERR "xt_policy: input policy not valid in " 156 printk(KERN_ERR "xt_policy: input policy not valid in "
157 "POST_ROUTING and OUTPUT\n"); 157 "POST_ROUTING and OUTPUT\n");
158 return 0; 158 return false;
159 } 159 }
160 if (info->len > XT_POLICY_MAX_ELEM) { 160 if (info->len > XT_POLICY_MAX_ELEM) {
161 printk(KERN_ERR "xt_policy: too many policy elements\n"); 161 printk(KERN_ERR "xt_policy: too many policy elements\n");
162 return 0; 162 return false;
163 } 163 }
164 return 1; 164 return true;
165} 165}
166 166
167static struct xt_match xt_policy_match[] = { 167static struct xt_match xt_policy_match[] __read_mostly = {
168 { 168 {
169 .name = "policy", 169 .name = "policy",
170 .family = AF_INET, 170 .family = AF_INET,
diff --git a/net/netfilter/xt_quota.c b/net/netfilter/xt_quota.c
index bfdde06ca0b7..dae97445b87b 100644
--- a/net/netfilter/xt_quota.c
+++ b/net/netfilter/xt_quota.c
@@ -16,19 +16,20 @@ MODULE_ALIAS("ip6t_quota");
16 16
17static DEFINE_SPINLOCK(quota_lock); 17static DEFINE_SPINLOCK(quota_lock);
18 18
19static int 19static bool
20match(const struct sk_buff *skb, 20match(const struct sk_buff *skb,
21 const struct net_device *in, const struct net_device *out, 21 const struct net_device *in, const struct net_device *out,
22 const struct xt_match *match, const void *matchinfo, 22 const struct xt_match *match, const void *matchinfo,
23 int offset, unsigned int protoff, int *hotdrop) 23 int offset, unsigned int protoff, bool *hotdrop)
24{ 24{
25 struct xt_quota_info *q = ((struct xt_quota_info *)matchinfo)->master; 25 struct xt_quota_info *q =
26 int ret = q->flags & XT_QUOTA_INVERT ? 1 : 0; 26 ((const struct xt_quota_info *)matchinfo)->master;
27 bool ret = q->flags & XT_QUOTA_INVERT;
27 28
28 spin_lock_bh(&quota_lock); 29 spin_lock_bh(&quota_lock);
29 if (q->quota >= skb->len) { 30 if (q->quota >= skb->len) {
30 q->quota -= skb->len; 31 q->quota -= skb->len;
31 ret ^= 1; 32 ret = !ret;
32 } else { 33 } else {
33 /* we do not allow even small packets from now on */ 34 /* we do not allow even small packets from now on */
34 q->quota = 0; 35 q->quota = 0;
@@ -38,21 +39,21 @@ match(const struct sk_buff *skb,
38 return ret; 39 return ret;
39} 40}
40 41
41static int 42static bool
42checkentry(const char *tablename, const void *entry, 43checkentry(const char *tablename, const void *entry,
43 const struct xt_match *match, void *matchinfo, 44 const struct xt_match *match, void *matchinfo,
44 unsigned int hook_mask) 45 unsigned int hook_mask)
45{ 46{
46 struct xt_quota_info *q = (struct xt_quota_info *)matchinfo; 47 struct xt_quota_info *q = matchinfo;
47 48
48 if (q->flags & ~XT_QUOTA_MASK) 49 if (q->flags & ~XT_QUOTA_MASK)
49 return 0; 50 return false;
50 /* For SMP, we only want to use one set of counters. */ 51 /* For SMP, we only want to use one set of counters. */
51 q->master = q; 52 q->master = q;
52 return 1; 53 return true;
53} 54}
54 55
55static struct xt_match xt_quota_match[] = { 56static struct xt_match xt_quota_match[] __read_mostly = {
56 { 57 {
57 .name = "quota", 58 .name = "quota",
58 .family = AF_INET, 59 .family = AF_INET,
diff --git a/net/netfilter/xt_realm.c b/net/netfilter/xt_realm.c
index c2017f8af9c4..cc3e76d77a99 100644
--- a/net/netfilter/xt_realm.c
+++ b/net/netfilter/xt_realm.c
@@ -21,7 +21,7 @@ MODULE_LICENSE("GPL");
21MODULE_DESCRIPTION("X_tables realm match"); 21MODULE_DESCRIPTION("X_tables realm match");
22MODULE_ALIAS("ipt_realm"); 22MODULE_ALIAS("ipt_realm");
23 23
24static int 24static bool
25match(const struct sk_buff *skb, 25match(const struct sk_buff *skb,
26 const struct net_device *in, 26 const struct net_device *in,
27 const struct net_device *out, 27 const struct net_device *out,
@@ -29,15 +29,15 @@ match(const struct sk_buff *skb,
29 const void *matchinfo, 29 const void *matchinfo,
30 int offset, 30 int offset,
31 unsigned int protoff, 31 unsigned int protoff,
32 int *hotdrop) 32 bool *hotdrop)
33{ 33{
34 const struct xt_realm_info *info = matchinfo; 34 const struct xt_realm_info *info = matchinfo;
35 struct dst_entry *dst = skb->dst; 35 const struct dst_entry *dst = skb->dst;
36 36
37 return (info->id == (dst->tclassid & info->mask)) ^ info->invert; 37 return (info->id == (dst->tclassid & info->mask)) ^ info->invert;
38} 38}
39 39
40static struct xt_match realm_match = { 40static struct xt_match realm_match __read_mostly = {
41 .name = "realm", 41 .name = "realm",
42 .match = match, 42 .match = match,
43 .matchsize = sizeof(struct xt_realm_info), 43 .matchsize = sizeof(struct xt_realm_info),
diff --git a/net/netfilter/xt_sctp.c b/net/netfilter/xt_sctp.c
index f86d8d769d47..c002153b80ab 100644
--- a/net/netfilter/xt_sctp.c
+++ b/net/netfilter/xt_sctp.c
@@ -23,7 +23,7 @@ MODULE_ALIAS("ipt_sctp");
23#define SCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \ 23#define SCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \
24 || (!!((invflag) & (option)) ^ (cond))) 24 || (!!((invflag) & (option)) ^ (cond)))
25 25
26static int 26static bool
27match_flags(const struct xt_sctp_flag_info *flag_info, 27match_flags(const struct xt_sctp_flag_info *flag_info,
28 const int flag_count, 28 const int flag_count,
29 u_int8_t chunktype, 29 u_int8_t chunktype,
@@ -31,23 +31,21 @@ match_flags(const struct xt_sctp_flag_info *flag_info,
31{ 31{
32 int i; 32 int i;
33 33
34 for (i = 0; i < flag_count; i++) { 34 for (i = 0; i < flag_count; i++)
35 if (flag_info[i].chunktype == chunktype) { 35 if (flag_info[i].chunktype == chunktype)
36 return (chunkflags & flag_info[i].flag_mask) == flag_info[i].flag; 36 return (chunkflags & flag_info[i].flag_mask) == flag_info[i].flag;
37 }
38 }
39 37
40 return 1; 38 return true;
41} 39}
42 40
43static inline int 41static inline bool
44match_packet(const struct sk_buff *skb, 42match_packet(const struct sk_buff *skb,
45 unsigned int offset, 43 unsigned int offset,
46 const u_int32_t *chunkmap, 44 const u_int32_t *chunkmap,
47 int chunk_match_type, 45 int chunk_match_type,
48 const struct xt_sctp_flag_info *flag_info, 46 const struct xt_sctp_flag_info *flag_info,
49 const int flag_count, 47 const int flag_count,
50 int *hotdrop) 48 bool *hotdrop)
51{ 49{
52 u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)]; 50 u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)];
53 sctp_chunkhdr_t _sch, *sch; 51 sctp_chunkhdr_t _sch, *sch;
@@ -56,16 +54,15 @@ match_packet(const struct sk_buff *skb,
56 int i = 0; 54 int i = 0;
57#endif 55#endif
58 56
59 if (chunk_match_type == SCTP_CHUNK_MATCH_ALL) { 57 if (chunk_match_type == SCTP_CHUNK_MATCH_ALL)
60 SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap); 58 SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap);
61 }
62 59
63 do { 60 do {
64 sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch); 61 sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch);
65 if (sch == NULL || sch->length == 0) { 62 if (sch == NULL || sch->length == 0) {
66 duprintf("Dropping invalid SCTP packet.\n"); 63 duprintf("Dropping invalid SCTP packet.\n");
67 *hotdrop = 1; 64 *hotdrop = true;
68 return 0; 65 return false;
69 } 66 }
70 67
71 duprintf("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d\tflags: %x\n", 68 duprintf("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d\tflags: %x\n",
@@ -80,28 +77,26 @@ match_packet(const struct sk_buff *skb,
80 case SCTP_CHUNK_MATCH_ANY: 77 case SCTP_CHUNK_MATCH_ANY:
81 if (match_flags(flag_info, flag_count, 78 if (match_flags(flag_info, flag_count,
82 sch->type, sch->flags)) { 79 sch->type, sch->flags)) {
83 return 1; 80 return true;
84 } 81 }
85 break; 82 break;
86 83
87 case SCTP_CHUNK_MATCH_ALL: 84 case SCTP_CHUNK_MATCH_ALL:
88 if (match_flags(flag_info, flag_count, 85 if (match_flags(flag_info, flag_count,
89 sch->type, sch->flags)) { 86 sch->type, sch->flags))
90 SCTP_CHUNKMAP_CLEAR(chunkmapcopy, sch->type); 87 SCTP_CHUNKMAP_CLEAR(chunkmapcopy, sch->type);
91 }
92 break; 88 break;
93 89
94 case SCTP_CHUNK_MATCH_ONLY: 90 case SCTP_CHUNK_MATCH_ONLY:
95 if (!match_flags(flag_info, flag_count, 91 if (!match_flags(flag_info, flag_count,
96 sch->type, sch->flags)) { 92 sch->type, sch->flags))
97 return 0; 93 return false;
98 }
99 break; 94 break;
100 } 95 }
101 } else { 96 } else {
102 switch (chunk_match_type) { 97 switch (chunk_match_type) {
103 case SCTP_CHUNK_MATCH_ONLY: 98 case SCTP_CHUNK_MATCH_ONLY:
104 return 0; 99 return false;
105 } 100 }
106 } 101 }
107 } while (offset < skb->len); 102 } while (offset < skb->len);
@@ -110,16 +105,16 @@ match_packet(const struct sk_buff *skb,
110 case SCTP_CHUNK_MATCH_ALL: 105 case SCTP_CHUNK_MATCH_ALL:
111 return SCTP_CHUNKMAP_IS_CLEAR(chunkmap); 106 return SCTP_CHUNKMAP_IS_CLEAR(chunkmap);
112 case SCTP_CHUNK_MATCH_ANY: 107 case SCTP_CHUNK_MATCH_ANY:
113 return 0; 108 return false;
114 case SCTP_CHUNK_MATCH_ONLY: 109 case SCTP_CHUNK_MATCH_ONLY:
115 return 1; 110 return true;
116 } 111 }
117 112
118 /* This will never be reached, but required to stop compiler whine */ 113 /* This will never be reached, but required to stop compiler whine */
119 return 0; 114 return false;
120} 115}
121 116
122static int 117static bool
123match(const struct sk_buff *skb, 118match(const struct sk_buff *skb,
124 const struct net_device *in, 119 const struct net_device *in,
125 const struct net_device *out, 120 const struct net_device *out,
@@ -127,29 +122,29 @@ match(const struct sk_buff *skb,
127 const void *matchinfo, 122 const void *matchinfo,
128 int offset, 123 int offset,
129 unsigned int protoff, 124 unsigned int protoff,
130 int *hotdrop) 125 bool *hotdrop)
131{ 126{
132 const struct xt_sctp_info *info = matchinfo; 127 const struct xt_sctp_info *info = matchinfo;
133 sctp_sctphdr_t _sh, *sh; 128 sctp_sctphdr_t _sh, *sh;
134 129
135 if (offset) { 130 if (offset) {
136 duprintf("Dropping non-first fragment.. FIXME\n"); 131 duprintf("Dropping non-first fragment.. FIXME\n");
137 return 0; 132 return false;
138 } 133 }
139 134
140 sh = skb_header_pointer(skb, protoff, sizeof(_sh), &_sh); 135 sh = skb_header_pointer(skb, protoff, sizeof(_sh), &_sh);
141 if (sh == NULL) { 136 if (sh == NULL) {
142 duprintf("Dropping evil TCP offset=0 tinygram.\n"); 137 duprintf("Dropping evil TCP offset=0 tinygram.\n");
143 *hotdrop = 1; 138 *hotdrop = true;
144 return 0; 139 return false;
145 } 140 }
146 duprintf("spt: %d\tdpt: %d\n", ntohs(sh->source), ntohs(sh->dest)); 141 duprintf("spt: %d\tdpt: %d\n", ntohs(sh->source), ntohs(sh->dest));
147 142
148 return SCCHECK(((ntohs(sh->source) >= info->spts[0]) 143 return SCCHECK(ntohs(sh->source) >= info->spts[0]
149 && (ntohs(sh->source) <= info->spts[1])), 144 && ntohs(sh->source) <= info->spts[1],
150 XT_SCTP_SRC_PORTS, info->flags, info->invflags) 145 XT_SCTP_SRC_PORTS, info->flags, info->invflags)
151 && SCCHECK(((ntohs(sh->dest) >= info->dpts[0]) 146 && SCCHECK(ntohs(sh->dest) >= info->dpts[0]
152 && (ntohs(sh->dest) <= info->dpts[1])), 147 && ntohs(sh->dest) <= info->dpts[1],
153 XT_SCTP_DEST_PORTS, info->flags, info->invflags) 148 XT_SCTP_DEST_PORTS, info->flags, info->invflags)
154 && SCCHECK(match_packet(skb, protoff + sizeof (sctp_sctphdr_t), 149 && SCCHECK(match_packet(skb, protoff + sizeof (sctp_sctphdr_t),
155 info->chunkmap, info->chunk_match_type, 150 info->chunkmap, info->chunk_match_type,
@@ -158,7 +153,7 @@ match(const struct sk_buff *skb,
158 XT_SCTP_CHUNK_TYPES, info->flags, info->invflags); 153 XT_SCTP_CHUNK_TYPES, info->flags, info->invflags);
159} 154}
160 155
161static int 156static bool
162checkentry(const char *tablename, 157checkentry(const char *tablename,
163 const void *inf, 158 const void *inf,
164 const struct xt_match *match, 159 const struct xt_match *match,
@@ -177,7 +172,7 @@ checkentry(const char *tablename,
177 | SCTP_CHUNK_MATCH_ONLY))); 172 | SCTP_CHUNK_MATCH_ONLY)));
178} 173}
179 174
180static struct xt_match xt_sctp_match[] = { 175static struct xt_match xt_sctp_match[] __read_mostly = {
181 { 176 {
182 .name = "sctp", 177 .name = "sctp",
183 .family = AF_INET, 178 .family = AF_INET,
diff --git a/net/netfilter/xt_state.c b/net/netfilter/xt_state.c
index 149294f7df71..e0a528df19a7 100644
--- a/net/netfilter/xt_state.c
+++ b/net/netfilter/xt_state.c
@@ -20,7 +20,7 @@ MODULE_DESCRIPTION("ip[6]_tables connection tracking state match module");
20MODULE_ALIAS("ipt_state"); 20MODULE_ALIAS("ipt_state");
21MODULE_ALIAS("ip6t_state"); 21MODULE_ALIAS("ip6t_state");
22 22
23static int 23static bool
24match(const struct sk_buff *skb, 24match(const struct sk_buff *skb,
25 const struct net_device *in, 25 const struct net_device *in,
26 const struct net_device *out, 26 const struct net_device *out,
@@ -28,7 +28,7 @@ match(const struct sk_buff *skb,
28 const void *matchinfo, 28 const void *matchinfo,
29 int offset, 29 int offset,
30 unsigned int protoff, 30 unsigned int protoff,
31 int *hotdrop) 31 bool *hotdrop)
32{ 32{
33 const struct xt_state_info *sinfo = matchinfo; 33 const struct xt_state_info *sinfo = matchinfo;
34 enum ip_conntrack_info ctinfo; 34 enum ip_conntrack_info ctinfo;
@@ -44,18 +44,18 @@ match(const struct sk_buff *skb,
44 return (sinfo->statemask & statebit); 44 return (sinfo->statemask & statebit);
45} 45}
46 46
47static int check(const char *tablename, 47static bool check(const char *tablename,
48 const void *inf, 48 const void *inf,
49 const struct xt_match *match, 49 const struct xt_match *match,
50 void *matchinfo, 50 void *matchinfo,
51 unsigned int hook_mask) 51 unsigned int hook_mask)
52{ 52{
53 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 53 if (nf_ct_l3proto_try_module_get(match->family) < 0) {
54 printk(KERN_WARNING "can't load conntrack support for " 54 printk(KERN_WARNING "can't load conntrack support for "
55 "proto=%d\n", match->family); 55 "proto=%d\n", match->family);
56 return 0; 56 return false;
57 } 57 }
58 return 1; 58 return true;
59} 59}
60 60
61static void 61static void
@@ -64,7 +64,7 @@ destroy(const struct xt_match *match, void *matchinfo)
64 nf_ct_l3proto_module_put(match->family); 64 nf_ct_l3proto_module_put(match->family);
65} 65}
66 66
67static struct xt_match xt_state_match[] = { 67static struct xt_match xt_state_match[] __read_mostly = {
68 { 68 {
69 .name = "state", 69 .name = "state",
70 .family = AF_INET, 70 .family = AF_INET,
diff --git a/net/netfilter/xt_statistic.c b/net/netfilter/xt_statistic.c
index 091a9f89f5d5..4089dae4e286 100644
--- a/net/netfilter/xt_statistic.c
+++ b/net/netfilter/xt_statistic.c
@@ -24,26 +24,26 @@ MODULE_ALIAS("ip6t_statistic");
24 24
25static DEFINE_SPINLOCK(nth_lock); 25static DEFINE_SPINLOCK(nth_lock);
26 26
27static int 27static bool
28match(const struct sk_buff *skb, 28match(const struct sk_buff *skb,
29 const struct net_device *in, const struct net_device *out, 29 const struct net_device *in, const struct net_device *out,
30 const struct xt_match *match, const void *matchinfo, 30 const struct xt_match *match, const void *matchinfo,
31 int offset, unsigned int protoff, int *hotdrop) 31 int offset, unsigned int protoff, bool *hotdrop)
32{ 32{
33 struct xt_statistic_info *info = (struct xt_statistic_info *)matchinfo; 33 struct xt_statistic_info *info = (struct xt_statistic_info *)matchinfo;
34 int ret = info->flags & XT_STATISTIC_INVERT ? 1 : 0; 34 bool ret = info->flags & XT_STATISTIC_INVERT;
35 35
36 switch (info->mode) { 36 switch (info->mode) {
37 case XT_STATISTIC_MODE_RANDOM: 37 case XT_STATISTIC_MODE_RANDOM:
38 if ((net_random() & 0x7FFFFFFF) < info->u.random.probability) 38 if ((net_random() & 0x7FFFFFFF) < info->u.random.probability)
39 ret ^= 1; 39 ret = !ret;
40 break; 40 break;
41 case XT_STATISTIC_MODE_NTH: 41 case XT_STATISTIC_MODE_NTH:
42 info = info->master; 42 info = info->master;
43 spin_lock_bh(&nth_lock); 43 spin_lock_bh(&nth_lock);
44 if (info->u.nth.count++ == info->u.nth.every) { 44 if (info->u.nth.count++ == info->u.nth.every) {
45 info->u.nth.count = 0; 45 info->u.nth.count = 0;
46 ret ^= 1; 46 ret = !ret;
47 } 47 }
48 spin_unlock_bh(&nth_lock); 48 spin_unlock_bh(&nth_lock);
49 break; 49 break;
@@ -52,21 +52,21 @@ match(const struct sk_buff *skb,
52 return ret; 52 return ret;
53} 53}
54 54
55static int 55static bool
56checkentry(const char *tablename, const void *entry, 56checkentry(const char *tablename, const void *entry,
57 const struct xt_match *match, void *matchinfo, 57 const struct xt_match *match, void *matchinfo,
58 unsigned int hook_mask) 58 unsigned int hook_mask)
59{ 59{
60 struct xt_statistic_info *info = (struct xt_statistic_info *)matchinfo; 60 struct xt_statistic_info *info = matchinfo;
61 61
62 if (info->mode > XT_STATISTIC_MODE_MAX || 62 if (info->mode > XT_STATISTIC_MODE_MAX ||
63 info->flags & ~XT_STATISTIC_MASK) 63 info->flags & ~XT_STATISTIC_MASK)
64 return 0; 64 return false;
65 info->master = info; 65 info->master = info;
66 return 1; 66 return true;
67} 67}
68 68
69static struct xt_match xt_statistic_match[] = { 69static struct xt_match xt_statistic_match[] __read_mostly = {
70 { 70 {
71 .name = "statistic", 71 .name = "statistic",
72 .family = AF_INET, 72 .family = AF_INET,
diff --git a/net/netfilter/xt_string.c b/net/netfilter/xt_string.c
index 999a005dbd0c..864133442cda 100644
--- a/net/netfilter/xt_string.c
+++ b/net/netfilter/xt_string.c
@@ -21,14 +21,14 @@ MODULE_LICENSE("GPL");
21MODULE_ALIAS("ipt_string"); 21MODULE_ALIAS("ipt_string");
22MODULE_ALIAS("ip6t_string"); 22MODULE_ALIAS("ip6t_string");
23 23
24static int match(const struct sk_buff *skb, 24static bool match(const struct sk_buff *skb,
25 const struct net_device *in, 25 const struct net_device *in,
26 const struct net_device *out, 26 const struct net_device *out,
27 const struct xt_match *match, 27 const struct xt_match *match,
28 const void *matchinfo, 28 const void *matchinfo,
29 int offset, 29 int offset,
30 unsigned int protoff, 30 unsigned int protoff,
31 int *hotdrop) 31 bool *hotdrop)
32{ 32{
33 const struct xt_string_info *conf = matchinfo; 33 const struct xt_string_info *conf = matchinfo;
34 struct ts_state state; 34 struct ts_state state;
@@ -42,30 +42,30 @@ static int match(const struct sk_buff *skb,
42 42
43#define STRING_TEXT_PRIV(m) ((struct xt_string_info *) m) 43#define STRING_TEXT_PRIV(m) ((struct xt_string_info *) m)
44 44
45static int checkentry(const char *tablename, 45static bool checkentry(const char *tablename,
46 const void *ip, 46 const void *ip,
47 const struct xt_match *match, 47 const struct xt_match *match,
48 void *matchinfo, 48 void *matchinfo,
49 unsigned int hook_mask) 49 unsigned int hook_mask)
50{ 50{
51 struct xt_string_info *conf = matchinfo; 51 struct xt_string_info *conf = matchinfo;
52 struct ts_config *ts_conf; 52 struct ts_config *ts_conf;
53 53
54 /* Damn, can't handle this case properly with iptables... */ 54 /* Damn, can't handle this case properly with iptables... */
55 if (conf->from_offset > conf->to_offset) 55 if (conf->from_offset > conf->to_offset)
56 return 0; 56 return false;
57 if (conf->algo[XT_STRING_MAX_ALGO_NAME_SIZE - 1] != '\0') 57 if (conf->algo[XT_STRING_MAX_ALGO_NAME_SIZE - 1] != '\0')
58 return 0; 58 return false;
59 if (conf->patlen > XT_STRING_MAX_PATTERN_SIZE) 59 if (conf->patlen > XT_STRING_MAX_PATTERN_SIZE)
60 return 0; 60 return false;
61 ts_conf = textsearch_prepare(conf->algo, conf->pattern, conf->patlen, 61 ts_conf = textsearch_prepare(conf->algo, conf->pattern, conf->patlen,
62 GFP_KERNEL, TS_AUTOLOAD); 62 GFP_KERNEL, TS_AUTOLOAD);
63 if (IS_ERR(ts_conf)) 63 if (IS_ERR(ts_conf))
64 return 0; 64 return false;
65 65
66 conf->config = ts_conf; 66 conf->config = ts_conf;
67 67
68 return 1; 68 return true;
69} 69}
70 70
71static void destroy(const struct xt_match *match, void *matchinfo) 71static void destroy(const struct xt_match *match, void *matchinfo)
@@ -73,7 +73,7 @@ static void destroy(const struct xt_match *match, void *matchinfo)
73 textsearch_destroy(STRING_TEXT_PRIV(matchinfo)->config); 73 textsearch_destroy(STRING_TEXT_PRIV(matchinfo)->config);
74} 74}
75 75
76static struct xt_match xt_string_match[] = { 76static struct xt_match xt_string_match[] __read_mostly = {
77 { 77 {
78 .name = "string", 78 .name = "string",
79 .family = AF_INET, 79 .family = AF_INET,
diff --git a/net/netfilter/xt_tcpmss.c b/net/netfilter/xt_tcpmss.c
index 80571d0749f7..cd5f6d758c68 100644
--- a/net/netfilter/xt_tcpmss.c
+++ b/net/netfilter/xt_tcpmss.c
@@ -23,7 +23,7 @@ MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
23MODULE_DESCRIPTION("iptables TCP MSS match module"); 23MODULE_DESCRIPTION("iptables TCP MSS match module");
24MODULE_ALIAS("ipt_tcpmss"); 24MODULE_ALIAS("ipt_tcpmss");
25 25
26static int 26static bool
27match(const struct sk_buff *skb, 27match(const struct sk_buff *skb,
28 const struct net_device *in, 28 const struct net_device *in,
29 const struct net_device *out, 29 const struct net_device *out,
@@ -31,7 +31,7 @@ match(const struct sk_buff *skb,
31 const void *matchinfo, 31 const void *matchinfo,
32 int offset, 32 int offset,
33 unsigned int protoff, 33 unsigned int protoff,
34 int *hotdrop) 34 bool *hotdrop)
35{ 35{
36 const struct xt_tcpmss_match_info *info = matchinfo; 36 const struct xt_tcpmss_match_info *info = matchinfo;
37 struct tcphdr _tcph, *th; 37 struct tcphdr _tcph, *th;
@@ -77,11 +77,11 @@ out:
77 return info->invert; 77 return info->invert;
78 78
79dropit: 79dropit:
80 *hotdrop = 1; 80 *hotdrop = true;
81 return 0; 81 return false;
82} 82}
83 83
84static struct xt_match xt_tcpmss_match[] = { 84static struct xt_match xt_tcpmss_match[] __read_mostly = {
85 { 85 {
86 .name = "tcpmss", 86 .name = "tcpmss",
87 .family = AF_INET, 87 .family = AF_INET,
diff --git a/net/netfilter/xt_tcpudp.c b/net/netfilter/xt_tcpudp.c
index 46414b562a19..ab7d845224fc 100644
--- a/net/netfilter/xt_tcpudp.c
+++ b/net/netfilter/xt_tcpudp.c
@@ -27,22 +27,19 @@ MODULE_ALIAS("ip6t_tcp");
27 27
28 28
29/* Returns 1 if the port is matched by the range, 0 otherwise */ 29/* Returns 1 if the port is matched by the range, 0 otherwise */
30static inline int 30static inline bool
31port_match(u_int16_t min, u_int16_t max, u_int16_t port, int invert) 31port_match(u_int16_t min, u_int16_t max, u_int16_t port, bool invert)
32{ 32{
33 int ret; 33 return (port >= min && port <= max) ^ invert;
34
35 ret = (port >= min && port <= max) ^ invert;
36 return ret;
37} 34}
38 35
39static int 36static bool
40tcp_find_option(u_int8_t option, 37tcp_find_option(u_int8_t option,
41 const struct sk_buff *skb, 38 const struct sk_buff *skb,
42 unsigned int protoff, 39 unsigned int protoff,
43 unsigned int optlen, 40 unsigned int optlen,
44 int invert, 41 bool invert,
45 int *hotdrop) 42 bool *hotdrop)
46{ 43{
47 /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ 44 /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */
48 u_int8_t _opt[60 - sizeof(struct tcphdr)], *op; 45 u_int8_t _opt[60 - sizeof(struct tcphdr)], *op;
@@ -57,8 +54,8 @@ tcp_find_option(u_int8_t option,
57 op = skb_header_pointer(skb, protoff + sizeof(struct tcphdr), 54 op = skb_header_pointer(skb, protoff + sizeof(struct tcphdr),
58 optlen, _opt); 55 optlen, _opt);
59 if (op == NULL) { 56 if (op == NULL) {
60 *hotdrop = 1; 57 *hotdrop = true;
61 return 0; 58 return false;
62 } 59 }
63 60
64 for (i = 0; i < optlen; ) { 61 for (i = 0; i < optlen; ) {
@@ -70,7 +67,7 @@ tcp_find_option(u_int8_t option,
70 return invert; 67 return invert;
71} 68}
72 69
73static int 70static bool
74tcp_match(const struct sk_buff *skb, 71tcp_match(const struct sk_buff *skb,
75 const struct net_device *in, 72 const struct net_device *in,
76 const struct net_device *out, 73 const struct net_device *out,
@@ -78,7 +75,7 @@ tcp_match(const struct sk_buff *skb,
78 const void *matchinfo, 75 const void *matchinfo,
79 int offset, 76 int offset,
80 unsigned int protoff, 77 unsigned int protoff,
81 int *hotdrop) 78 bool *hotdrop)
82{ 79{
83 struct tcphdr _tcph, *th; 80 struct tcphdr _tcph, *th;
84 const struct xt_tcp *tcpinfo = matchinfo; 81 const struct xt_tcp *tcpinfo = matchinfo;
@@ -92,51 +89,51 @@ tcp_match(const struct sk_buff *skb,
92 */ 89 */
93 if (offset == 1) { 90 if (offset == 1) {
94 duprintf("Dropping evil TCP offset=1 frag.\n"); 91 duprintf("Dropping evil TCP offset=1 frag.\n");
95 *hotdrop = 1; 92 *hotdrop = true;
96 } 93 }
97 /* Must not be a fragment. */ 94 /* Must not be a fragment. */
98 return 0; 95 return false;
99 } 96 }
100 97
101#define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg)) 98#define FWINVTCP(bool, invflg) ((bool) ^ !!(tcpinfo->invflags & (invflg)))
102 99
103 th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph); 100 th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph);
104 if (th == NULL) { 101 if (th == NULL) {
105 /* We've been asked to examine this packet, and we 102 /* We've been asked to examine this packet, and we
106 can't. Hence, no choice but to drop. */ 103 can't. Hence, no choice but to drop. */
107 duprintf("Dropping evil TCP offset=0 tinygram.\n"); 104 duprintf("Dropping evil TCP offset=0 tinygram.\n");
108 *hotdrop = 1; 105 *hotdrop = true;
109 return 0; 106 return false;
110 } 107 }
111 108
112 if (!port_match(tcpinfo->spts[0], tcpinfo->spts[1], 109 if (!port_match(tcpinfo->spts[0], tcpinfo->spts[1],
113 ntohs(th->source), 110 ntohs(th->source),
114 !!(tcpinfo->invflags & XT_TCP_INV_SRCPT))) 111 !!(tcpinfo->invflags & XT_TCP_INV_SRCPT)))
115 return 0; 112 return false;
116 if (!port_match(tcpinfo->dpts[0], tcpinfo->dpts[1], 113 if (!port_match(tcpinfo->dpts[0], tcpinfo->dpts[1],
117 ntohs(th->dest), 114 ntohs(th->dest),
118 !!(tcpinfo->invflags & XT_TCP_INV_DSTPT))) 115 !!(tcpinfo->invflags & XT_TCP_INV_DSTPT)))
119 return 0; 116 return false;
120 if (!FWINVTCP((((unsigned char *)th)[13] & tcpinfo->flg_mask) 117 if (!FWINVTCP((((unsigned char *)th)[13] & tcpinfo->flg_mask)
121 == tcpinfo->flg_cmp, 118 == tcpinfo->flg_cmp,
122 XT_TCP_INV_FLAGS)) 119 XT_TCP_INV_FLAGS))
123 return 0; 120 return false;
124 if (tcpinfo->option) { 121 if (tcpinfo->option) {
125 if (th->doff * 4 < sizeof(_tcph)) { 122 if (th->doff * 4 < sizeof(_tcph)) {
126 *hotdrop = 1; 123 *hotdrop = true;
127 return 0; 124 return false;
128 } 125 }
129 if (!tcp_find_option(tcpinfo->option, skb, protoff, 126 if (!tcp_find_option(tcpinfo->option, skb, protoff,
130 th->doff*4 - sizeof(_tcph), 127 th->doff*4 - sizeof(_tcph),
131 tcpinfo->invflags & XT_TCP_INV_OPTION, 128 tcpinfo->invflags & XT_TCP_INV_OPTION,
132 hotdrop)) 129 hotdrop))
133 return 0; 130 return false;
134 } 131 }
135 return 1; 132 return true;
136} 133}
137 134
138/* Called when user tries to insert an entry of this type. */ 135/* Called when user tries to insert an entry of this type. */
139static int 136static bool
140tcp_checkentry(const char *tablename, 137tcp_checkentry(const char *tablename,
141 const void *info, 138 const void *info,
142 const struct xt_match *match, 139 const struct xt_match *match,
@@ -149,7 +146,7 @@ tcp_checkentry(const char *tablename,
149 return !(tcpinfo->invflags & ~XT_TCP_INV_MASK); 146 return !(tcpinfo->invflags & ~XT_TCP_INV_MASK);
150} 147}
151 148
152static int 149static bool
153udp_match(const struct sk_buff *skb, 150udp_match(const struct sk_buff *skb,
154 const struct net_device *in, 151 const struct net_device *in,
155 const struct net_device *out, 152 const struct net_device *out,
@@ -157,22 +154,22 @@ udp_match(const struct sk_buff *skb,
157 const void *matchinfo, 154 const void *matchinfo,
158 int offset, 155 int offset,
159 unsigned int protoff, 156 unsigned int protoff,
160 int *hotdrop) 157 bool *hotdrop)
161{ 158{
162 struct udphdr _udph, *uh; 159 struct udphdr _udph, *uh;
163 const struct xt_udp *udpinfo = matchinfo; 160 const struct xt_udp *udpinfo = matchinfo;
164 161
165 /* Must not be a fragment. */ 162 /* Must not be a fragment. */
166 if (offset) 163 if (offset)
167 return 0; 164 return false;
168 165
169 uh = skb_header_pointer(skb, protoff, sizeof(_udph), &_udph); 166 uh = skb_header_pointer(skb, protoff, sizeof(_udph), &_udph);
170 if (uh == NULL) { 167 if (uh == NULL) {
171 /* We've been asked to examine this packet, and we 168 /* We've been asked to examine this packet, and we
172 can't. Hence, no choice but to drop. */ 169 can't. Hence, no choice but to drop. */
173 duprintf("Dropping evil UDP tinygram.\n"); 170 duprintf("Dropping evil UDP tinygram.\n");
174 *hotdrop = 1; 171 *hotdrop = true;
175 return 0; 172 return false;
176 } 173 }
177 174
178 return port_match(udpinfo->spts[0], udpinfo->spts[1], 175 return port_match(udpinfo->spts[0], udpinfo->spts[1],
@@ -184,7 +181,7 @@ udp_match(const struct sk_buff *skb,
184} 181}
185 182
186/* Called when user tries to insert an entry of this type. */ 183/* Called when user tries to insert an entry of this type. */
187static int 184static bool
188udp_checkentry(const char *tablename, 185udp_checkentry(const char *tablename,
189 const void *info, 186 const void *info,
190 const struct xt_match *match, 187 const struct xt_match *match,
@@ -197,7 +194,7 @@ udp_checkentry(const char *tablename,
197 return !(udpinfo->invflags & ~XT_UDP_INV_MASK); 194 return !(udpinfo->invflags & ~XT_UDP_INV_MASK);
198} 195}
199 196
200static struct xt_match xt_tcpudp_match[] = { 197static struct xt_match xt_tcpudp_match[] __read_mostly = {
201 { 198 {
202 .name = "tcp", 199 .name = "tcp",
203 .family = AF_INET, 200 .family = AF_INET,
diff --git a/net/netfilter/xt_u32.c b/net/netfilter/xt_u32.c
new file mode 100644
index 000000000000..04b677ae8dae
--- /dev/null
+++ b/net/netfilter/xt_u32.c
@@ -0,0 +1,135 @@
1/*
2 * xt_u32 - kernel module to match u32 packet content
3 *
4 * Original author: Don Cohen <don@isis.cs3-inc.com>
5 * © Jan Engelhardt <jengelh@gmx.de>, 2007
6 */
7
8#include <linux/module.h>
9#include <linux/moduleparam.h>
10#include <linux/spinlock.h>
11#include <linux/skbuff.h>
12#include <linux/types.h>
13#include <linux/netfilter/x_tables.h>
14#include <linux/netfilter/xt_u32.h>
15
16static bool u32_match_it(const struct xt_u32 *data,
17 const struct sk_buff *skb)
18{
19 const struct xt_u32_test *ct;
20 unsigned int testind;
21 unsigned int nnums;
22 unsigned int nvals;
23 unsigned int i;
24 u_int32_t pos;
25 u_int32_t val;
26 u_int32_t at;
27 int ret;
28
29 /*
30 * Small example: "0 >> 28 == 4 && 8 & 0xFF0000 >> 16 = 6, 17"
31 * (=IPv4 and (TCP or UDP)). Outer loop runs over the "&&" operands.
32 */
33 for (testind = 0; testind < data->ntests; ++testind) {
34 ct = &data->tests[testind];
35 at = 0;
36 pos = ct->location[0].number;
37
38 if (skb->len < 4 || pos > skb->len - 4);
39 return false;
40
41 ret = skb_copy_bits(skb, pos, &val, sizeof(val));
42 BUG_ON(ret < 0);
43 val = ntohl(val);
44 nnums = ct->nnums;
45
46 /* Inner loop runs over "&", "<<", ">>" and "@" operands */
47 for (i = 1; i < nnums; ++i) {
48 u_int32_t number = ct->location[i].number;
49 switch (ct->location[i].nextop) {
50 case XT_U32_AND:
51 val &= number;
52 break;
53 case XT_U32_LEFTSH:
54 val <<= number;
55 break;
56 case XT_U32_RIGHTSH:
57 val >>= number;
58 break;
59 case XT_U32_AT:
60 if (at + val < at)
61 return false;
62 at += val;
63 pos = number;
64 if (at + 4 < at || skb->len < at + 4 ||
65 pos > skb->len - at - 4)
66 return false;
67
68 ret = skb_copy_bits(skb, at + pos, &val,
69 sizeof(val));
70 BUG_ON(ret < 0);
71 val = ntohl(val);
72 break;
73 }
74 }
75
76 /* Run over the "," and ":" operands */
77 nvals = ct->nvalues;
78 for (i = 0; i < nvals; ++i)
79 if (ct->value[i].min <= val && val <= ct->value[i].max)
80 break;
81
82 if (i >= ct->nvalues)
83 return false;
84 }
85
86 return true;
87}
88
89static bool u32_match(const struct sk_buff *skb,
90 const struct net_device *in,
91 const struct net_device *out,
92 const struct xt_match *match, const void *matchinfo,
93 int offset, unsigned int protoff, bool *hotdrop)
94{
95 const struct xt_u32 *data = matchinfo;
96 bool ret;
97
98 ret = u32_match_it(data, skb);
99 return ret ^ data->invert;
100}
101
102static struct xt_match u32_reg[] __read_mostly = {
103 {
104 .name = "u32",
105 .family = AF_INET,
106 .match = u32_match,
107 .matchsize = sizeof(struct xt_u32),
108 .me = THIS_MODULE,
109 },
110 {
111 .name = "u32",
112 .family = AF_INET6,
113 .match = u32_match,
114 .matchsize = sizeof(struct xt_u32),
115 .me = THIS_MODULE,
116 },
117};
118
119static int __init xt_u32_init(void)
120{
121 return xt_register_matches(u32_reg, ARRAY_SIZE(u32_reg));
122}
123
124static void __exit xt_u32_exit(void)
125{
126 xt_unregister_matches(u32_reg, ARRAY_SIZE(u32_reg));
127}
128
129module_init(xt_u32_init);
130module_exit(xt_u32_exit);
131MODULE_AUTHOR("Jan Engelhardt <jengelh@gmx.de>");
132MODULE_DESCRIPTION("netfilter u32 match module");
133MODULE_LICENSE("GPL");
134MODULE_ALIAS("ipt_u32");
135MODULE_ALIAS("ip6t_u32");
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 1f15821c8da4..a3c8e692f493 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1713,7 +1713,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v)
1713 return 0; 1713 return 0;
1714} 1714}
1715 1715
1716static struct seq_operations netlink_seq_ops = { 1716static const struct seq_operations netlink_seq_ops = {
1717 .start = netlink_seq_start, 1717 .start = netlink_seq_start,
1718 .next = netlink_seq_next, 1718 .next = netlink_seq_next,
1719 .stop = netlink_seq_stop, 1719 .stop = netlink_seq_stop,
diff --git a/net/netlink/attr.c b/net/netlink/attr.c
index c591212793ee..e4d7bed99c2e 100644
--- a/net/netlink/attr.c
+++ b/net/netlink/attr.c
@@ -72,6 +72,17 @@ static int validate_nla(struct nlattr *nla, int maxtype,
72 return -ERANGE; 72 return -ERANGE;
73 break; 73 break;
74 74
75 case NLA_NESTED_COMPAT:
76 if (attrlen < pt->len)
77 return -ERANGE;
78 if (attrlen < NLA_ALIGN(pt->len))
79 break;
80 if (attrlen < NLA_ALIGN(pt->len) + NLA_HDRLEN)
81 return -ERANGE;
82 nla = nla_data(nla) + NLA_ALIGN(pt->len);
83 if (attrlen < NLA_ALIGN(pt->len) + NLA_HDRLEN + nla_len(nla))
84 return -ERANGE;
85 break;
75 default: 86 default:
76 if (pt->len) 87 if (pt->len)
77 minlen = pt->len; 88 minlen = pt->len;
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 5d4a26c2aa0c..5d66490dd290 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -1328,7 +1328,7 @@ static int nr_info_show(struct seq_file *seq, void *v)
1328 return 0; 1328 return 0;
1329} 1329}
1330 1330
1331static struct seq_operations nr_info_seqops = { 1331static const struct seq_operations nr_info_seqops = {
1332 .start = nr_info_start, 1332 .start = nr_info_start,
1333 .next = nr_info_next, 1333 .next = nr_info_next,
1334 .stop = nr_info_stop, 1334 .stop = nr_info_stop,
diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c
index 2f76e062609d..24fe4a66d297 100644
--- a/net/netrom/nr_route.c
+++ b/net/netrom/nr_route.c
@@ -922,7 +922,7 @@ static int nr_node_show(struct seq_file *seq, void *v)
922 return 0; 922 return 0;
923} 923}
924 924
925static struct seq_operations nr_node_seqops = { 925static const struct seq_operations nr_node_seqops = {
926 .start = nr_node_start, 926 .start = nr_node_start,
927 .next = nr_node_next, 927 .next = nr_node_next,
928 .stop = nr_node_stop, 928 .stop = nr_node_stop,
@@ -1006,7 +1006,7 @@ static int nr_neigh_show(struct seq_file *seq, void *v)
1006 return 0; 1006 return 0;
1007} 1007}
1008 1008
1009static struct seq_operations nr_neigh_seqops = { 1009static const struct seq_operations nr_neigh_seqops = {
1010 .start = nr_neigh_start, 1010 .start = nr_neigh_start,
1011 .next = nr_neigh_next, 1011 .next = nr_neigh_next,
1012 .stop = nr_neigh_stop, 1012 .stop = nr_neigh_stop,
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index f8b83014ccca..7c27bd389b7e 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1928,7 +1928,7 @@ static int packet_seq_show(struct seq_file *seq, void *v)
1928 return 0; 1928 return 0;
1929} 1929}
1930 1930
1931static struct seq_operations packet_seq_ops = { 1931static const struct seq_operations packet_seq_ops = {
1932 .start = packet_seq_start, 1932 .start = packet_seq_start,
1933 .next = packet_seq_next, 1933 .next = packet_seq_next,
1934 .stop = packet_seq_stop, 1934 .stop = packet_seq_stop,
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index d476c43d5216..f4d3aba00800 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -1454,7 +1454,7 @@ static int rose_info_show(struct seq_file *seq, void *v)
1454 return 0; 1454 return 0;
1455} 1455}
1456 1456
1457static struct seq_operations rose_info_seqops = { 1457static const struct seq_operations rose_info_seqops = {
1458 .start = rose_info_start, 1458 .start = rose_info_start,
1459 .next = rose_info_next, 1459 .next = rose_info_next,
1460 .stop = rose_info_stop, 1460 .stop = rose_info_stop,
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
index 929a784a86d7..bbcbad1da0d0 100644
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -1118,7 +1118,7 @@ static int rose_node_show(struct seq_file *seq, void *v)
1118 return 0; 1118 return 0;
1119} 1119}
1120 1120
1121static struct seq_operations rose_node_seqops = { 1121static const struct seq_operations rose_node_seqops = {
1122 .start = rose_node_start, 1122 .start = rose_node_start,
1123 .next = rose_node_next, 1123 .next = rose_node_next,
1124 .stop = rose_node_stop, 1124 .stop = rose_node_stop,
@@ -1200,7 +1200,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
1200} 1200}
1201 1201
1202 1202
1203static struct seq_operations rose_neigh_seqops = { 1203static const struct seq_operations rose_neigh_seqops = {
1204 .start = rose_neigh_start, 1204 .start = rose_neigh_start,
1205 .next = rose_neigh_next, 1205 .next = rose_neigh_next,
1206 .stop = rose_neigh_stop, 1206 .stop = rose_neigh_stop,
@@ -1284,7 +1284,7 @@ static int rose_route_show(struct seq_file *seq, void *v)
1284 return 0; 1284 return 0;
1285} 1285}
1286 1286
1287static struct seq_operations rose_route_seqops = { 1287static const struct seq_operations rose_route_seqops = {
1288 .start = rose_route_start, 1288 .start = rose_route_start,
1289 .next = rose_route_next, 1289 .next = rose_route_next,
1290 .stop = rose_route_stop, 1290 .stop = rose_route_stop,
diff --git a/net/rxrpc/ar-proc.c b/net/rxrpc/ar-proc.c
index 1c0be0e77b16..2e83ce325d15 100644
--- a/net/rxrpc/ar-proc.c
+++ b/net/rxrpc/ar-proc.c
@@ -30,31 +30,13 @@ static const char *rxrpc_conn_states[] = {
30 */ 30 */
31static void *rxrpc_call_seq_start(struct seq_file *seq, loff_t *_pos) 31static void *rxrpc_call_seq_start(struct seq_file *seq, loff_t *_pos)
32{ 32{
33 struct list_head *_p;
34 loff_t pos = *_pos;
35
36 read_lock(&rxrpc_call_lock); 33 read_lock(&rxrpc_call_lock);
37 if (!pos) 34 return seq_list_start_head(&rxrpc_calls, *_pos);
38 return SEQ_START_TOKEN;
39 pos--;
40
41 list_for_each(_p, &rxrpc_calls)
42 if (!pos--)
43 break;
44
45 return _p != &rxrpc_calls ? _p : NULL;
46} 35}
47 36
48static void *rxrpc_call_seq_next(struct seq_file *seq, void *v, loff_t *pos) 37static void *rxrpc_call_seq_next(struct seq_file *seq, void *v, loff_t *pos)
49{ 38{
50 struct list_head *_p; 39 return seq_list_next(v, &rxrpc_calls, pos);
51
52 (*pos)++;
53
54 _p = v;
55 _p = (v == SEQ_START_TOKEN) ? rxrpc_calls.next : _p->next;
56
57 return _p != &rxrpc_calls ? _p : NULL;
58} 40}
59 41
60static void rxrpc_call_seq_stop(struct seq_file *seq, void *v) 42static void rxrpc_call_seq_stop(struct seq_file *seq, void *v)
@@ -68,7 +50,7 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
68 struct rxrpc_call *call; 50 struct rxrpc_call *call;
69 char lbuff[4 + 4 + 4 + 4 + 5 + 1], rbuff[4 + 4 + 4 + 4 + 5 + 1]; 51 char lbuff[4 + 4 + 4 + 4 + 5 + 1], rbuff[4 + 4 + 4 + 4 + 5 + 1];
70 52
71 if (v == SEQ_START_TOKEN) { 53 if (v == &rxrpc_calls) {
72 seq_puts(seq, 54 seq_puts(seq,
73 "Proto Local Remote " 55 "Proto Local Remote "
74 " SvID ConnID CallID End Use State Abort " 56 " SvID ConnID CallID End Use State Abort "
@@ -104,7 +86,7 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
104 return 0; 86 return 0;
105} 87}
106 88
107static struct seq_operations rxrpc_call_seq_ops = { 89static const struct seq_operations rxrpc_call_seq_ops = {
108 .start = rxrpc_call_seq_start, 90 .start = rxrpc_call_seq_start,
109 .next = rxrpc_call_seq_next, 91 .next = rxrpc_call_seq_next,
110 .stop = rxrpc_call_seq_stop, 92 .stop = rxrpc_call_seq_stop,
@@ -129,32 +111,14 @@ struct file_operations rxrpc_call_seq_fops = {
129 */ 111 */
130static void *rxrpc_connection_seq_start(struct seq_file *seq, loff_t *_pos) 112static void *rxrpc_connection_seq_start(struct seq_file *seq, loff_t *_pos)
131{ 113{
132 struct list_head *_p;
133 loff_t pos = *_pos;
134
135 read_lock(&rxrpc_connection_lock); 114 read_lock(&rxrpc_connection_lock);
136 if (!pos) 115 return seq_list_start_head(&rxrpc_connections, *_pos);
137 return SEQ_START_TOKEN;
138 pos--;
139
140 list_for_each(_p, &rxrpc_connections)
141 if (!pos--)
142 break;
143
144 return _p != &rxrpc_connections ? _p : NULL;
145} 116}
146 117
147static void *rxrpc_connection_seq_next(struct seq_file *seq, void *v, 118static void *rxrpc_connection_seq_next(struct seq_file *seq, void *v,
148 loff_t *pos) 119 loff_t *pos)
149{ 120{
150 struct list_head *_p; 121 return seq_list_next(v, &rxrpc_connections, pos);
151
152 (*pos)++;
153
154 _p = v;
155 _p = (v == SEQ_START_TOKEN) ? rxrpc_connections.next : _p->next;
156
157 return _p != &rxrpc_connections ? _p : NULL;
158} 122}
159 123
160static void rxrpc_connection_seq_stop(struct seq_file *seq, void *v) 124static void rxrpc_connection_seq_stop(struct seq_file *seq, void *v)
@@ -168,7 +132,7 @@ static int rxrpc_connection_seq_show(struct seq_file *seq, void *v)
168 struct rxrpc_transport *trans; 132 struct rxrpc_transport *trans;
169 char lbuff[4 + 4 + 4 + 4 + 5 + 1], rbuff[4 + 4 + 4 + 4 + 5 + 1]; 133 char lbuff[4 + 4 + 4 + 4 + 5 + 1], rbuff[4 + 4 + 4 + 4 + 5 + 1];
170 134
171 if (v == SEQ_START_TOKEN) { 135 if (v == &rxrpc_connections) {
172 seq_puts(seq, 136 seq_puts(seq,
173 "Proto Local Remote " 137 "Proto Local Remote "
174 " SvID ConnID Calls End Use State Key " 138 " SvID ConnID Calls End Use State Key "
@@ -206,7 +170,7 @@ static int rxrpc_connection_seq_show(struct seq_file *seq, void *v)
206 return 0; 170 return 0;
207} 171}
208 172
209static struct seq_operations rxrpc_connection_seq_ops = { 173static const struct seq_operations rxrpc_connection_seq_ops = {
210 .start = rxrpc_connection_seq_start, 174 .start = rxrpc_connection_seq_start,
211 .next = rxrpc_connection_seq_next, 175 .next = rxrpc_connection_seq_next,
212 .stop = rxrpc_connection_seq_stop, 176 .stop = rxrpc_connection_seq_stop,
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 475df8449be9..b4662888bdbd 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -111,6 +111,17 @@ config NET_SCH_PRIO
111 To compile this code as a module, choose M here: the 111 To compile this code as a module, choose M here: the
112 module will be called sch_prio. 112 module will be called sch_prio.
113 113
114config NET_SCH_RR
115 tristate "Multi Band Round Robin Queuing (RR)"
116 select NET_SCH_PRIO
117 ---help---
118 Say Y here if you want to use an n-band round robin packet
119 scheduler.
120
121 The module uses sch_prio for its framework and is aliased as
122 sch_rr, so it will load sch_prio, although it is referred
123 to using sch_rr.
124
114config NET_SCH_RED 125config NET_SCH_RED
115 tristate "Random Early Detection (RED)" 126 tristate "Random Early Detection (RED)"
116 ---help--- 127 ---help---
@@ -275,7 +286,6 @@ config CLS_U32_MARK
275config NET_CLS_RSVP 286config NET_CLS_RSVP
276 tristate "IPv4 Resource Reservation Protocol (RSVP)" 287 tristate "IPv4 Resource Reservation Protocol (RSVP)"
277 select NET_CLS 288 select NET_CLS
278 select NET_ESTIMATOR
279 ---help--- 289 ---help---
280 The Resource Reservation Protocol (RSVP) permits end systems to 290 The Resource Reservation Protocol (RSVP) permits end systems to
281 request a minimum and maximum data flow rate for a connection; this 291 request a minimum and maximum data flow rate for a connection; this
@@ -290,7 +300,6 @@ config NET_CLS_RSVP
290config NET_CLS_RSVP6 300config NET_CLS_RSVP6
291 tristate "IPv6 Resource Reservation Protocol (RSVP6)" 301 tristate "IPv6 Resource Reservation Protocol (RSVP6)"
292 select NET_CLS 302 select NET_CLS
293 select NET_ESTIMATOR
294 ---help--- 303 ---help---
295 The Resource Reservation Protocol (RSVP) permits end systems to 304 The Resource Reservation Protocol (RSVP) permits end systems to
296 request a minimum and maximum data flow rate for a connection; this 305 request a minimum and maximum data flow rate for a connection; this
@@ -382,7 +391,6 @@ config NET_EMATCH_TEXT
382 391
383config NET_CLS_ACT 392config NET_CLS_ACT
384 bool "Actions" 393 bool "Actions"
385 select NET_ESTIMATOR
386 ---help--- 394 ---help---
387 Say Y here if you want to use traffic control actions. Actions 395 Say Y here if you want to use traffic control actions. Actions
388 get attached to classifiers and are invoked after a successful 396 get attached to classifiers and are invoked after a successful
@@ -465,7 +473,6 @@ config NET_ACT_SIMP
465config NET_CLS_POLICE 473config NET_CLS_POLICE
466 bool "Traffic Policing (obsolete)" 474 bool "Traffic Policing (obsolete)"
467 depends on NET_CLS_ACT!=y 475 depends on NET_CLS_ACT!=y
468 select NET_ESTIMATOR
469 ---help--- 476 ---help---
470 Say Y here if you want to do traffic policing, i.e. strict 477 Say Y here if you want to do traffic policing, i.e. strict
471 bandwidth limiting. This option is obsoleted by the traffic 478 bandwidth limiting. This option is obsoleted by the traffic
@@ -480,14 +487,6 @@ config NET_CLS_IND
480 classification based on the incoming device. This option is 487 classification based on the incoming device. This option is
481 likely to disappear in favour of the metadata ematch. 488 likely to disappear in favour of the metadata ematch.
482 489
483config NET_ESTIMATOR
484 bool "Rate estimator"
485 ---help---
486 Say Y here to allow using rate estimators to estimate the current
487 rate-of-flow for network devices, queues, etc. This module is
488 automatically selected if needed but can be selected manually for
489 statistical purposes.
490
491endif # NET_SCHED 490endif # NET_SCHED
492 491
493endmenu 492endmenu
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 711dd26c95c3..feef366cad5d 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -11,23 +11,13 @@
11 * 11 *
12 */ 12 */
13 13
14#include <asm/uaccess.h>
15#include <asm/system.h>
16#include <linux/bitops.h>
17#include <linux/types.h> 14#include <linux/types.h>
18#include <linux/kernel.h> 15#include <linux/kernel.h>
19#include <linux/string.h> 16#include <linux/string.h>
20#include <linux/mm.h>
21#include <linux/socket.h>
22#include <linux/sockios.h>
23#include <linux/in.h>
24#include <linux/errno.h> 17#include <linux/errno.h>
25#include <linux/interrupt.h>
26#include <linux/netdevice.h>
27#include <linux/skbuff.h> 18#include <linux/skbuff.h>
28#include <linux/init.h> 19#include <linux/init.h>
29#include <linux/kmod.h> 20#include <linux/kmod.h>
30#include <net/sock.h>
31#include <net/sch_generic.h> 21#include <net/sch_generic.h>
32#include <net/act_api.h> 22#include <net/act_api.h>
33#include <net/netlink.h> 23#include <net/netlink.h>
@@ -42,10 +32,8 @@ void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo)
42 write_lock_bh(hinfo->lock); 32 write_lock_bh(hinfo->lock);
43 *p1p = p->tcfc_next; 33 *p1p = p->tcfc_next;
44 write_unlock_bh(hinfo->lock); 34 write_unlock_bh(hinfo->lock);
45#ifdef CONFIG_NET_ESTIMATOR
46 gen_kill_estimator(&p->tcfc_bstats, 35 gen_kill_estimator(&p->tcfc_bstats,
47 &p->tcfc_rate_est); 36 &p->tcfc_rate_est);
48#endif
49 kfree(p); 37 kfree(p);
50 return; 38 return;
51 } 39 }
@@ -232,15 +220,12 @@ struct tcf_common *tcf_hash_create(u32 index, struct rtattr *est, struct tc_acti
232 p->tcfc_bindcnt = 1; 220 p->tcfc_bindcnt = 1;
233 221
234 spin_lock_init(&p->tcfc_lock); 222 spin_lock_init(&p->tcfc_lock);
235 p->tcfc_stats_lock = &p->tcfc_lock;
236 p->tcfc_index = index ? index : tcf_hash_new_index(idx_gen, hinfo); 223 p->tcfc_index = index ? index : tcf_hash_new_index(idx_gen, hinfo);
237 p->tcfc_tm.install = jiffies; 224 p->tcfc_tm.install = jiffies;
238 p->tcfc_tm.lastuse = jiffies; 225 p->tcfc_tm.lastuse = jiffies;
239#ifdef CONFIG_NET_ESTIMATOR
240 if (est) 226 if (est)
241 gen_new_estimator(&p->tcfc_bstats, &p->tcfc_rate_est, 227 gen_new_estimator(&p->tcfc_bstats, &p->tcfc_rate_est,
242 p->tcfc_stats_lock, est); 228 &p->tcfc_lock, est);
243#endif
244 a->priv = (void *) p; 229 a->priv = (void *) p;
245 return p; 230 return p;
246} 231}
@@ -599,12 +584,12 @@ int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a,
599 if (compat_mode) { 584 if (compat_mode) {
600 if (a->type == TCA_OLD_COMPAT) 585 if (a->type == TCA_OLD_COMPAT)
601 err = gnet_stats_start_copy_compat(skb, 0, 586 err = gnet_stats_start_copy_compat(skb, 0,
602 TCA_STATS, TCA_XSTATS, h->tcf_stats_lock, &d); 587 TCA_STATS, TCA_XSTATS, &h->tcf_lock, &d);
603 else 588 else
604 return 0; 589 return 0;
605 } else 590 } else
606 err = gnet_stats_start_copy(skb, TCA_ACT_STATS, 591 err = gnet_stats_start_copy(skb, TCA_ACT_STATS,
607 h->tcf_stats_lock, &d); 592 &h->tcf_lock, &d);
608 593
609 if (err < 0) 594 if (err < 0)
610 goto errout; 595 goto errout;
@@ -614,9 +599,7 @@ int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a,
614 goto errout; 599 goto errout;
615 600
616 if (gnet_stats_copy_basic(&d, &h->tcf_bstats) < 0 || 601 if (gnet_stats_copy_basic(&d, &h->tcf_bstats) < 0 ||
617#ifdef CONFIG_NET_ESTIMATOR
618 gnet_stats_copy_rate_est(&d, &h->tcf_rate_est) < 0 || 602 gnet_stats_copy_rate_est(&d, &h->tcf_rate_est) < 0 ||
619#endif
620 gnet_stats_copy_queue(&d, &h->tcf_qstats) < 0) 603 gnet_stats_copy_queue(&d, &h->tcf_qstats) < 0)
621 goto errout; 604 goto errout;
622 605
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c
index 7517f3791541..a9631e426d91 100644
--- a/net/sched/act_gact.c
+++ b/net/sched/act_gact.c
@@ -10,26 +10,15 @@
10 * 10 *
11 */ 11 */
12 12
13#include <asm/uaccess.h>
14#include <asm/system.h>
15#include <linux/bitops.h>
16#include <linux/types.h> 13#include <linux/types.h>
17#include <linux/kernel.h> 14#include <linux/kernel.h>
18#include <linux/string.h> 15#include <linux/string.h>
19#include <linux/mm.h>
20#include <linux/socket.h>
21#include <linux/sockios.h>
22#include <linux/in.h>
23#include <linux/errno.h> 16#include <linux/errno.h>
24#include <linux/interrupt.h>
25#include <linux/netdevice.h>
26#include <linux/skbuff.h> 17#include <linux/skbuff.h>
27#include <linux/rtnetlink.h> 18#include <linux/rtnetlink.h>
28#include <linux/module.h> 19#include <linux/module.h>
29#include <linux/init.h> 20#include <linux/init.h>
30#include <linux/proc_fs.h>
31#include <net/netlink.h> 21#include <net/netlink.h>
32#include <net/sock.h>
33#include <net/pkt_sched.h> 22#include <net/pkt_sched.h>
34#include <linux/tc_act/tc_gact.h> 23#include <linux/tc_act/tc_gact.h>
35#include <net/tc_act/tc_gact.h> 24#include <net/tc_act/tc_gact.h>
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index 00b05f422d45..6b407ece953c 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -11,27 +11,15 @@
11 * Copyright: Jamal Hadi Salim (2002-4) 11 * Copyright: Jamal Hadi Salim (2002-4)
12 */ 12 */
13 13
14#include <asm/uaccess.h>
15#include <asm/system.h>
16#include <asm/bitops.h>
17#include <linux/types.h> 14#include <linux/types.h>
18#include <linux/kernel.h> 15#include <linux/kernel.h>
19#include <linux/string.h> 16#include <linux/string.h>
20#include <linux/mm.h>
21#include <linux/socket.h>
22#include <linux/sockios.h>
23#include <linux/in.h>
24#include <linux/errno.h> 17#include <linux/errno.h>
25#include <linux/interrupt.h>
26#include <linux/netdevice.h>
27#include <linux/skbuff.h> 18#include <linux/skbuff.h>
28#include <linux/rtnetlink.h> 19#include <linux/rtnetlink.h>
29#include <linux/module.h> 20#include <linux/module.h>
30#include <linux/init.h> 21#include <linux/init.h>
31#include <linux/proc_fs.h>
32#include <linux/kmod.h>
33#include <net/netlink.h> 22#include <net/netlink.h>
34#include <net/sock.h>
35#include <net/pkt_sched.h> 23#include <net/pkt_sched.h>
36#include <linux/tc_act/tc_ipt.h> 24#include <linux/tc_act/tc_ipt.h>
37#include <net/tc_act/tc_ipt.h> 25#include <net/tc_act/tc_ipt.h>
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index de21c92faaa2..579578944ae7 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -12,31 +12,19 @@
12 * 12 *
13 */ 13 */
14 14
15#include <asm/uaccess.h>
16#include <asm/system.h>
17#include <asm/bitops.h>
18#include <linux/types.h> 15#include <linux/types.h>
19#include <linux/kernel.h> 16#include <linux/kernel.h>
20#include <linux/string.h> 17#include <linux/string.h>
21#include <linux/mm.h>
22#include <linux/socket.h>
23#include <linux/sockios.h>
24#include <linux/in.h>
25#include <linux/errno.h> 18#include <linux/errno.h>
26#include <linux/interrupt.h>
27#include <linux/netdevice.h>
28#include <linux/skbuff.h> 19#include <linux/skbuff.h>
29#include <linux/rtnetlink.h> 20#include <linux/rtnetlink.h>
30#include <linux/module.h> 21#include <linux/module.h>
31#include <linux/init.h> 22#include <linux/init.h>
32#include <linux/proc_fs.h>
33#include <net/netlink.h> 23#include <net/netlink.h>
34#include <net/sock.h>
35#include <net/pkt_sched.h> 24#include <net/pkt_sched.h>
36#include <linux/tc_act/tc_mirred.h> 25#include <linux/tc_act/tc_mirred.h>
37#include <net/tc_act/tc_mirred.h> 26#include <net/tc_act/tc_mirred.h>
38 27
39#include <linux/etherdevice.h>
40#include <linux/if_arp.h> 28#include <linux/if_arp.h>
41 29
42#define MIRRED_TAB_MASK 7 30#define MIRRED_TAB_MASK 7
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c
index 6f8684b5617e..b46fab5fb323 100644
--- a/net/sched/act_pedit.c
+++ b/net/sched/act_pedit.c
@@ -9,26 +9,15 @@
9 * Authors: Jamal Hadi Salim (2002-4) 9 * Authors: Jamal Hadi Salim (2002-4)
10 */ 10 */
11 11
12#include <asm/uaccess.h>
13#include <asm/system.h>
14#include <asm/bitops.h>
15#include <linux/types.h> 12#include <linux/types.h>
16#include <linux/kernel.h> 13#include <linux/kernel.h>
17#include <linux/string.h> 14#include <linux/string.h>
18#include <linux/mm.h>
19#include <linux/socket.h>
20#include <linux/sockios.h>
21#include <linux/in.h>
22#include <linux/errno.h> 15#include <linux/errno.h>
23#include <linux/interrupt.h>
24#include <linux/netdevice.h>
25#include <linux/skbuff.h> 16#include <linux/skbuff.h>
26#include <linux/rtnetlink.h> 17#include <linux/rtnetlink.h>
27#include <linux/module.h> 18#include <linux/module.h>
28#include <linux/init.h> 19#include <linux/init.h>
29#include <linux/proc_fs.h>
30#include <net/netlink.h> 20#include <net/netlink.h>
31#include <net/sock.h>
32#include <net/pkt_sched.h> 21#include <net/pkt_sched.h>
33#include <linux/tc_act/tc_pedit.h> 22#include <linux/tc_act/tc_pedit.h>
34#include <net/tc_act/tc_pedit.h> 23#include <net/tc_act/tc_pedit.h>
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index 616f465f407e..d20403890877 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -10,25 +10,15 @@
10 * J Hadi Salim (action changes) 10 * J Hadi Salim (action changes)
11 */ 11 */
12 12
13#include <asm/uaccess.h>
14#include <asm/system.h>
15#include <linux/bitops.h>
16#include <linux/module.h> 13#include <linux/module.h>
17#include <linux/types.h> 14#include <linux/types.h>
18#include <linux/kernel.h> 15#include <linux/kernel.h>
19#include <linux/string.h> 16#include <linux/string.h>
20#include <linux/mm.h>
21#include <linux/socket.h>
22#include <linux/sockios.h>
23#include <linux/in.h>
24#include <linux/errno.h> 17#include <linux/errno.h>
25#include <linux/interrupt.h>
26#include <linux/netdevice.h>
27#include <linux/skbuff.h> 18#include <linux/skbuff.h>
28#include <linux/module.h> 19#include <linux/module.h>
29#include <linux/rtnetlink.h> 20#include <linux/rtnetlink.h>
30#include <linux/init.h> 21#include <linux/init.h>
31#include <net/sock.h>
32#include <net/act_api.h> 22#include <net/act_api.h>
33#include <net/netlink.h> 23#include <net/netlink.h>
34 24
@@ -118,10 +108,8 @@ void tcf_police_destroy(struct tcf_police *p)
118 write_lock_bh(&police_lock); 108 write_lock_bh(&police_lock);
119 *p1p = p->tcf_next; 109 *p1p = p->tcf_next;
120 write_unlock_bh(&police_lock); 110 write_unlock_bh(&police_lock);
121#ifdef CONFIG_NET_ESTIMATOR
122 gen_kill_estimator(&p->tcf_bstats, 111 gen_kill_estimator(&p->tcf_bstats,
123 &p->tcf_rate_est); 112 &p->tcf_rate_est);
124#endif
125 if (p->tcfp_R_tab) 113 if (p->tcfp_R_tab)
126 qdisc_put_rtab(p->tcfp_R_tab); 114 qdisc_put_rtab(p->tcfp_R_tab);
127 if (p->tcfp_P_tab) 115 if (p->tcfp_P_tab)
@@ -185,7 +173,6 @@ static int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est,
185 ret = ACT_P_CREATED; 173 ret = ACT_P_CREATED;
186 police->tcf_refcnt = 1; 174 police->tcf_refcnt = 1;
187 spin_lock_init(&police->tcf_lock); 175 spin_lock_init(&police->tcf_lock);
188 police->tcf_stats_lock = &police->tcf_lock;
189 if (bind) 176 if (bind)
190 police->tcf_bindcnt = 1; 177 police->tcf_bindcnt = 1;
191override: 178override:
@@ -227,15 +214,13 @@ override:
227 police->tcfp_ptoks = L2T_P(police, police->tcfp_mtu); 214 police->tcfp_ptoks = L2T_P(police, police->tcfp_mtu);
228 police->tcf_action = parm->action; 215 police->tcf_action = parm->action;
229 216
230#ifdef CONFIG_NET_ESTIMATOR
231 if (tb[TCA_POLICE_AVRATE-1]) 217 if (tb[TCA_POLICE_AVRATE-1])
232 police->tcfp_ewma_rate = 218 police->tcfp_ewma_rate =
233 *(u32*)RTA_DATA(tb[TCA_POLICE_AVRATE-1]); 219 *(u32*)RTA_DATA(tb[TCA_POLICE_AVRATE-1]);
234 if (est) 220 if (est)
235 gen_replace_estimator(&police->tcf_bstats, 221 gen_replace_estimator(&police->tcf_bstats,
236 &police->tcf_rate_est, 222 &police->tcf_rate_est,
237 police->tcf_stats_lock, est); 223 &police->tcf_lock, est);
238#endif
239 224
240 spin_unlock_bh(&police->tcf_lock); 225 spin_unlock_bh(&police->tcf_lock);
241 if (ret != ACT_P_CREATED) 226 if (ret != ACT_P_CREATED)
@@ -281,14 +266,12 @@ static int tcf_act_police(struct sk_buff *skb, struct tc_action *a,
281 police->tcf_bstats.bytes += skb->len; 266 police->tcf_bstats.bytes += skb->len;
282 police->tcf_bstats.packets++; 267 police->tcf_bstats.packets++;
283 268
284#ifdef CONFIG_NET_ESTIMATOR
285 if (police->tcfp_ewma_rate && 269 if (police->tcfp_ewma_rate &&
286 police->tcf_rate_est.bps >= police->tcfp_ewma_rate) { 270 police->tcf_rate_est.bps >= police->tcfp_ewma_rate) {
287 police->tcf_qstats.overlimits++; 271 police->tcf_qstats.overlimits++;
288 spin_unlock(&police->tcf_lock); 272 spin_unlock(&police->tcf_lock);
289 return police->tcf_action; 273 return police->tcf_action;
290 } 274 }
291#endif
292 275
293 if (skb->len <= police->tcfp_mtu) { 276 if (skb->len <= police->tcfp_mtu) {
294 if (police->tcfp_R_tab == NULL) { 277 if (police->tcfp_R_tab == NULL) {
@@ -348,10 +331,8 @@ tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
348 if (police->tcfp_result) 331 if (police->tcfp_result)
349 RTA_PUT(skb, TCA_POLICE_RESULT, sizeof(int), 332 RTA_PUT(skb, TCA_POLICE_RESULT, sizeof(int),
350 &police->tcfp_result); 333 &police->tcfp_result);
351#ifdef CONFIG_NET_ESTIMATOR
352 if (police->tcfp_ewma_rate) 334 if (police->tcfp_ewma_rate)
353 RTA_PUT(skb, TCA_POLICE_AVRATE, 4, &police->tcfp_ewma_rate); 335 RTA_PUT(skb, TCA_POLICE_AVRATE, 4, &police->tcfp_ewma_rate);
354#endif
355 return skb->len; 336 return skb->len;
356 337
357rtattr_failure: 338rtattr_failure:
@@ -458,7 +439,6 @@ struct tcf_police *tcf_police_locate(struct rtattr *rta, struct rtattr *est)
458 439
459 police->tcf_refcnt = 1; 440 police->tcf_refcnt = 1;
460 spin_lock_init(&police->tcf_lock); 441 spin_lock_init(&police->tcf_lock);
461 police->tcf_stats_lock = &police->tcf_lock;
462 if (parm->rate.rate) { 442 if (parm->rate.rate) {
463 police->tcfp_R_tab = 443 police->tcfp_R_tab =
464 qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE-1]); 444 qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE-1]);
@@ -477,14 +457,12 @@ struct tcf_police *tcf_police_locate(struct rtattr *rta, struct rtattr *est)
477 goto failure; 457 goto failure;
478 police->tcfp_result = *(u32*)RTA_DATA(tb[TCA_POLICE_RESULT-1]); 458 police->tcfp_result = *(u32*)RTA_DATA(tb[TCA_POLICE_RESULT-1]);
479 } 459 }
480#ifdef CONFIG_NET_ESTIMATOR
481 if (tb[TCA_POLICE_AVRATE-1]) { 460 if (tb[TCA_POLICE_AVRATE-1]) {
482 if (RTA_PAYLOAD(tb[TCA_POLICE_AVRATE-1]) != sizeof(u32)) 461 if (RTA_PAYLOAD(tb[TCA_POLICE_AVRATE-1]) != sizeof(u32))
483 goto failure; 462 goto failure;
484 police->tcfp_ewma_rate = 463 police->tcfp_ewma_rate =
485 *(u32*)RTA_DATA(tb[TCA_POLICE_AVRATE-1]); 464 *(u32*)RTA_DATA(tb[TCA_POLICE_AVRATE-1]);
486 } 465 }
487#endif
488 police->tcfp_toks = police->tcfp_burst = parm->burst; 466 police->tcfp_toks = police->tcfp_burst = parm->burst;
489 police->tcfp_mtu = parm->mtu; 467 police->tcfp_mtu = parm->mtu;
490 if (police->tcfp_mtu == 0) { 468 if (police->tcfp_mtu == 0) {
@@ -498,11 +476,9 @@ struct tcf_police *tcf_police_locate(struct rtattr *rta, struct rtattr *est)
498 police->tcf_index = parm->index ? parm->index : 476 police->tcf_index = parm->index ? parm->index :
499 tcf_police_new_index(); 477 tcf_police_new_index();
500 police->tcf_action = parm->action; 478 police->tcf_action = parm->action;
501#ifdef CONFIG_NET_ESTIMATOR
502 if (est) 479 if (est)
503 gen_new_estimator(&police->tcf_bstats, &police->tcf_rate_est, 480 gen_new_estimator(&police->tcf_bstats, &police->tcf_rate_est,
504 police->tcf_stats_lock, est); 481 &police->tcf_lock, est);
505#endif
506 h = tcf_hash(police->tcf_index, POL_TAB_MASK); 482 h = tcf_hash(police->tcf_index, POL_TAB_MASK);
507 write_lock_bh(&police_lock); 483 write_lock_bh(&police_lock);
508 police->tcf_next = tcf_police_ht[h]; 484 police->tcf_next = tcf_police_ht[h];
@@ -528,14 +504,12 @@ int tcf_police(struct sk_buff *skb, struct tcf_police *police)
528 police->tcf_bstats.bytes += skb->len; 504 police->tcf_bstats.bytes += skb->len;
529 police->tcf_bstats.packets++; 505 police->tcf_bstats.packets++;
530 506
531#ifdef CONFIG_NET_ESTIMATOR
532 if (police->tcfp_ewma_rate && 507 if (police->tcfp_ewma_rate &&
533 police->tcf_rate_est.bps >= police->tcfp_ewma_rate) { 508 police->tcf_rate_est.bps >= police->tcfp_ewma_rate) {
534 police->tcf_qstats.overlimits++; 509 police->tcf_qstats.overlimits++;
535 spin_unlock(&police->tcf_lock); 510 spin_unlock(&police->tcf_lock);
536 return police->tcf_action; 511 return police->tcf_action;
537 } 512 }
538#endif
539 if (skb->len <= police->tcfp_mtu) { 513 if (skb->len <= police->tcfp_mtu) {
540 if (police->tcfp_R_tab == NULL) { 514 if (police->tcfp_R_tab == NULL) {
541 spin_unlock(&police->tcf_lock); 515 spin_unlock(&police->tcf_lock);
@@ -591,10 +565,8 @@ int tcf_police_dump(struct sk_buff *skb, struct tcf_police *police)
591 if (police->tcfp_result) 565 if (police->tcfp_result)
592 RTA_PUT(skb, TCA_POLICE_RESULT, sizeof(int), 566 RTA_PUT(skb, TCA_POLICE_RESULT, sizeof(int),
593 &police->tcfp_result); 567 &police->tcfp_result);
594#ifdef CONFIG_NET_ESTIMATOR
595 if (police->tcfp_ewma_rate) 568 if (police->tcfp_ewma_rate)
596 RTA_PUT(skb, TCA_POLICE_AVRATE, 4, &police->tcfp_ewma_rate); 569 RTA_PUT(skb, TCA_POLICE_AVRATE, 4, &police->tcfp_ewma_rate);
597#endif
598 return skb->len; 570 return skb->len;
599 571
600rtattr_failure: 572rtattr_failure:
@@ -607,14 +579,12 @@ int tcf_police_dump_stats(struct sk_buff *skb, struct tcf_police *police)
607 struct gnet_dump d; 579 struct gnet_dump d;
608 580
609 if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, 581 if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS,
610 TCA_XSTATS, police->tcf_stats_lock, 582 TCA_XSTATS, &police->tcf_lock,
611 &d) < 0) 583 &d) < 0)
612 goto errout; 584 goto errout;
613 585
614 if (gnet_stats_copy_basic(&d, &police->tcf_bstats) < 0 || 586 if (gnet_stats_copy_basic(&d, &police->tcf_bstats) < 0 ||
615#ifdef CONFIG_NET_ESTIMATOR
616 gnet_stats_copy_rate_est(&d, &police->tcf_rate_est) < 0 || 587 gnet_stats_copy_rate_est(&d, &police->tcf_rate_est) < 0 ||
617#endif
618 gnet_stats_copy_queue(&d, &police->tcf_qstats) < 0) 588 gnet_stats_copy_queue(&d, &police->tcf_qstats) < 0)
619 goto errout; 589 goto errout;
620 590
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
index 36e1edad5990..fb84ef33d14f 100644
--- a/net/sched/act_simple.c
+++ b/net/sched/act_simple.c
@@ -13,7 +13,6 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/netdevice.h>
17#include <linux/skbuff.h> 16#include <linux/skbuff.h>
18#include <linux/rtnetlink.h> 17#include <linux/rtnetlink.h>
19#include <net/netlink.h> 18#include <net/netlink.h>
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index ebf94edf0478..36b72aab1bde 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -14,26 +14,16 @@
14 * 14 *
15 */ 15 */
16 16
17#include <asm/uaccess.h>
18#include <asm/system.h>
19#include <linux/bitops.h>
20#include <linux/module.h> 17#include <linux/module.h>
21#include <linux/types.h> 18#include <linux/types.h>
22#include <linux/kernel.h> 19#include <linux/kernel.h>
23#include <linux/string.h> 20#include <linux/string.h>
24#include <linux/mm.h>
25#include <linux/socket.h>
26#include <linux/sockios.h>
27#include <linux/in.h>
28#include <linux/errno.h> 21#include <linux/errno.h>
29#include <linux/interrupt.h>
30#include <linux/netdevice.h>
31#include <linux/skbuff.h> 22#include <linux/skbuff.h>
32#include <linux/init.h> 23#include <linux/init.h>
33#include <linux/kmod.h> 24#include <linux/kmod.h>
34#include <linux/netlink.h> 25#include <linux/netlink.h>
35#include <net/netlink.h> 26#include <net/netlink.h>
36#include <net/sock.h>
37#include <net/pkt_sched.h> 27#include <net/pkt_sched.h>
38#include <net/pkt_cls.h> 28#include <net/pkt_cls.h>
39 29
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index c885412d79d5..8dbcf2771a46 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -13,7 +13,6 @@
13#include <linux/types.h> 13#include <linux/types.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/string.h> 15#include <linux/string.h>
16#include <linux/mm.h>
17#include <linux/errno.h> 16#include <linux/errno.h>
18#include <linux/rtnetlink.h> 17#include <linux/rtnetlink.h>
19#include <linux/skbuff.h> 18#include <linux/skbuff.h>
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index bbec4a0d4dcb..8adbd6a37d14 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -19,29 +19,12 @@
19 */ 19 */
20 20
21#include <linux/module.h> 21#include <linux/module.h>
22#include <asm/uaccess.h>
23#include <asm/system.h>
24#include <linux/bitops.h>
25#include <linux/types.h> 22#include <linux/types.h>
26#include <linux/kernel.h> 23#include <linux/kernel.h>
27#include <linux/string.h> 24#include <linux/string.h>
28#include <linux/mm.h>
29#include <linux/socket.h>
30#include <linux/sockios.h>
31#include <linux/in.h>
32#include <linux/errno.h> 25#include <linux/errno.h>
33#include <linux/interrupt.h>
34#include <linux/if_ether.h>
35#include <linux/inet.h>
36#include <linux/netdevice.h>
37#include <linux/etherdevice.h>
38#include <linux/notifier.h>
39#include <linux/netfilter.h>
40#include <net/ip.h>
41#include <net/netlink.h>
42#include <net/route.h>
43#include <linux/skbuff.h> 26#include <linux/skbuff.h>
44#include <net/sock.h> 27#include <net/netlink.h>
45#include <net/act_api.h> 28#include <net/act_api.h>
46#include <net/pkt_cls.h> 29#include <net/pkt_cls.h>
47 30
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index cc941d0ee3a5..0a8409c1d28a 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -10,28 +10,14 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <asm/uaccess.h>
14#include <asm/system.h>
15#include <linux/bitops.h>
16#include <linux/types.h> 13#include <linux/types.h>
17#include <linux/kernel.h> 14#include <linux/kernel.h>
18#include <linux/string.h> 15#include <linux/string.h>
19#include <linux/mm.h>
20#include <linux/socket.h>
21#include <linux/sockios.h>
22#include <linux/in.h>
23#include <linux/errno.h> 16#include <linux/errno.h>
24#include <linux/interrupt.h>
25#include <linux/if_ether.h>
26#include <linux/inet.h>
27#include <linux/netdevice.h>
28#include <linux/etherdevice.h>
29#include <linux/notifier.h>
30#include <net/ip.h>
31#include <net/netlink.h>
32#include <net/route.h>
33#include <linux/skbuff.h> 17#include <linux/skbuff.h>
34#include <net/sock.h> 18#include <net/dst.h>
19#include <net/route.h>
20#include <net/netlink.h>
35#include <net/act_api.h> 21#include <net/act_api.h>
36#include <net/pkt_cls.h> 22#include <net/pkt_cls.h>
37 23
diff --git a/net/sched/cls_rsvp.c b/net/sched/cls_rsvp.c
index 0a683c07c648..cbb5e0d600f3 100644
--- a/net/sched/cls_rsvp.c
+++ b/net/sched/cls_rsvp.c
@@ -10,27 +10,12 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <asm/uaccess.h>
14#include <asm/system.h>
15#include <linux/bitops.h>
16#include <linux/types.h> 13#include <linux/types.h>
17#include <linux/kernel.h> 14#include <linux/kernel.h>
18#include <linux/string.h> 15#include <linux/string.h>
19#include <linux/mm.h>
20#include <linux/socket.h>
21#include <linux/sockios.h>
22#include <linux/in.h>
23#include <linux/errno.h> 16#include <linux/errno.h>
24#include <linux/interrupt.h>
25#include <linux/if_ether.h>
26#include <linux/inet.h>
27#include <linux/netdevice.h>
28#include <linux/etherdevice.h>
29#include <linux/notifier.h>
30#include <net/ip.h>
31#include <net/route.h>
32#include <linux/skbuff.h> 17#include <linux/skbuff.h>
33#include <net/sock.h> 18#include <net/ip.h>
34#include <net/netlink.h> 19#include <net/netlink.h>
35#include <net/act_api.h> 20#include <net/act_api.h>
36#include <net/pkt_cls.h> 21#include <net/pkt_cls.h>
diff --git a/net/sched/cls_rsvp6.c b/net/sched/cls_rsvp6.c
index 93b6abed57db..dd08aea2aee5 100644
--- a/net/sched/cls_rsvp6.c
+++ b/net/sched/cls_rsvp6.c
@@ -10,28 +10,12 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <asm/uaccess.h>
14#include <asm/system.h>
15#include <linux/bitops.h>
16#include <linux/types.h> 13#include <linux/types.h>
17#include <linux/kernel.h> 14#include <linux/kernel.h>
18#include <linux/string.h> 15#include <linux/string.h>
19#include <linux/mm.h>
20#include <linux/socket.h>
21#include <linux/sockios.h>
22#include <linux/in.h>
23#include <linux/errno.h> 16#include <linux/errno.h>
24#include <linux/interrupt.h>
25#include <linux/if_ether.h>
26#include <linux/inet.h>
27#include <linux/netdevice.h>
28#include <linux/etherdevice.h>
29#include <linux/notifier.h>
30#include <net/ip.h>
31#include <linux/ipv6.h> 17#include <linux/ipv6.h>
32#include <net/route.h>
33#include <linux/skbuff.h> 18#include <linux/skbuff.h>
34#include <net/sock.h>
35#include <net/act_api.h> 19#include <net/act_api.h>
36#include <net/pkt_cls.h> 20#include <net/pkt_cls.h>
37#include <net/netlink.h> 21#include <net/netlink.h>
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index 47ac0c556429..2314820a080a 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -9,12 +9,9 @@
9#include <linux/kernel.h> 9#include <linux/kernel.h>
10#include <linux/skbuff.h> 10#include <linux/skbuff.h>
11#include <linux/errno.h> 11#include <linux/errno.h>
12#include <linux/netdevice.h>
13#include <net/ip.h>
14#include <net/act_api.h> 12#include <net/act_api.h>
15#include <net/netlink.h> 13#include <net/netlink.h>
16#include <net/pkt_cls.h> 14#include <net/pkt_cls.h>
17#include <net/route.h>
18 15
19 16
20/* 17/*
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index c7a347bd6d70..77961e2314dc 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -30,30 +30,14 @@
30 * nfmark match added by Catalin(ux aka Dino) BOIE <catab at umbrella.ro> 30 * nfmark match added by Catalin(ux aka Dino) BOIE <catab at umbrella.ro>
31 */ 31 */
32 32
33#include <asm/uaccess.h>
34#include <asm/system.h>
35#include <linux/bitops.h>
36#include <linux/module.h> 33#include <linux/module.h>
37#include <linux/types.h> 34#include <linux/types.h>
38#include <linux/kernel.h> 35#include <linux/kernel.h>
39#include <linux/string.h> 36#include <linux/string.h>
40#include <linux/mm.h>
41#include <linux/socket.h>
42#include <linux/sockios.h>
43#include <linux/in.h>
44#include <linux/errno.h> 37#include <linux/errno.h>
45#include <linux/interrupt.h>
46#include <linux/if_ether.h>
47#include <linux/inet.h>
48#include <linux/netdevice.h>
49#include <linux/etherdevice.h>
50#include <linux/notifier.h>
51#include <linux/rtnetlink.h> 38#include <linux/rtnetlink.h>
52#include <net/ip.h>
53#include <net/netlink.h>
54#include <net/route.h>
55#include <linux/skbuff.h> 39#include <linux/skbuff.h>
56#include <net/sock.h> 40#include <net/netlink.h>
57#include <net/act_api.h> 41#include <net/act_api.h>
58#include <net/pkt_cls.h> 42#include <net/pkt_cls.h>
59 43
diff --git a/net/sched/em_cmp.c b/net/sched/em_cmp.c
index 8d6dacd81900..cc49c932641d 100644
--- a/net/sched/em_cmp.c
+++ b/net/sched/em_cmp.c
@@ -98,3 +98,4 @@ MODULE_LICENSE("GPL");
98module_init(init_em_cmp); 98module_init(init_em_cmp);
99module_exit(exit_em_cmp); 99module_exit(exit_em_cmp);
100 100
101MODULE_ALIAS_TCF_EMATCH(TCF_EM_CMP);
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
index 60acf8cdb27b..650f09c8bd6a 100644
--- a/net/sched/em_meta.c
+++ b/net/sched/em_meta.c
@@ -848,3 +848,5 @@ MODULE_LICENSE("GPL");
848 848
849module_init(init_em_meta); 849module_init(init_em_meta);
850module_exit(exit_em_meta); 850module_exit(exit_em_meta);
851
852MODULE_ALIAS_TCF_EMATCH(TCF_EM_META);
diff --git a/net/sched/em_nbyte.c b/net/sched/em_nbyte.c
index b4b36efce292..370a1b2ea317 100644
--- a/net/sched/em_nbyte.c
+++ b/net/sched/em_nbyte.c
@@ -76,3 +76,5 @@ MODULE_LICENSE("GPL");
76 76
77module_init(init_em_nbyte); 77module_init(init_em_nbyte);
78module_exit(exit_em_nbyte); 78module_exit(exit_em_nbyte);
79
80MODULE_ALIAS_TCF_EMATCH(TCF_EM_NBYTE);
diff --git a/net/sched/em_text.c b/net/sched/em_text.c
index e8f46169449d..d5cd86efb7d0 100644
--- a/net/sched/em_text.c
+++ b/net/sched/em_text.c
@@ -150,3 +150,5 @@ MODULE_LICENSE("GPL");
150 150
151module_init(init_em_text); 151module_init(init_em_text);
152module_exit(exit_em_text); 152module_exit(exit_em_text);
153
154MODULE_ALIAS_TCF_EMATCH(TCF_EM_TEXT);
diff --git a/net/sched/em_u32.c b/net/sched/em_u32.c
index 0a2a7fe08de3..112796e4a7c4 100644
--- a/net/sched/em_u32.c
+++ b/net/sched/em_u32.c
@@ -60,3 +60,5 @@ MODULE_LICENSE("GPL");
60 60
61module_init(init_em_u32); 61module_init(init_em_u32);
62module_exit(exit_em_u32); 62module_exit(exit_em_u32);
63
64MODULE_ALIAS_TCF_EMATCH(TCF_EM_U32);
diff --git a/net/sched/ematch.c b/net/sched/ematch.c
index 63146d339d81..f3a104e323bd 100644
--- a/net/sched/ematch.c
+++ b/net/sched/ematch.c
@@ -84,9 +84,7 @@
84#include <linux/module.h> 84#include <linux/module.h>
85#include <linux/types.h> 85#include <linux/types.h>
86#include <linux/kernel.h> 86#include <linux/kernel.h>
87#include <linux/mm.h>
88#include <linux/errno.h> 87#include <linux/errno.h>
89#include <linux/interrupt.h>
90#include <linux/rtnetlink.h> 88#include <linux/rtnetlink.h>
91#include <linux/skbuff.h> 89#include <linux/skbuff.h>
92#include <net/pkt_cls.h> 90#include <net/pkt_cls.h>
@@ -224,6 +222,19 @@ static int tcf_em_validate(struct tcf_proto *tp,
224 222
225 if (em->ops == NULL) { 223 if (em->ops == NULL) {
226 err = -ENOENT; 224 err = -ENOENT;
225#ifdef CONFIG_KMOD
226 __rtnl_unlock();
227 request_module("ematch-kind-%u", em_hdr->kind);
228 rtnl_lock();
229 em->ops = tcf_em_lookup(em_hdr->kind);
230 if (em->ops) {
231 /* We dropped the RTNL mutex in order to
232 * perform the module load. Tell the caller
233 * to replay the request. */
234 module_put(em->ops->owner);
235 err = -EAGAIN;
236 }
237#endif
227 goto errout; 238 goto errout;
228 } 239 }
229 240
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index bec600af03ca..d92ea26982c5 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -19,30 +19,18 @@
19#include <linux/types.h> 19#include <linux/types.h>
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/string.h> 21#include <linux/string.h>
22#include <linux/mm.h>
23#include <linux/socket.h>
24#include <linux/sockios.h>
25#include <linux/in.h>
26#include <linux/errno.h> 22#include <linux/errno.h>
27#include <linux/interrupt.h>
28#include <linux/netdevice.h>
29#include <linux/skbuff.h> 23#include <linux/skbuff.h>
30#include <linux/init.h> 24#include <linux/init.h>
31#include <linux/proc_fs.h> 25#include <linux/proc_fs.h>
32#include <linux/seq_file.h> 26#include <linux/seq_file.h>
33#include <linux/kmod.h> 27#include <linux/kmod.h>
34#include <linux/list.h> 28#include <linux/list.h>
35#include <linux/bitops.h>
36#include <linux/hrtimer.h> 29#include <linux/hrtimer.h>
37 30
38#include <net/netlink.h> 31#include <net/netlink.h>
39#include <net/sock.h>
40#include <net/pkt_sched.h> 32#include <net/pkt_sched.h>
41 33
42#include <asm/processor.h>
43#include <asm/uaccess.h>
44#include <asm/system.h>
45
46static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n, u32 clid, 34static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n, u32 clid,
47 struct Qdisc *old, struct Qdisc *new); 35 struct Qdisc *old, struct Qdisc *new);
48static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n, 36static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n,
@@ -515,7 +503,6 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp)
515 sch->handle = handle; 503 sch->handle = handle;
516 504
517 if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) { 505 if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) {
518#ifdef CONFIG_NET_ESTIMATOR
519 if (tca[TCA_RATE-1]) { 506 if (tca[TCA_RATE-1]) {
520 err = gen_new_estimator(&sch->bstats, &sch->rate_est, 507 err = gen_new_estimator(&sch->bstats, &sch->rate_est,
521 sch->stats_lock, 508 sch->stats_lock,
@@ -531,7 +518,6 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp)
531 goto err_out3; 518 goto err_out3;
532 } 519 }
533 } 520 }
534#endif
535 qdisc_lock_tree(dev); 521 qdisc_lock_tree(dev);
536 list_add_tail(&sch->list, &dev->qdisc_list); 522 list_add_tail(&sch->list, &dev->qdisc_list);
537 qdisc_unlock_tree(dev); 523 qdisc_unlock_tree(dev);
@@ -559,11 +545,9 @@ static int qdisc_change(struct Qdisc *sch, struct rtattr **tca)
559 if (err) 545 if (err)
560 return err; 546 return err;
561 } 547 }
562#ifdef CONFIG_NET_ESTIMATOR
563 if (tca[TCA_RATE-1]) 548 if (tca[TCA_RATE-1])
564 gen_replace_estimator(&sch->bstats, &sch->rate_est, 549 gen_replace_estimator(&sch->bstats, &sch->rate_est,
565 sch->stats_lock, tca[TCA_RATE-1]); 550 sch->stats_lock, tca[TCA_RATE-1]);
566#endif
567 return 0; 551 return 0;
568} 552}
569 553
@@ -839,9 +823,7 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
839 goto rtattr_failure; 823 goto rtattr_failure;
840 824
841 if (gnet_stats_copy_basic(&d, &q->bstats) < 0 || 825 if (gnet_stats_copy_basic(&d, &q->bstats) < 0 ||
842#ifdef CONFIG_NET_ESTIMATOR
843 gnet_stats_copy_rate_est(&d, &q->rate_est) < 0 || 826 gnet_stats_copy_rate_est(&d, &q->rate_est) < 0 ||
844#endif
845 gnet_stats_copy_queue(&d, &q->qstats) < 0) 827 gnet_stats_copy_queue(&d, &q->qstats) < 0)
846 goto rtattr_failure; 828 goto rtattr_failure;
847 829
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index d1c383fca82c..54b92d22796c 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -8,15 +8,12 @@
8#include <linux/string.h> 8#include <linux/string.h>
9#include <linux/errno.h> 9#include <linux/errno.h>
10#include <linux/skbuff.h> 10#include <linux/skbuff.h>
11#include <linux/interrupt.h>
12#include <linux/atmdev.h> 11#include <linux/atmdev.h>
13#include <linux/atmclip.h> 12#include <linux/atmclip.h>
14#include <linux/netdevice.h>
15#include <linux/rtnetlink.h> 13#include <linux/rtnetlink.h>
16#include <linux/file.h> /* for fput */ 14#include <linux/file.h> /* for fput */
17#include <net/netlink.h> 15#include <net/netlink.h>
18#include <net/pkt_sched.h> 16#include <net/pkt_sched.h>
19#include <net/sock.h>
20 17
21 18
22extern struct socket *sockfd_lookup(int fd, int *err); /* @@@ fix this */ 19extern struct socket *sockfd_lookup(int fd, int *err); /* @@@ fix this */
@@ -71,7 +68,6 @@ struct atm_flow_data {
71 int ref; /* reference count */ 68 int ref; /* reference count */
72 struct gnet_stats_basic bstats; 69 struct gnet_stats_basic bstats;
73 struct gnet_stats_queue qstats; 70 struct gnet_stats_queue qstats;
74 spinlock_t *stats_lock;
75 struct atm_flow_data *next; 71 struct atm_flow_data *next;
76 struct atm_flow_data *excess; /* flow for excess traffic; 72 struct atm_flow_data *excess; /* flow for excess traffic;
77 NULL to set CLP instead */ 73 NULL to set CLP instead */
diff --git a/net/sched/sch_blackhole.c b/net/sched/sch_blackhole.c
index cb0c456aa349..f914fc43a124 100644
--- a/net/sched/sch_blackhole.c
+++ b/net/sched/sch_blackhole.c
@@ -14,7 +14,6 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/types.h> 15#include <linux/types.h>
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/netdevice.h>
18#include <linux/skbuff.h> 17#include <linux/skbuff.h>
19#include <net/pkt_sched.h> 18#include <net/pkt_sched.h>
20 19
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index ee2d5967d109..b184c3545145 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -11,28 +11,12 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <asm/uaccess.h>
15#include <asm/system.h>
16#include <linux/bitops.h>
17#include <linux/types.h> 14#include <linux/types.h>
18#include <linux/kernel.h> 15#include <linux/kernel.h>
19#include <linux/string.h> 16#include <linux/string.h>
20#include <linux/mm.h>
21#include <linux/socket.h>
22#include <linux/sockios.h>
23#include <linux/in.h>
24#include <linux/errno.h> 17#include <linux/errno.h>
25#include <linux/interrupt.h>
26#include <linux/if_ether.h>
27#include <linux/inet.h>
28#include <linux/netdevice.h>
29#include <linux/etherdevice.h>
30#include <linux/notifier.h>
31#include <net/ip.h>
32#include <net/netlink.h>
33#include <net/route.h>
34#include <linux/skbuff.h> 18#include <linux/skbuff.h>
35#include <net/sock.h> 19#include <net/netlink.h>
36#include <net/pkt_sched.h> 20#include <net/pkt_sched.h>
37 21
38 22
@@ -148,7 +132,6 @@ struct cbq_class
148 struct gnet_stats_basic bstats; 132 struct gnet_stats_basic bstats;
149 struct gnet_stats_queue qstats; 133 struct gnet_stats_queue qstats;
150 struct gnet_stats_rate_est rate_est; 134 struct gnet_stats_rate_est rate_est;
151 spinlock_t *stats_lock;
152 struct tc_cbq_xstats xstats; 135 struct tc_cbq_xstats xstats;
153 136
154 struct tcf_proto *filter_list; 137 struct tcf_proto *filter_list;
@@ -1442,7 +1425,6 @@ static int cbq_init(struct Qdisc *sch, struct rtattr *opt)
1442 q->link.ewma_log = TC_CBQ_DEF_EWMA; 1425 q->link.ewma_log = TC_CBQ_DEF_EWMA;
1443 q->link.avpkt = q->link.allot/2; 1426 q->link.avpkt = q->link.allot/2;
1444 q->link.minidle = -0x7FFFFFFF; 1427 q->link.minidle = -0x7FFFFFFF;
1445 q->link.stats_lock = &sch->dev->queue_lock;
1446 1428
1447 qdisc_watchdog_init(&q->watchdog, sch); 1429 qdisc_watchdog_init(&q->watchdog, sch);
1448 hrtimer_init(&q->delay_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); 1430 hrtimer_init(&q->delay_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
@@ -1653,9 +1635,7 @@ cbq_dump_class_stats(struct Qdisc *sch, unsigned long arg,
1653 cl->xstats.undertime = cl->undertime - q->now; 1635 cl->xstats.undertime = cl->undertime - q->now;
1654 1636
1655 if (gnet_stats_copy_basic(d, &cl->bstats) < 0 || 1637 if (gnet_stats_copy_basic(d, &cl->bstats) < 0 ||
1656#ifdef CONFIG_NET_ESTIMATOR
1657 gnet_stats_copy_rate_est(d, &cl->rate_est) < 0 || 1638 gnet_stats_copy_rate_est(d, &cl->rate_est) < 0 ||
1658#endif
1659 gnet_stats_copy_queue(d, &cl->qstats) < 0) 1639 gnet_stats_copy_queue(d, &cl->qstats) < 0)
1660 return -1; 1640 return -1;
1661 1641
@@ -1726,9 +1706,7 @@ static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl)
1726 tcf_destroy_chain(cl->filter_list); 1706 tcf_destroy_chain(cl->filter_list);
1727 qdisc_destroy(cl->q); 1707 qdisc_destroy(cl->q);
1728 qdisc_put_rtab(cl->R_tab); 1708 qdisc_put_rtab(cl->R_tab);
1729#ifdef CONFIG_NET_ESTIMATOR
1730 gen_kill_estimator(&cl->bstats, &cl->rate_est); 1709 gen_kill_estimator(&cl->bstats, &cl->rate_est);
1731#endif
1732 if (cl != &q->link) 1710 if (cl != &q->link)
1733 kfree(cl); 1711 kfree(cl);
1734} 1712}
@@ -1873,11 +1851,10 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct rtattr **t
1873 1851
1874 sch_tree_unlock(sch); 1852 sch_tree_unlock(sch);
1875 1853
1876#ifdef CONFIG_NET_ESTIMATOR
1877 if (tca[TCA_RATE-1]) 1854 if (tca[TCA_RATE-1])
1878 gen_replace_estimator(&cl->bstats, &cl->rate_est, 1855 gen_replace_estimator(&cl->bstats, &cl->rate_est,
1879 cl->stats_lock, tca[TCA_RATE-1]); 1856 &sch->dev->queue_lock,
1880#endif 1857 tca[TCA_RATE-1]);
1881 return 0; 1858 return 0;
1882 } 1859 }
1883 1860
@@ -1935,7 +1912,6 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct rtattr **t
1935 cl->allot = parent->allot; 1912 cl->allot = parent->allot;
1936 cl->quantum = cl->allot; 1913 cl->quantum = cl->allot;
1937 cl->weight = cl->R_tab->rate.rate; 1914 cl->weight = cl->R_tab->rate.rate;
1938 cl->stats_lock = &sch->dev->queue_lock;
1939 1915
1940 sch_tree_lock(sch); 1916 sch_tree_lock(sch);
1941 cbq_link_class(cl); 1917 cbq_link_class(cl);
@@ -1963,11 +1939,9 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct rtattr **t
1963 cbq_set_fopt(cl, RTA_DATA(tb[TCA_CBQ_FOPT-1])); 1939 cbq_set_fopt(cl, RTA_DATA(tb[TCA_CBQ_FOPT-1]));
1964 sch_tree_unlock(sch); 1940 sch_tree_unlock(sch);
1965 1941
1966#ifdef CONFIG_NET_ESTIMATOR
1967 if (tca[TCA_RATE-1]) 1942 if (tca[TCA_RATE-1])
1968 gen_new_estimator(&cl->bstats, &cl->rate_est, 1943 gen_new_estimator(&cl->bstats, &cl->rate_est,
1969 cl->stats_lock, tca[TCA_RATE-1]); 1944 &sch->dev->queue_lock, tca[TCA_RATE-1]);
1970#endif
1971 1945
1972 *arg = (unsigned long)cl; 1946 *arg = (unsigned long)cl;
1973 return 0; 1947 return 0;
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index 3c6fd181263f..4d2c233a8611 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -9,7 +9,6 @@
9#include <linux/string.h> 9#include <linux/string.h>
10#include <linux/errno.h> 10#include <linux/errno.h>
11#include <linux/skbuff.h> 11#include <linux/skbuff.h>
12#include <linux/netdevice.h> /* for pkt_sched */
13#include <linux/rtnetlink.h> 12#include <linux/rtnetlink.h>
14#include <net/pkt_sched.h> 13#include <net/pkt_sched.h>
15#include <net/dsfield.h> 14#include <net/dsfield.h>
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c
index c2689f4ba8de..c264308f17c1 100644
--- a/net/sched/sch_fifo.c
+++ b/net/sched/sch_fifo.c
@@ -13,7 +13,6 @@
13#include <linux/types.h> 13#include <linux/types.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/netdevice.h>
17#include <linux/skbuff.h> 16#include <linux/skbuff.h>
18#include <net/pkt_sched.h> 17#include <net/pkt_sched.h>
19 18
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index f4d34480a093..c81649cf0b9e 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -11,27 +11,19 @@
11 * - Ingress support 11 * - Ingress support
12 */ 12 */
13 13
14#include <asm/uaccess.h>
15#include <asm/system.h>
16#include <linux/bitops.h> 14#include <linux/bitops.h>
17#include <linux/module.h> 15#include <linux/module.h>
18#include <linux/types.h> 16#include <linux/types.h>
19#include <linux/kernel.h> 17#include <linux/kernel.h>
20#include <linux/sched.h> 18#include <linux/sched.h>
21#include <linux/string.h> 19#include <linux/string.h>
22#include <linux/mm.h>
23#include <linux/socket.h>
24#include <linux/sockios.h>
25#include <linux/in.h>
26#include <linux/errno.h> 20#include <linux/errno.h>
27#include <linux/interrupt.h>
28#include <linux/netdevice.h> 21#include <linux/netdevice.h>
29#include <linux/skbuff.h> 22#include <linux/skbuff.h>
30#include <linux/rtnetlink.h> 23#include <linux/rtnetlink.h>
31#include <linux/init.h> 24#include <linux/init.h>
32#include <linux/rcupdate.h> 25#include <linux/rcupdate.h>
33#include <linux/list.h> 26#include <linux/list.h>
34#include <net/sock.h>
35#include <net/pkt_sched.h> 27#include <net/pkt_sched.h>
36 28
37/* Main transmission queue. */ 29/* Main transmission queue. */
@@ -59,122 +51,143 @@ void qdisc_unlock_tree(struct net_device *dev)
59 spin_unlock_bh(&dev->queue_lock); 51 spin_unlock_bh(&dev->queue_lock);
60} 52}
61 53
62/* 54static inline int qdisc_qlen(struct Qdisc *q)
63 dev->queue_lock serializes queue accesses for this device 55{
64 AND dev->qdisc pointer itself. 56 return q->q.qlen;
57}
65 58
66 netif_tx_lock serializes accesses to device driver. 59static inline int dev_requeue_skb(struct sk_buff *skb, struct net_device *dev,
60 struct Qdisc *q)
61{
62 if (unlikely(skb->next))
63 dev->gso_skb = skb;
64 else
65 q->ops->requeue(skb, q);
67 66
68 dev->queue_lock and netif_tx_lock are mutually exclusive, 67 netif_schedule(dev);
69 if one is grabbed, another must be free. 68 return 0;
70 */ 69}
71 70
71static inline struct sk_buff *dev_dequeue_skb(struct net_device *dev,
72 struct Qdisc *q)
73{
74 struct sk_buff *skb;
72 75
73/* Kick device. 76 if ((skb = dev->gso_skb))
77 dev->gso_skb = NULL;
78 else
79 skb = q->dequeue(q);
74 80
75 Returns: 0 - queue is empty or throttled. 81 return skb;
76 >0 - queue is not empty. 82}
77 83
78 NOTE: Called under dev->queue_lock with locally disabled BH. 84static inline int handle_dev_cpu_collision(struct sk_buff *skb,
79*/ 85 struct net_device *dev,
86 struct Qdisc *q)
87{
88 int ret;
80 89
90 if (unlikely(dev->xmit_lock_owner == smp_processor_id())) {
91 /*
92 * Same CPU holding the lock. It may be a transient
93 * configuration error, when hard_start_xmit() recurses. We
94 * detect it by checking xmit owner and drop the packet when
95 * deadloop is detected. Return OK to try the next skb.
96 */
97 kfree_skb(skb);
98 if (net_ratelimit())
99 printk(KERN_WARNING "Dead loop on netdevice %s, "
100 "fix it urgently!\n", dev->name);
101 ret = qdisc_qlen(q);
102 } else {
103 /*
104 * Another cpu is holding lock, requeue & delay xmits for
105 * some time.
106 */
107 __get_cpu_var(netdev_rx_stat).cpu_collision++;
108 ret = dev_requeue_skb(skb, dev, q);
109 }
110
111 return ret;
112}
113
114/*
115 * NOTE: Called under dev->queue_lock with locally disabled BH.
116 *
117 * __LINK_STATE_QDISC_RUNNING guarantees only one CPU can process this
118 * device at a time. dev->queue_lock serializes queue accesses for
119 * this device AND dev->qdisc pointer itself.
120 *
121 * netif_tx_lock serializes accesses to device driver.
122 *
123 * dev->queue_lock and netif_tx_lock are mutually exclusive,
124 * if one is grabbed, another must be free.
125 *
126 * Note, that this procedure can be called by a watchdog timer
127 *
128 * Returns to the caller:
129 * 0 - queue is empty or throttled.
130 * >0 - queue is not empty.
131 *
132 */
81static inline int qdisc_restart(struct net_device *dev) 133static inline int qdisc_restart(struct net_device *dev)
82{ 134{
83 struct Qdisc *q = dev->qdisc; 135 struct Qdisc *q = dev->qdisc;
84 struct sk_buff *skb; 136 struct sk_buff *skb;
137 unsigned lockless;
138 int ret;
85 139
86 /* Dequeue packet */ 140 /* Dequeue packet */
87 if (((skb = dev->gso_skb)) || ((skb = q->dequeue(q)))) { 141 if (unlikely((skb = dev_dequeue_skb(dev, q)) == NULL))
88 unsigned nolock = (dev->features & NETIF_F_LLTX); 142 return 0;
143
144 /*
145 * When the driver has LLTX set, it does its own locking in
146 * start_xmit. These checks are worth it because even uncongested
147 * locks can be quite expensive. The driver can do a trylock, as
148 * is being done here; in case of lock contention it should return
149 * NETDEV_TX_LOCKED and the packet will be requeued.
150 */
151 lockless = (dev->features & NETIF_F_LLTX);
89 152
90 dev->gso_skb = NULL; 153 if (!lockless && !netif_tx_trylock(dev)) {
154 /* Another CPU grabbed the driver tx lock */
155 return handle_dev_cpu_collision(skb, dev, q);
156 }
91 157
92 /* 158 /* And release queue */
93 * When the driver has LLTX set it does its own locking 159 spin_unlock(&dev->queue_lock);
94 * in start_xmit. No need to add additional overhead by
95 * locking again. These checks are worth it because
96 * even uncongested locks can be quite expensive.
97 * The driver can do trylock like here too, in case
98 * of lock congestion it should return -1 and the packet
99 * will be requeued.
100 */
101 if (!nolock) {
102 if (!netif_tx_trylock(dev)) {
103 collision:
104 /* So, someone grabbed the driver. */
105
106 /* It may be transient configuration error,
107 when hard_start_xmit() recurses. We detect
108 it by checking xmit owner and drop the
109 packet when deadloop is detected.
110 */
111 if (dev->xmit_lock_owner == smp_processor_id()) {
112 kfree_skb(skb);
113 if (net_ratelimit())
114 printk(KERN_DEBUG "Dead loop on netdevice %s, fix it urgently!\n", dev->name);
115 goto out;
116 }
117 __get_cpu_var(netdev_rx_stat).cpu_collision++;
118 goto requeue;
119 }
120 }
121 160
122 { 161 ret = dev_hard_start_xmit(skb, dev);
123 /* And release queue */
124 spin_unlock(&dev->queue_lock);
125
126 if (!netif_queue_stopped(dev)) {
127 int ret;
128
129 ret = dev_hard_start_xmit(skb, dev);
130 if (ret == NETDEV_TX_OK) {
131 if (!nolock) {
132 netif_tx_unlock(dev);
133 }
134 spin_lock(&dev->queue_lock);
135 q = dev->qdisc;
136 goto out;
137 }
138 if (ret == NETDEV_TX_LOCKED && nolock) {
139 spin_lock(&dev->queue_lock);
140 q = dev->qdisc;
141 goto collision;
142 }
143 }
144 162
145 /* NETDEV_TX_BUSY - we need to requeue */ 163 if (!lockless)
146 /* Release the driver */ 164 netif_tx_unlock(dev);
147 if (!nolock) {
148 netif_tx_unlock(dev);
149 }
150 spin_lock(&dev->queue_lock);
151 q = dev->qdisc;
152 }
153 165
154 /* Device kicked us out :( 166 spin_lock(&dev->queue_lock);
155 This is possible in three cases: 167 q = dev->qdisc;
156 168
157 0. driver is locked 169 switch (ret) {
158 1. fastroute is enabled 170 case NETDEV_TX_OK:
159 2. device cannot determine busy state 171 /* Driver sent out skb successfully */
160 before start of transmission (f.e. dialout) 172 ret = qdisc_qlen(q);
161 3. device is buggy (ppp) 173 break;
162 */
163 174
164requeue: 175 case NETDEV_TX_LOCKED:
165 if (unlikely(q == &noop_qdisc)) 176 /* Driver try lock failed */
166 kfree_skb(skb); 177 ret = handle_dev_cpu_collision(skb, dev, q);
167 else if (skb->next) 178 break;
168 dev->gso_skb = skb; 179
169 else 180 default:
170 q->ops->requeue(skb, q); 181 /* Driver returned NETDEV_TX_BUSY - requeue skb */
171 netif_schedule(dev); 182 if (unlikely (ret != NETDEV_TX_BUSY && net_ratelimit()))
183 printk(KERN_WARNING "BUG %s code %d qlen %d\n",
184 dev->name, ret, q->q.qlen);
185
186 ret = dev_requeue_skb(skb, dev, q);
187 break;
172 } 188 }
173 return 0;
174 189
175out: 190 return ret;
176 BUG_ON((int) q->q.qlen < 0);
177 return q->q.qlen;
178} 191}
179 192
180void __qdisc_run(struct net_device *dev) 193void __qdisc_run(struct net_device *dev)
@@ -493,9 +506,7 @@ void qdisc_destroy(struct Qdisc *qdisc)
493 return; 506 return;
494 507
495 list_del(&qdisc->list); 508 list_del(&qdisc->list);
496#ifdef CONFIG_NET_ESTIMATOR
497 gen_kill_estimator(&qdisc->bstats, &qdisc->rate_est); 509 gen_kill_estimator(&qdisc->bstats, &qdisc->rate_est);
498#endif
499 if (ops->reset) 510 if (ops->reset)
500 ops->reset(qdisc); 511 ops->reset(qdisc);
501 if (ops->destroy) 512 if (ops->destroy)
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c
index fa1b4fe7a5fd..3cc6dda02e2e 100644
--- a/net/sched/sch_gred.c
+++ b/net/sched/sch_gred.c
@@ -21,7 +21,6 @@
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/types.h> 22#include <linux/types.h>
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/netdevice.h>
25#include <linux/skbuff.h> 24#include <linux/skbuff.h>
26#include <net/pkt_sched.h> 25#include <net/pkt_sched.h>
27#include <net/red.h> 26#include <net/red.h>
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 9d124c4ee3a7..874452c41a01 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -53,7 +53,6 @@
53#include <linux/module.h> 53#include <linux/module.h>
54#include <linux/types.h> 54#include <linux/types.h>
55#include <linux/errno.h> 55#include <linux/errno.h>
56#include <linux/jiffies.h>
57#include <linux/compiler.h> 56#include <linux/compiler.h>
58#include <linux/spinlock.h> 57#include <linux/spinlock.h>
59#include <linux/skbuff.h> 58#include <linux/skbuff.h>
@@ -62,13 +61,11 @@
62#include <linux/list.h> 61#include <linux/list.h>
63#include <linux/rbtree.h> 62#include <linux/rbtree.h>
64#include <linux/init.h> 63#include <linux/init.h>
65#include <linux/netdevice.h>
66#include <linux/rtnetlink.h> 64#include <linux/rtnetlink.h>
67#include <linux/pkt_sched.h> 65#include <linux/pkt_sched.h>
68#include <net/netlink.h> 66#include <net/netlink.h>
69#include <net/pkt_sched.h> 67#include <net/pkt_sched.h>
70#include <net/pkt_cls.h> 68#include <net/pkt_cls.h>
71#include <asm/system.h>
72#include <asm/div64.h> 69#include <asm/div64.h>
73 70
74/* 71/*
@@ -122,7 +119,6 @@ struct hfsc_class
122 struct gnet_stats_basic bstats; 119 struct gnet_stats_basic bstats;
123 struct gnet_stats_queue qstats; 120 struct gnet_stats_queue qstats;
124 struct gnet_stats_rate_est rate_est; 121 struct gnet_stats_rate_est rate_est;
125 spinlock_t *stats_lock;
126 unsigned int level; /* class level in hierarchy */ 122 unsigned int level; /* class level in hierarchy */
127 struct tcf_proto *filter_list; /* filter list */ 123 struct tcf_proto *filter_list; /* filter list */
128 unsigned int filter_cnt; /* filter count */ 124 unsigned int filter_cnt; /* filter count */
@@ -1054,11 +1050,10 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
1054 } 1050 }
1055 sch_tree_unlock(sch); 1051 sch_tree_unlock(sch);
1056 1052
1057#ifdef CONFIG_NET_ESTIMATOR
1058 if (tca[TCA_RATE-1]) 1053 if (tca[TCA_RATE-1])
1059 gen_replace_estimator(&cl->bstats, &cl->rate_est, 1054 gen_replace_estimator(&cl->bstats, &cl->rate_est,
1060 cl->stats_lock, tca[TCA_RATE-1]); 1055 &sch->dev->queue_lock,
1061#endif 1056 tca[TCA_RATE-1]);
1062 return 0; 1057 return 0;
1063 } 1058 }
1064 1059
@@ -1098,7 +1093,6 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
1098 cl->qdisc = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops, classid); 1093 cl->qdisc = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops, classid);
1099 if (cl->qdisc == NULL) 1094 if (cl->qdisc == NULL)
1100 cl->qdisc = &noop_qdisc; 1095 cl->qdisc = &noop_qdisc;
1101 cl->stats_lock = &sch->dev->queue_lock;
1102 INIT_LIST_HEAD(&cl->children); 1096 INIT_LIST_HEAD(&cl->children);
1103 cl->vt_tree = RB_ROOT; 1097 cl->vt_tree = RB_ROOT;
1104 cl->cf_tree = RB_ROOT; 1098 cl->cf_tree = RB_ROOT;
@@ -1112,11 +1106,9 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
1112 cl->cl_pcvtoff = parent->cl_cvtoff; 1106 cl->cl_pcvtoff = parent->cl_cvtoff;
1113 sch_tree_unlock(sch); 1107 sch_tree_unlock(sch);
1114 1108
1115#ifdef CONFIG_NET_ESTIMATOR
1116 if (tca[TCA_RATE-1]) 1109 if (tca[TCA_RATE-1])
1117 gen_new_estimator(&cl->bstats, &cl->rate_est, 1110 gen_new_estimator(&cl->bstats, &cl->rate_est,
1118 cl->stats_lock, tca[TCA_RATE-1]); 1111 &sch->dev->queue_lock, tca[TCA_RATE-1]);
1119#endif
1120 *arg = (unsigned long)cl; 1112 *arg = (unsigned long)cl;
1121 return 0; 1113 return 0;
1122} 1114}
@@ -1128,9 +1120,7 @@ hfsc_destroy_class(struct Qdisc *sch, struct hfsc_class *cl)
1128 1120
1129 tcf_destroy_chain(cl->filter_list); 1121 tcf_destroy_chain(cl->filter_list);
1130 qdisc_destroy(cl->qdisc); 1122 qdisc_destroy(cl->qdisc);
1131#ifdef CONFIG_NET_ESTIMATOR
1132 gen_kill_estimator(&cl->bstats, &cl->rate_est); 1123 gen_kill_estimator(&cl->bstats, &cl->rate_est);
1133#endif
1134 if (cl != &q->root) 1124 if (cl != &q->root)
1135 kfree(cl); 1125 kfree(cl);
1136} 1126}
@@ -1384,9 +1374,7 @@ hfsc_dump_class_stats(struct Qdisc *sch, unsigned long arg,
1384 xstats.rtwork = cl->cl_cumul; 1374 xstats.rtwork = cl->cl_cumul;
1385 1375
1386 if (gnet_stats_copy_basic(d, &cl->bstats) < 0 || 1376 if (gnet_stats_copy_basic(d, &cl->bstats) < 0 ||
1387#ifdef CONFIG_NET_ESTIMATOR
1388 gnet_stats_copy_rate_est(d, &cl->rate_est) < 0 || 1377 gnet_stats_copy_rate_est(d, &cl->rate_est) < 0 ||
1389#endif
1390 gnet_stats_copy_queue(d, &cl->qstats) < 0) 1378 gnet_stats_copy_queue(d, &cl->qstats) < 0)
1391 return -1; 1379 return -1;
1392 1380
@@ -1448,8 +1436,6 @@ hfsc_init_qdisc(struct Qdisc *sch, struct rtattr *opt)
1448 return -EINVAL; 1436 return -EINVAL;
1449 qopt = RTA_DATA(opt); 1437 qopt = RTA_DATA(opt);
1450 1438
1451 sch->stats_lock = &sch->dev->queue_lock;
1452
1453 q->defcls = qopt->defcls; 1439 q->defcls = qopt->defcls;
1454 for (i = 0; i < HFSC_HSIZE; i++) 1440 for (i = 0; i < HFSC_HSIZE; i++)
1455 INIT_LIST_HEAD(&q->clhash[i]); 1441 INIT_LIST_HEAD(&q->clhash[i]);
@@ -1464,7 +1450,6 @@ hfsc_init_qdisc(struct Qdisc *sch, struct rtattr *opt)
1464 sch->handle); 1450 sch->handle);
1465 if (q->root.qdisc == NULL) 1451 if (q->root.qdisc == NULL)
1466 q->root.qdisc = &noop_qdisc; 1452 q->root.qdisc = &noop_qdisc;
1467 q->root.stats_lock = &sch->dev->queue_lock;
1468 INIT_LIST_HEAD(&q->root.children); 1453 INIT_LIST_HEAD(&q->root.children);
1469 q->root.vt_tree = RB_ROOT; 1454 q->root.vt_tree = RB_ROOT;
1470 q->root.cf_tree = RB_ROOT; 1455 q->root.cf_tree = RB_ROOT;
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 035788c5b7f8..b417a95df322 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -28,32 +28,16 @@
28 * $Id: sch_htb.c,v 1.25 2003/12/07 11:08:25 devik Exp devik $ 28 * $Id: sch_htb.c,v 1.25 2003/12/07 11:08:25 devik Exp devik $
29 */ 29 */
30#include <linux/module.h> 30#include <linux/module.h>
31#include <asm/uaccess.h>
32#include <asm/system.h>
33#include <linux/bitops.h>
34#include <linux/types.h> 31#include <linux/types.h>
35#include <linux/kernel.h> 32#include <linux/kernel.h>
36#include <linux/string.h> 33#include <linux/string.h>
37#include <linux/mm.h>
38#include <linux/socket.h>
39#include <linux/sockios.h>
40#include <linux/in.h>
41#include <linux/errno.h> 34#include <linux/errno.h>
42#include <linux/interrupt.h>
43#include <linux/if_ether.h>
44#include <linux/inet.h>
45#include <linux/netdevice.h>
46#include <linux/etherdevice.h>
47#include <linux/notifier.h>
48#include <net/ip.h>
49#include <net/route.h>
50#include <linux/skbuff.h> 35#include <linux/skbuff.h>
51#include <linux/list.h> 36#include <linux/list.h>
52#include <linux/compiler.h> 37#include <linux/compiler.h>
38#include <linux/rbtree.h>
53#include <net/netlink.h> 39#include <net/netlink.h>
54#include <net/sock.h>
55#include <net/pkt_sched.h> 40#include <net/pkt_sched.h>
56#include <linux/rbtree.h>
57 41
58/* HTB algorithm. 42/* HTB algorithm.
59 Author: devik@cdi.cz 43 Author: devik@cdi.cz
@@ -69,8 +53,6 @@
69*/ 53*/
70 54
71#define HTB_HSIZE 16 /* classid hash size */ 55#define HTB_HSIZE 16 /* classid hash size */
72#define HTB_EWMAC 2 /* rate average over HTB_EWMAC*HTB_HSIZE sec */
73#define HTB_RATECM 1 /* whether to use rate computer */
74#define HTB_HYSTERESIS 1 /* whether to use mode hysteresis for speedup */ 56#define HTB_HYSTERESIS 1 /* whether to use mode hysteresis for speedup */
75#define HTB_VER 0x30011 /* major must be matched with number suplied by TC as version */ 57#define HTB_VER 0x30011 /* major must be matched with number suplied by TC as version */
76 58
@@ -95,12 +77,6 @@ struct htb_class {
95 struct tc_htb_xstats xstats; /* our special stats */ 77 struct tc_htb_xstats xstats; /* our special stats */
96 int refcnt; /* usage count of this class */ 78 int refcnt; /* usage count of this class */
97 79
98#ifdef HTB_RATECM
99 /* rate measurement counters */
100 unsigned long rate_bytes, sum_bytes;
101 unsigned long rate_packets, sum_packets;
102#endif
103
104 /* topology */ 80 /* topology */
105 int level; /* our level (see above) */ 81 int level; /* our level (see above) */
106 struct htb_class *parent; /* parent class */ 82 struct htb_class *parent; /* parent class */
@@ -153,15 +129,12 @@ struct htb_class {
153 /* of un.leaf originals should be done. */ 129 /* of un.leaf originals should be done. */
154}; 130};
155 131
156/* TODO: maybe compute rate when size is too large .. or drop ? */
157static inline long L2T(struct htb_class *cl, struct qdisc_rate_table *rate, 132static inline long L2T(struct htb_class *cl, struct qdisc_rate_table *rate,
158 int size) 133 int size)
159{ 134{
160 int slot = size >> rate->rate.cell_log; 135 int slot = size >> rate->rate.cell_log;
161 if (slot > 255) { 136 if (slot > 255)
162 cl->xstats.giants++; 137 return (rate->data[255]*(slot >> 8) + rate->data[slot & 0xFF]);
163 slot = 255;
164 }
165 return rate->data[slot]; 138 return rate->data[slot];
166} 139}
167 140
@@ -194,10 +167,6 @@ struct htb_sched {
194 int rate2quantum; /* quant = rate / rate2quantum */ 167 int rate2quantum; /* quant = rate / rate2quantum */
195 psched_time_t now; /* cached dequeue time */ 168 psched_time_t now; /* cached dequeue time */
196 struct qdisc_watchdog watchdog; 169 struct qdisc_watchdog watchdog;
197#ifdef HTB_RATECM
198 struct timer_list rttim; /* rate computer timer */
199 int recmp_bucket; /* which hash bucket to recompute next */
200#endif
201 170
202 /* non shaped skbs; let them go directly thru */ 171 /* non shaped skbs; let them go directly thru */
203 struct sk_buff_head direct_queue; 172 struct sk_buff_head direct_queue;
@@ -634,13 +603,14 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
634 cl->qstats.drops++; 603 cl->qstats.drops++;
635 return NET_XMIT_DROP; 604 return NET_XMIT_DROP;
636 } else { 605 } else {
637 cl->bstats.packets++; 606 cl->bstats.packets +=
607 skb_is_gso(skb)?skb_shinfo(skb)->gso_segs:1;
638 cl->bstats.bytes += skb->len; 608 cl->bstats.bytes += skb->len;
639 htb_activate(q, cl); 609 htb_activate(q, cl);
640 } 610 }
641 611
642 sch->q.qlen++; 612 sch->q.qlen++;
643 sch->bstats.packets++; 613 sch->bstats.packets += skb_is_gso(skb)?skb_shinfo(skb)->gso_segs:1;
644 sch->bstats.bytes += skb->len; 614 sch->bstats.bytes += skb->len;
645 return NET_XMIT_SUCCESS; 615 return NET_XMIT_SUCCESS;
646} 616}
@@ -677,34 +647,6 @@ static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch)
677 return NET_XMIT_SUCCESS; 647 return NET_XMIT_SUCCESS;
678} 648}
679 649
680#ifdef HTB_RATECM
681#define RT_GEN(D,R) R+=D-(R/HTB_EWMAC);D=0
682static void htb_rate_timer(unsigned long arg)
683{
684 struct Qdisc *sch = (struct Qdisc *)arg;
685 struct htb_sched *q = qdisc_priv(sch);
686 struct hlist_node *p;
687 struct htb_class *cl;
688
689
690 /* lock queue so that we can muck with it */
691 spin_lock_bh(&sch->dev->queue_lock);
692
693 q->rttim.expires = jiffies + HZ;
694 add_timer(&q->rttim);
695
696 /* scan and recompute one bucket at time */
697 if (++q->recmp_bucket >= HTB_HSIZE)
698 q->recmp_bucket = 0;
699
700 hlist_for_each_entry(cl,p, q->hash + q->recmp_bucket, hlist) {
701 RT_GEN(cl->sum_bytes, cl->rate_bytes);
702 RT_GEN(cl->sum_packets, cl->rate_packets);
703 }
704 spin_unlock_bh(&sch->dev->queue_lock);
705}
706#endif
707
708/** 650/**
709 * htb_charge_class - charges amount "bytes" to leaf and ancestors 651 * htb_charge_class - charges amount "bytes" to leaf and ancestors
710 * 652 *
@@ -717,8 +659,9 @@ static void htb_rate_timer(unsigned long arg)
717 * In such case we remove class from event queue first. 659 * In such case we remove class from event queue first.
718 */ 660 */
719static void htb_charge_class(struct htb_sched *q, struct htb_class *cl, 661static void htb_charge_class(struct htb_sched *q, struct htb_class *cl,
720 int level, int bytes) 662 int level, struct sk_buff *skb)
721{ 663{
664 int bytes = skb->len;
722 long toks, diff; 665 long toks, diff;
723 enum htb_cmode old_mode; 666 enum htb_cmode old_mode;
724 667
@@ -750,16 +693,12 @@ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl,
750 if (cl->cmode != HTB_CAN_SEND) 693 if (cl->cmode != HTB_CAN_SEND)
751 htb_add_to_wait_tree(q, cl, diff); 694 htb_add_to_wait_tree(q, cl, diff);
752 } 695 }
753#ifdef HTB_RATECM
754 /* update rate counters */
755 cl->sum_bytes += bytes;
756 cl->sum_packets++;
757#endif
758 696
759 /* update byte stats except for leaves which are already updated */ 697 /* update byte stats except for leaves which are already updated */
760 if (cl->level) { 698 if (cl->level) {
761 cl->bstats.bytes += bytes; 699 cl->bstats.bytes += bytes;
762 cl->bstats.packets++; 700 cl->bstats.packets += skb_is_gso(skb)?
701 skb_shinfo(skb)->gso_segs:1;
763 } 702 }
764 cl = cl->parent; 703 cl = cl->parent;
765 } 704 }
@@ -943,7 +882,7 @@ next:
943 gives us slightly better performance */ 882 gives us slightly better performance */
944 if (!cl->un.leaf.q->q.qlen) 883 if (!cl->un.leaf.q->q.qlen)
945 htb_deactivate(q, cl); 884 htb_deactivate(q, cl);
946 htb_charge_class(q, cl, level, skb->len); 885 htb_charge_class(q, cl, level, skb);
947 } 886 }
948 return skb; 887 return skb;
949} 888}
@@ -1095,13 +1034,6 @@ static int htb_init(struct Qdisc *sch, struct rtattr *opt)
1095 if (q->direct_qlen < 2) /* some devices have zero tx_queue_len */ 1034 if (q->direct_qlen < 2) /* some devices have zero tx_queue_len */
1096 q->direct_qlen = 2; 1035 q->direct_qlen = 2;
1097 1036
1098#ifdef HTB_RATECM
1099 init_timer(&q->rttim);
1100 q->rttim.function = htb_rate_timer;
1101 q->rttim.data = (unsigned long)sch;
1102 q->rttim.expires = jiffies + HZ;
1103 add_timer(&q->rttim);
1104#endif
1105 if ((q->rate2quantum = gopt->rate2quantum) < 1) 1037 if ((q->rate2quantum = gopt->rate2quantum) < 1)
1106 q->rate2quantum = 1; 1038 q->rate2quantum = 1;
1107 q->defcls = gopt->defcls; 1039 q->defcls = gopt->defcls;
@@ -1175,11 +1107,6 @@ htb_dump_class_stats(struct Qdisc *sch, unsigned long arg, struct gnet_dump *d)
1175{ 1107{
1176 struct htb_class *cl = (struct htb_class *)arg; 1108 struct htb_class *cl = (struct htb_class *)arg;
1177 1109
1178#ifdef HTB_RATECM
1179 cl->rate_est.bps = cl->rate_bytes / (HTB_EWMAC * HTB_HSIZE);
1180 cl->rate_est.pps = cl->rate_packets / (HTB_EWMAC * HTB_HSIZE);
1181#endif
1182
1183 if (!cl->level && cl->un.leaf.q) 1110 if (!cl->level && cl->un.leaf.q)
1184 cl->qstats.qlen = cl->un.leaf.q->q.qlen; 1111 cl->qstats.qlen = cl->un.leaf.q->q.qlen;
1185 cl->xstats.tokens = cl->tokens; 1112 cl->xstats.tokens = cl->tokens;
@@ -1277,6 +1204,7 @@ static void htb_destroy_class(struct Qdisc *sch, struct htb_class *cl)
1277 BUG_TRAP(cl->un.leaf.q); 1204 BUG_TRAP(cl->un.leaf.q);
1278 qdisc_destroy(cl->un.leaf.q); 1205 qdisc_destroy(cl->un.leaf.q);
1279 } 1206 }
1207 gen_kill_estimator(&cl->bstats, &cl->rate_est);
1280 qdisc_put_rtab(cl->rate); 1208 qdisc_put_rtab(cl->rate);
1281 qdisc_put_rtab(cl->ceil); 1209 qdisc_put_rtab(cl->ceil);
1282 1210
@@ -1305,9 +1233,6 @@ static void htb_destroy(struct Qdisc *sch)
1305 struct htb_sched *q = qdisc_priv(sch); 1233 struct htb_sched *q = qdisc_priv(sch);
1306 1234
1307 qdisc_watchdog_cancel(&q->watchdog); 1235 qdisc_watchdog_cancel(&q->watchdog);
1308#ifdef HTB_RATECM
1309 del_timer_sync(&q->rttim);
1310#endif
1311 /* This line used to be after htb_destroy_class call below 1236 /* This line used to be after htb_destroy_class call below
1312 and surprisingly it worked in 2.4. But it must precede it 1237 and surprisingly it worked in 2.4. But it must precede it
1313 because filter need its target class alive to be able to call 1238 because filter need its target class alive to be able to call
@@ -1403,6 +1328,20 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
1403 if (!cl) { /* new class */ 1328 if (!cl) { /* new class */
1404 struct Qdisc *new_q; 1329 struct Qdisc *new_q;
1405 int prio; 1330 int prio;
1331 struct {
1332 struct rtattr rta;
1333 struct gnet_estimator opt;
1334 } est = {
1335 .rta = {
1336 .rta_len = RTA_LENGTH(sizeof(est.opt)),
1337 .rta_type = TCA_RATE,
1338 },
1339 .opt = {
1340 /* 4s interval, 16s averaging constant */
1341 .interval = 2,
1342 .ewma_log = 2,
1343 },
1344 };
1406 1345
1407 /* check for valid classid */ 1346 /* check for valid classid */
1408 if (!classid || TC_H_MAJ(classid ^ sch->handle) 1347 if (!classid || TC_H_MAJ(classid ^ sch->handle)
@@ -1418,6 +1357,9 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
1418 if ((cl = kzalloc(sizeof(*cl), GFP_KERNEL)) == NULL) 1357 if ((cl = kzalloc(sizeof(*cl), GFP_KERNEL)) == NULL)
1419 goto failure; 1358 goto failure;
1420 1359
1360 gen_new_estimator(&cl->bstats, &cl->rate_est,
1361 &sch->dev->queue_lock,
1362 tca[TCA_RATE-1] ? : &est.rta);
1421 cl->refcnt = 1; 1363 cl->refcnt = 1;
1422 INIT_LIST_HEAD(&cl->sibling); 1364 INIT_LIST_HEAD(&cl->sibling);
1423 INIT_HLIST_NODE(&cl->hlist); 1365 INIT_HLIST_NODE(&cl->hlist);
@@ -1469,8 +1411,13 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
1469 hlist_add_head(&cl->hlist, q->hash + htb_hash(classid)); 1411 hlist_add_head(&cl->hlist, q->hash + htb_hash(classid));
1470 list_add_tail(&cl->sibling, 1412 list_add_tail(&cl->sibling,
1471 parent ? &parent->children : &q->root); 1413 parent ? &parent->children : &q->root);
1472 } else 1414 } else {
1415 if (tca[TCA_RATE-1])
1416 gen_replace_estimator(&cl->bstats, &cl->rate_est,
1417 &sch->dev->queue_lock,
1418 tca[TCA_RATE-1]);
1473 sch_tree_lock(sch); 1419 sch_tree_lock(sch);
1420 }
1474 1421
1475 /* it used to be a nasty bug here, we have to check that node 1422 /* it used to be a nasty bug here, we have to check that node
1476 is really leaf before changing cl->un.leaf ! */ 1423 is really leaf before changing cl->un.leaf ! */
diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c
index f8b9f1cdf738..cd0aab6a2a7c 100644
--- a/net/sched/sch_ingress.c
+++ b/net/sched/sch_ingress.c
@@ -9,21 +9,14 @@
9 9
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/types.h> 11#include <linux/types.h>
12#include <linux/list.h>
12#include <linux/skbuff.h> 13#include <linux/skbuff.h>
13#include <linux/netdevice.h>
14#include <linux/rtnetlink.h> 14#include <linux/rtnetlink.h>
15#include <linux/netfilter_ipv4.h> 15#include <linux/netfilter_ipv4.h>
16#include <linux/netfilter_ipv6.h> 16#include <linux/netfilter_ipv6.h>
17#include <linux/netfilter.h> 17#include <linux/netfilter.h>
18#include <linux/smp.h>
19#include <net/netlink.h> 18#include <net/netlink.h>
20#include <net/pkt_sched.h> 19#include <net/pkt_sched.h>
21#include <asm/byteorder.h>
22#include <asm/uaccess.h>
23#include <linux/kmod.h>
24#include <linux/stat.h>
25#include <linux/interrupt.h>
26#include <linux/list.h>
27 20
28 21
29#undef DEBUG_INGRESS 22#undef DEBUG_INGRESS
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 5d9d8bc9cc3a..9e5e87e81f00 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -14,11 +14,9 @@
14 */ 14 */
15 15
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/bitops.h>
18#include <linux/types.h> 17#include <linux/types.h>
19#include <linux/kernel.h> 18#include <linux/kernel.h>
20#include <linux/errno.h> 19#include <linux/errno.h>
21#include <linux/netdevice.h>
22#include <linux/skbuff.h> 20#include <linux/skbuff.h>
23#include <linux/rtnetlink.h> 21#include <linux/rtnetlink.h>
24 22
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index 6d7542c26e47..2d8c08493d6e 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -12,37 +12,23 @@
12 */ 12 */
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <asm/uaccess.h>
16#include <asm/system.h>
17#include <linux/bitops.h>
18#include <linux/types.h> 15#include <linux/types.h>
19#include <linux/kernel.h> 16#include <linux/kernel.h>
20#include <linux/string.h> 17#include <linux/string.h>
21#include <linux/mm.h>
22#include <linux/socket.h>
23#include <linux/sockios.h>
24#include <linux/in.h>
25#include <linux/errno.h> 18#include <linux/errno.h>
26#include <linux/interrupt.h>
27#include <linux/if_ether.h>
28#include <linux/inet.h>
29#include <linux/netdevice.h>
30#include <linux/etherdevice.h>
31#include <linux/notifier.h>
32#include <net/ip.h>
33#include <net/route.h>
34#include <linux/skbuff.h> 19#include <linux/skbuff.h>
35#include <net/netlink.h> 20#include <net/netlink.h>
36#include <net/sock.h>
37#include <net/pkt_sched.h> 21#include <net/pkt_sched.h>
38 22
39 23
40struct prio_sched_data 24struct prio_sched_data
41{ 25{
42 int bands; 26 int bands;
27 int curband; /* for round-robin */
43 struct tcf_proto *filter_list; 28 struct tcf_proto *filter_list;
44 u8 prio2band[TC_PRIO_MAX+1]; 29 u8 prio2band[TC_PRIO_MAX+1];
45 struct Qdisc *queues[TCQ_PRIO_BANDS]; 30 struct Qdisc *queues[TCQ_PRIO_BANDS];
31 int mq;
46}; 32};
47 33
48 34
@@ -70,14 +56,17 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
70#endif 56#endif
71 if (TC_H_MAJ(band)) 57 if (TC_H_MAJ(band))
72 band = 0; 58 band = 0;
73 return q->queues[q->prio2band[band&TC_PRIO_MAX]]; 59 band = q->prio2band[band&TC_PRIO_MAX];
60 goto out;
74 } 61 }
75 band = res.classid; 62 band = res.classid;
76 } 63 }
77 band = TC_H_MIN(band) - 1; 64 band = TC_H_MIN(band) - 1;
78 if (band >= q->bands) 65 if (band >= q->bands)
79 return q->queues[q->prio2band[0]]; 66 band = q->prio2band[0];
80 67out:
68 if (q->mq)
69 skb_set_queue_mapping(skb, band);
81 return q->queues[band]; 70 return q->queues[band];
82} 71}
83 72
@@ -144,17 +133,58 @@ prio_dequeue(struct Qdisc* sch)
144 struct Qdisc *qdisc; 133 struct Qdisc *qdisc;
145 134
146 for (prio = 0; prio < q->bands; prio++) { 135 for (prio = 0; prio < q->bands; prio++) {
147 qdisc = q->queues[prio]; 136 /* Check if the target subqueue is available before
148 skb = qdisc->dequeue(qdisc); 137 * pulling an skb. This way we avoid excessive requeues
149 if (skb) { 138 * for slower queues.
150 sch->q.qlen--; 139 */
151 return skb; 140 if (!netif_subqueue_stopped(sch->dev, (q->mq ? prio : 0))) {
141 qdisc = q->queues[prio];
142 skb = qdisc->dequeue(qdisc);
143 if (skb) {
144 sch->q.qlen--;
145 return skb;
146 }
152 } 147 }
153 } 148 }
154 return NULL; 149 return NULL;
155 150
156} 151}
157 152
153static struct sk_buff *rr_dequeue(struct Qdisc* sch)
154{
155 struct sk_buff *skb;
156 struct prio_sched_data *q = qdisc_priv(sch);
157 struct Qdisc *qdisc;
158 int bandcount;
159
160 /* Only take one pass through the queues. If nothing is available,
161 * return nothing.
162 */
163 for (bandcount = 0; bandcount < q->bands; bandcount++) {
164 /* Check if the target subqueue is available before
165 * pulling an skb. This way we avoid excessive requeues
166 * for slower queues. If the queue is stopped, try the
167 * next queue.
168 */
169 if (!netif_subqueue_stopped(sch->dev,
170 (q->mq ? q->curband : 0))) {
171 qdisc = q->queues[q->curband];
172 skb = qdisc->dequeue(qdisc);
173 if (skb) {
174 sch->q.qlen--;
175 q->curband++;
176 if (q->curband >= q->bands)
177 q->curband = 0;
178 return skb;
179 }
180 }
181 q->curband++;
182 if (q->curband >= q->bands)
183 q->curband = 0;
184 }
185 return NULL;
186}
187
158static unsigned int prio_drop(struct Qdisc* sch) 188static unsigned int prio_drop(struct Qdisc* sch)
159{ 189{
160 struct prio_sched_data *q = qdisc_priv(sch); 190 struct prio_sched_data *q = qdisc_priv(sch);
@@ -198,21 +228,41 @@ prio_destroy(struct Qdisc* sch)
198static int prio_tune(struct Qdisc *sch, struct rtattr *opt) 228static int prio_tune(struct Qdisc *sch, struct rtattr *opt)
199{ 229{
200 struct prio_sched_data *q = qdisc_priv(sch); 230 struct prio_sched_data *q = qdisc_priv(sch);
201 struct tc_prio_qopt *qopt = RTA_DATA(opt); 231 struct tc_prio_qopt *qopt;
232 struct rtattr *tb[TCA_PRIO_MAX];
202 int i; 233 int i;
203 234
204 if (opt->rta_len < RTA_LENGTH(sizeof(*qopt))) 235 if (rtattr_parse_nested_compat(tb, TCA_PRIO_MAX, opt, qopt,
236 sizeof(*qopt)))
205 return -EINVAL; 237 return -EINVAL;
206 if (qopt->bands > TCQ_PRIO_BANDS || qopt->bands < 2) 238 q->bands = qopt->bands;
239 /* If we're multiqueue, make sure the number of incoming bands
240 * matches the number of queues on the device we're associating with.
241 * If the number of bands requested is zero, then set q->bands to
242 * dev->egress_subqueue_count.
243 */
244 q->mq = RTA_GET_FLAG(tb[TCA_PRIO_MQ - 1]);
245 if (q->mq) {
246 if (sch->handle != TC_H_ROOT)
247 return -EINVAL;
248 if (netif_is_multiqueue(sch->dev)) {
249 if (q->bands == 0)
250 q->bands = sch->dev->egress_subqueue_count;
251 else if (q->bands != sch->dev->egress_subqueue_count)
252 return -EINVAL;
253 } else
254 return -EOPNOTSUPP;
255 }
256
257 if (q->bands > TCQ_PRIO_BANDS || q->bands < 2)
207 return -EINVAL; 258 return -EINVAL;
208 259
209 for (i=0; i<=TC_PRIO_MAX; i++) { 260 for (i=0; i<=TC_PRIO_MAX; i++) {
210 if (qopt->priomap[i] >= qopt->bands) 261 if (qopt->priomap[i] >= q->bands)
211 return -EINVAL; 262 return -EINVAL;
212 } 263 }
213 264
214 sch_tree_lock(sch); 265 sch_tree_lock(sch);
215 q->bands = qopt->bands;
216 memcpy(q->prio2band, qopt->priomap, TC_PRIO_MAX+1); 266 memcpy(q->prio2band, qopt->priomap, TC_PRIO_MAX+1);
217 267
218 for (i=q->bands; i<TCQ_PRIO_BANDS; i++) { 268 for (i=q->bands; i<TCQ_PRIO_BANDS; i++) {
@@ -268,11 +318,17 @@ static int prio_dump(struct Qdisc *sch, struct sk_buff *skb)
268{ 318{
269 struct prio_sched_data *q = qdisc_priv(sch); 319 struct prio_sched_data *q = qdisc_priv(sch);
270 unsigned char *b = skb_tail_pointer(skb); 320 unsigned char *b = skb_tail_pointer(skb);
321 struct rtattr *nest;
271 struct tc_prio_qopt opt; 322 struct tc_prio_qopt opt;
272 323
273 opt.bands = q->bands; 324 opt.bands = q->bands;
274 memcpy(&opt.priomap, q->prio2band, TC_PRIO_MAX+1); 325 memcpy(&opt.priomap, q->prio2band, TC_PRIO_MAX+1);
275 RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt); 326
327 nest = RTA_NEST_COMPAT(skb, TCA_OPTIONS, sizeof(opt), &opt);
328 if (q->mq)
329 RTA_PUT_FLAG(skb, TCA_PRIO_MQ);
330 RTA_NEST_COMPAT_END(skb, nest);
331
276 return skb->len; 332 return skb->len;
277 333
278rtattr_failure: 334rtattr_failure:
@@ -443,17 +499,44 @@ static struct Qdisc_ops prio_qdisc_ops = {
443 .owner = THIS_MODULE, 499 .owner = THIS_MODULE,
444}; 500};
445 501
502static struct Qdisc_ops rr_qdisc_ops = {
503 .next = NULL,
504 .cl_ops = &prio_class_ops,
505 .id = "rr",
506 .priv_size = sizeof(struct prio_sched_data),
507 .enqueue = prio_enqueue,
508 .dequeue = rr_dequeue,
509 .requeue = prio_requeue,
510 .drop = prio_drop,
511 .init = prio_init,
512 .reset = prio_reset,
513 .destroy = prio_destroy,
514 .change = prio_tune,
515 .dump = prio_dump,
516 .owner = THIS_MODULE,
517};
518
446static int __init prio_module_init(void) 519static int __init prio_module_init(void)
447{ 520{
448 return register_qdisc(&prio_qdisc_ops); 521 int err;
522
523 err = register_qdisc(&prio_qdisc_ops);
524 if (err < 0)
525 return err;
526 err = register_qdisc(&rr_qdisc_ops);
527 if (err < 0)
528 unregister_qdisc(&prio_qdisc_ops);
529 return err;
449} 530}
450 531
451static void __exit prio_module_exit(void) 532static void __exit prio_module_exit(void)
452{ 533{
453 unregister_qdisc(&prio_qdisc_ops); 534 unregister_qdisc(&prio_qdisc_ops);
535 unregister_qdisc(&rr_qdisc_ops);
454} 536}
455 537
456module_init(prio_module_init) 538module_init(prio_module_init)
457module_exit(prio_module_exit) 539module_exit(prio_module_exit)
458 540
459MODULE_LICENSE("GPL"); 541MODULE_LICENSE("GPL");
542MODULE_ALIAS("sch_rr");
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
index 00db53eb8159..9b95fefb70f4 100644
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -17,7 +17,6 @@
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/types.h> 18#include <linux/types.h>
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/netdevice.h>
21#include <linux/skbuff.h> 20#include <linux/skbuff.h>
22#include <net/pkt_sched.h> 21#include <net/pkt_sched.h>
23#include <net/inet_ecn.h> 22#include <net/inet_ecn.h>
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 96dfdf78d32c..957957309859 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -10,31 +10,17 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <asm/uaccess.h>
14#include <asm/system.h>
15#include <linux/bitops.h>
16#include <linux/types.h> 13#include <linux/types.h>
17#include <linux/kernel.h> 14#include <linux/kernel.h>
18#include <linux/jiffies.h> 15#include <linux/jiffies.h>
19#include <linux/string.h> 16#include <linux/string.h>
20#include <linux/mm.h>
21#include <linux/socket.h>
22#include <linux/sockios.h>
23#include <linux/in.h> 17#include <linux/in.h>
24#include <linux/errno.h> 18#include <linux/errno.h>
25#include <linux/interrupt.h>
26#include <linux/if_ether.h>
27#include <linux/inet.h>
28#include <linux/netdevice.h>
29#include <linux/etherdevice.h>
30#include <linux/notifier.h>
31#include <linux/init.h> 19#include <linux/init.h>
32#include <net/ip.h>
33#include <net/netlink.h>
34#include <linux/ipv6.h> 20#include <linux/ipv6.h>
35#include <net/route.h>
36#include <linux/skbuff.h> 21#include <linux/skbuff.h>
37#include <net/sock.h> 22#include <net/ip.h>
23#include <net/netlink.h>
38#include <net/pkt_sched.h> 24#include <net/pkt_sched.h>
39 25
40 26
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index 53862953baaf..22e431dace54 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -13,29 +13,12 @@
13 */ 13 */
14 14
15#include <linux/module.h> 15#include <linux/module.h>
16#include <asm/uaccess.h>
17#include <asm/system.h>
18#include <linux/bitops.h>
19#include <linux/types.h> 16#include <linux/types.h>
20#include <linux/kernel.h> 17#include <linux/kernel.h>
21#include <linux/jiffies.h>
22#include <linux/string.h> 18#include <linux/string.h>
23#include <linux/mm.h>
24#include <linux/socket.h>
25#include <linux/sockios.h>
26#include <linux/in.h>
27#include <linux/errno.h> 19#include <linux/errno.h>
28#include <linux/interrupt.h>
29#include <linux/if_ether.h>
30#include <linux/inet.h>
31#include <linux/netdevice.h>
32#include <linux/etherdevice.h>
33#include <linux/notifier.h>
34#include <net/ip.h>
35#include <net/netlink.h>
36#include <net/route.h>
37#include <linux/skbuff.h> 20#include <linux/skbuff.h>
38#include <net/sock.h> 21#include <net/netlink.h>
39#include <net/pkt_sched.h> 22#include <net/pkt_sched.h>
40 23
41 24
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index f05ad9a30b4c..0968184ea6be 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -9,30 +9,17 @@
9 */ 9 */
10 10
11#include <linux/module.h> 11#include <linux/module.h>
12#include <asm/uaccess.h>
13#include <asm/system.h>
14#include <linux/bitops.h>
15#include <linux/types.h> 12#include <linux/types.h>
16#include <linux/kernel.h> 13#include <linux/kernel.h>
17#include <linux/string.h> 14#include <linux/string.h>
18#include <linux/mm.h>
19#include <linux/socket.h>
20#include <linux/sockios.h>
21#include <linux/in.h>
22#include <linux/errno.h> 15#include <linux/errno.h>
23#include <linux/interrupt.h>
24#include <linux/if_arp.h> 16#include <linux/if_arp.h>
25#include <linux/if_ether.h>
26#include <linux/inet.h>
27#include <linux/netdevice.h> 17#include <linux/netdevice.h>
28#include <linux/etherdevice.h>
29#include <linux/notifier.h>
30#include <linux/init.h> 18#include <linux/init.h>
31#include <net/ip.h>
32#include <net/route.h>
33#include <linux/skbuff.h> 19#include <linux/skbuff.h>
34#include <linux/moduleparam.h> 20#include <linux/moduleparam.h>
35#include <net/sock.h> 21#include <net/dst.h>
22#include <net/neighbour.h>
36#include <net/pkt_sched.h> 23#include <net/pkt_sched.h>
37 24
38/* 25/*
@@ -225,7 +212,6 @@ static int teql_qdisc_init(struct Qdisc *sch, struct rtattr *opt)
225 return 0; 212 return 0;
226} 213}
227 214
228/* "teql*" netdevice routines */
229 215
230static int 216static int
231__teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *dev) 217__teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *dev)
@@ -277,6 +263,7 @@ static int teql_master_xmit(struct sk_buff *skb, struct net_device *dev)
277 int busy; 263 int busy;
278 int nores; 264 int nores;
279 int len = skb->len; 265 int len = skb->len;
266 int subq = skb->queue_mapping;
280 struct sk_buff *skb_res = NULL; 267 struct sk_buff *skb_res = NULL;
281 268
282 start = master->slaves; 269 start = master->slaves;
@@ -293,7 +280,9 @@ restart:
293 280
294 if (slave->qdisc_sleeping != q) 281 if (slave->qdisc_sleeping != q)
295 continue; 282 continue;
296 if (netif_queue_stopped(slave) || ! netif_running(slave)) { 283 if (netif_queue_stopped(slave) ||
284 netif_subqueue_stopped(slave, subq) ||
285 !netif_running(slave)) {
297 busy = 1; 286 busy = 1;
298 continue; 287 continue;
299 } 288 }
@@ -302,6 +291,7 @@ restart:
302 case 0: 291 case 0:
303 if (netif_tx_trylock(slave)) { 292 if (netif_tx_trylock(slave)) {
304 if (!netif_queue_stopped(slave) && 293 if (!netif_queue_stopped(slave) &&
294 !netif_subqueue_stopped(slave, subq) &&
305 slave->hard_start_xmit(skb, slave) == 0) { 295 slave->hard_start_xmit(skb, slave) == 0) {
306 netif_tx_unlock(slave); 296 netif_tx_unlock(slave);
307 master->slaves = NEXT_SLAVE(q); 297 master->slaves = NEXT_SLAVE(q);
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index 2f12bf2d8d3c..e4cd841a22e4 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -250,7 +250,7 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v)
250 return 0; 250 return 0;
251} 251}
252 252
253static struct seq_operations sctp_eps_ops = { 253static const struct seq_operations sctp_eps_ops = {
254 .start = sctp_eps_seq_start, 254 .start = sctp_eps_seq_start,
255 .next = sctp_eps_seq_next, 255 .next = sctp_eps_seq_next,
256 .stop = sctp_eps_seq_stop, 256 .stop = sctp_eps_seq_stop,
@@ -361,7 +361,7 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
361 return 0; 361 return 0;
362} 362}
363 363
364static struct seq_operations sctp_assoc_ops = { 364static const struct seq_operations sctp_assoc_ops = {
365 .start = sctp_assocs_seq_start, 365 .start = sctp_assocs_seq_start,
366 .next = sctp_assocs_seq_next, 366 .next = sctp_assocs_seq_next,
367 .stop = sctp_assocs_seq_stop, 367 .stop = sctp_assocs_seq_stop,
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index 9527f2bb1744..aa55d0a03e6f 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -13,17 +13,22 @@
13#include <linux/errno.h> 13#include <linux/errno.h>
14#include <linux/sunrpc/clnt.h> 14#include <linux/sunrpc/clnt.h>
15#include <linux/spinlock.h> 15#include <linux/spinlock.h>
16#include <linux/smp_lock.h>
16 17
17#ifdef RPC_DEBUG 18#ifdef RPC_DEBUG
18# define RPCDBG_FACILITY RPCDBG_AUTH 19# define RPCDBG_FACILITY RPCDBG_AUTH
19#endif 20#endif
20 21
21static struct rpc_authops * auth_flavors[RPC_AUTH_MAXFLAVOR] = { 22static DEFINE_SPINLOCK(rpc_authflavor_lock);
23static const struct rpc_authops *auth_flavors[RPC_AUTH_MAXFLAVOR] = {
22 &authnull_ops, /* AUTH_NULL */ 24 &authnull_ops, /* AUTH_NULL */
23 &authunix_ops, /* AUTH_UNIX */ 25 &authunix_ops, /* AUTH_UNIX */
24 NULL, /* others can be loadable modules */ 26 NULL, /* others can be loadable modules */
25}; 27};
26 28
29static LIST_HEAD(cred_unused);
30static unsigned long number_cred_unused;
31
27static u32 32static u32
28pseudoflavor_to_flavor(u32 flavor) { 33pseudoflavor_to_flavor(u32 flavor) {
29 if (flavor >= RPC_AUTH_MAXFLAVOR) 34 if (flavor >= RPC_AUTH_MAXFLAVOR)
@@ -32,55 +37,67 @@ pseudoflavor_to_flavor(u32 flavor) {
32} 37}
33 38
34int 39int
35rpcauth_register(struct rpc_authops *ops) 40rpcauth_register(const struct rpc_authops *ops)
36{ 41{
37 rpc_authflavor_t flavor; 42 rpc_authflavor_t flavor;
43 int ret = -EPERM;
38 44
39 if ((flavor = ops->au_flavor) >= RPC_AUTH_MAXFLAVOR) 45 if ((flavor = ops->au_flavor) >= RPC_AUTH_MAXFLAVOR)
40 return -EINVAL; 46 return -EINVAL;
41 if (auth_flavors[flavor] != NULL) 47 spin_lock(&rpc_authflavor_lock);
42 return -EPERM; /* what else? */ 48 if (auth_flavors[flavor] == NULL) {
43 auth_flavors[flavor] = ops; 49 auth_flavors[flavor] = ops;
44 return 0; 50 ret = 0;
51 }
52 spin_unlock(&rpc_authflavor_lock);
53 return ret;
45} 54}
46 55
47int 56int
48rpcauth_unregister(struct rpc_authops *ops) 57rpcauth_unregister(const struct rpc_authops *ops)
49{ 58{
50 rpc_authflavor_t flavor; 59 rpc_authflavor_t flavor;
60 int ret = -EPERM;
51 61
52 if ((flavor = ops->au_flavor) >= RPC_AUTH_MAXFLAVOR) 62 if ((flavor = ops->au_flavor) >= RPC_AUTH_MAXFLAVOR)
53 return -EINVAL; 63 return -EINVAL;
54 if (auth_flavors[flavor] != ops) 64 spin_lock(&rpc_authflavor_lock);
55 return -EPERM; /* what else? */ 65 if (auth_flavors[flavor] == ops) {
56 auth_flavors[flavor] = NULL; 66 auth_flavors[flavor] = NULL;
57 return 0; 67 ret = 0;
68 }
69 spin_unlock(&rpc_authflavor_lock);
70 return ret;
58} 71}
59 72
60struct rpc_auth * 73struct rpc_auth *
61rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt) 74rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt)
62{ 75{
63 struct rpc_auth *auth; 76 struct rpc_auth *auth;
64 struct rpc_authops *ops; 77 const struct rpc_authops *ops;
65 u32 flavor = pseudoflavor_to_flavor(pseudoflavor); 78 u32 flavor = pseudoflavor_to_flavor(pseudoflavor);
66 79
67 auth = ERR_PTR(-EINVAL); 80 auth = ERR_PTR(-EINVAL);
68 if (flavor >= RPC_AUTH_MAXFLAVOR) 81 if (flavor >= RPC_AUTH_MAXFLAVOR)
69 goto out; 82 goto out;
70 83
71 /* FIXME - auth_flavors[] really needs an rw lock,
72 * and module refcounting. */
73#ifdef CONFIG_KMOD 84#ifdef CONFIG_KMOD
74 if ((ops = auth_flavors[flavor]) == NULL) 85 if ((ops = auth_flavors[flavor]) == NULL)
75 request_module("rpc-auth-%u", flavor); 86 request_module("rpc-auth-%u", flavor);
76#endif 87#endif
77 if ((ops = auth_flavors[flavor]) == NULL) 88 spin_lock(&rpc_authflavor_lock);
89 ops = auth_flavors[flavor];
90 if (ops == NULL || !try_module_get(ops->owner)) {
91 spin_unlock(&rpc_authflavor_lock);
78 goto out; 92 goto out;
93 }
94 spin_unlock(&rpc_authflavor_lock);
79 auth = ops->create(clnt, pseudoflavor); 95 auth = ops->create(clnt, pseudoflavor);
96 module_put(ops->owner);
80 if (IS_ERR(auth)) 97 if (IS_ERR(auth))
81 return auth; 98 return auth;
82 if (clnt->cl_auth) 99 if (clnt->cl_auth)
83 rpcauth_destroy(clnt->cl_auth); 100 rpcauth_release(clnt->cl_auth);
84 clnt->cl_auth = auth; 101 clnt->cl_auth = auth;
85 102
86out: 103out:
@@ -88,7 +105,7 @@ out:
88} 105}
89 106
90void 107void
91rpcauth_destroy(struct rpc_auth *auth) 108rpcauth_release(struct rpc_auth *auth)
92{ 109{
93 if (!atomic_dec_and_test(&auth->au_count)) 110 if (!atomic_dec_and_test(&auth->au_count))
94 return; 111 return;
@@ -97,11 +114,31 @@ rpcauth_destroy(struct rpc_auth *auth)
97 114
98static DEFINE_SPINLOCK(rpc_credcache_lock); 115static DEFINE_SPINLOCK(rpc_credcache_lock);
99 116
117static void
118rpcauth_unhash_cred_locked(struct rpc_cred *cred)
119{
120 hlist_del_rcu(&cred->cr_hash);
121 smp_mb__before_clear_bit();
122 clear_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags);
123}
124
125static void
126rpcauth_unhash_cred(struct rpc_cred *cred)
127{
128 spinlock_t *cache_lock;
129
130 cache_lock = &cred->cr_auth->au_credcache->lock;
131 spin_lock(cache_lock);
132 if (atomic_read(&cred->cr_count) == 0)
133 rpcauth_unhash_cred_locked(cred);
134 spin_unlock(cache_lock);
135}
136
100/* 137/*
101 * Initialize RPC credential cache 138 * Initialize RPC credential cache
102 */ 139 */
103int 140int
104rpcauth_init_credcache(struct rpc_auth *auth, unsigned long expire) 141rpcauth_init_credcache(struct rpc_auth *auth)
105{ 142{
106 struct rpc_cred_cache *new; 143 struct rpc_cred_cache *new;
107 int i; 144 int i;
@@ -111,8 +148,7 @@ rpcauth_init_credcache(struct rpc_auth *auth, unsigned long expire)
111 return -ENOMEM; 148 return -ENOMEM;
112 for (i = 0; i < RPC_CREDCACHE_NR; i++) 149 for (i = 0; i < RPC_CREDCACHE_NR; i++)
113 INIT_HLIST_HEAD(&new->hashtable[i]); 150 INIT_HLIST_HEAD(&new->hashtable[i]);
114 new->expire = expire; 151 spin_lock_init(&new->lock);
115 new->nextgc = jiffies + (expire >> 1);
116 auth->au_credcache = new; 152 auth->au_credcache = new;
117 return 0; 153 return 0;
118} 154}
@@ -121,13 +157,13 @@ rpcauth_init_credcache(struct rpc_auth *auth, unsigned long expire)
121 * Destroy a list of credentials 157 * Destroy a list of credentials
122 */ 158 */
123static inline 159static inline
124void rpcauth_destroy_credlist(struct hlist_head *head) 160void rpcauth_destroy_credlist(struct list_head *head)
125{ 161{
126 struct rpc_cred *cred; 162 struct rpc_cred *cred;
127 163
128 while (!hlist_empty(head)) { 164 while (!list_empty(head)) {
129 cred = hlist_entry(head->first, struct rpc_cred, cr_hash); 165 cred = list_entry(head->next, struct rpc_cred, cr_lru);
130 hlist_del_init(&cred->cr_hash); 166 list_del_init(&cred->cr_lru);
131 put_rpccred(cred); 167 put_rpccred(cred);
132 } 168 }
133} 169}
@@ -137,58 +173,95 @@ void rpcauth_destroy_credlist(struct hlist_head *head)
137 * that are not referenced. 173 * that are not referenced.
138 */ 174 */
139void 175void
140rpcauth_free_credcache(struct rpc_auth *auth) 176rpcauth_clear_credcache(struct rpc_cred_cache *cache)
141{ 177{
142 struct rpc_cred_cache *cache = auth->au_credcache; 178 LIST_HEAD(free);
143 HLIST_HEAD(free); 179 struct hlist_head *head;
144 struct hlist_node *pos, *next;
145 struct rpc_cred *cred; 180 struct rpc_cred *cred;
146 int i; 181 int i;
147 182
148 spin_lock(&rpc_credcache_lock); 183 spin_lock(&rpc_credcache_lock);
184 spin_lock(&cache->lock);
149 for (i = 0; i < RPC_CREDCACHE_NR; i++) { 185 for (i = 0; i < RPC_CREDCACHE_NR; i++) {
150 hlist_for_each_safe(pos, next, &cache->hashtable[i]) { 186 head = &cache->hashtable[i];
151 cred = hlist_entry(pos, struct rpc_cred, cr_hash); 187 while (!hlist_empty(head)) {
152 __hlist_del(&cred->cr_hash); 188 cred = hlist_entry(head->first, struct rpc_cred, cr_hash);
153 hlist_add_head(&cred->cr_hash, &free); 189 get_rpccred(cred);
190 if (!list_empty(&cred->cr_lru)) {
191 list_del(&cred->cr_lru);
192 number_cred_unused--;
193 }
194 list_add_tail(&cred->cr_lru, &free);
195 rpcauth_unhash_cred_locked(cred);
154 } 196 }
155 } 197 }
198 spin_unlock(&cache->lock);
156 spin_unlock(&rpc_credcache_lock); 199 spin_unlock(&rpc_credcache_lock);
157 rpcauth_destroy_credlist(&free); 200 rpcauth_destroy_credlist(&free);
158} 201}
159 202
160static void 203/*
161rpcauth_prune_expired(struct rpc_auth *auth, struct rpc_cred *cred, struct hlist_head *free) 204 * Destroy the RPC credential cache
205 */
206void
207rpcauth_destroy_credcache(struct rpc_auth *auth)
162{ 208{
163 if (atomic_read(&cred->cr_count) != 1) 209 struct rpc_cred_cache *cache = auth->au_credcache;
164 return; 210
165 if (time_after(jiffies, cred->cr_expire + auth->au_credcache->expire)) 211 if (cache) {
166 cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE; 212 auth->au_credcache = NULL;
167 if (!(cred->cr_flags & RPCAUTH_CRED_UPTODATE)) { 213 rpcauth_clear_credcache(cache);
168 __hlist_del(&cred->cr_hash); 214 kfree(cache);
169 hlist_add_head(&cred->cr_hash, free);
170 } 215 }
171} 216}
172 217
173/* 218/*
174 * Remove stale credentials. Avoid sleeping inside the loop. 219 * Remove stale credentials. Avoid sleeping inside the loop.
175 */ 220 */
176static void 221static int
177rpcauth_gc_credcache(struct rpc_auth *auth, struct hlist_head *free) 222rpcauth_prune_expired(struct list_head *free, int nr_to_scan)
178{ 223{
179 struct rpc_cred_cache *cache = auth->au_credcache; 224 spinlock_t *cache_lock;
180 struct hlist_node *pos, *next; 225 struct rpc_cred *cred;
181 struct rpc_cred *cred;
182 int i;
183 226
184 dprintk("RPC: gc'ing RPC credentials for auth %p\n", auth); 227 while (!list_empty(&cred_unused)) {
185 for (i = 0; i < RPC_CREDCACHE_NR; i++) { 228 cred = list_entry(cred_unused.next, struct rpc_cred, cr_lru);
186 hlist_for_each_safe(pos, next, &cache->hashtable[i]) { 229 list_del_init(&cred->cr_lru);
187 cred = hlist_entry(pos, struct rpc_cred, cr_hash); 230 number_cred_unused--;
188 rpcauth_prune_expired(auth, cred, free); 231 if (atomic_read(&cred->cr_count) != 0)
232 continue;
233 cache_lock = &cred->cr_auth->au_credcache->lock;
234 spin_lock(cache_lock);
235 if (atomic_read(&cred->cr_count) == 0) {
236 get_rpccred(cred);
237 list_add_tail(&cred->cr_lru, free);
238 rpcauth_unhash_cred_locked(cred);
239 nr_to_scan--;
189 } 240 }
241 spin_unlock(cache_lock);
242 if (nr_to_scan == 0)
243 break;
190 } 244 }
191 cache->nextgc = jiffies + cache->expire; 245 return nr_to_scan;
246}
247
248/*
249 * Run memory cache shrinker.
250 */
251static int
252rpcauth_cache_shrinker(int nr_to_scan, gfp_t gfp_mask)
253{
254 LIST_HEAD(free);
255 int res;
256
257 if (list_empty(&cred_unused))
258 return 0;
259 spin_lock(&rpc_credcache_lock);
260 nr_to_scan = rpcauth_prune_expired(&free, nr_to_scan);
261 res = (number_cred_unused / 100) * sysctl_vfs_cache_pressure;
262 spin_unlock(&rpc_credcache_lock);
263 rpcauth_destroy_credlist(&free);
264 return res;
192} 265}
193 266
194/* 267/*
@@ -198,53 +271,56 @@ struct rpc_cred *
198rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, 271rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
199 int flags) 272 int flags)
200{ 273{
274 LIST_HEAD(free);
201 struct rpc_cred_cache *cache = auth->au_credcache; 275 struct rpc_cred_cache *cache = auth->au_credcache;
202 HLIST_HEAD(free); 276 struct hlist_node *pos;
203 struct hlist_node *pos, *next; 277 struct rpc_cred *cred = NULL,
204 struct rpc_cred *new = NULL, 278 *entry, *new;
205 *cred = NULL;
206 int nr = 0; 279 int nr = 0;
207 280
208 if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) 281 if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS))
209 nr = acred->uid & RPC_CREDCACHE_MASK; 282 nr = acred->uid & RPC_CREDCACHE_MASK;
210retry: 283
211 spin_lock(&rpc_credcache_lock); 284 rcu_read_lock();
212 if (time_before(cache->nextgc, jiffies)) 285 hlist_for_each_entry_rcu(entry, pos, &cache->hashtable[nr], cr_hash) {
213 rpcauth_gc_credcache(auth, &free); 286 if (!entry->cr_ops->crmatch(acred, entry, flags))
214 hlist_for_each_safe(pos, next, &cache->hashtable[nr]) { 287 continue;
215 struct rpc_cred *entry; 288 spin_lock(&cache->lock);
216 entry = hlist_entry(pos, struct rpc_cred, cr_hash); 289 if (test_bit(RPCAUTH_CRED_HASHED, &entry->cr_flags) == 0) {
217 if (entry->cr_ops->crmatch(acred, entry, flags)) { 290 spin_unlock(&cache->lock);
218 hlist_del(&entry->cr_hash); 291 continue;
219 cred = entry;
220 break;
221 } 292 }
222 rpcauth_prune_expired(auth, entry, &free); 293 cred = get_rpccred(entry);
294 spin_unlock(&cache->lock);
295 break;
223 } 296 }
224 if (new) { 297 rcu_read_unlock();
225 if (cred)
226 hlist_add_head(&new->cr_hash, &free);
227 else
228 cred = new;
229 }
230 if (cred) {
231 hlist_add_head(&cred->cr_hash, &cache->hashtable[nr]);
232 get_rpccred(cred);
233 }
234 spin_unlock(&rpc_credcache_lock);
235 298
236 rpcauth_destroy_credlist(&free); 299 if (cred != NULL)
300 goto found;
237 301
238 if (!cred) { 302 new = auth->au_ops->crcreate(auth, acred, flags);
239 new = auth->au_ops->crcreate(auth, acred, flags); 303 if (IS_ERR(new)) {
240 if (!IS_ERR(new)) { 304 cred = new;
241#ifdef RPC_DEBUG 305 goto out;
242 new->cr_magic = RPCAUTH_CRED_MAGIC; 306 }
243#endif 307
244 goto retry; 308 spin_lock(&cache->lock);
245 } else 309 hlist_for_each_entry(entry, pos, &cache->hashtable[nr], cr_hash) {
246 cred = new; 310 if (!entry->cr_ops->crmatch(acred, entry, flags))
247 } else if ((cred->cr_flags & RPCAUTH_CRED_NEW) 311 continue;
312 cred = get_rpccred(entry);
313 break;
314 }
315 if (cred == NULL) {
316 cred = new;
317 set_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags);
318 hlist_add_head_rcu(&cred->cr_hash, &cache->hashtable[nr]);
319 } else
320 list_add_tail(&new->cr_lru, &free);
321 spin_unlock(&cache->lock);
322found:
323 if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags)
248 && cred->cr_ops->cr_init != NULL 324 && cred->cr_ops->cr_init != NULL
249 && !(flags & RPCAUTH_LOOKUP_NEW)) { 325 && !(flags & RPCAUTH_LOOKUP_NEW)) {
250 int res = cred->cr_ops->cr_init(auth, cred); 326 int res = cred->cr_ops->cr_init(auth, cred);
@@ -253,8 +329,9 @@ retry:
253 cred = ERR_PTR(res); 329 cred = ERR_PTR(res);
254 } 330 }
255 } 331 }
256 332 rpcauth_destroy_credlist(&free);
257 return (struct rpc_cred *) cred; 333out:
334 return cred;
258} 335}
259 336
260struct rpc_cred * 337struct rpc_cred *
@@ -275,10 +352,27 @@ rpcauth_lookupcred(struct rpc_auth *auth, int flags)
275 return ret; 352 return ret;
276} 353}
277 354
355void
356rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred,
357 struct rpc_auth *auth, const struct rpc_credops *ops)
358{
359 INIT_HLIST_NODE(&cred->cr_hash);
360 INIT_LIST_HEAD(&cred->cr_lru);
361 atomic_set(&cred->cr_count, 1);
362 cred->cr_auth = auth;
363 cred->cr_ops = ops;
364 cred->cr_expire = jiffies;
365#ifdef RPC_DEBUG
366 cred->cr_magic = RPCAUTH_CRED_MAGIC;
367#endif
368 cred->cr_uid = acred->uid;
369}
370EXPORT_SYMBOL(rpcauth_init_cred);
371
278struct rpc_cred * 372struct rpc_cred *
279rpcauth_bindcred(struct rpc_task *task) 373rpcauth_bindcred(struct rpc_task *task)
280{ 374{
281 struct rpc_auth *auth = task->tk_auth; 375 struct rpc_auth *auth = task->tk_client->cl_auth;
282 struct auth_cred acred = { 376 struct auth_cred acred = {
283 .uid = current->fsuid, 377 .uid = current->fsuid,
284 .gid = current->fsgid, 378 .gid = current->fsgid,
@@ -288,7 +382,7 @@ rpcauth_bindcred(struct rpc_task *task)
288 int flags = 0; 382 int flags = 0;
289 383
290 dprintk("RPC: %5u looking up %s cred\n", 384 dprintk("RPC: %5u looking up %s cred\n",
291 task->tk_pid, task->tk_auth->au_ops->au_name); 385 task->tk_pid, task->tk_client->cl_auth->au_ops->au_name);
292 get_group_info(acred.group_info); 386 get_group_info(acred.group_info);
293 if (task->tk_flags & RPC_TASK_ROOTCREDS) 387 if (task->tk_flags & RPC_TASK_ROOTCREDS)
294 flags |= RPCAUTH_LOOKUP_ROOTCREDS; 388 flags |= RPCAUTH_LOOKUP_ROOTCREDS;
@@ -304,19 +398,42 @@ rpcauth_bindcred(struct rpc_task *task)
304void 398void
305rpcauth_holdcred(struct rpc_task *task) 399rpcauth_holdcred(struct rpc_task *task)
306{ 400{
307 dprintk("RPC: %5u holding %s cred %p\n", 401 struct rpc_cred *cred = task->tk_msg.rpc_cred;
308 task->tk_pid, task->tk_auth->au_ops->au_name, 402 if (cred != NULL) {
309 task->tk_msg.rpc_cred); 403 get_rpccred(cred);
310 if (task->tk_msg.rpc_cred) 404 dprintk("RPC: %5u holding %s cred %p\n", task->tk_pid,
311 get_rpccred(task->tk_msg.rpc_cred); 405 cred->cr_auth->au_ops->au_name, cred);
406 }
312} 407}
313 408
314void 409void
315put_rpccred(struct rpc_cred *cred) 410put_rpccred(struct rpc_cred *cred)
316{ 411{
317 cred->cr_expire = jiffies; 412 /* Fast path for unhashed credentials */
413 if (test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0)
414 goto need_lock;
415
318 if (!atomic_dec_and_test(&cred->cr_count)) 416 if (!atomic_dec_and_test(&cred->cr_count))
319 return; 417 return;
418 goto out_destroy;
419need_lock:
420 if (!atomic_dec_and_lock(&cred->cr_count, &rpc_credcache_lock))
421 return;
422 if (!list_empty(&cred->cr_lru)) {
423 number_cred_unused--;
424 list_del_init(&cred->cr_lru);
425 }
426 if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) == 0)
427 rpcauth_unhash_cred(cred);
428 else if (test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) {
429 cred->cr_expire = jiffies;
430 list_add_tail(&cred->cr_lru, &cred_unused);
431 number_cred_unused++;
432 spin_unlock(&rpc_credcache_lock);
433 return;
434 }
435 spin_unlock(&rpc_credcache_lock);
436out_destroy:
320 cred->cr_ops->crdestroy(cred); 437 cred->cr_ops->crdestroy(cred);
321} 438}
322 439
@@ -326,7 +443,7 @@ rpcauth_unbindcred(struct rpc_task *task)
326 struct rpc_cred *cred = task->tk_msg.rpc_cred; 443 struct rpc_cred *cred = task->tk_msg.rpc_cred;
327 444
328 dprintk("RPC: %5u releasing %s cred %p\n", 445 dprintk("RPC: %5u releasing %s cred %p\n",
329 task->tk_pid, task->tk_auth->au_ops->au_name, cred); 446 task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
330 447
331 put_rpccred(cred); 448 put_rpccred(cred);
332 task->tk_msg.rpc_cred = NULL; 449 task->tk_msg.rpc_cred = NULL;
@@ -338,7 +455,7 @@ rpcauth_marshcred(struct rpc_task *task, __be32 *p)
338 struct rpc_cred *cred = task->tk_msg.rpc_cred; 455 struct rpc_cred *cred = task->tk_msg.rpc_cred;
339 456
340 dprintk("RPC: %5u marshaling %s cred %p\n", 457 dprintk("RPC: %5u marshaling %s cred %p\n",
341 task->tk_pid, task->tk_auth->au_ops->au_name, cred); 458 task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
342 459
343 return cred->cr_ops->crmarshal(task, p); 460 return cred->cr_ops->crmarshal(task, p);
344} 461}
@@ -349,7 +466,7 @@ rpcauth_checkverf(struct rpc_task *task, __be32 *p)
349 struct rpc_cred *cred = task->tk_msg.rpc_cred; 466 struct rpc_cred *cred = task->tk_msg.rpc_cred;
350 467
351 dprintk("RPC: %5u validating %s cred %p\n", 468 dprintk("RPC: %5u validating %s cred %p\n",
352 task->tk_pid, task->tk_auth->au_ops->au_name, cred); 469 task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
353 470
354 return cred->cr_ops->crvalidate(task, p); 471 return cred->cr_ops->crvalidate(task, p);
355} 472}
@@ -359,13 +476,17 @@ rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp,
359 __be32 *data, void *obj) 476 __be32 *data, void *obj)
360{ 477{
361 struct rpc_cred *cred = task->tk_msg.rpc_cred; 478 struct rpc_cred *cred = task->tk_msg.rpc_cred;
479 int ret;
362 480
363 dprintk("RPC: %5u using %s cred %p to wrap rpc data\n", 481 dprintk("RPC: %5u using %s cred %p to wrap rpc data\n",
364 task->tk_pid, cred->cr_ops->cr_name, cred); 482 task->tk_pid, cred->cr_ops->cr_name, cred);
365 if (cred->cr_ops->crwrap_req) 483 if (cred->cr_ops->crwrap_req)
366 return cred->cr_ops->crwrap_req(task, encode, rqstp, data, obj); 484 return cred->cr_ops->crwrap_req(task, encode, rqstp, data, obj);
367 /* By default, we encode the arguments normally. */ 485 /* By default, we encode the arguments normally. */
368 return encode(rqstp, data, obj); 486 lock_kernel();
487 ret = encode(rqstp, data, obj);
488 unlock_kernel();
489 return ret;
369} 490}
370 491
371int 492int
@@ -373,6 +494,7 @@ rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp,
373 __be32 *data, void *obj) 494 __be32 *data, void *obj)
374{ 495{
375 struct rpc_cred *cred = task->tk_msg.rpc_cred; 496 struct rpc_cred *cred = task->tk_msg.rpc_cred;
497 int ret;
376 498
377 dprintk("RPC: %5u using %s cred %p to unwrap rpc data\n", 499 dprintk("RPC: %5u using %s cred %p to unwrap rpc data\n",
378 task->tk_pid, cred->cr_ops->cr_name, cred); 500 task->tk_pid, cred->cr_ops->cr_name, cred);
@@ -380,7 +502,10 @@ rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp,
380 return cred->cr_ops->crunwrap_resp(task, decode, rqstp, 502 return cred->cr_ops->crunwrap_resp(task, decode, rqstp,
381 data, obj); 503 data, obj);
382 /* By default, we decode the arguments normally. */ 504 /* By default, we decode the arguments normally. */
383 return decode(rqstp, data, obj); 505 lock_kernel();
506 ret = decode(rqstp, data, obj);
507 unlock_kernel();
508 return ret;
384} 509}
385 510
386int 511int
@@ -390,7 +515,7 @@ rpcauth_refreshcred(struct rpc_task *task)
390 int err; 515 int err;
391 516
392 dprintk("RPC: %5u refreshing %s cred %p\n", 517 dprintk("RPC: %5u refreshing %s cred %p\n",
393 task->tk_pid, task->tk_auth->au_ops->au_name, cred); 518 task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
394 519
395 err = cred->cr_ops->crrefresh(task); 520 err = cred->cr_ops->crrefresh(task);
396 if (err < 0) 521 if (err < 0)
@@ -401,17 +526,34 @@ rpcauth_refreshcred(struct rpc_task *task)
401void 526void
402rpcauth_invalcred(struct rpc_task *task) 527rpcauth_invalcred(struct rpc_task *task)
403{ 528{
529 struct rpc_cred *cred = task->tk_msg.rpc_cred;
530
404 dprintk("RPC: %5u invalidating %s cred %p\n", 531 dprintk("RPC: %5u invalidating %s cred %p\n",
405 task->tk_pid, task->tk_auth->au_ops->au_name, task->tk_msg.rpc_cred); 532 task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
406 spin_lock(&rpc_credcache_lock); 533 if (cred)
407 if (task->tk_msg.rpc_cred) 534 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
408 task->tk_msg.rpc_cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
409 spin_unlock(&rpc_credcache_lock);
410} 535}
411 536
412int 537int
413rpcauth_uptodatecred(struct rpc_task *task) 538rpcauth_uptodatecred(struct rpc_task *task)
414{ 539{
415 return !(task->tk_msg.rpc_cred) || 540 struct rpc_cred *cred = task->tk_msg.rpc_cred;
416 (task->tk_msg.rpc_cred->cr_flags & RPCAUTH_CRED_UPTODATE); 541
542 return cred == NULL ||
543 test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0;
544}
545
546
547static struct shrinker *rpc_cred_shrinker;
548
549void __init rpcauth_init_module(void)
550{
551 rpc_init_authunix();
552 rpc_cred_shrinker = set_shrinker(DEFAULT_SEEKS, rpcauth_cache_shrinker);
553}
554
555void __exit rpcauth_remove_module(void)
556{
557 if (rpc_cred_shrinker != NULL)
558 remove_shrinker(rpc_cred_shrinker);
417} 559}
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 4e4ccc5b6fea..baf4096d52d4 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -54,9 +54,10 @@
54#include <linux/sunrpc/gss_api.h> 54#include <linux/sunrpc/gss_api.h>
55#include <asm/uaccess.h> 55#include <asm/uaccess.h>
56 56
57static struct rpc_authops authgss_ops; 57static const struct rpc_authops authgss_ops;
58 58
59static struct rpc_credops gss_credops; 59static const struct rpc_credops gss_credops;
60static const struct rpc_credops gss_nullops;
60 61
61#ifdef RPC_DEBUG 62#ifdef RPC_DEBUG
62# define RPCDBG_FACILITY RPCDBG_AUTH 63# define RPCDBG_FACILITY RPCDBG_AUTH
@@ -64,7 +65,6 @@ static struct rpc_credops gss_credops;
64 65
65#define NFS_NGROUPS 16 66#define NFS_NGROUPS 16
66 67
67#define GSS_CRED_EXPIRE (60 * HZ) /* XXX: reasonable? */
68#define GSS_CRED_SLACK 1024 /* XXX: unused */ 68#define GSS_CRED_SLACK 1024 /* XXX: unused */
69/* length of a krb5 verifier (48), plus data added before arguments when 69/* length of a krb5 verifier (48), plus data added before arguments when
70 * using integrity (two 4-byte integers): */ 70 * using integrity (two 4-byte integers): */
@@ -79,19 +79,16 @@ static struct rpc_credops gss_credops;
79/* dump the buffer in `emacs-hexl' style */ 79/* dump the buffer in `emacs-hexl' style */
80#define isprint(c) ((c > 0x1f) && (c < 0x7f)) 80#define isprint(c) ((c > 0x1f) && (c < 0x7f))
81 81
82static DEFINE_RWLOCK(gss_ctx_lock);
83
84struct gss_auth { 82struct gss_auth {
83 struct kref kref;
85 struct rpc_auth rpc_auth; 84 struct rpc_auth rpc_auth;
86 struct gss_api_mech *mech; 85 struct gss_api_mech *mech;
87 enum rpc_gss_svc service; 86 enum rpc_gss_svc service;
88 struct list_head upcalls;
89 struct rpc_clnt *client; 87 struct rpc_clnt *client;
90 struct dentry *dentry; 88 struct dentry *dentry;
91 spinlock_t lock;
92}; 89};
93 90
94static void gss_destroy_ctx(struct gss_cl_ctx *); 91static void gss_free_ctx(struct gss_cl_ctx *);
95static struct rpc_pipe_ops gss_upcall_ops; 92static struct rpc_pipe_ops gss_upcall_ops;
96 93
97static inline struct gss_cl_ctx * 94static inline struct gss_cl_ctx *
@@ -105,20 +102,24 @@ static inline void
105gss_put_ctx(struct gss_cl_ctx *ctx) 102gss_put_ctx(struct gss_cl_ctx *ctx)
106{ 103{
107 if (atomic_dec_and_test(&ctx->count)) 104 if (atomic_dec_and_test(&ctx->count))
108 gss_destroy_ctx(ctx); 105 gss_free_ctx(ctx);
109} 106}
110 107
108/* gss_cred_set_ctx:
109 * called by gss_upcall_callback and gss_create_upcall in order
110 * to set the gss context. The actual exchange of an old context
111 * and a new one is protected by the inode->i_lock.
112 */
111static void 113static void
112gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx) 114gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx)
113{ 115{
114 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base); 116 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
115 struct gss_cl_ctx *old; 117 struct gss_cl_ctx *old;
116 write_lock(&gss_ctx_lock); 118
117 old = gss_cred->gc_ctx; 119 old = gss_cred->gc_ctx;
118 gss_cred->gc_ctx = ctx; 120 rcu_assign_pointer(gss_cred->gc_ctx, ctx);
119 cred->cr_flags |= RPCAUTH_CRED_UPTODATE; 121 set_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
120 cred->cr_flags &= ~RPCAUTH_CRED_NEW; 122 clear_bit(RPCAUTH_CRED_NEW, &cred->cr_flags);
121 write_unlock(&gss_ctx_lock);
122 if (old) 123 if (old)
123 gss_put_ctx(old); 124 gss_put_ctx(old);
124} 125}
@@ -129,10 +130,10 @@ gss_cred_is_uptodate_ctx(struct rpc_cred *cred)
129 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base); 130 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
130 int res = 0; 131 int res = 0;
131 132
132 read_lock(&gss_ctx_lock); 133 rcu_read_lock();
133 if ((cred->cr_flags & RPCAUTH_CRED_UPTODATE) && gss_cred->gc_ctx) 134 if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) && gss_cred->gc_ctx)
134 res = 1; 135 res = 1;
135 read_unlock(&gss_ctx_lock); 136 rcu_read_unlock();
136 return res; 137 return res;
137} 138}
138 139
@@ -171,10 +172,10 @@ gss_cred_get_ctx(struct rpc_cred *cred)
171 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base); 172 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
172 struct gss_cl_ctx *ctx = NULL; 173 struct gss_cl_ctx *ctx = NULL;
173 174
174 read_lock(&gss_ctx_lock); 175 rcu_read_lock();
175 if (gss_cred->gc_ctx) 176 if (gss_cred->gc_ctx)
176 ctx = gss_get_ctx(gss_cred->gc_ctx); 177 ctx = gss_get_ctx(gss_cred->gc_ctx);
177 read_unlock(&gss_ctx_lock); 178 rcu_read_unlock();
178 return ctx; 179 return ctx;
179} 180}
180 181
@@ -269,10 +270,10 @@ gss_release_msg(struct gss_upcall_msg *gss_msg)
269} 270}
270 271
271static struct gss_upcall_msg * 272static struct gss_upcall_msg *
272__gss_find_upcall(struct gss_auth *gss_auth, uid_t uid) 273__gss_find_upcall(struct rpc_inode *rpci, uid_t uid)
273{ 274{
274 struct gss_upcall_msg *pos; 275 struct gss_upcall_msg *pos;
275 list_for_each_entry(pos, &gss_auth->upcalls, list) { 276 list_for_each_entry(pos, &rpci->in_downcall, list) {
276 if (pos->uid != uid) 277 if (pos->uid != uid)
277 continue; 278 continue;
278 atomic_inc(&pos->count); 279 atomic_inc(&pos->count);
@@ -290,24 +291,24 @@ __gss_find_upcall(struct gss_auth *gss_auth, uid_t uid)
290static inline struct gss_upcall_msg * 291static inline struct gss_upcall_msg *
291gss_add_msg(struct gss_auth *gss_auth, struct gss_upcall_msg *gss_msg) 292gss_add_msg(struct gss_auth *gss_auth, struct gss_upcall_msg *gss_msg)
292{ 293{
294 struct inode *inode = gss_auth->dentry->d_inode;
295 struct rpc_inode *rpci = RPC_I(inode);
293 struct gss_upcall_msg *old; 296 struct gss_upcall_msg *old;
294 297
295 spin_lock(&gss_auth->lock); 298 spin_lock(&inode->i_lock);
296 old = __gss_find_upcall(gss_auth, gss_msg->uid); 299 old = __gss_find_upcall(rpci, gss_msg->uid);
297 if (old == NULL) { 300 if (old == NULL) {
298 atomic_inc(&gss_msg->count); 301 atomic_inc(&gss_msg->count);
299 list_add(&gss_msg->list, &gss_auth->upcalls); 302 list_add(&gss_msg->list, &rpci->in_downcall);
300 } else 303 } else
301 gss_msg = old; 304 gss_msg = old;
302 spin_unlock(&gss_auth->lock); 305 spin_unlock(&inode->i_lock);
303 return gss_msg; 306 return gss_msg;
304} 307}
305 308
306static void 309static void
307__gss_unhash_msg(struct gss_upcall_msg *gss_msg) 310__gss_unhash_msg(struct gss_upcall_msg *gss_msg)
308{ 311{
309 if (list_empty(&gss_msg->list))
310 return;
311 list_del_init(&gss_msg->list); 312 list_del_init(&gss_msg->list);
312 rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno); 313 rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno);
313 wake_up_all(&gss_msg->waitqueue); 314 wake_up_all(&gss_msg->waitqueue);
@@ -318,10 +319,14 @@ static void
318gss_unhash_msg(struct gss_upcall_msg *gss_msg) 319gss_unhash_msg(struct gss_upcall_msg *gss_msg)
319{ 320{
320 struct gss_auth *gss_auth = gss_msg->auth; 321 struct gss_auth *gss_auth = gss_msg->auth;
322 struct inode *inode = gss_auth->dentry->d_inode;
321 323
322 spin_lock(&gss_auth->lock); 324 if (list_empty(&gss_msg->list))
323 __gss_unhash_msg(gss_msg); 325 return;
324 spin_unlock(&gss_auth->lock); 326 spin_lock(&inode->i_lock);
327 if (!list_empty(&gss_msg->list))
328 __gss_unhash_msg(gss_msg);
329 spin_unlock(&inode->i_lock);
325} 330}
326 331
327static void 332static void
@@ -330,16 +335,16 @@ gss_upcall_callback(struct rpc_task *task)
330 struct gss_cred *gss_cred = container_of(task->tk_msg.rpc_cred, 335 struct gss_cred *gss_cred = container_of(task->tk_msg.rpc_cred,
331 struct gss_cred, gc_base); 336 struct gss_cred, gc_base);
332 struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall; 337 struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall;
338 struct inode *inode = gss_msg->auth->dentry->d_inode;
333 339
334 BUG_ON(gss_msg == NULL); 340 spin_lock(&inode->i_lock);
335 if (gss_msg->ctx) 341 if (gss_msg->ctx)
336 gss_cred_set_ctx(task->tk_msg.rpc_cred, gss_get_ctx(gss_msg->ctx)); 342 gss_cred_set_ctx(task->tk_msg.rpc_cred, gss_get_ctx(gss_msg->ctx));
337 else 343 else
338 task->tk_status = gss_msg->msg.errno; 344 task->tk_status = gss_msg->msg.errno;
339 spin_lock(&gss_msg->auth->lock);
340 gss_cred->gc_upcall = NULL; 345 gss_cred->gc_upcall = NULL;
341 rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno); 346 rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno);
342 spin_unlock(&gss_msg->auth->lock); 347 spin_unlock(&inode->i_lock);
343 gss_release_msg(gss_msg); 348 gss_release_msg(gss_msg);
344} 349}
345 350
@@ -386,11 +391,12 @@ static inline int
386gss_refresh_upcall(struct rpc_task *task) 391gss_refresh_upcall(struct rpc_task *task)
387{ 392{
388 struct rpc_cred *cred = task->tk_msg.rpc_cred; 393 struct rpc_cred *cred = task->tk_msg.rpc_cred;
389 struct gss_auth *gss_auth = container_of(task->tk_client->cl_auth, 394 struct gss_auth *gss_auth = container_of(cred->cr_auth,
390 struct gss_auth, rpc_auth); 395 struct gss_auth, rpc_auth);
391 struct gss_cred *gss_cred = container_of(cred, 396 struct gss_cred *gss_cred = container_of(cred,
392 struct gss_cred, gc_base); 397 struct gss_cred, gc_base);
393 struct gss_upcall_msg *gss_msg; 398 struct gss_upcall_msg *gss_msg;
399 struct inode *inode = gss_auth->dentry->d_inode;
394 int err = 0; 400 int err = 0;
395 401
396 dprintk("RPC: %5u gss_refresh_upcall for uid %u\n", task->tk_pid, 402 dprintk("RPC: %5u gss_refresh_upcall for uid %u\n", task->tk_pid,
@@ -400,7 +406,7 @@ gss_refresh_upcall(struct rpc_task *task)
400 err = PTR_ERR(gss_msg); 406 err = PTR_ERR(gss_msg);
401 goto out; 407 goto out;
402 } 408 }
403 spin_lock(&gss_auth->lock); 409 spin_lock(&inode->i_lock);
404 if (gss_cred->gc_upcall != NULL) 410 if (gss_cred->gc_upcall != NULL)
405 rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL, NULL); 411 rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL, NULL);
406 else if (gss_msg->ctx == NULL && gss_msg->msg.errno >= 0) { 412 else if (gss_msg->ctx == NULL && gss_msg->msg.errno >= 0) {
@@ -411,7 +417,7 @@ gss_refresh_upcall(struct rpc_task *task)
411 rpc_sleep_on(&gss_msg->rpc_waitqueue, task, gss_upcall_callback, NULL); 417 rpc_sleep_on(&gss_msg->rpc_waitqueue, task, gss_upcall_callback, NULL);
412 } else 418 } else
413 err = gss_msg->msg.errno; 419 err = gss_msg->msg.errno;
414 spin_unlock(&gss_auth->lock); 420 spin_unlock(&inode->i_lock);
415 gss_release_msg(gss_msg); 421 gss_release_msg(gss_msg);
416out: 422out:
417 dprintk("RPC: %5u gss_refresh_upcall for uid %u result %d\n", 423 dprintk("RPC: %5u gss_refresh_upcall for uid %u result %d\n",
@@ -422,6 +428,7 @@ out:
422static inline int 428static inline int
423gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) 429gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
424{ 430{
431 struct inode *inode = gss_auth->dentry->d_inode;
425 struct rpc_cred *cred = &gss_cred->gc_base; 432 struct rpc_cred *cred = &gss_cred->gc_base;
426 struct gss_upcall_msg *gss_msg; 433 struct gss_upcall_msg *gss_msg;
427 DEFINE_WAIT(wait); 434 DEFINE_WAIT(wait);
@@ -435,12 +442,11 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
435 } 442 }
436 for (;;) { 443 for (;;) {
437 prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_INTERRUPTIBLE); 444 prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_INTERRUPTIBLE);
438 spin_lock(&gss_auth->lock); 445 spin_lock(&inode->i_lock);
439 if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) { 446 if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) {
440 spin_unlock(&gss_auth->lock);
441 break; 447 break;
442 } 448 }
443 spin_unlock(&gss_auth->lock); 449 spin_unlock(&inode->i_lock);
444 if (signalled()) { 450 if (signalled()) {
445 err = -ERESTARTSYS; 451 err = -ERESTARTSYS;
446 goto out_intr; 452 goto out_intr;
@@ -451,6 +457,7 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
451 gss_cred_set_ctx(cred, gss_get_ctx(gss_msg->ctx)); 457 gss_cred_set_ctx(cred, gss_get_ctx(gss_msg->ctx));
452 else 458 else
453 err = gss_msg->msg.errno; 459 err = gss_msg->msg.errno;
460 spin_unlock(&inode->i_lock);
454out_intr: 461out_intr:
455 finish_wait(&gss_msg->waitqueue, &wait); 462 finish_wait(&gss_msg->waitqueue, &wait);
456 gss_release_msg(gss_msg); 463 gss_release_msg(gss_msg);
@@ -489,12 +496,11 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
489 const void *p, *end; 496 const void *p, *end;
490 void *buf; 497 void *buf;
491 struct rpc_clnt *clnt; 498 struct rpc_clnt *clnt;
492 struct gss_auth *gss_auth;
493 struct rpc_cred *cred;
494 struct gss_upcall_msg *gss_msg; 499 struct gss_upcall_msg *gss_msg;
500 struct inode *inode = filp->f_path.dentry->d_inode;
495 struct gss_cl_ctx *ctx; 501 struct gss_cl_ctx *ctx;
496 uid_t uid; 502 uid_t uid;
497 int err = -EFBIG; 503 ssize_t err = -EFBIG;
498 504
499 if (mlen > MSG_BUF_MAXSIZE) 505 if (mlen > MSG_BUF_MAXSIZE)
500 goto out; 506 goto out;
@@ -503,7 +509,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
503 if (!buf) 509 if (!buf)
504 goto out; 510 goto out;
505 511
506 clnt = RPC_I(filp->f_path.dentry->d_inode)->private; 512 clnt = RPC_I(inode)->private;
507 err = -EFAULT; 513 err = -EFAULT;
508 if (copy_from_user(buf, src, mlen)) 514 if (copy_from_user(buf, src, mlen))
509 goto err; 515 goto err;
@@ -519,43 +525,38 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
519 ctx = gss_alloc_context(); 525 ctx = gss_alloc_context();
520 if (ctx == NULL) 526 if (ctx == NULL)
521 goto err; 527 goto err;
522 err = 0; 528
523 gss_auth = container_of(clnt->cl_auth, struct gss_auth, rpc_auth); 529 err = -ENOENT;
524 p = gss_fill_context(p, end, ctx, gss_auth->mech); 530 /* Find a matching upcall */
531 spin_lock(&inode->i_lock);
532 gss_msg = __gss_find_upcall(RPC_I(inode), uid);
533 if (gss_msg == NULL) {
534 spin_unlock(&inode->i_lock);
535 goto err_put_ctx;
536 }
537 list_del_init(&gss_msg->list);
538 spin_unlock(&inode->i_lock);
539
540 p = gss_fill_context(p, end, ctx, gss_msg->auth->mech);
525 if (IS_ERR(p)) { 541 if (IS_ERR(p)) {
526 err = PTR_ERR(p); 542 err = PTR_ERR(p);
527 if (err != -EACCES) 543 gss_msg->msg.errno = (err == -EACCES) ? -EACCES : -EAGAIN;
528 goto err_put_ctx; 544 goto err_release_msg;
529 }
530 spin_lock(&gss_auth->lock);
531 gss_msg = __gss_find_upcall(gss_auth, uid);
532 if (gss_msg) {
533 if (err == 0 && gss_msg->ctx == NULL)
534 gss_msg->ctx = gss_get_ctx(ctx);
535 gss_msg->msg.errno = err;
536 __gss_unhash_msg(gss_msg);
537 spin_unlock(&gss_auth->lock);
538 gss_release_msg(gss_msg);
539 } else {
540 struct auth_cred acred = { .uid = uid };
541 spin_unlock(&gss_auth->lock);
542 cred = rpcauth_lookup_credcache(clnt->cl_auth, &acred, RPCAUTH_LOOKUP_NEW);
543 if (IS_ERR(cred)) {
544 err = PTR_ERR(cred);
545 goto err_put_ctx;
546 }
547 gss_cred_set_ctx(cred, gss_get_ctx(ctx));
548 } 545 }
549 gss_put_ctx(ctx); 546 gss_msg->ctx = gss_get_ctx(ctx);
550 kfree(buf); 547 err = mlen;
551 dprintk("RPC: gss_pipe_downcall returning length %Zu\n", mlen); 548
552 return mlen; 549err_release_msg:
550 spin_lock(&inode->i_lock);
551 __gss_unhash_msg(gss_msg);
552 spin_unlock(&inode->i_lock);
553 gss_release_msg(gss_msg);
553err_put_ctx: 554err_put_ctx:
554 gss_put_ctx(ctx); 555 gss_put_ctx(ctx);
555err: 556err:
556 kfree(buf); 557 kfree(buf);
557out: 558out:
558 dprintk("RPC: gss_pipe_downcall returning %d\n", err); 559 dprintk("RPC: gss_pipe_downcall returning %Zd\n", err);
559 return err; 560 return err;
560} 561}
561 562
@@ -563,27 +564,21 @@ static void
563gss_pipe_release(struct inode *inode) 564gss_pipe_release(struct inode *inode)
564{ 565{
565 struct rpc_inode *rpci = RPC_I(inode); 566 struct rpc_inode *rpci = RPC_I(inode);
566 struct rpc_clnt *clnt; 567 struct gss_upcall_msg *gss_msg;
567 struct rpc_auth *auth;
568 struct gss_auth *gss_auth;
569 568
570 clnt = rpci->private; 569 spin_lock(&inode->i_lock);
571 auth = clnt->cl_auth; 570 while (!list_empty(&rpci->in_downcall)) {
572 gss_auth = container_of(auth, struct gss_auth, rpc_auth);
573 spin_lock(&gss_auth->lock);
574 while (!list_empty(&gss_auth->upcalls)) {
575 struct gss_upcall_msg *gss_msg;
576 571
577 gss_msg = list_entry(gss_auth->upcalls.next, 572 gss_msg = list_entry(rpci->in_downcall.next,
578 struct gss_upcall_msg, list); 573 struct gss_upcall_msg, list);
579 gss_msg->msg.errno = -EPIPE; 574 gss_msg->msg.errno = -EPIPE;
580 atomic_inc(&gss_msg->count); 575 atomic_inc(&gss_msg->count);
581 __gss_unhash_msg(gss_msg); 576 __gss_unhash_msg(gss_msg);
582 spin_unlock(&gss_auth->lock); 577 spin_unlock(&inode->i_lock);
583 gss_release_msg(gss_msg); 578 gss_release_msg(gss_msg);
584 spin_lock(&gss_auth->lock); 579 spin_lock(&inode->i_lock);
585 } 580 }
586 spin_unlock(&gss_auth->lock); 581 spin_unlock(&inode->i_lock);
587} 582}
588 583
589static void 584static void
@@ -637,18 +632,13 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
637 gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor); 632 gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor);
638 if (gss_auth->service == 0) 633 if (gss_auth->service == 0)
639 goto err_put_mech; 634 goto err_put_mech;
640 INIT_LIST_HEAD(&gss_auth->upcalls);
641 spin_lock_init(&gss_auth->lock);
642 auth = &gss_auth->rpc_auth; 635 auth = &gss_auth->rpc_auth;
643 auth->au_cslack = GSS_CRED_SLACK >> 2; 636 auth->au_cslack = GSS_CRED_SLACK >> 2;
644 auth->au_rslack = GSS_VERF_SLACK >> 2; 637 auth->au_rslack = GSS_VERF_SLACK >> 2;
645 auth->au_ops = &authgss_ops; 638 auth->au_ops = &authgss_ops;
646 auth->au_flavor = flavor; 639 auth->au_flavor = flavor;
647 atomic_set(&auth->au_count, 1); 640 atomic_set(&auth->au_count, 1);
648 641 kref_init(&gss_auth->kref);
649 err = rpcauth_init_credcache(auth, GSS_CRED_EXPIRE);
650 if (err)
651 goto err_put_mech;
652 642
653 gss_auth->dentry = rpc_mkpipe(clnt->cl_dentry, gss_auth->mech->gm_name, 643 gss_auth->dentry = rpc_mkpipe(clnt->cl_dentry, gss_auth->mech->gm_name,
654 clnt, &gss_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN); 644 clnt, &gss_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
@@ -657,7 +647,13 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
657 goto err_put_mech; 647 goto err_put_mech;
658 } 648 }
659 649
650 err = rpcauth_init_credcache(auth);
651 if (err)
652 goto err_unlink_pipe;
653
660 return auth; 654 return auth;
655err_unlink_pipe:
656 rpc_unlink(gss_auth->dentry);
661err_put_mech: 657err_put_mech:
662 gss_mech_put(gss_auth->mech); 658 gss_mech_put(gss_auth->mech);
663err_free: 659err_free:
@@ -668,6 +664,25 @@ out_dec:
668} 664}
669 665
670static void 666static void
667gss_free(struct gss_auth *gss_auth)
668{
669 rpc_unlink(gss_auth->dentry);
670 gss_auth->dentry = NULL;
671 gss_mech_put(gss_auth->mech);
672
673 kfree(gss_auth);
674 module_put(THIS_MODULE);
675}
676
677static void
678gss_free_callback(struct kref *kref)
679{
680 struct gss_auth *gss_auth = container_of(kref, struct gss_auth, kref);
681
682 gss_free(gss_auth);
683}
684
685static void
671gss_destroy(struct rpc_auth *auth) 686gss_destroy(struct rpc_auth *auth)
672{ 687{
673 struct gss_auth *gss_auth; 688 struct gss_auth *gss_auth;
@@ -675,23 +690,51 @@ gss_destroy(struct rpc_auth *auth)
675 dprintk("RPC: destroying GSS authenticator %p flavor %d\n", 690 dprintk("RPC: destroying GSS authenticator %p flavor %d\n",
676 auth, auth->au_flavor); 691 auth, auth->au_flavor);
677 692
693 rpcauth_destroy_credcache(auth);
694
678 gss_auth = container_of(auth, struct gss_auth, rpc_auth); 695 gss_auth = container_of(auth, struct gss_auth, rpc_auth);
679 rpc_unlink(gss_auth->dentry); 696 kref_put(&gss_auth->kref, gss_free_callback);
680 gss_auth->dentry = NULL; 697}
681 gss_mech_put(gss_auth->mech);
682 698
683 rpcauth_free_credcache(auth); 699/*
684 kfree(gss_auth); 700 * gss_destroying_context will cause the RPCSEC_GSS to send a NULL RPC call
685 module_put(THIS_MODULE); 701 * to the server with the GSS control procedure field set to
702 * RPC_GSS_PROC_DESTROY. This should normally cause the server to release
703 * all RPCSEC_GSS state associated with that context.
704 */
705static int
706gss_destroying_context(struct rpc_cred *cred)
707{
708 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
709 struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth);
710 struct rpc_task *task;
711
712 if (gss_cred->gc_ctx == NULL ||
713 gss_cred->gc_ctx->gc_proc == RPC_GSS_PROC_DESTROY)
714 return 0;
715
716 gss_cred->gc_ctx->gc_proc = RPC_GSS_PROC_DESTROY;
717 cred->cr_ops = &gss_nullops;
718
719 /* Take a reference to ensure the cred will be destroyed either
720 * by the RPC call or by the put_rpccred() below */
721 get_rpccred(cred);
722
723 task = rpc_call_null(gss_auth->client, cred, RPC_TASK_ASYNC);
724 if (!IS_ERR(task))
725 rpc_put_task(task);
726
727 put_rpccred(cred);
728 return 1;
686} 729}
687 730
688/* gss_destroy_cred (and gss_destroy_ctx) are used to clean up after failure 731/* gss_destroy_cred (and gss_free_ctx) are used to clean up after failure
689 * to create a new cred or context, so they check that things have been 732 * to create a new cred or context, so they check that things have been
690 * allocated before freeing them. */ 733 * allocated before freeing them. */
691static void 734static void
692gss_destroy_ctx(struct gss_cl_ctx *ctx) 735gss_do_free_ctx(struct gss_cl_ctx *ctx)
693{ 736{
694 dprintk("RPC: gss_destroy_ctx\n"); 737 dprintk("RPC: gss_free_ctx\n");
695 738
696 if (ctx->gc_gss_ctx) 739 if (ctx->gc_gss_ctx)
697 gss_delete_sec_context(&ctx->gc_gss_ctx); 740 gss_delete_sec_context(&ctx->gc_gss_ctx);
@@ -701,15 +744,46 @@ gss_destroy_ctx(struct gss_cl_ctx *ctx)
701} 744}
702 745
703static void 746static void
704gss_destroy_cred(struct rpc_cred *rc) 747gss_free_ctx_callback(struct rcu_head *head)
705{ 748{
706 struct gss_cred *cred = container_of(rc, struct gss_cred, gc_base); 749 struct gss_cl_ctx *ctx = container_of(head, struct gss_cl_ctx, gc_rcu);
750 gss_do_free_ctx(ctx);
751}
707 752
708 dprintk("RPC: gss_destroy_cred \n"); 753static void
754gss_free_ctx(struct gss_cl_ctx *ctx)
755{
756 call_rcu(&ctx->gc_rcu, gss_free_ctx_callback);
757}
709 758
710 if (cred->gc_ctx) 759static void
711 gss_put_ctx(cred->gc_ctx); 760gss_free_cred(struct gss_cred *gss_cred)
712 kfree(cred); 761{
762 dprintk("RPC: gss_free_cred %p\n", gss_cred);
763 kfree(gss_cred);
764}
765
766static void
767gss_free_cred_callback(struct rcu_head *head)
768{
769 struct gss_cred *gss_cred = container_of(head, struct gss_cred, gc_base.cr_rcu);
770 gss_free_cred(gss_cred);
771}
772
773static void
774gss_destroy_cred(struct rpc_cred *cred)
775{
776 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
777 struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth);
778 struct gss_cl_ctx *ctx = gss_cred->gc_ctx;
779
780 if (gss_destroying_context(cred))
781 return;
782 rcu_assign_pointer(gss_cred->gc_ctx, NULL);
783 call_rcu(&cred->cr_rcu, gss_free_cred_callback);
784 if (ctx)
785 gss_put_ctx(ctx);
786 kref_put(&gss_auth->kref, gss_free_callback);
713} 787}
714 788
715/* 789/*
@@ -734,16 +808,14 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
734 if (!(cred = kzalloc(sizeof(*cred), GFP_KERNEL))) 808 if (!(cred = kzalloc(sizeof(*cred), GFP_KERNEL)))
735 goto out_err; 809 goto out_err;
736 810
737 atomic_set(&cred->gc_count, 1); 811 rpcauth_init_cred(&cred->gc_base, acred, auth, &gss_credops);
738 cred->gc_uid = acred->uid;
739 /* 812 /*
740 * Note: in order to force a call to call_refresh(), we deliberately 813 * Note: in order to force a call to call_refresh(), we deliberately
741 * fail to flag the credential as RPCAUTH_CRED_UPTODATE. 814 * fail to flag the credential as RPCAUTH_CRED_UPTODATE.
742 */ 815 */
743 cred->gc_flags = 0; 816 cred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_NEW;
744 cred->gc_base.cr_ops = &gss_credops;
745 cred->gc_base.cr_flags = RPCAUTH_CRED_NEW;
746 cred->gc_service = gss_auth->service; 817 cred->gc_service = gss_auth->service;
818 kref_get(&gss_auth->kref);
747 return &cred->gc_base; 819 return &cred->gc_base;
748 820
749out_err: 821out_err:
@@ -774,7 +846,7 @@ gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags)
774 * we don't really care if the credential has expired or not, 846 * we don't really care if the credential has expired or not,
775 * since the caller should be prepared to reinitialise it. 847 * since the caller should be prepared to reinitialise it.
776 */ 848 */
777 if ((flags & RPCAUTH_LOOKUP_NEW) && (rc->cr_flags & RPCAUTH_CRED_NEW)) 849 if ((flags & RPCAUTH_LOOKUP_NEW) && test_bit(RPCAUTH_CRED_NEW, &rc->cr_flags))
778 goto out; 850 goto out;
779 /* Don't match with creds that have expired. */ 851 /* Don't match with creds that have expired. */
780 if (gss_cred->gc_ctx && time_after(jiffies, gss_cred->gc_ctx->gc_expiry)) 852 if (gss_cred->gc_ctx && time_after(jiffies, gss_cred->gc_ctx->gc_expiry))
@@ -830,7 +902,7 @@ gss_marshal(struct rpc_task *task, __be32 *p)
830 mic.data = (u8 *)(p + 1); 902 mic.data = (u8 *)(p + 1);
831 maj_stat = gss_get_mic(ctx->gc_gss_ctx, &verf_buf, &mic); 903 maj_stat = gss_get_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
832 if (maj_stat == GSS_S_CONTEXT_EXPIRED) { 904 if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
833 cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE; 905 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
834 } else if (maj_stat != 0) { 906 } else if (maj_stat != 0) {
835 printk("gss_marshal: gss_get_mic FAILED (%d)\n", maj_stat); 907 printk("gss_marshal: gss_get_mic FAILED (%d)\n", maj_stat);
836 goto out_put_ctx; 908 goto out_put_ctx;
@@ -855,6 +927,13 @@ gss_refresh(struct rpc_task *task)
855 return 0; 927 return 0;
856} 928}
857 929
930/* Dummy refresh routine: used only when destroying the context */
931static int
932gss_refresh_null(struct rpc_task *task)
933{
934 return -EACCES;
935}
936
858static __be32 * 937static __be32 *
859gss_validate(struct rpc_task *task, __be32 *p) 938gss_validate(struct rpc_task *task, __be32 *p)
860{ 939{
@@ -883,12 +962,15 @@ gss_validate(struct rpc_task *task, __be32 *p)
883 962
884 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic); 963 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
885 if (maj_stat == GSS_S_CONTEXT_EXPIRED) 964 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
886 cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE; 965 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
887 if (maj_stat) 966 if (maj_stat) {
967 dprintk("RPC: %5u gss_validate: gss_verify_mic returned"
968 "error 0x%08x\n", task->tk_pid, maj_stat);
888 goto out_bad; 969 goto out_bad;
970 }
889 /* We leave it to unwrap to calculate au_rslack. For now we just 971 /* We leave it to unwrap to calculate au_rslack. For now we just
890 * calculate the length of the verifier: */ 972 * calculate the length of the verifier: */
891 task->tk_auth->au_verfsize = XDR_QUADLEN(len) + 2; 973 cred->cr_auth->au_verfsize = XDR_QUADLEN(len) + 2;
892 gss_put_ctx(ctx); 974 gss_put_ctx(ctx);
893 dprintk("RPC: %5u gss_validate: gss_verify_mic succeeded.\n", 975 dprintk("RPC: %5u gss_validate: gss_verify_mic succeeded.\n",
894 task->tk_pid); 976 task->tk_pid);
@@ -917,7 +999,9 @@ gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
917 offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; 999 offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
918 *p++ = htonl(rqstp->rq_seqno); 1000 *p++ = htonl(rqstp->rq_seqno);
919 1001
1002 lock_kernel();
920 status = encode(rqstp, p, obj); 1003 status = encode(rqstp, p, obj);
1004 unlock_kernel();
921 if (status) 1005 if (status)
922 return status; 1006 return status;
923 1007
@@ -937,7 +1021,7 @@ gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
937 maj_stat = gss_get_mic(ctx->gc_gss_ctx, &integ_buf, &mic); 1021 maj_stat = gss_get_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
938 status = -EIO; /* XXX? */ 1022 status = -EIO; /* XXX? */
939 if (maj_stat == GSS_S_CONTEXT_EXPIRED) 1023 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
940 cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE; 1024 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
941 else if (maj_stat) 1025 else if (maj_stat)
942 return status; 1026 return status;
943 q = xdr_encode_opaque(p, NULL, mic.len); 1027 q = xdr_encode_opaque(p, NULL, mic.len);
@@ -1011,7 +1095,9 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
1011 offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; 1095 offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
1012 *p++ = htonl(rqstp->rq_seqno); 1096 *p++ = htonl(rqstp->rq_seqno);
1013 1097
1098 lock_kernel();
1014 status = encode(rqstp, p, obj); 1099 status = encode(rqstp, p, obj);
1100 unlock_kernel();
1015 if (status) 1101 if (status)
1016 return status; 1102 return status;
1017 1103
@@ -1036,7 +1122,7 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
1036 /* We're assuming that when GSS_S_CONTEXT_EXPIRED, the encryption was 1122 /* We're assuming that when GSS_S_CONTEXT_EXPIRED, the encryption was
1037 * done anyway, so it's safe to put the request on the wire: */ 1123 * done anyway, so it's safe to put the request on the wire: */
1038 if (maj_stat == GSS_S_CONTEXT_EXPIRED) 1124 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
1039 cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE; 1125 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1040 else if (maj_stat) 1126 else if (maj_stat)
1041 return status; 1127 return status;
1042 1128
@@ -1070,12 +1156,16 @@ gss_wrap_req(struct rpc_task *task,
1070 /* The spec seems a little ambiguous here, but I think that not 1156 /* The spec seems a little ambiguous here, but I think that not
1071 * wrapping context destruction requests makes the most sense. 1157 * wrapping context destruction requests makes the most sense.
1072 */ 1158 */
1159 lock_kernel();
1073 status = encode(rqstp, p, obj); 1160 status = encode(rqstp, p, obj);
1161 unlock_kernel();
1074 goto out; 1162 goto out;
1075 } 1163 }
1076 switch (gss_cred->gc_service) { 1164 switch (gss_cred->gc_service) {
1077 case RPC_GSS_SVC_NONE: 1165 case RPC_GSS_SVC_NONE:
1166 lock_kernel();
1078 status = encode(rqstp, p, obj); 1167 status = encode(rqstp, p, obj);
1168 unlock_kernel();
1079 break; 1169 break;
1080 case RPC_GSS_SVC_INTEGRITY: 1170 case RPC_GSS_SVC_INTEGRITY:
1081 status = gss_wrap_req_integ(cred, ctx, encode, 1171 status = gss_wrap_req_integ(cred, ctx, encode,
@@ -1123,7 +1213,7 @@ gss_unwrap_resp_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
1123 1213
1124 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &integ_buf, &mic); 1214 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
1125 if (maj_stat == GSS_S_CONTEXT_EXPIRED) 1215 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
1126 cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE; 1216 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1127 if (maj_stat != GSS_S_COMPLETE) 1217 if (maj_stat != GSS_S_COMPLETE)
1128 return status; 1218 return status;
1129 return 0; 1219 return 0;
@@ -1148,7 +1238,7 @@ gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
1148 1238
1149 maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset, rcv_buf); 1239 maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset, rcv_buf);
1150 if (maj_stat == GSS_S_CONTEXT_EXPIRED) 1240 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
1151 cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE; 1241 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1152 if (maj_stat != GSS_S_COMPLETE) 1242 if (maj_stat != GSS_S_COMPLETE)
1153 return status; 1243 return status;
1154 if (ntohl(*(*p)++) != rqstp->rq_seqno) 1244 if (ntohl(*(*p)++) != rqstp->rq_seqno)
@@ -1188,10 +1278,12 @@ gss_unwrap_resp(struct rpc_task *task,
1188 break; 1278 break;
1189 } 1279 }
1190 /* take into account extra slack for integrity and privacy cases: */ 1280 /* take into account extra slack for integrity and privacy cases: */
1191 task->tk_auth->au_rslack = task->tk_auth->au_verfsize + (p - savedp) 1281 cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize + (p - savedp)
1192 + (savedlen - head->iov_len); 1282 + (savedlen - head->iov_len);
1193out_decode: 1283out_decode:
1284 lock_kernel();
1194 status = decode(rqstp, p, obj); 1285 status = decode(rqstp, p, obj);
1286 unlock_kernel();
1195out: 1287out:
1196 gss_put_ctx(ctx); 1288 gss_put_ctx(ctx);
1197 dprintk("RPC: %5u gss_unwrap_resp returning %d\n", task->tk_pid, 1289 dprintk("RPC: %5u gss_unwrap_resp returning %d\n", task->tk_pid,
@@ -1199,7 +1291,7 @@ out:
1199 return status; 1291 return status;
1200} 1292}
1201 1293
1202static struct rpc_authops authgss_ops = { 1294static const struct rpc_authops authgss_ops = {
1203 .owner = THIS_MODULE, 1295 .owner = THIS_MODULE,
1204 .au_flavor = RPC_AUTH_GSS, 1296 .au_flavor = RPC_AUTH_GSS,
1205#ifdef RPC_DEBUG 1297#ifdef RPC_DEBUG
@@ -1211,7 +1303,7 @@ static struct rpc_authops authgss_ops = {
1211 .crcreate = gss_create_cred 1303 .crcreate = gss_create_cred
1212}; 1304};
1213 1305
1214static struct rpc_credops gss_credops = { 1306static const struct rpc_credops gss_credops = {
1215 .cr_name = "AUTH_GSS", 1307 .cr_name = "AUTH_GSS",
1216 .crdestroy = gss_destroy_cred, 1308 .crdestroy = gss_destroy_cred,
1217 .cr_init = gss_cred_init, 1309 .cr_init = gss_cred_init,
@@ -1223,6 +1315,17 @@ static struct rpc_credops gss_credops = {
1223 .crunwrap_resp = gss_unwrap_resp, 1315 .crunwrap_resp = gss_unwrap_resp,
1224}; 1316};
1225 1317
1318static const struct rpc_credops gss_nullops = {
1319 .cr_name = "AUTH_GSS",
1320 .crdestroy = gss_destroy_cred,
1321 .crmatch = gss_match,
1322 .crmarshal = gss_marshal,
1323 .crrefresh = gss_refresh_null,
1324 .crvalidate = gss_validate,
1325 .crwrap_req = gss_wrap_req,
1326 .crunwrap_resp = gss_unwrap_resp,
1327};
1328
1226static struct rpc_pipe_ops gss_upcall_ops = { 1329static struct rpc_pipe_ops gss_upcall_ops = {
1227 .upcall = gss_pipe_upcall, 1330 .upcall = gss_pipe_upcall,
1228 .downcall = gss_pipe_downcall, 1331 .downcall = gss_pipe_downcall,
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
index 7b1943217053..71b9daefdff3 100644
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
@@ -201,7 +201,7 @@ gss_delete_sec_context_kerberos(void *internal_ctx) {
201 kfree(kctx); 201 kfree(kctx);
202} 202}
203 203
204static struct gss_api_ops gss_kerberos_ops = { 204static const struct gss_api_ops gss_kerberos_ops = {
205 .gss_import_sec_context = gss_import_sec_context_kerberos, 205 .gss_import_sec_context = gss_import_sec_context_kerberos,
206 .gss_get_mic = gss_get_mic_kerberos, 206 .gss_get_mic = gss_get_mic_kerberos,
207 .gss_verify_mic = gss_verify_mic_kerberos, 207 .gss_verify_mic = gss_verify_mic_kerberos,
diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c
index 7e15aa68ae64..577d590e755f 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_mech.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c
@@ -202,7 +202,7 @@ gss_get_mic_spkm3(struct gss_ctx *ctx,
202 return err; 202 return err;
203} 203}
204 204
205static struct gss_api_ops gss_spkm3_ops = { 205static const struct gss_api_ops gss_spkm3_ops = {
206 .gss_import_sec_context = gss_import_sec_context_spkm3, 206 .gss_import_sec_context = gss_import_sec_context_spkm3,
207 .gss_get_mic = gss_get_mic_spkm3, 207 .gss_get_mic = gss_get_mic_spkm3,
208 .gss_verify_mic = gss_verify_mic_spkm3, 208 .gss_verify_mic = gss_verify_mic_spkm3,
diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c
index 3df9fccab2f8..537d0e8589dd 100644
--- a/net/sunrpc/auth_null.c
+++ b/net/sunrpc/auth_null.c
@@ -76,7 +76,7 @@ nul_marshal(struct rpc_task *task, __be32 *p)
76static int 76static int
77nul_refresh(struct rpc_task *task) 77nul_refresh(struct rpc_task *task)
78{ 78{
79 task->tk_msg.rpc_cred->cr_flags |= RPCAUTH_CRED_UPTODATE; 79 set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_msg.rpc_cred->cr_flags);
80 return 0; 80 return 0;
81} 81}
82 82
@@ -101,7 +101,7 @@ nul_validate(struct rpc_task *task, __be32 *p)
101 return p; 101 return p;
102} 102}
103 103
104struct rpc_authops authnull_ops = { 104const struct rpc_authops authnull_ops = {
105 .owner = THIS_MODULE, 105 .owner = THIS_MODULE,
106 .au_flavor = RPC_AUTH_NULL, 106 .au_flavor = RPC_AUTH_NULL,
107#ifdef RPC_DEBUG 107#ifdef RPC_DEBUG
@@ -122,7 +122,7 @@ struct rpc_auth null_auth = {
122}; 122};
123 123
124static 124static
125struct rpc_credops null_credops = { 125const struct rpc_credops null_credops = {
126 .cr_name = "AUTH_NULL", 126 .cr_name = "AUTH_NULL",
127 .crdestroy = nul_destroy_cred, 127 .crdestroy = nul_destroy_cred,
128 .crmatch = nul_match, 128 .crmatch = nul_match,
@@ -133,9 +133,11 @@ struct rpc_credops null_credops = {
133 133
134static 134static
135struct rpc_cred null_cred = { 135struct rpc_cred null_cred = {
136 .cr_lru = LIST_HEAD_INIT(null_cred.cr_lru),
137 .cr_auth = &null_auth,
136 .cr_ops = &null_credops, 138 .cr_ops = &null_credops,
137 .cr_count = ATOMIC_INIT(1), 139 .cr_count = ATOMIC_INIT(1),
138 .cr_flags = RPCAUTH_CRED_UPTODATE, 140 .cr_flags = 1UL << RPCAUTH_CRED_UPTODATE,
139#ifdef RPC_DEBUG 141#ifdef RPC_DEBUG
140 .cr_magic = RPCAUTH_CRED_MAGIC, 142 .cr_magic = RPCAUTH_CRED_MAGIC,
141#endif 143#endif
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index 4e7733aee36e..5ed91e5bcee4 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -20,11 +20,6 @@ struct unx_cred {
20 gid_t uc_gids[NFS_NGROUPS]; 20 gid_t uc_gids[NFS_NGROUPS];
21}; 21};
22#define uc_uid uc_base.cr_uid 22#define uc_uid uc_base.cr_uid
23#define uc_count uc_base.cr_count
24#define uc_flags uc_base.cr_flags
25#define uc_expire uc_base.cr_expire
26
27#define UNX_CRED_EXPIRE (60 * HZ)
28 23
29#define UNX_WRITESLACK (21 + (UNX_MAXNODENAME >> 2)) 24#define UNX_WRITESLACK (21 + (UNX_MAXNODENAME >> 2))
30 25
@@ -34,15 +29,14 @@ struct unx_cred {
34 29
35static struct rpc_auth unix_auth; 30static struct rpc_auth unix_auth;
36static struct rpc_cred_cache unix_cred_cache; 31static struct rpc_cred_cache unix_cred_cache;
37static struct rpc_credops unix_credops; 32static const struct rpc_credops unix_credops;
38 33
39static struct rpc_auth * 34static struct rpc_auth *
40unx_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor) 35unx_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
41{ 36{
42 dprintk("RPC: creating UNIX authenticator for client %p\n", 37 dprintk("RPC: creating UNIX authenticator for client %p\n",
43 clnt); 38 clnt);
44 if (atomic_inc_return(&unix_auth.au_count) == 0) 39 atomic_inc(&unix_auth.au_count);
45 unix_cred_cache.nextgc = jiffies + (unix_cred_cache.expire >> 1);
46 return &unix_auth; 40 return &unix_auth;
47} 41}
48 42
@@ -50,7 +44,7 @@ static void
50unx_destroy(struct rpc_auth *auth) 44unx_destroy(struct rpc_auth *auth)
51{ 45{
52 dprintk("RPC: destroying UNIX authenticator %p\n", auth); 46 dprintk("RPC: destroying UNIX authenticator %p\n", auth);
53 rpcauth_free_credcache(auth); 47 rpcauth_clear_credcache(auth->au_credcache);
54} 48}
55 49
56/* 50/*
@@ -74,8 +68,8 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
74 if (!(cred = kmalloc(sizeof(*cred), GFP_KERNEL))) 68 if (!(cred = kmalloc(sizeof(*cred), GFP_KERNEL)))
75 return ERR_PTR(-ENOMEM); 69 return ERR_PTR(-ENOMEM);
76 70
77 atomic_set(&cred->uc_count, 1); 71 rpcauth_init_cred(&cred->uc_base, acred, auth, &unix_credops);
78 cred->uc_flags = RPCAUTH_CRED_UPTODATE; 72 cred->uc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE;
79 if (flags & RPCAUTH_LOOKUP_ROOTCREDS) { 73 if (flags & RPCAUTH_LOOKUP_ROOTCREDS) {
80 cred->uc_uid = 0; 74 cred->uc_uid = 0;
81 cred->uc_gid = 0; 75 cred->uc_gid = 0;
@@ -85,22 +79,34 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
85 if (groups > NFS_NGROUPS) 79 if (groups > NFS_NGROUPS)
86 groups = NFS_NGROUPS; 80 groups = NFS_NGROUPS;
87 81
88 cred->uc_uid = acred->uid;
89 cred->uc_gid = acred->gid; 82 cred->uc_gid = acred->gid;
90 for (i = 0; i < groups; i++) 83 for (i = 0; i < groups; i++)
91 cred->uc_gids[i] = GROUP_AT(acred->group_info, i); 84 cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
92 if (i < NFS_NGROUPS) 85 if (i < NFS_NGROUPS)
93 cred->uc_gids[i] = NOGROUP; 86 cred->uc_gids[i] = NOGROUP;
94 } 87 }
95 cred->uc_base.cr_ops = &unix_credops;
96 88
97 return (struct rpc_cred *) cred; 89 return &cred->uc_base;
90}
91
92static void
93unx_free_cred(struct unx_cred *unx_cred)
94{
95 dprintk("RPC: unx_free_cred %p\n", unx_cred);
96 kfree(unx_cred);
97}
98
99static void
100unx_free_cred_callback(struct rcu_head *head)
101{
102 struct unx_cred *unx_cred = container_of(head, struct unx_cred, uc_base.cr_rcu);
103 unx_free_cred(unx_cred);
98} 104}
99 105
100static void 106static void
101unx_destroy_cred(struct rpc_cred *cred) 107unx_destroy_cred(struct rpc_cred *cred)
102{ 108{
103 kfree(cred); 109 call_rcu(&cred->cr_rcu, unx_free_cred_callback);
104} 110}
105 111
106/* 112/*
@@ -111,7 +117,7 @@ unx_destroy_cred(struct rpc_cred *cred)
111static int 117static int
112unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags) 118unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
113{ 119{
114 struct unx_cred *cred = (struct unx_cred *) rcred; 120 struct unx_cred *cred = container_of(rcred, struct unx_cred, uc_base);
115 int i; 121 int i;
116 122
117 if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) { 123 if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) {
@@ -142,7 +148,7 @@ static __be32 *
142unx_marshal(struct rpc_task *task, __be32 *p) 148unx_marshal(struct rpc_task *task, __be32 *p)
143{ 149{
144 struct rpc_clnt *clnt = task->tk_client; 150 struct rpc_clnt *clnt = task->tk_client;
145 struct unx_cred *cred = (struct unx_cred *) task->tk_msg.rpc_cred; 151 struct unx_cred *cred = container_of(task->tk_msg.rpc_cred, struct unx_cred, uc_base);
146 __be32 *base, *hold; 152 __be32 *base, *hold;
147 int i; 153 int i;
148 154
@@ -175,7 +181,7 @@ unx_marshal(struct rpc_task *task, __be32 *p)
175static int 181static int
176unx_refresh(struct rpc_task *task) 182unx_refresh(struct rpc_task *task)
177{ 183{
178 task->tk_msg.rpc_cred->cr_flags |= RPCAUTH_CRED_UPTODATE; 184 set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_msg.rpc_cred->cr_flags);
179 return 0; 185 return 0;
180} 186}
181 187
@@ -198,13 +204,18 @@ unx_validate(struct rpc_task *task, __be32 *p)
198 printk("RPC: giant verf size: %u\n", size); 204 printk("RPC: giant verf size: %u\n", size);
199 return NULL; 205 return NULL;
200 } 206 }
201 task->tk_auth->au_rslack = (size >> 2) + 2; 207 task->tk_msg.rpc_cred->cr_auth->au_rslack = (size >> 2) + 2;
202 p += (size >> 2); 208 p += (size >> 2);
203 209
204 return p; 210 return p;
205} 211}
206 212
207struct rpc_authops authunix_ops = { 213void __init rpc_init_authunix(void)
214{
215 spin_lock_init(&unix_cred_cache.lock);
216}
217
218const struct rpc_authops authunix_ops = {
208 .owner = THIS_MODULE, 219 .owner = THIS_MODULE,
209 .au_flavor = RPC_AUTH_UNIX, 220 .au_flavor = RPC_AUTH_UNIX,
210#ifdef RPC_DEBUG 221#ifdef RPC_DEBUG
@@ -218,7 +229,6 @@ struct rpc_authops authunix_ops = {
218 229
219static 230static
220struct rpc_cred_cache unix_cred_cache = { 231struct rpc_cred_cache unix_cred_cache = {
221 .expire = UNX_CRED_EXPIRE,
222}; 232};
223 233
224static 234static
@@ -232,7 +242,7 @@ struct rpc_auth unix_auth = {
232}; 242};
233 243
234static 244static
235struct rpc_credops unix_credops = { 245const struct rpc_credops unix_credops = {
236 .cr_name = "AUTH_UNIX", 246 .cr_name = "AUTH_UNIX",
237 .crdestroy = unx_destroy_cred, 247 .crdestroy = unx_destroy_cred,
238 .crmatch = unx_match, 248 .crmatch = unx_match,
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 543b085ae2c1..01c3c4105204 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -1210,7 +1210,7 @@ static int c_show(struct seq_file *m, void *p)
1210 return cd->cache_show(m, cd, cp); 1210 return cd->cache_show(m, cd, cp);
1211} 1211}
1212 1212
1213static struct seq_operations cache_content_op = { 1213static const struct seq_operations cache_content_op = {
1214 .start = c_start, 1214 .start = c_start,
1215 .next = c_next, 1215 .next = c_next,
1216 .stop = c_stop, 1216 .stop = c_stop,
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index d8fbee40a19c..52429b1ffcc1 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -44,6 +44,12 @@
44 dprintk("RPC: %5u %s (status %d)\n", t->tk_pid, \ 44 dprintk("RPC: %5u %s (status %d)\n", t->tk_pid, \
45 __FUNCTION__, t->tk_status) 45 __FUNCTION__, t->tk_status)
46 46
47/*
48 * All RPC clients are linked into this list
49 */
50static LIST_HEAD(all_clients);
51static DEFINE_SPINLOCK(rpc_client_lock);
52
47static DECLARE_WAIT_QUEUE_HEAD(destroy_wait); 53static DECLARE_WAIT_QUEUE_HEAD(destroy_wait);
48 54
49 55
@@ -66,6 +72,21 @@ static void call_connect_status(struct rpc_task *task);
66static __be32 * call_header(struct rpc_task *task); 72static __be32 * call_header(struct rpc_task *task);
67static __be32 * call_verify(struct rpc_task *task); 73static __be32 * call_verify(struct rpc_task *task);
68 74
75static int rpc_ping(struct rpc_clnt *clnt, int flags);
76
77static void rpc_register_client(struct rpc_clnt *clnt)
78{
79 spin_lock(&rpc_client_lock);
80 list_add(&clnt->cl_clients, &all_clients);
81 spin_unlock(&rpc_client_lock);
82}
83
84static void rpc_unregister_client(struct rpc_clnt *clnt)
85{
86 spin_lock(&rpc_client_lock);
87 list_del(&clnt->cl_clients);
88 spin_unlock(&rpc_client_lock);
89}
69 90
70static int 91static int
71rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name) 92rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name)
@@ -111,6 +132,9 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
111 dprintk("RPC: creating %s client for %s (xprt %p)\n", 132 dprintk("RPC: creating %s client for %s (xprt %p)\n",
112 program->name, servname, xprt); 133 program->name, servname, xprt);
113 134
135 err = rpciod_up();
136 if (err)
137 goto out_no_rpciod;
114 err = -EINVAL; 138 err = -EINVAL;
115 if (!xprt) 139 if (!xprt)
116 goto out_no_xprt; 140 goto out_no_xprt;
@@ -121,8 +145,6 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
121 clnt = kzalloc(sizeof(*clnt), GFP_KERNEL); 145 clnt = kzalloc(sizeof(*clnt), GFP_KERNEL);
122 if (!clnt) 146 if (!clnt)
123 goto out_err; 147 goto out_err;
124 atomic_set(&clnt->cl_users, 0);
125 atomic_set(&clnt->cl_count, 1);
126 clnt->cl_parent = clnt; 148 clnt->cl_parent = clnt;
127 149
128 clnt->cl_server = clnt->cl_inline_name; 150 clnt->cl_server = clnt->cl_inline_name;
@@ -148,6 +170,8 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
148 if (clnt->cl_metrics == NULL) 170 if (clnt->cl_metrics == NULL)
149 goto out_no_stats; 171 goto out_no_stats;
150 clnt->cl_program = program; 172 clnt->cl_program = program;
173 INIT_LIST_HEAD(&clnt->cl_tasks);
174 spin_lock_init(&clnt->cl_lock);
151 175
152 if (!xprt_bound(clnt->cl_xprt)) 176 if (!xprt_bound(clnt->cl_xprt))
153 clnt->cl_autobind = 1; 177 clnt->cl_autobind = 1;
@@ -155,6 +179,8 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
155 clnt->cl_rtt = &clnt->cl_rtt_default; 179 clnt->cl_rtt = &clnt->cl_rtt_default;
156 rpc_init_rtt(&clnt->cl_rtt_default, xprt->timeout.to_initval); 180 rpc_init_rtt(&clnt->cl_rtt_default, xprt->timeout.to_initval);
157 181
182 kref_init(&clnt->cl_kref);
183
158 err = rpc_setup_pipedir(clnt, program->pipe_dir_name); 184 err = rpc_setup_pipedir(clnt, program->pipe_dir_name);
159 if (err < 0) 185 if (err < 0)
160 goto out_no_path; 186 goto out_no_path;
@@ -172,6 +198,7 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
172 if (clnt->cl_nodelen > UNX_MAXNODENAME) 198 if (clnt->cl_nodelen > UNX_MAXNODENAME)
173 clnt->cl_nodelen = UNX_MAXNODENAME; 199 clnt->cl_nodelen = UNX_MAXNODENAME;
174 memcpy(clnt->cl_nodename, utsname()->nodename, clnt->cl_nodelen); 200 memcpy(clnt->cl_nodename, utsname()->nodename, clnt->cl_nodelen);
201 rpc_register_client(clnt);
175 return clnt; 202 return clnt;
176 203
177out_no_auth: 204out_no_auth:
@@ -188,6 +215,8 @@ out_no_stats:
188out_err: 215out_err:
189 xprt_put(xprt); 216 xprt_put(xprt);
190out_no_xprt: 217out_no_xprt:
218 rpciod_down();
219out_no_rpciod:
191 return ERR_PTR(err); 220 return ERR_PTR(err);
192} 221}
193 222
@@ -205,13 +234,32 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
205{ 234{
206 struct rpc_xprt *xprt; 235 struct rpc_xprt *xprt;
207 struct rpc_clnt *clnt; 236 struct rpc_clnt *clnt;
237 struct rpc_xprtsock_create xprtargs = {
238 .proto = args->protocol,
239 .srcaddr = args->saddress,
240 .dstaddr = args->address,
241 .addrlen = args->addrsize,
242 .timeout = args->timeout
243 };
244 char servername[20];
208 245
209 xprt = xprt_create_transport(args->protocol, args->address, 246 xprt = xprt_create_transport(&xprtargs);
210 args->addrsize, args->timeout);
211 if (IS_ERR(xprt)) 247 if (IS_ERR(xprt))
212 return (struct rpc_clnt *)xprt; 248 return (struct rpc_clnt *)xprt;
213 249
214 /* 250 /*
251 * If the caller chooses not to specify a hostname, whip
252 * up a string representation of the passed-in address.
253 */
254 if (args->servername == NULL) {
255 struct sockaddr_in *addr =
256 (struct sockaddr_in *) &args->address;
257 snprintf(servername, sizeof(servername), NIPQUAD_FMT,
258 NIPQUAD(addr->sin_addr.s_addr));
259 args->servername = servername;
260 }
261
262 /*
215 * By default, kernel RPC client connects from a reserved port. 263 * By default, kernel RPC client connects from a reserved port.
216 * CAP_NET_BIND_SERVICE will not be set for unprivileged requesters, 264 * CAP_NET_BIND_SERVICE will not be set for unprivileged requesters,
217 * but it is always enabled for rpciod, which handles the connect 265 * but it is always enabled for rpciod, which handles the connect
@@ -245,8 +293,6 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
245 clnt->cl_intr = 1; 293 clnt->cl_intr = 1;
246 if (args->flags & RPC_CLNT_CREATE_AUTOBIND) 294 if (args->flags & RPC_CLNT_CREATE_AUTOBIND)
247 clnt->cl_autobind = 1; 295 clnt->cl_autobind = 1;
248 if (args->flags & RPC_CLNT_CREATE_ONESHOT)
249 clnt->cl_oneshot = 1;
250 if (args->flags & RPC_CLNT_CREATE_DISCRTRY) 296 if (args->flags & RPC_CLNT_CREATE_DISCRTRY)
251 clnt->cl_discrtry = 1; 297 clnt->cl_discrtry = 1;
252 298
@@ -268,24 +314,25 @@ rpc_clone_client(struct rpc_clnt *clnt)
268 new = kmemdup(clnt, sizeof(*new), GFP_KERNEL); 314 new = kmemdup(clnt, sizeof(*new), GFP_KERNEL);
269 if (!new) 315 if (!new)
270 goto out_no_clnt; 316 goto out_no_clnt;
271 atomic_set(&new->cl_count, 1); 317 new->cl_parent = clnt;
272 atomic_set(&new->cl_users, 0); 318 /* Turn off autobind on clones */
319 new->cl_autobind = 0;
320 INIT_LIST_HEAD(&new->cl_tasks);
321 spin_lock_init(&new->cl_lock);
322 rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval);
273 new->cl_metrics = rpc_alloc_iostats(clnt); 323 new->cl_metrics = rpc_alloc_iostats(clnt);
274 if (new->cl_metrics == NULL) 324 if (new->cl_metrics == NULL)
275 goto out_no_stats; 325 goto out_no_stats;
326 kref_init(&new->cl_kref);
276 err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name); 327 err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name);
277 if (err != 0) 328 if (err != 0)
278 goto out_no_path; 329 goto out_no_path;
279 new->cl_parent = clnt;
280 atomic_inc(&clnt->cl_count);
281 new->cl_xprt = xprt_get(clnt->cl_xprt);
282 /* Turn off autobind on clones */
283 new->cl_autobind = 0;
284 new->cl_oneshot = 0;
285 new->cl_dead = 0;
286 rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval);
287 if (new->cl_auth) 330 if (new->cl_auth)
288 atomic_inc(&new->cl_auth->au_count); 331 atomic_inc(&new->cl_auth->au_count);
332 xprt_get(clnt->cl_xprt);
333 kref_get(&clnt->cl_kref);
334 rpc_register_client(new);
335 rpciod_up();
289 return new; 336 return new;
290out_no_path: 337out_no_path:
291 rpc_free_iostats(new->cl_metrics); 338 rpc_free_iostats(new->cl_metrics);
@@ -298,86 +345,86 @@ out_no_clnt:
298 345
299/* 346/*
300 * Properly shut down an RPC client, terminating all outstanding 347 * Properly shut down an RPC client, terminating all outstanding
301 * requests. Note that we must be certain that cl_oneshot and 348 * requests.
302 * cl_dead are cleared, or else the client would be destroyed
303 * when the last task releases it.
304 */ 349 */
305int 350void rpc_shutdown_client(struct rpc_clnt *clnt)
306rpc_shutdown_client(struct rpc_clnt *clnt)
307{ 351{
308 dprintk("RPC: shutting down %s client for %s, tasks=%d\n", 352 dprintk("RPC: shutting down %s client for %s\n",
309 clnt->cl_protname, clnt->cl_server, 353 clnt->cl_protname, clnt->cl_server);
310 atomic_read(&clnt->cl_users)); 354
311 355 while (!list_empty(&clnt->cl_tasks)) {
312 while (atomic_read(&clnt->cl_users) > 0) {
313 /* Don't let rpc_release_client destroy us */
314 clnt->cl_oneshot = 0;
315 clnt->cl_dead = 0;
316 rpc_killall_tasks(clnt); 356 rpc_killall_tasks(clnt);
317 wait_event_timeout(destroy_wait, 357 wait_event_timeout(destroy_wait,
318 !atomic_read(&clnt->cl_users), 1*HZ); 358 list_empty(&clnt->cl_tasks), 1*HZ);
319 }
320
321 if (atomic_read(&clnt->cl_users) < 0) {
322 printk(KERN_ERR "RPC: rpc_shutdown_client clnt %p tasks=%d\n",
323 clnt, atomic_read(&clnt->cl_users));
324#ifdef RPC_DEBUG
325 rpc_show_tasks();
326#endif
327 BUG();
328 } 359 }
329 360
330 return rpc_destroy_client(clnt); 361 rpc_release_client(clnt);
331} 362}
332 363
333/* 364/*
334 * Delete an RPC client 365 * Free an RPC client
335 */ 366 */
336int 367static void
337rpc_destroy_client(struct rpc_clnt *clnt) 368rpc_free_client(struct kref *kref)
338{ 369{
339 if (!atomic_dec_and_test(&clnt->cl_count)) 370 struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref);
340 return 1;
341 BUG_ON(atomic_read(&clnt->cl_users) != 0);
342 371
343 dprintk("RPC: destroying %s client for %s\n", 372 dprintk("RPC: destroying %s client for %s\n",
344 clnt->cl_protname, clnt->cl_server); 373 clnt->cl_protname, clnt->cl_server);
345 if (clnt->cl_auth) {
346 rpcauth_destroy(clnt->cl_auth);
347 clnt->cl_auth = NULL;
348 }
349 if (!IS_ERR(clnt->cl_dentry)) { 374 if (!IS_ERR(clnt->cl_dentry)) {
350 rpc_rmdir(clnt->cl_dentry); 375 rpc_rmdir(clnt->cl_dentry);
351 rpc_put_mount(); 376 rpc_put_mount();
352 } 377 }
353 if (clnt->cl_parent != clnt) { 378 if (clnt->cl_parent != clnt) {
354 rpc_destroy_client(clnt->cl_parent); 379 rpc_release_client(clnt->cl_parent);
355 goto out_free; 380 goto out_free;
356 } 381 }
357 if (clnt->cl_server != clnt->cl_inline_name) 382 if (clnt->cl_server != clnt->cl_inline_name)
358 kfree(clnt->cl_server); 383 kfree(clnt->cl_server);
359out_free: 384out_free:
385 rpc_unregister_client(clnt);
360 rpc_free_iostats(clnt->cl_metrics); 386 rpc_free_iostats(clnt->cl_metrics);
361 clnt->cl_metrics = NULL; 387 clnt->cl_metrics = NULL;
362 xprt_put(clnt->cl_xprt); 388 xprt_put(clnt->cl_xprt);
389 rpciod_down();
363 kfree(clnt); 390 kfree(clnt);
364 return 0;
365} 391}
366 392
367/* 393/*
368 * Release an RPC client 394 * Free an RPC client
395 */
396static void
397rpc_free_auth(struct kref *kref)
398{
399 struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref);
400
401 if (clnt->cl_auth == NULL) {
402 rpc_free_client(kref);
403 return;
404 }
405
406 /*
407 * Note: RPCSEC_GSS may need to send NULL RPC calls in order to
408 * release remaining GSS contexts. This mechanism ensures
409 * that it can do so safely.
410 */
411 kref_init(kref);
412 rpcauth_release(clnt->cl_auth);
413 clnt->cl_auth = NULL;
414 kref_put(kref, rpc_free_client);
415}
416
417/*
418 * Release reference to the RPC client
369 */ 419 */
370void 420void
371rpc_release_client(struct rpc_clnt *clnt) 421rpc_release_client(struct rpc_clnt *clnt)
372{ 422{
373 dprintk("RPC: rpc_release_client(%p, %d)\n", 423 dprintk("RPC: rpc_release_client(%p)\n", clnt);
374 clnt, atomic_read(&clnt->cl_users));
375 424
376 if (!atomic_dec_and_test(&clnt->cl_users)) 425 if (list_empty(&clnt->cl_tasks))
377 return; 426 wake_up(&destroy_wait);
378 wake_up(&destroy_wait); 427 kref_put(&clnt->cl_kref, rpc_free_auth);
379 if (clnt->cl_oneshot || clnt->cl_dead)
380 rpc_destroy_client(clnt);
381} 428}
382 429
383/** 430/**
@@ -468,82 +515,96 @@ void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset)
468 rpc_restore_sigmask(oldset); 515 rpc_restore_sigmask(oldset);
469} 516}
470 517
471/* 518static
472 * New rpc_call implementation 519struct rpc_task *rpc_do_run_task(struct rpc_clnt *clnt,
520 struct rpc_message *msg,
521 int flags,
522 const struct rpc_call_ops *ops,
523 void *data)
524{
525 struct rpc_task *task, *ret;
526 sigset_t oldset;
527
528 task = rpc_new_task(clnt, flags, ops, data);
529 if (task == NULL) {
530 rpc_release_calldata(ops, data);
531 return ERR_PTR(-ENOMEM);
532 }
533
534 /* Mask signals on synchronous RPC calls and RPCSEC_GSS upcalls */
535 rpc_task_sigmask(task, &oldset);
536 if (msg != NULL) {
537 rpc_call_setup(task, msg, 0);
538 if (task->tk_status != 0) {
539 ret = ERR_PTR(task->tk_status);
540 rpc_put_task(task);
541 goto out;
542 }
543 }
544 atomic_inc(&task->tk_count);
545 rpc_execute(task);
546 ret = task;
547out:
548 rpc_restore_sigmask(&oldset);
549 return ret;
550}
551
552/**
553 * rpc_call_sync - Perform a synchronous RPC call
554 * @clnt: pointer to RPC client
555 * @msg: RPC call parameters
556 * @flags: RPC call flags
473 */ 557 */
474int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags) 558int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
475{ 559{
476 struct rpc_task *task; 560 struct rpc_task *task;
477 sigset_t oldset; 561 int status;
478 int status;
479
480 /* If this client is slain all further I/O fails */
481 if (clnt->cl_dead)
482 return -EIO;
483 562
484 BUG_ON(flags & RPC_TASK_ASYNC); 563 BUG_ON(flags & RPC_TASK_ASYNC);
485 564
486 task = rpc_new_task(clnt, flags, &rpc_default_ops, NULL); 565 task = rpc_do_run_task(clnt, msg, flags, &rpc_default_ops, NULL);
487 if (task == NULL) 566 if (IS_ERR(task))
488 return -ENOMEM; 567 return PTR_ERR(task);
489
490 /* Mask signals on RPC calls _and_ GSS_AUTH upcalls */
491 rpc_task_sigmask(task, &oldset);
492
493 /* Set up the call info struct and execute the task */
494 rpc_call_setup(task, msg, 0);
495 if (task->tk_status == 0) {
496 atomic_inc(&task->tk_count);
497 rpc_execute(task);
498 }
499 status = task->tk_status; 568 status = task->tk_status;
500 rpc_put_task(task); 569 rpc_put_task(task);
501 rpc_restore_sigmask(&oldset);
502 return status; 570 return status;
503} 571}
504 572
505/* 573/**
506 * New rpc_call implementation 574 * rpc_call_async - Perform an asynchronous RPC call
575 * @clnt: pointer to RPC client
576 * @msg: RPC call parameters
577 * @flags: RPC call flags
578 * @ops: RPC call ops
579 * @data: user call data
507 */ 580 */
508int 581int
509rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags, 582rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
510 const struct rpc_call_ops *tk_ops, void *data) 583 const struct rpc_call_ops *tk_ops, void *data)
511{ 584{
512 struct rpc_task *task; 585 struct rpc_task *task;
513 sigset_t oldset;
514 int status;
515
516 /* If this client is slain all further I/O fails */
517 status = -EIO;
518 if (clnt->cl_dead)
519 goto out_release;
520
521 flags |= RPC_TASK_ASYNC;
522
523 /* Create/initialize a new RPC task */
524 status = -ENOMEM;
525 if (!(task = rpc_new_task(clnt, flags, tk_ops, data)))
526 goto out_release;
527
528 /* Mask signals on GSS_AUTH upcalls */
529 rpc_task_sigmask(task, &oldset);
530 586
531 rpc_call_setup(task, msg, 0); 587 task = rpc_do_run_task(clnt, msg, flags|RPC_TASK_ASYNC, tk_ops, data);
532 588 if (IS_ERR(task))
533 /* Set up the call info struct and execute the task */ 589 return PTR_ERR(task);
534 status = task->tk_status; 590 rpc_put_task(task);
535 if (status == 0) 591 return 0;
536 rpc_execute(task);
537 else
538 rpc_put_task(task);
539
540 rpc_restore_sigmask(&oldset);
541 return status;
542out_release:
543 rpc_release_calldata(tk_ops, data);
544 return status;
545} 592}
546 593
594/**
595 * rpc_run_task - Allocate a new RPC task, then run rpc_execute against it
596 * @clnt: pointer to RPC client
597 * @flags: RPC flags
598 * @ops: RPC call ops
599 * @data: user call data
600 */
601struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags,
602 const struct rpc_call_ops *tk_ops,
603 void *data)
604{
605 return rpc_do_run_task(clnt, NULL, flags, tk_ops, data);
606}
607EXPORT_SYMBOL(rpc_run_task);
547 608
548void 609void
549rpc_call_setup(struct rpc_task *task, struct rpc_message *msg, int flags) 610rpc_call_setup(struct rpc_task *task, struct rpc_message *msg, int flags)
@@ -745,7 +806,7 @@ call_reserveresult(struct rpc_task *task)
745static void 806static void
746call_allocate(struct rpc_task *task) 807call_allocate(struct rpc_task *task)
747{ 808{
748 unsigned int slack = task->tk_auth->au_cslack; 809 unsigned int slack = task->tk_msg.rpc_cred->cr_auth->au_cslack;
749 struct rpc_rqst *req = task->tk_rqstp; 810 struct rpc_rqst *req = task->tk_rqstp;
750 struct rpc_xprt *xprt = task->tk_xprt; 811 struct rpc_xprt *xprt = task->tk_xprt;
751 struct rpc_procinfo *proc = task->tk_msg.rpc_proc; 812 struct rpc_procinfo *proc = task->tk_msg.rpc_proc;
@@ -843,10 +904,8 @@ call_encode(struct rpc_task *task)
843 if (encode == NULL) 904 if (encode == NULL)
844 return; 905 return;
845 906
846 lock_kernel();
847 task->tk_status = rpcauth_wrap_req(task, encode, req, p, 907 task->tk_status = rpcauth_wrap_req(task, encode, req, p,
848 task->tk_msg.rpc_argp); 908 task->tk_msg.rpc_argp);
849 unlock_kernel();
850 if (task->tk_status == -ENOMEM) { 909 if (task->tk_status == -ENOMEM) {
851 /* XXX: Is this sane? */ 910 /* XXX: Is this sane? */
852 rpc_delay(task, 3*HZ); 911 rpc_delay(task, 3*HZ);
@@ -1177,10 +1236,8 @@ call_decode(struct rpc_task *task)
1177 task->tk_action = rpc_exit_task; 1236 task->tk_action = rpc_exit_task;
1178 1237
1179 if (decode) { 1238 if (decode) {
1180 lock_kernel();
1181 task->tk_status = rpcauth_unwrap_resp(task, decode, req, p, 1239 task->tk_status = rpcauth_unwrap_resp(task, decode, req, p,
1182 task->tk_msg.rpc_resp); 1240 task->tk_msg.rpc_resp);
1183 unlock_kernel();
1184 } 1241 }
1185 dprintk("RPC: %5u call_decode result %d\n", task->tk_pid, 1242 dprintk("RPC: %5u call_decode result %d\n", task->tk_pid,
1186 task->tk_status); 1243 task->tk_status);
@@ -1273,9 +1330,9 @@ call_verify(struct rpc_task *task)
1273 * - if it isn't pointer subtraction in the NFS client may give 1330 * - if it isn't pointer subtraction in the NFS client may give
1274 * undefined results 1331 * undefined results
1275 */ 1332 */
1276 printk(KERN_WARNING 1333 dprintk("RPC: %5u %s: XDR representation not a multiple of"
1277 "call_verify: XDR representation not a multiple of" 1334 " 4 bytes: 0x%x\n", task->tk_pid, __FUNCTION__,
1278 " 4 bytes: 0x%x\n", task->tk_rqstp->rq_rcv_buf.len); 1335 task->tk_rqstp->rq_rcv_buf.len);
1279 goto out_eio; 1336 goto out_eio;
1280 } 1337 }
1281 if ((len -= 3) < 0) 1338 if ((len -= 3) < 0)
@@ -1283,7 +1340,8 @@ call_verify(struct rpc_task *task)
1283 p += 1; /* skip XID */ 1340 p += 1; /* skip XID */
1284 1341
1285 if ((n = ntohl(*p++)) != RPC_REPLY) { 1342 if ((n = ntohl(*p++)) != RPC_REPLY) {
1286 printk(KERN_WARNING "call_verify: not an RPC reply: %x\n", n); 1343 dprintk("RPC: %5u %s: not an RPC reply: %x\n",
1344 task->tk_pid, __FUNCTION__, n);
1287 goto out_garbage; 1345 goto out_garbage;
1288 } 1346 }
1289 if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) { 1347 if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) {
@@ -1334,7 +1392,8 @@ call_verify(struct rpc_task *task)
1334 "authentication.\n", task->tk_client->cl_server); 1392 "authentication.\n", task->tk_client->cl_server);
1335 break; 1393 break;
1336 default: 1394 default:
1337 printk(KERN_WARNING "call_verify: unknown auth error: %x\n", n); 1395 dprintk("RPC: %5u %s: unknown auth error: %x\n",
1396 task->tk_pid, __FUNCTION__, n);
1338 error = -EIO; 1397 error = -EIO;
1339 } 1398 }
1340 dprintk("RPC: %5u %s: call rejected %d\n", 1399 dprintk("RPC: %5u %s: call rejected %d\n",
@@ -1342,7 +1401,8 @@ call_verify(struct rpc_task *task)
1342 goto out_err; 1401 goto out_err;
1343 } 1402 }
1344 if (!(p = rpcauth_checkverf(task, p))) { 1403 if (!(p = rpcauth_checkverf(task, p))) {
1345 printk(KERN_WARNING "call_verify: auth check failed\n"); 1404 dprintk("RPC: %5u %s: auth check failed\n",
1405 task->tk_pid, __FUNCTION__);
1346 goto out_garbage; /* bad verifier, retry */ 1406 goto out_garbage; /* bad verifier, retry */
1347 } 1407 }
1348 len = p - (__be32 *)iov->iov_base - 1; 1408 len = p - (__be32 *)iov->iov_base - 1;
@@ -1381,7 +1441,8 @@ call_verify(struct rpc_task *task)
1381 task->tk_pid, __FUNCTION__); 1441 task->tk_pid, __FUNCTION__);
1382 break; /* retry */ 1442 break; /* retry */
1383 default: 1443 default:
1384 printk(KERN_WARNING "call_verify: server accept status: %x\n", n); 1444 dprintk("RPC: %5u %s: server accept status: %x\n",
1445 task->tk_pid, __FUNCTION__, n);
1385 /* Also retry */ 1446 /* Also retry */
1386 } 1447 }
1387 1448
@@ -1395,14 +1456,16 @@ out_garbage:
1395out_retry: 1456out_retry:
1396 return ERR_PTR(-EAGAIN); 1457 return ERR_PTR(-EAGAIN);
1397 } 1458 }
1398 printk(KERN_WARNING "RPC %s: retry failed, exit EIO\n", __FUNCTION__);
1399out_eio: 1459out_eio:
1400 error = -EIO; 1460 error = -EIO;
1401out_err: 1461out_err:
1402 rpc_exit(task, error); 1462 rpc_exit(task, error);
1463 dprintk("RPC: %5u %s: call failed with error %d\n", task->tk_pid,
1464 __FUNCTION__, error);
1403 return ERR_PTR(error); 1465 return ERR_PTR(error);
1404out_overflow: 1466out_overflow:
1405 printk(KERN_WARNING "RPC %s: server reply was truncated.\n", __FUNCTION__); 1467 dprintk("RPC: %5u %s: server reply was truncated.\n", task->tk_pid,
1468 __FUNCTION__);
1406 goto out_garbage; 1469 goto out_garbage;
1407} 1470}
1408 1471
@@ -1421,7 +1484,7 @@ static struct rpc_procinfo rpcproc_null = {
1421 .p_decode = rpcproc_decode_null, 1484 .p_decode = rpcproc_decode_null,
1422}; 1485};
1423 1486
1424int rpc_ping(struct rpc_clnt *clnt, int flags) 1487static int rpc_ping(struct rpc_clnt *clnt, int flags)
1425{ 1488{
1426 struct rpc_message msg = { 1489 struct rpc_message msg = {
1427 .rpc_proc = &rpcproc_null, 1490 .rpc_proc = &rpcproc_null,
@@ -1432,3 +1495,51 @@ int rpc_ping(struct rpc_clnt *clnt, int flags)
1432 put_rpccred(msg.rpc_cred); 1495 put_rpccred(msg.rpc_cred);
1433 return err; 1496 return err;
1434} 1497}
1498
1499struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, int flags)
1500{
1501 struct rpc_message msg = {
1502 .rpc_proc = &rpcproc_null,
1503 .rpc_cred = cred,
1504 };
1505 return rpc_do_run_task(clnt, &msg, flags, &rpc_default_ops, NULL);
1506}
1507EXPORT_SYMBOL(rpc_call_null);
1508
1509#ifdef RPC_DEBUG
1510void rpc_show_tasks(void)
1511{
1512 struct rpc_clnt *clnt;
1513 struct rpc_task *t;
1514
1515 spin_lock(&rpc_client_lock);
1516 if (list_empty(&all_clients))
1517 goto out;
1518 printk("-pid- proc flgs status -client- -prog- --rqstp- -timeout "
1519 "-rpcwait -action- ---ops--\n");
1520 list_for_each_entry(clnt, &all_clients, cl_clients) {
1521 if (list_empty(&clnt->cl_tasks))
1522 continue;
1523 spin_lock(&clnt->cl_lock);
1524 list_for_each_entry(t, &clnt->cl_tasks, tk_task) {
1525 const char *rpc_waitq = "none";
1526
1527 if (RPC_IS_QUEUED(t))
1528 rpc_waitq = rpc_qname(t->u.tk_wait.rpc_waitq);
1529
1530 printk("%5u %04d %04x %6d %8p %6d %8p %8ld %8s %8p %8p\n",
1531 t->tk_pid,
1532 (t->tk_msg.rpc_proc ? t->tk_msg.rpc_proc->p_proc : -1),
1533 t->tk_flags, t->tk_status,
1534 t->tk_client,
1535 (t->tk_client ? t->tk_client->cl_prog : 0),
1536 t->tk_rqstp, t->tk_timeout,
1537 rpc_waitq,
1538 t->tk_action, t->tk_ops);
1539 }
1540 spin_unlock(&clnt->cl_lock);
1541 }
1542out:
1543 spin_unlock(&rpc_client_lock);
1544}
1545#endif
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 5887457dc936..e787b6a43eee 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -344,7 +344,7 @@ rpc_info_open(struct inode *inode, struct file *file)
344 mutex_lock(&inode->i_mutex); 344 mutex_lock(&inode->i_mutex);
345 clnt = RPC_I(inode)->private; 345 clnt = RPC_I(inode)->private;
346 if (clnt) { 346 if (clnt) {
347 atomic_inc(&clnt->cl_users); 347 kref_get(&clnt->cl_kref);
348 m->private = clnt; 348 m->private = clnt;
349 } else { 349 } else {
350 single_release(inode, file); 350 single_release(inode, file);
@@ -448,6 +448,15 @@ void rpc_put_mount(void)
448 simple_release_fs(&rpc_mount, &rpc_mount_count); 448 simple_release_fs(&rpc_mount, &rpc_mount_count);
449} 449}
450 450
451static int rpc_delete_dentry(struct dentry *dentry)
452{
453 return 1;
454}
455
456static struct dentry_operations rpc_dentry_operations = {
457 .d_delete = rpc_delete_dentry,
458};
459
451static int 460static int
452rpc_lookup_parent(char *path, struct nameidata *nd) 461rpc_lookup_parent(char *path, struct nameidata *nd)
453{ 462{
@@ -506,7 +515,7 @@ rpc_get_inode(struct super_block *sb, int mode)
506 * FIXME: This probably has races. 515 * FIXME: This probably has races.
507 */ 516 */
508static void 517static void
509rpc_depopulate(struct dentry *parent) 518rpc_depopulate(struct dentry *parent, int start, int eof)
510{ 519{
511 struct inode *dir = parent->d_inode; 520 struct inode *dir = parent->d_inode;
512 struct list_head *pos, *next; 521 struct list_head *pos, *next;
@@ -518,6 +527,10 @@ repeat:
518 spin_lock(&dcache_lock); 527 spin_lock(&dcache_lock);
519 list_for_each_safe(pos, next, &parent->d_subdirs) { 528 list_for_each_safe(pos, next, &parent->d_subdirs) {
520 dentry = list_entry(pos, struct dentry, d_u.d_child); 529 dentry = list_entry(pos, struct dentry, d_u.d_child);
530 if (!dentry->d_inode ||
531 dentry->d_inode->i_ino < start ||
532 dentry->d_inode->i_ino >= eof)
533 continue;
521 spin_lock(&dentry->d_lock); 534 spin_lock(&dentry->d_lock);
522 if (!d_unhashed(dentry)) { 535 if (!d_unhashed(dentry)) {
523 dget_locked(dentry); 536 dget_locked(dentry);
@@ -533,11 +546,11 @@ repeat:
533 if (n) { 546 if (n) {
534 do { 547 do {
535 dentry = dvec[--n]; 548 dentry = dvec[--n];
536 if (dentry->d_inode) { 549 if (S_ISREG(dentry->d_inode->i_mode))
537 rpc_close_pipes(dentry->d_inode);
538 simple_unlink(dir, dentry); 550 simple_unlink(dir, dentry);
539 } 551 else if (S_ISDIR(dentry->d_inode->i_mode))
540 inode_dir_notify(dir, DN_DELETE); 552 simple_rmdir(dir, dentry);
553 d_delete(dentry);
541 dput(dentry); 554 dput(dentry);
542 } while (n); 555 } while (n);
543 goto repeat; 556 goto repeat;
@@ -560,6 +573,7 @@ rpc_populate(struct dentry *parent,
560 dentry = d_alloc_name(parent, files[i].name); 573 dentry = d_alloc_name(parent, files[i].name);
561 if (!dentry) 574 if (!dentry)
562 goto out_bad; 575 goto out_bad;
576 dentry->d_op = &rpc_dentry_operations;
563 mode = files[i].mode; 577 mode = files[i].mode;
564 inode = rpc_get_inode(dir->i_sb, mode); 578 inode = rpc_get_inode(dir->i_sb, mode);
565 if (!inode) { 579 if (!inode) {
@@ -607,21 +621,14 @@ static int
607__rpc_rmdir(struct inode *dir, struct dentry *dentry) 621__rpc_rmdir(struct inode *dir, struct dentry *dentry)
608{ 622{
609 int error; 623 int error;
610 624 error = simple_rmdir(dir, dentry);
611 shrink_dcache_parent(dentry); 625 if (!error)
612 if (d_unhashed(dentry)) 626 d_delete(dentry);
613 return 0; 627 return error;
614 if ((error = simple_rmdir(dir, dentry)) != 0)
615 return error;
616 if (!error) {
617 inode_dir_notify(dir, DN_DELETE);
618 d_drop(dentry);
619 }
620 return 0;
621} 628}
622 629
623static struct dentry * 630static struct dentry *
624rpc_lookup_create(struct dentry *parent, const char *name, int len) 631rpc_lookup_create(struct dentry *parent, const char *name, int len, int exclusive)
625{ 632{
626 struct inode *dir = parent->d_inode; 633 struct inode *dir = parent->d_inode;
627 struct dentry *dentry; 634 struct dentry *dentry;
@@ -630,7 +637,9 @@ rpc_lookup_create(struct dentry *parent, const char *name, int len)
630 dentry = lookup_one_len(name, parent, len); 637 dentry = lookup_one_len(name, parent, len);
631 if (IS_ERR(dentry)) 638 if (IS_ERR(dentry))
632 goto out_err; 639 goto out_err;
633 if (dentry->d_inode) { 640 if (!dentry->d_inode)
641 dentry->d_op = &rpc_dentry_operations;
642 else if (exclusive) {
634 dput(dentry); 643 dput(dentry);
635 dentry = ERR_PTR(-EEXIST); 644 dentry = ERR_PTR(-EEXIST);
636 goto out_err; 645 goto out_err;
@@ -649,7 +658,7 @@ rpc_lookup_negative(char *path, struct nameidata *nd)
649 658
650 if ((error = rpc_lookup_parent(path, nd)) != 0) 659 if ((error = rpc_lookup_parent(path, nd)) != 0)
651 return ERR_PTR(error); 660 return ERR_PTR(error);
652 dentry = rpc_lookup_create(nd->dentry, nd->last.name, nd->last.len); 661 dentry = rpc_lookup_create(nd->dentry, nd->last.name, nd->last.len, 1);
653 if (IS_ERR(dentry)) 662 if (IS_ERR(dentry))
654 rpc_release_path(nd); 663 rpc_release_path(nd);
655 return dentry; 664 return dentry;
@@ -681,7 +690,7 @@ out:
681 rpc_release_path(&nd); 690 rpc_release_path(&nd);
682 return dentry; 691 return dentry;
683err_depopulate: 692err_depopulate:
684 rpc_depopulate(dentry); 693 rpc_depopulate(dentry, RPCAUTH_info, RPCAUTH_EOF);
685 __rpc_rmdir(dir, dentry); 694 __rpc_rmdir(dir, dentry);
686err_dput: 695err_dput:
687 dput(dentry); 696 dput(dentry);
@@ -701,7 +710,7 @@ rpc_rmdir(struct dentry *dentry)
701 parent = dget_parent(dentry); 710 parent = dget_parent(dentry);
702 dir = parent->d_inode; 711 dir = parent->d_inode;
703 mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); 712 mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
704 rpc_depopulate(dentry); 713 rpc_depopulate(dentry, RPCAUTH_info, RPCAUTH_EOF);
705 error = __rpc_rmdir(dir, dentry); 714 error = __rpc_rmdir(dir, dentry);
706 dput(dentry); 715 dput(dentry);
707 mutex_unlock(&dir->i_mutex); 716 mutex_unlock(&dir->i_mutex);
@@ -716,10 +725,21 @@ rpc_mkpipe(struct dentry *parent, const char *name, void *private, struct rpc_pi
716 struct inode *dir, *inode; 725 struct inode *dir, *inode;
717 struct rpc_inode *rpci; 726 struct rpc_inode *rpci;
718 727
719 dentry = rpc_lookup_create(parent, name, strlen(name)); 728 dentry = rpc_lookup_create(parent, name, strlen(name), 0);
720 if (IS_ERR(dentry)) 729 if (IS_ERR(dentry))
721 return dentry; 730 return dentry;
722 dir = parent->d_inode; 731 dir = parent->d_inode;
732 if (dentry->d_inode) {
733 rpci = RPC_I(dentry->d_inode);
734 if (rpci->private != private ||
735 rpci->ops != ops ||
736 rpci->flags != flags) {
737 dput (dentry);
738 dentry = ERR_PTR(-EBUSY);
739 }
740 rpci->nkern_readwriters++;
741 goto out;
742 }
723 inode = rpc_get_inode(dir->i_sb, S_IFIFO | S_IRUSR | S_IWUSR); 743 inode = rpc_get_inode(dir->i_sb, S_IFIFO | S_IRUSR | S_IWUSR);
724 if (!inode) 744 if (!inode)
725 goto err_dput; 745 goto err_dput;
@@ -730,6 +750,7 @@ rpc_mkpipe(struct dentry *parent, const char *name, void *private, struct rpc_pi
730 rpci->private = private; 750 rpci->private = private;
731 rpci->flags = flags; 751 rpci->flags = flags;
732 rpci->ops = ops; 752 rpci->ops = ops;
753 rpci->nkern_readwriters = 1;
733 inode_dir_notify(dir, DN_CREATE); 754 inode_dir_notify(dir, DN_CREATE);
734 dget(dentry); 755 dget(dentry);
735out: 756out:
@@ -754,13 +775,11 @@ rpc_unlink(struct dentry *dentry)
754 parent = dget_parent(dentry); 775 parent = dget_parent(dentry);
755 dir = parent->d_inode; 776 dir = parent->d_inode;
756 mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); 777 mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
757 if (!d_unhashed(dentry)) { 778 if (--RPC_I(dentry->d_inode)->nkern_readwriters == 0) {
758 d_drop(dentry); 779 rpc_close_pipes(dentry->d_inode);
759 if (dentry->d_inode) { 780 error = simple_unlink(dir, dentry);
760 rpc_close_pipes(dentry->d_inode); 781 if (!error)
761 error = simple_unlink(dir, dentry); 782 d_delete(dentry);
762 }
763 inode_dir_notify(dir, DN_DELETE);
764 } 783 }
765 dput(dentry); 784 dput(dentry);
766 mutex_unlock(&dir->i_mutex); 785 mutex_unlock(&dir->i_mutex);
@@ -833,6 +852,7 @@ init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
833 rpci->nreaders = 0; 852 rpci->nreaders = 0;
834 rpci->nwriters = 0; 853 rpci->nwriters = 0;
835 INIT_LIST_HEAD(&rpci->in_upcall); 854 INIT_LIST_HEAD(&rpci->in_upcall);
855 INIT_LIST_HEAD(&rpci->in_downcall);
836 INIT_LIST_HEAD(&rpci->pipe); 856 INIT_LIST_HEAD(&rpci->pipe);
837 rpci->pipelen = 0; 857 rpci->pipelen = 0;
838 init_waitqueue_head(&rpci->waitq); 858 init_waitqueue_head(&rpci->waitq);
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 6c7aa8a1f0c6..d1740dbab991 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -12,6 +12,8 @@
12 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> 12 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
13 */ 13 */
14 14
15#include <linux/module.h>
16
15#include <linux/types.h> 17#include <linux/types.h>
16#include <linux/socket.h> 18#include <linux/socket.h>
17#include <linux/kernel.h> 19#include <linux/kernel.h>
@@ -184,8 +186,8 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
184 .program = &rpcb_program, 186 .program = &rpcb_program,
185 .version = version, 187 .version = version,
186 .authflavor = RPC_AUTH_UNIX, 188 .authflavor = RPC_AUTH_UNIX,
187 .flags = (RPC_CLNT_CREATE_ONESHOT | 189 .flags = (RPC_CLNT_CREATE_NOPING |
188 RPC_CLNT_CREATE_NOPING), 190 RPC_CLNT_CREATE_INTR),
189 }; 191 };
190 192
191 ((struct sockaddr_in *)srvaddr)->sin_port = htons(RPCBIND_PORT); 193 ((struct sockaddr_in *)srvaddr)->sin_port = htons(RPCBIND_PORT);
@@ -238,6 +240,7 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
238 240
239 error = rpc_call_sync(rpcb_clnt, &msg, 0); 241 error = rpc_call_sync(rpcb_clnt, &msg, 0);
240 242
243 rpc_shutdown_client(rpcb_clnt);
241 if (error < 0) 244 if (error < 0)
242 printk(KERN_WARNING "RPC: failed to contact local rpcbind " 245 printk(KERN_WARNING "RPC: failed to contact local rpcbind "
243 "server (errno %d).\n", -error); 246 "server (errno %d).\n", -error);
@@ -246,21 +249,20 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
246 return error; 249 return error;
247} 250}
248 251
249#ifdef CONFIG_ROOT_NFS
250/** 252/**
251 * rpcb_getport_external - obtain the port for an RPC service on a given host 253 * rpcb_getport_sync - obtain the port for an RPC service on a given host
252 * @sin: address of remote peer 254 * @sin: address of remote peer
253 * @prog: RPC program number to bind 255 * @prog: RPC program number to bind
254 * @vers: RPC version number to bind 256 * @vers: RPC version number to bind
255 * @prot: transport protocol to use to make this request 257 * @prot: transport protocol to use to make this request
256 * 258 *
257 * Called from outside the RPC client in a synchronous task context. 259 * Called from outside the RPC client in a synchronous task context.
260 * Uses default timeout parameters specified by underlying transport.
258 * 261 *
259 * For now, this supports only version 2 queries, but is used only by 262 * XXX: Needs to support IPv6, and rpcbind versions 3 and 4
260 * mount_clnt for NFS_ROOT.
261 */ 263 */
262int rpcb_getport_external(struct sockaddr_in *sin, __u32 prog, 264int rpcb_getport_sync(struct sockaddr_in *sin, __u32 prog,
263 __u32 vers, int prot) 265 __u32 vers, int prot)
264{ 266{
265 struct rpcbind_args map = { 267 struct rpcbind_args map = {
266 .r_prog = prog, 268 .r_prog = prog,
@@ -277,15 +279,16 @@ int rpcb_getport_external(struct sockaddr_in *sin, __u32 prog,
277 char hostname[40]; 279 char hostname[40];
278 int status; 280 int status;
279 281
280 dprintk("RPC: rpcb_getport_external(%u.%u.%u.%u, %u, %u, %d)\n", 282 dprintk("RPC: %s(" NIPQUAD_FMT ", %u, %u, %d)\n",
281 NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot); 283 __FUNCTION__, NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot);
282 284
283 sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(sin->sin_addr.s_addr)); 285 sprintf(hostname, NIPQUAD_FMT, NIPQUAD(sin->sin_addr.s_addr));
284 rpcb_clnt = rpcb_create(hostname, (struct sockaddr *)sin, prot, 2, 0); 286 rpcb_clnt = rpcb_create(hostname, (struct sockaddr *)sin, prot, 2, 0);
285 if (IS_ERR(rpcb_clnt)) 287 if (IS_ERR(rpcb_clnt))
286 return PTR_ERR(rpcb_clnt); 288 return PTR_ERR(rpcb_clnt);
287 289
288 status = rpc_call_sync(rpcb_clnt, &msg, 0); 290 status = rpc_call_sync(rpcb_clnt, &msg, 0);
291 rpc_shutdown_client(rpcb_clnt);
289 292
290 if (status >= 0) { 293 if (status >= 0) {
291 if (map.r_port != 0) 294 if (map.r_port != 0)
@@ -294,16 +297,16 @@ int rpcb_getport_external(struct sockaddr_in *sin, __u32 prog,
294 } 297 }
295 return status; 298 return status;
296} 299}
297#endif 300EXPORT_SYMBOL_GPL(rpcb_getport_sync);
298 301
299/** 302/**
300 * rpcb_getport - obtain the port for a given RPC service on a given host 303 * rpcb_getport_async - obtain the port for a given RPC service on a given host
301 * @task: task that is waiting for portmapper request 304 * @task: task that is waiting for portmapper request
302 * 305 *
303 * This one can be called for an ongoing RPC request, and can be used in 306 * This one can be called for an ongoing RPC request, and can be used in
304 * an async (rpciod) context. 307 * an async (rpciod) context.
305 */ 308 */
306void rpcb_getport(struct rpc_task *task) 309void rpcb_getport_async(struct rpc_task *task)
307{ 310{
308 struct rpc_clnt *clnt = task->tk_client; 311 struct rpc_clnt *clnt = task->tk_client;
309 int bind_version; 312 int bind_version;
@@ -314,17 +317,17 @@ void rpcb_getport(struct rpc_task *task)
314 struct sockaddr addr; 317 struct sockaddr addr;
315 int status; 318 int status;
316 319
317 dprintk("RPC: %5u rpcb_getport(%s, %u, %u, %d)\n", 320 dprintk("RPC: %5u %s(%s, %u, %u, %d)\n",
318 task->tk_pid, clnt->cl_server, 321 task->tk_pid, __FUNCTION__,
319 clnt->cl_prog, clnt->cl_vers, xprt->prot); 322 clnt->cl_server, clnt->cl_prog, clnt->cl_vers, xprt->prot);
320 323
321 /* Autobind on cloned rpc clients is discouraged */ 324 /* Autobind on cloned rpc clients is discouraged */
322 BUG_ON(clnt->cl_parent != clnt); 325 BUG_ON(clnt->cl_parent != clnt);
323 326
324 if (xprt_test_and_set_binding(xprt)) { 327 if (xprt_test_and_set_binding(xprt)) {
325 status = -EACCES; /* tell caller to check again */ 328 status = -EACCES; /* tell caller to check again */
326 dprintk("RPC: %5u rpcb_getport waiting for another binder\n", 329 dprintk("RPC: %5u %s: waiting for another binder\n",
327 task->tk_pid); 330 task->tk_pid, __FUNCTION__);
328 goto bailout_nowake; 331 goto bailout_nowake;
329 } 332 }
330 333
@@ -335,27 +338,28 @@ void rpcb_getport(struct rpc_task *task)
335 /* Someone else may have bound if we slept */ 338 /* Someone else may have bound if we slept */
336 if (xprt_bound(xprt)) { 339 if (xprt_bound(xprt)) {
337 status = 0; 340 status = 0;
338 dprintk("RPC: %5u rpcb_getport already bound\n", task->tk_pid); 341 dprintk("RPC: %5u %s: already bound\n",
342 task->tk_pid, __FUNCTION__);
339 goto bailout_nofree; 343 goto bailout_nofree;
340 } 344 }
341 345
342 if (rpcb_next_version[xprt->bind_index].rpc_proc == NULL) { 346 if (rpcb_next_version[xprt->bind_index].rpc_proc == NULL) {
343 xprt->bind_index = 0; 347 xprt->bind_index = 0;
344 status = -EACCES; /* tell caller to try again later */ 348 status = -EACCES; /* tell caller to try again later */
345 dprintk("RPC: %5u rpcb_getport no more getport versions " 349 dprintk("RPC: %5u %s: no more getport versions available\n",
346 "available\n", task->tk_pid); 350 task->tk_pid, __FUNCTION__);
347 goto bailout_nofree; 351 goto bailout_nofree;
348 } 352 }
349 bind_version = rpcb_next_version[xprt->bind_index].rpc_vers; 353 bind_version = rpcb_next_version[xprt->bind_index].rpc_vers;
350 354
351 dprintk("RPC: %5u rpcb_getport trying rpcbind version %u\n", 355 dprintk("RPC: %5u %s: trying rpcbind version %u\n",
352 task->tk_pid, bind_version); 356 task->tk_pid, __FUNCTION__, bind_version);
353 357
354 map = kzalloc(sizeof(struct rpcbind_args), GFP_ATOMIC); 358 map = kzalloc(sizeof(struct rpcbind_args), GFP_ATOMIC);
355 if (!map) { 359 if (!map) {
356 status = -ENOMEM; 360 status = -ENOMEM;
357 dprintk("RPC: %5u rpcb_getport no memory available\n", 361 dprintk("RPC: %5u %s: no memory available\n",
358 task->tk_pid); 362 task->tk_pid, __FUNCTION__);
359 goto bailout_nofree; 363 goto bailout_nofree;
360 } 364 }
361 map->r_prog = clnt->cl_prog; 365 map->r_prog = clnt->cl_prog;
@@ -373,16 +377,17 @@ void rpcb_getport(struct rpc_task *task)
373 rpcb_clnt = rpcb_create(clnt->cl_server, &addr, xprt->prot, bind_version, 0); 377 rpcb_clnt = rpcb_create(clnt->cl_server, &addr, xprt->prot, bind_version, 0);
374 if (IS_ERR(rpcb_clnt)) { 378 if (IS_ERR(rpcb_clnt)) {
375 status = PTR_ERR(rpcb_clnt); 379 status = PTR_ERR(rpcb_clnt);
376 dprintk("RPC: %5u rpcb_getport rpcb_create failed, error %ld\n", 380 dprintk("RPC: %5u %s: rpcb_create failed, error %ld\n",
377 task->tk_pid, PTR_ERR(rpcb_clnt)); 381 task->tk_pid, __FUNCTION__, PTR_ERR(rpcb_clnt));
378 goto bailout; 382 goto bailout;
379 } 383 }
380 384
381 child = rpc_run_task(rpcb_clnt, RPC_TASK_ASYNC, &rpcb_getport_ops, map); 385 child = rpc_run_task(rpcb_clnt, RPC_TASK_ASYNC, &rpcb_getport_ops, map);
386 rpc_release_client(rpcb_clnt);
382 if (IS_ERR(child)) { 387 if (IS_ERR(child)) {
383 status = -EIO; 388 status = -EIO;
384 dprintk("RPC: %5u rpcb_getport rpc_run_task failed\n", 389 dprintk("RPC: %5u %s: rpc_run_task failed\n",
385 task->tk_pid); 390 task->tk_pid, __FUNCTION__);
386 goto bailout_nofree; 391 goto bailout_nofree;
387 } 392 }
388 rpc_put_task(child); 393 rpc_put_task(child);
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 944d75396fb3..2ac43c41c3a9 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -25,7 +25,6 @@
25#ifdef RPC_DEBUG 25#ifdef RPC_DEBUG
26#define RPCDBG_FACILITY RPCDBG_SCHED 26#define RPCDBG_FACILITY RPCDBG_SCHED
27#define RPC_TASK_MAGIC_ID 0xf00baa 27#define RPC_TASK_MAGIC_ID 0xf00baa
28static int rpc_task_id;
29#endif 28#endif
30 29
31/* 30/*
@@ -40,7 +39,6 @@ static mempool_t *rpc_task_mempool __read_mostly;
40static mempool_t *rpc_buffer_mempool __read_mostly; 39static mempool_t *rpc_buffer_mempool __read_mostly;
41 40
42static void __rpc_default_timer(struct rpc_task *task); 41static void __rpc_default_timer(struct rpc_task *task);
43static void rpciod_killall(void);
44static void rpc_async_schedule(struct work_struct *); 42static void rpc_async_schedule(struct work_struct *);
45static void rpc_release_task(struct rpc_task *task); 43static void rpc_release_task(struct rpc_task *task);
46 44
@@ -50,23 +48,13 @@ static void rpc_release_task(struct rpc_task *task);
50static RPC_WAITQ(delay_queue, "delayq"); 48static RPC_WAITQ(delay_queue, "delayq");
51 49
52/* 50/*
53 * All RPC tasks are linked into this list
54 */
55static LIST_HEAD(all_tasks);
56
57/*
58 * rpciod-related stuff 51 * rpciod-related stuff
59 */ 52 */
60static DEFINE_MUTEX(rpciod_mutex); 53static DEFINE_MUTEX(rpciod_mutex);
61static unsigned int rpciod_users; 54static atomic_t rpciod_users = ATOMIC_INIT(0);
62struct workqueue_struct *rpciod_workqueue; 55struct workqueue_struct *rpciod_workqueue;
63 56
64/* 57/*
65 * Spinlock for other critical sections of code.
66 */
67static DEFINE_SPINLOCK(rpc_sched_lock);
68
69/*
70 * Disable the timer for a given RPC task. Should be called with 58 * Disable the timer for a given RPC task. Should be called with
71 * queue->lock and bh_disabled in order to avoid races within 59 * queue->lock and bh_disabled in order to avoid races within
72 * rpc_run_timer(). 60 * rpc_run_timer().
@@ -267,18 +255,33 @@ static int rpc_wait_bit_interruptible(void *word)
267 return 0; 255 return 0;
268} 256}
269 257
258#ifdef RPC_DEBUG
259static void rpc_task_set_debuginfo(struct rpc_task *task)
260{
261 static atomic_t rpc_pid;
262
263 task->tk_magic = RPC_TASK_MAGIC_ID;
264 task->tk_pid = atomic_inc_return(&rpc_pid);
265}
266#else
267static inline void rpc_task_set_debuginfo(struct rpc_task *task)
268{
269}
270#endif
271
270static void rpc_set_active(struct rpc_task *task) 272static void rpc_set_active(struct rpc_task *task)
271{ 273{
274 struct rpc_clnt *clnt;
272 if (test_and_set_bit(RPC_TASK_ACTIVE, &task->tk_runstate) != 0) 275 if (test_and_set_bit(RPC_TASK_ACTIVE, &task->tk_runstate) != 0)
273 return; 276 return;
274 spin_lock(&rpc_sched_lock); 277 rpc_task_set_debuginfo(task);
275#ifdef RPC_DEBUG
276 task->tk_magic = RPC_TASK_MAGIC_ID;
277 task->tk_pid = rpc_task_id++;
278#endif
279 /* Add to global list of all tasks */ 278 /* Add to global list of all tasks */
280 list_add_tail(&task->tk_task, &all_tasks); 279 clnt = task->tk_client;
281 spin_unlock(&rpc_sched_lock); 280 if (clnt != NULL) {
281 spin_lock(&clnt->cl_lock);
282 list_add_tail(&task->tk_task, &clnt->cl_tasks);
283 spin_unlock(&clnt->cl_lock);
284 }
282} 285}
283 286
284/* 287/*
@@ -818,6 +821,7 @@ void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, int flags, cons
818 if (tk_ops->rpc_call_prepare != NULL) 821 if (tk_ops->rpc_call_prepare != NULL)
819 task->tk_action = rpc_prepare_task; 822 task->tk_action = rpc_prepare_task;
820 task->tk_calldata = calldata; 823 task->tk_calldata = calldata;
824 INIT_LIST_HEAD(&task->tk_task);
821 825
822 /* Initialize retry counters */ 826 /* Initialize retry counters */
823 task->tk_garb_retry = 2; 827 task->tk_garb_retry = 2;
@@ -830,7 +834,7 @@ void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, int flags, cons
830 task->tk_workqueue = rpciod_workqueue; 834 task->tk_workqueue = rpciod_workqueue;
831 835
832 if (clnt) { 836 if (clnt) {
833 atomic_inc(&clnt->cl_users); 837 kref_get(&clnt->cl_kref);
834 if (clnt->cl_softrtry) 838 if (clnt->cl_softrtry)
835 task->tk_flags |= RPC_TASK_SOFT; 839 task->tk_flags |= RPC_TASK_SOFT;
836 if (!clnt->cl_intr) 840 if (!clnt->cl_intr)
@@ -860,9 +864,7 @@ static void rpc_free_task(struct rcu_head *rcu)
860} 864}
861 865
862/* 866/*
863 * Create a new task for the specified client. We have to 867 * Create a new task for the specified client.
864 * clean up after an allocation failure, as the client may
865 * have specified "oneshot".
866 */ 868 */
867struct rpc_task *rpc_new_task(struct rpc_clnt *clnt, int flags, const struct rpc_call_ops *tk_ops, void *calldata) 869struct rpc_task *rpc_new_task(struct rpc_clnt *clnt, int flags, const struct rpc_call_ops *tk_ops, void *calldata)
868{ 870{
@@ -870,7 +872,7 @@ struct rpc_task *rpc_new_task(struct rpc_clnt *clnt, int flags, const struct rpc
870 872
871 task = rpc_alloc_task(); 873 task = rpc_alloc_task();
872 if (!task) 874 if (!task)
873 goto cleanup; 875 goto out;
874 876
875 rpc_init_task(task, clnt, flags, tk_ops, calldata); 877 rpc_init_task(task, clnt, flags, tk_ops, calldata);
876 878
@@ -878,16 +880,6 @@ struct rpc_task *rpc_new_task(struct rpc_clnt *clnt, int flags, const struct rpc
878 task->tk_flags |= RPC_TASK_DYNAMIC; 880 task->tk_flags |= RPC_TASK_DYNAMIC;
879out: 881out:
880 return task; 882 return task;
881
882cleanup:
883 /* Check whether to release the client */
884 if (clnt) {
885 printk("rpc_new_task: failed, users=%d, oneshot=%d\n",
886 atomic_read(&clnt->cl_users), clnt->cl_oneshot);
887 atomic_inc(&clnt->cl_users); /* pretend we were used ... */
888 rpc_release_client(clnt);
889 }
890 goto out;
891} 883}
892 884
893 885
@@ -920,11 +912,13 @@ static void rpc_release_task(struct rpc_task *task)
920#endif 912#endif
921 dprintk("RPC: %5u release task\n", task->tk_pid); 913 dprintk("RPC: %5u release task\n", task->tk_pid);
922 914
923 /* Remove from global task list */ 915 if (!list_empty(&task->tk_task)) {
924 spin_lock(&rpc_sched_lock); 916 struct rpc_clnt *clnt = task->tk_client;
925 list_del(&task->tk_task); 917 /* Remove from client task list */
926 spin_unlock(&rpc_sched_lock); 918 spin_lock(&clnt->cl_lock);
927 919 list_del(&task->tk_task);
920 spin_unlock(&clnt->cl_lock);
921 }
928 BUG_ON (RPC_IS_QUEUED(task)); 922 BUG_ON (RPC_IS_QUEUED(task));
929 923
930 /* Synchronously delete any running timer */ 924 /* Synchronously delete any running timer */
@@ -939,29 +933,6 @@ static void rpc_release_task(struct rpc_task *task)
939 rpc_put_task(task); 933 rpc_put_task(task);
940} 934}
941 935
942/**
943 * rpc_run_task - Allocate a new RPC task, then run rpc_execute against it
944 * @clnt: pointer to RPC client
945 * @flags: RPC flags
946 * @ops: RPC call ops
947 * @data: user call data
948 */
949struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags,
950 const struct rpc_call_ops *ops,
951 void *data)
952{
953 struct rpc_task *task;
954 task = rpc_new_task(clnt, flags, ops, data);
955 if (task == NULL) {
956 rpc_release_calldata(ops, data);
957 return ERR_PTR(-ENOMEM);
958 }
959 atomic_inc(&task->tk_count);
960 rpc_execute(task);
961 return task;
962}
963EXPORT_SYMBOL(rpc_run_task);
964
965/* 936/*
966 * Kill all tasks for the given client. 937 * Kill all tasks for the given client.
967 * XXX: kill their descendants as well? 938 * XXX: kill their descendants as well?
@@ -969,44 +940,25 @@ EXPORT_SYMBOL(rpc_run_task);
969void rpc_killall_tasks(struct rpc_clnt *clnt) 940void rpc_killall_tasks(struct rpc_clnt *clnt)
970{ 941{
971 struct rpc_task *rovr; 942 struct rpc_task *rovr;
972 struct list_head *le;
973 943
974 dprintk("RPC: killing all tasks for client %p\n", clnt);
975 944
945 if (list_empty(&clnt->cl_tasks))
946 return;
947 dprintk("RPC: killing all tasks for client %p\n", clnt);
976 /* 948 /*
977 * Spin lock all_tasks to prevent changes... 949 * Spin lock all_tasks to prevent changes...
978 */ 950 */
979 spin_lock(&rpc_sched_lock); 951 spin_lock(&clnt->cl_lock);
980 alltask_for_each(rovr, le, &all_tasks) { 952 list_for_each_entry(rovr, &clnt->cl_tasks, tk_task) {
981 if (! RPC_IS_ACTIVATED(rovr)) 953 if (! RPC_IS_ACTIVATED(rovr))
982 continue; 954 continue;
983 if (!clnt || rovr->tk_client == clnt) { 955 if (!(rovr->tk_flags & RPC_TASK_KILLED)) {
984 rovr->tk_flags |= RPC_TASK_KILLED; 956 rovr->tk_flags |= RPC_TASK_KILLED;
985 rpc_exit(rovr, -EIO); 957 rpc_exit(rovr, -EIO);
986 rpc_wake_up_task(rovr); 958 rpc_wake_up_task(rovr);
987 } 959 }
988 } 960 }
989 spin_unlock(&rpc_sched_lock); 961 spin_unlock(&clnt->cl_lock);
990}
991
992static void rpciod_killall(void)
993{
994 unsigned long flags;
995
996 while (!list_empty(&all_tasks)) {
997 clear_thread_flag(TIF_SIGPENDING);
998 rpc_killall_tasks(NULL);
999 flush_workqueue(rpciod_workqueue);
1000 if (!list_empty(&all_tasks)) {
1001 dprintk("RPC: rpciod_killall: waiting for tasks "
1002 "to exit\n");
1003 yield();
1004 }
1005 }
1006
1007 spin_lock_irqsave(&current->sighand->siglock, flags);
1008 recalc_sigpending();
1009 spin_unlock_irqrestore(&current->sighand->siglock, flags);
1010} 962}
1011 963
1012/* 964/*
@@ -1018,28 +970,27 @@ rpciod_up(void)
1018 struct workqueue_struct *wq; 970 struct workqueue_struct *wq;
1019 int error = 0; 971 int error = 0;
1020 972
973 if (atomic_inc_not_zero(&rpciod_users))
974 return 0;
975
1021 mutex_lock(&rpciod_mutex); 976 mutex_lock(&rpciod_mutex);
1022 dprintk("RPC: rpciod_up: users %u\n", rpciod_users); 977
1023 rpciod_users++; 978 /* Guard against races with rpciod_down() */
1024 if (rpciod_workqueue) 979 if (rpciod_workqueue != NULL)
1025 goto out; 980 goto out_ok;
1026 /*
1027 * If there's no pid, we should be the first user.
1028 */
1029 if (rpciod_users > 1)
1030 printk(KERN_WARNING "rpciod_up: no workqueue, %u users??\n", rpciod_users);
1031 /* 981 /*
1032 * Create the rpciod thread and wait for it to start. 982 * Create the rpciod thread and wait for it to start.
1033 */ 983 */
984 dprintk("RPC: creating workqueue rpciod\n");
1034 error = -ENOMEM; 985 error = -ENOMEM;
1035 wq = create_workqueue("rpciod"); 986 wq = create_workqueue("rpciod");
1036 if (wq == NULL) { 987 if (wq == NULL)
1037 printk(KERN_WARNING "rpciod_up: create workqueue failed, error=%d\n", error);
1038 rpciod_users--;
1039 goto out; 988 goto out;
1040 } 989
1041 rpciod_workqueue = wq; 990 rpciod_workqueue = wq;
1042 error = 0; 991 error = 0;
992out_ok:
993 atomic_inc(&rpciod_users);
1043out: 994out:
1044 mutex_unlock(&rpciod_mutex); 995 mutex_unlock(&rpciod_mutex);
1045 return error; 996 return error;
@@ -1048,59 +999,19 @@ out:
1048void 999void
1049rpciod_down(void) 1000rpciod_down(void)
1050{ 1001{
1002 if (!atomic_dec_and_test(&rpciod_users))
1003 return;
1004
1051 mutex_lock(&rpciod_mutex); 1005 mutex_lock(&rpciod_mutex);
1052 dprintk("RPC: rpciod_down sema %u\n", rpciod_users); 1006 dprintk("RPC: destroying workqueue rpciod\n");
1053 if (rpciod_users) {
1054 if (--rpciod_users)
1055 goto out;
1056 } else
1057 printk(KERN_WARNING "rpciod_down: no users??\n");
1058 1007
1059 if (!rpciod_workqueue) { 1008 if (atomic_read(&rpciod_users) == 0 && rpciod_workqueue != NULL) {
1060 dprintk("RPC: rpciod_down: Nothing to do!\n"); 1009 destroy_workqueue(rpciod_workqueue);
1061 goto out; 1010 rpciod_workqueue = NULL;
1062 } 1011 }
1063 rpciod_killall();
1064
1065 destroy_workqueue(rpciod_workqueue);
1066 rpciod_workqueue = NULL;
1067 out:
1068 mutex_unlock(&rpciod_mutex); 1012 mutex_unlock(&rpciod_mutex);
1069} 1013}
1070 1014
1071#ifdef RPC_DEBUG
1072void rpc_show_tasks(void)
1073{
1074 struct list_head *le;
1075 struct rpc_task *t;
1076
1077 spin_lock(&rpc_sched_lock);
1078 if (list_empty(&all_tasks)) {
1079 spin_unlock(&rpc_sched_lock);
1080 return;
1081 }
1082 printk("-pid- proc flgs status -client- -prog- --rqstp- -timeout "
1083 "-rpcwait -action- ---ops--\n");
1084 alltask_for_each(t, le, &all_tasks) {
1085 const char *rpc_waitq = "none";
1086
1087 if (RPC_IS_QUEUED(t))
1088 rpc_waitq = rpc_qname(t->u.tk_wait.rpc_waitq);
1089
1090 printk("%5u %04d %04x %6d %8p %6d %8p %8ld %8s %8p %8p\n",
1091 t->tk_pid,
1092 (t->tk_msg.rpc_proc ? t->tk_msg.rpc_proc->p_proc : -1),
1093 t->tk_flags, t->tk_status,
1094 t->tk_client,
1095 (t->tk_client ? t->tk_client->cl_prog : 0),
1096 t->tk_rqstp, t->tk_timeout,
1097 rpc_waitq,
1098 t->tk_action, t->tk_ops);
1099 }
1100 spin_unlock(&rpc_sched_lock);
1101}
1102#endif
1103
1104void 1015void
1105rpc_destroy_mempool(void) 1016rpc_destroy_mempool(void)
1106{ 1017{
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index 73075dec83c0..384c4ad5ab86 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -28,15 +28,11 @@ EXPORT_SYMBOL(rpc_init_task);
28EXPORT_SYMBOL(rpc_sleep_on); 28EXPORT_SYMBOL(rpc_sleep_on);
29EXPORT_SYMBOL(rpc_wake_up_next); 29EXPORT_SYMBOL(rpc_wake_up_next);
30EXPORT_SYMBOL(rpc_wake_up_task); 30EXPORT_SYMBOL(rpc_wake_up_task);
31EXPORT_SYMBOL(rpciod_down);
32EXPORT_SYMBOL(rpciod_up);
33EXPORT_SYMBOL(rpc_new_task);
34EXPORT_SYMBOL(rpc_wake_up_status); 31EXPORT_SYMBOL(rpc_wake_up_status);
35 32
36/* RPC client functions */ 33/* RPC client functions */
37EXPORT_SYMBOL(rpc_clone_client); 34EXPORT_SYMBOL(rpc_clone_client);
38EXPORT_SYMBOL(rpc_bind_new_program); 35EXPORT_SYMBOL(rpc_bind_new_program);
39EXPORT_SYMBOL(rpc_destroy_client);
40EXPORT_SYMBOL(rpc_shutdown_client); 36EXPORT_SYMBOL(rpc_shutdown_client);
41EXPORT_SYMBOL(rpc_killall_tasks); 37EXPORT_SYMBOL(rpc_killall_tasks);
42EXPORT_SYMBOL(rpc_call_sync); 38EXPORT_SYMBOL(rpc_call_sync);
@@ -61,7 +57,7 @@ EXPORT_SYMBOL(rpcauth_unregister);
61EXPORT_SYMBOL(rpcauth_create); 57EXPORT_SYMBOL(rpcauth_create);
62EXPORT_SYMBOL(rpcauth_lookupcred); 58EXPORT_SYMBOL(rpcauth_lookupcred);
63EXPORT_SYMBOL(rpcauth_lookup_credcache); 59EXPORT_SYMBOL(rpcauth_lookup_credcache);
64EXPORT_SYMBOL(rpcauth_free_credcache); 60EXPORT_SYMBOL(rpcauth_destroy_credcache);
65EXPORT_SYMBOL(rpcauth_init_credcache); 61EXPORT_SYMBOL(rpcauth_init_credcache);
66EXPORT_SYMBOL(put_rpccred); 62EXPORT_SYMBOL(put_rpccred);
67 63
@@ -156,6 +152,7 @@ init_sunrpc(void)
156 cache_register(&ip_map_cache); 152 cache_register(&ip_map_cache);
157 cache_register(&unix_gid_cache); 153 cache_register(&unix_gid_cache);
158 init_socket_xprt(); 154 init_socket_xprt();
155 rpcauth_init_module();
159out: 156out:
160 return err; 157 return err;
161} 158}
@@ -163,6 +160,7 @@ out:
163static void __exit 160static void __exit
164cleanup_sunrpc(void) 161cleanup_sunrpc(void)
165{ 162{
163 rpcauth_remove_module();
166 cleanup_socket_xprt(); 164 cleanup_socket_xprt();
167 unregister_rpc_pipefs(); 165 unregister_rpc_pipefs();
168 rpc_destroy_mempool(); 166 rpc_destroy_mempool();
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 5baf48de2558..64b9b8c743c4 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -644,6 +644,7 @@ svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr, int buflen)
644 struct msghdr msg = { 644 struct msghdr msg = {
645 .msg_flags = MSG_DONTWAIT, 645 .msg_flags = MSG_DONTWAIT,
646 }; 646 };
647 struct sockaddr *sin;
647 int len; 648 int len;
648 649
649 len = kernel_recvmsg(svsk->sk_sock, &msg, iov, nr, buflen, 650 len = kernel_recvmsg(svsk->sk_sock, &msg, iov, nr, buflen,
@@ -654,6 +655,19 @@ svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr, int buflen)
654 memcpy(&rqstp->rq_addr, &svsk->sk_remote, svsk->sk_remotelen); 655 memcpy(&rqstp->rq_addr, &svsk->sk_remote, svsk->sk_remotelen);
655 rqstp->rq_addrlen = svsk->sk_remotelen; 656 rqstp->rq_addrlen = svsk->sk_remotelen;
656 657
658 /* Destination address in request is needed for binding the
659 * source address in RPC callbacks later.
660 */
661 sin = (struct sockaddr *)&svsk->sk_local;
662 switch (sin->sa_family) {
663 case AF_INET:
664 rqstp->rq_daddr.addr = ((struct sockaddr_in *)sin)->sin_addr;
665 break;
666 case AF_INET6:
667 rqstp->rq_daddr.addr6 = ((struct sockaddr_in6 *)sin)->sin6_addr;
668 break;
669 }
670
657 dprintk("svc: socket %p recvfrom(%p, %Zu) = %d\n", 671 dprintk("svc: socket %p recvfrom(%p, %Zu) = %d\n",
658 svsk, iov[0].iov_base, iov[0].iov_len, len); 672 svsk, iov[0].iov_base, iov[0].iov_len, len);
659 673
@@ -1064,6 +1078,12 @@ svc_tcp_accept(struct svc_sock *svsk)
1064 goto failed; 1078 goto failed;
1065 memcpy(&newsvsk->sk_remote, sin, slen); 1079 memcpy(&newsvsk->sk_remote, sin, slen);
1066 newsvsk->sk_remotelen = slen; 1080 newsvsk->sk_remotelen = slen;
1081 err = kernel_getsockname(newsock, sin, &slen);
1082 if (unlikely(err < 0)) {
1083 dprintk("svc_tcp_accept: kernel_getsockname error %d\n", -err);
1084 slen = offsetof(struct sockaddr, sa_data);
1085 }
1086 memcpy(&newsvsk->sk_local, sin, slen);
1067 1087
1068 svc_sock_received(newsvsk); 1088 svc_sock_received(newsvsk);
1069 1089
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 5b05b73e4c1d..c8c2edccad7e 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -127,7 +127,7 @@ static void xprt_clear_locked(struct rpc_xprt *xprt)
127 clear_bit(XPRT_LOCKED, &xprt->state); 127 clear_bit(XPRT_LOCKED, &xprt->state);
128 smp_mb__after_clear_bit(); 128 smp_mb__after_clear_bit();
129 } else 129 } else
130 schedule_work(&xprt->task_cleanup); 130 queue_work(rpciod_workqueue, &xprt->task_cleanup);
131} 131}
132 132
133/* 133/*
@@ -515,7 +515,7 @@ xprt_init_autodisconnect(unsigned long data)
515 if (xprt_connecting(xprt)) 515 if (xprt_connecting(xprt))
516 xprt_release_write(xprt, NULL); 516 xprt_release_write(xprt, NULL);
517 else 517 else
518 schedule_work(&xprt->task_cleanup); 518 queue_work(rpciod_workqueue, &xprt->task_cleanup);
519 return; 519 return;
520out_abort: 520out_abort:
521 spin_unlock(&xprt->transport_lock); 521 spin_unlock(&xprt->transport_lock);
@@ -886,27 +886,24 @@ void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long i
886 886
887/** 887/**
888 * xprt_create_transport - create an RPC transport 888 * xprt_create_transport - create an RPC transport
889 * @proto: requested transport protocol 889 * @args: rpc transport creation arguments
890 * @ap: remote peer address
891 * @size: length of address
892 * @to: timeout parameters
893 * 890 *
894 */ 891 */
895struct rpc_xprt *xprt_create_transport(int proto, struct sockaddr *ap, size_t size, struct rpc_timeout *to) 892struct rpc_xprt *xprt_create_transport(struct rpc_xprtsock_create *args)
896{ 893{
897 struct rpc_xprt *xprt; 894 struct rpc_xprt *xprt;
898 struct rpc_rqst *req; 895 struct rpc_rqst *req;
899 896
900 switch (proto) { 897 switch (args->proto) {
901 case IPPROTO_UDP: 898 case IPPROTO_UDP:
902 xprt = xs_setup_udp(ap, size, to); 899 xprt = xs_setup_udp(args);
903 break; 900 break;
904 case IPPROTO_TCP: 901 case IPPROTO_TCP:
905 xprt = xs_setup_tcp(ap, size, to); 902 xprt = xs_setup_tcp(args);
906 break; 903 break;
907 default: 904 default:
908 printk(KERN_ERR "RPC: unrecognized transport protocol: %d\n", 905 printk(KERN_ERR "RPC: unrecognized transport protocol: %d\n",
909 proto); 906 args->proto);
910 return ERR_PTR(-EIO); 907 return ERR_PTR(-EIO);
911 } 908 }
912 if (IS_ERR(xprt)) { 909 if (IS_ERR(xprt)) {
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index cc33c5880abb..4ae7eed7f617 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -235,6 +235,7 @@ struct sock_xprt {
235 * Connection of transports 235 * Connection of transports
236 */ 236 */
237 struct delayed_work connect_worker; 237 struct delayed_work connect_worker;
238 struct sockaddr_storage addr;
238 unsigned short port; 239 unsigned short port;
239 240
240 /* 241 /*
@@ -653,8 +654,7 @@ static void xs_destroy(struct rpc_xprt *xprt)
653 654
654 dprintk("RPC: xs_destroy xprt %p\n", xprt); 655 dprintk("RPC: xs_destroy xprt %p\n", xprt);
655 656
656 cancel_delayed_work(&transport->connect_worker); 657 cancel_rearming_delayed_work(&transport->connect_worker);
657 flush_scheduled_work();
658 658
659 xprt_disconnect(xprt); 659 xprt_disconnect(xprt);
660 xs_close(xprt); 660 xs_close(xprt);
@@ -1001,7 +1001,7 @@ static void xs_tcp_state_change(struct sock *sk)
1001 /* Try to schedule an autoclose RPC calls */ 1001 /* Try to schedule an autoclose RPC calls */
1002 set_bit(XPRT_CLOSE_WAIT, &xprt->state); 1002 set_bit(XPRT_CLOSE_WAIT, &xprt->state);
1003 if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0) 1003 if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0)
1004 schedule_work(&xprt->task_cleanup); 1004 queue_work(rpciod_workqueue, &xprt->task_cleanup);
1005 default: 1005 default:
1006 xprt_disconnect(xprt); 1006 xprt_disconnect(xprt);
1007 } 1007 }
@@ -1146,31 +1146,36 @@ static void xs_set_port(struct rpc_xprt *xprt, unsigned short port)
1146 sap->sin_port = htons(port); 1146 sap->sin_port = htons(port);
1147} 1147}
1148 1148
1149static int xs_bindresvport(struct sock_xprt *transport, struct socket *sock) 1149static int xs_bind(struct sock_xprt *transport, struct socket *sock)
1150{ 1150{
1151 struct sockaddr_in myaddr = { 1151 struct sockaddr_in myaddr = {
1152 .sin_family = AF_INET, 1152 .sin_family = AF_INET,
1153 }; 1153 };
1154 struct sockaddr_in *sa;
1154 int err; 1155 int err;
1155 unsigned short port = transport->port; 1156 unsigned short port = transport->port;
1156 1157
1158 if (!transport->xprt.resvport)
1159 port = 0;
1160 sa = (struct sockaddr_in *)&transport->addr;
1161 myaddr.sin_addr = sa->sin_addr;
1157 do { 1162 do {
1158 myaddr.sin_port = htons(port); 1163 myaddr.sin_port = htons(port);
1159 err = kernel_bind(sock, (struct sockaddr *) &myaddr, 1164 err = kernel_bind(sock, (struct sockaddr *) &myaddr,
1160 sizeof(myaddr)); 1165 sizeof(myaddr));
1166 if (!transport->xprt.resvport)
1167 break;
1161 if (err == 0) { 1168 if (err == 0) {
1162 transport->port = port; 1169 transport->port = port;
1163 dprintk("RPC: xs_bindresvport bound to port %u\n", 1170 break;
1164 port);
1165 return 0;
1166 } 1171 }
1167 if (port <= xprt_min_resvport) 1172 if (port <= xprt_min_resvport)
1168 port = xprt_max_resvport; 1173 port = xprt_max_resvport;
1169 else 1174 else
1170 port--; 1175 port--;
1171 } while (err == -EADDRINUSE && port != transport->port); 1176 } while (err == -EADDRINUSE && port != transport->port);
1172 1177 dprintk("RPC: xs_bind "NIPQUAD_FMT":%u: %s (%d)\n",
1173 dprintk("RPC: can't bind to reserved port (%d).\n", -err); 1178 NIPQUAD(myaddr.sin_addr), port, err ? "failed" : "ok", err);
1174 return err; 1179 return err;
1175} 1180}
1176 1181
@@ -1229,7 +1234,7 @@ static void xs_udp_connect_worker(struct work_struct *work)
1229 } 1234 }
1230 xs_reclassify_socket(sock); 1235 xs_reclassify_socket(sock);
1231 1236
1232 if (xprt->resvport && xs_bindresvport(transport, sock) < 0) { 1237 if (xs_bind(transport, sock)) {
1233 sock_release(sock); 1238 sock_release(sock);
1234 goto out; 1239 goto out;
1235 } 1240 }
@@ -1316,7 +1321,7 @@ static void xs_tcp_connect_worker(struct work_struct *work)
1316 } 1321 }
1317 xs_reclassify_socket(sock); 1322 xs_reclassify_socket(sock);
1318 1323
1319 if (xprt->resvport && xs_bindresvport(transport, sock) < 0) { 1324 if (xs_bind(transport, sock)) {
1320 sock_release(sock); 1325 sock_release(sock);
1321 goto out; 1326 goto out;
1322 } 1327 }
@@ -1410,18 +1415,16 @@ static void xs_connect(struct rpc_task *task)
1410 dprintk("RPC: xs_connect delayed xprt %p for %lu " 1415 dprintk("RPC: xs_connect delayed xprt %p for %lu "
1411 "seconds\n", 1416 "seconds\n",
1412 xprt, xprt->reestablish_timeout / HZ); 1417 xprt, xprt->reestablish_timeout / HZ);
1413 schedule_delayed_work(&transport->connect_worker, 1418 queue_delayed_work(rpciod_workqueue,
1414 xprt->reestablish_timeout); 1419 &transport->connect_worker,
1420 xprt->reestablish_timeout);
1415 xprt->reestablish_timeout <<= 1; 1421 xprt->reestablish_timeout <<= 1;
1416 if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO) 1422 if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO)
1417 xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO; 1423 xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO;
1418 } else { 1424 } else {
1419 dprintk("RPC: xs_connect scheduled xprt %p\n", xprt); 1425 dprintk("RPC: xs_connect scheduled xprt %p\n", xprt);
1420 schedule_delayed_work(&transport->connect_worker, 0); 1426 queue_delayed_work(rpciod_workqueue,
1421 1427 &transport->connect_worker, 0);
1422 /* flush_scheduled_work can sleep... */
1423 if (!RPC_IS_ASYNC(task))
1424 flush_scheduled_work();
1425 } 1428 }
1426} 1429}
1427 1430
@@ -1476,7 +1479,7 @@ static struct rpc_xprt_ops xs_udp_ops = {
1476 .set_buffer_size = xs_udp_set_buffer_size, 1479 .set_buffer_size = xs_udp_set_buffer_size,
1477 .reserve_xprt = xprt_reserve_xprt_cong, 1480 .reserve_xprt = xprt_reserve_xprt_cong,
1478 .release_xprt = xprt_release_xprt_cong, 1481 .release_xprt = xprt_release_xprt_cong,
1479 .rpcbind = rpcb_getport, 1482 .rpcbind = rpcb_getport_async,
1480 .set_port = xs_set_port, 1483 .set_port = xs_set_port,
1481 .connect = xs_connect, 1484 .connect = xs_connect,
1482 .buf_alloc = rpc_malloc, 1485 .buf_alloc = rpc_malloc,
@@ -1493,7 +1496,7 @@ static struct rpc_xprt_ops xs_udp_ops = {
1493static struct rpc_xprt_ops xs_tcp_ops = { 1496static struct rpc_xprt_ops xs_tcp_ops = {
1494 .reserve_xprt = xprt_reserve_xprt, 1497 .reserve_xprt = xprt_reserve_xprt,
1495 .release_xprt = xs_tcp_release_xprt, 1498 .release_xprt = xs_tcp_release_xprt,
1496 .rpcbind = rpcb_getport, 1499 .rpcbind = rpcb_getport_async,
1497 .set_port = xs_set_port, 1500 .set_port = xs_set_port,
1498 .connect = xs_connect, 1501 .connect = xs_connect,
1499 .buf_alloc = rpc_malloc, 1502 .buf_alloc = rpc_malloc,
@@ -1505,12 +1508,12 @@ static struct rpc_xprt_ops xs_tcp_ops = {
1505 .print_stats = xs_tcp_print_stats, 1508 .print_stats = xs_tcp_print_stats,
1506}; 1509};
1507 1510
1508static struct rpc_xprt *xs_setup_xprt(struct sockaddr *addr, size_t addrlen, unsigned int slot_table_size) 1511static struct rpc_xprt *xs_setup_xprt(struct rpc_xprtsock_create *args, unsigned int slot_table_size)
1509{ 1512{
1510 struct rpc_xprt *xprt; 1513 struct rpc_xprt *xprt;
1511 struct sock_xprt *new; 1514 struct sock_xprt *new;
1512 1515
1513 if (addrlen > sizeof(xprt->addr)) { 1516 if (args->addrlen > sizeof(xprt->addr)) {
1514 dprintk("RPC: xs_setup_xprt: address too large\n"); 1517 dprintk("RPC: xs_setup_xprt: address too large\n");
1515 return ERR_PTR(-EBADF); 1518 return ERR_PTR(-EBADF);
1516 } 1519 }
@@ -1532,8 +1535,10 @@ static struct rpc_xprt *xs_setup_xprt(struct sockaddr *addr, size_t addrlen, uns
1532 return ERR_PTR(-ENOMEM); 1535 return ERR_PTR(-ENOMEM);
1533 } 1536 }
1534 1537
1535 memcpy(&xprt->addr, addr, addrlen); 1538 memcpy(&xprt->addr, args->dstaddr, args->addrlen);
1536 xprt->addrlen = addrlen; 1539 xprt->addrlen = args->addrlen;
1540 if (args->srcaddr)
1541 memcpy(&new->addr, args->srcaddr, args->addrlen);
1537 new->port = xs_get_random_port(); 1542 new->port = xs_get_random_port();
1538 1543
1539 return xprt; 1544 return xprt;
@@ -1541,22 +1546,20 @@ static struct rpc_xprt *xs_setup_xprt(struct sockaddr *addr, size_t addrlen, uns
1541 1546
1542/** 1547/**
1543 * xs_setup_udp - Set up transport to use a UDP socket 1548 * xs_setup_udp - Set up transport to use a UDP socket
1544 * @addr: address of remote server 1549 * @args: rpc transport creation arguments
1545 * @addrlen: length of address in bytes
1546 * @to: timeout parameters
1547 * 1550 *
1548 */ 1551 */
1549struct rpc_xprt *xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to) 1552struct rpc_xprt *xs_setup_udp(struct rpc_xprtsock_create *args)
1550{ 1553{
1551 struct rpc_xprt *xprt; 1554 struct rpc_xprt *xprt;
1552 struct sock_xprt *transport; 1555 struct sock_xprt *transport;
1553 1556
1554 xprt = xs_setup_xprt(addr, addrlen, xprt_udp_slot_table_entries); 1557 xprt = xs_setup_xprt(args, xprt_udp_slot_table_entries);
1555 if (IS_ERR(xprt)) 1558 if (IS_ERR(xprt))
1556 return xprt; 1559 return xprt;
1557 transport = container_of(xprt, struct sock_xprt, xprt); 1560 transport = container_of(xprt, struct sock_xprt, xprt);
1558 1561
1559 if (ntohs(((struct sockaddr_in *)addr)->sin_port) != 0) 1562 if (ntohs(((struct sockaddr_in *)args->dstaddr)->sin_port) != 0)
1560 xprt_set_bound(xprt); 1563 xprt_set_bound(xprt);
1561 1564
1562 xprt->prot = IPPROTO_UDP; 1565 xprt->prot = IPPROTO_UDP;
@@ -1572,8 +1575,8 @@ struct rpc_xprt *xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_
1572 1575
1573 xprt->ops = &xs_udp_ops; 1576 xprt->ops = &xs_udp_ops;
1574 1577
1575 if (to) 1578 if (args->timeout)
1576 xprt->timeout = *to; 1579 xprt->timeout = *args->timeout;
1577 else 1580 else
1578 xprt_set_timeout(&xprt->timeout, 5, 5 * HZ); 1581 xprt_set_timeout(&xprt->timeout, 5, 5 * HZ);
1579 1582
@@ -1586,22 +1589,20 @@ struct rpc_xprt *xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_
1586 1589
1587/** 1590/**
1588 * xs_setup_tcp - Set up transport to use a TCP socket 1591 * xs_setup_tcp - Set up transport to use a TCP socket
1589 * @addr: address of remote server 1592 * @args: rpc transport creation arguments
1590 * @addrlen: length of address in bytes
1591 * @to: timeout parameters
1592 * 1593 *
1593 */ 1594 */
1594struct rpc_xprt *xs_setup_tcp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to) 1595struct rpc_xprt *xs_setup_tcp(struct rpc_xprtsock_create *args)
1595{ 1596{
1596 struct rpc_xprt *xprt; 1597 struct rpc_xprt *xprt;
1597 struct sock_xprt *transport; 1598 struct sock_xprt *transport;
1598 1599
1599 xprt = xs_setup_xprt(addr, addrlen, xprt_tcp_slot_table_entries); 1600 xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries);
1600 if (IS_ERR(xprt)) 1601 if (IS_ERR(xprt))
1601 return xprt; 1602 return xprt;
1602 transport = container_of(xprt, struct sock_xprt, xprt); 1603 transport = container_of(xprt, struct sock_xprt, xprt);
1603 1604
1604 if (ntohs(((struct sockaddr_in *)addr)->sin_port) != 0) 1605 if (ntohs(((struct sockaddr_in *)args->dstaddr)->sin_port) != 0)
1605 xprt_set_bound(xprt); 1606 xprt_set_bound(xprt);
1606 1607
1607 xprt->prot = IPPROTO_TCP; 1608 xprt->prot = IPPROTO_TCP;
@@ -1616,8 +1617,8 @@ struct rpc_xprt *xs_setup_tcp(struct sockaddr *addr, size_t addrlen, struct rpc_
1616 1617
1617 xprt->ops = &xs_tcp_ops; 1618 xprt->ops = &xs_tcp_ops;
1618 1619
1619 if (to) 1620 if (args->timeout)
1620 xprt->timeout = *to; 1621 xprt->timeout = *args->timeout;
1621 else 1622 else
1622 xprt_set_timeout(&xprt->timeout, 2, 60 * HZ); 1623 xprt_set_timeout(&xprt->timeout, 2, 60 * HZ);
1623 1624
diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c
index 77d2d9ce8962..711ca4b1f051 100644
--- a/net/tipc/eth_media.c
+++ b/net/tipc/eth_media.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * net/tipc/eth_media.c: Ethernet bearer support for TIPC 2 * net/tipc/eth_media.c: Ethernet bearer support for TIPC
3 * 3 *
4 * Copyright (c) 2001-2006, Ericsson AB 4 * Copyright (c) 2001-2007, Ericsson AB
5 * Copyright (c) 2005-2006, Wind River Systems 5 * Copyright (c) 2005-2007, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -87,6 +87,9 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr,
87/** 87/**
88 * recv_msg - handle incoming TIPC message from an Ethernet interface 88 * recv_msg - handle incoming TIPC message from an Ethernet interface
89 * 89 *
90 * Accept only packets explicitly sent to this node, or broadcast packets;
91 * ignores packets sent using Ethernet multicast, and traffic sent to other
92 * nodes (which can happen if interface is running in promiscuous mode).
90 * Routine truncates any Ethernet padding/CRC appended to the message, 93 * Routine truncates any Ethernet padding/CRC appended to the message,
91 * and ensures message size matches actual length 94 * and ensures message size matches actual length
92 */ 95 */
@@ -98,9 +101,7 @@ static int recv_msg(struct sk_buff *buf, struct net_device *dev,
98 u32 size; 101 u32 size;
99 102
100 if (likely(eb_ptr->bearer)) { 103 if (likely(eb_ptr->bearer)) {
101 if (likely(!dev->promiscuity) || 104 if (likely(buf->pkt_type <= PACKET_BROADCAST)) {
102 !memcmp(skb_mac_header(buf), dev->dev_addr, ETH_ALEN) ||
103 !memcmp(skb_mac_header(buf), dev->broadcast, ETH_ALEN)) {
104 size = msg_size((struct tipc_msg *)buf->data); 105 size = msg_size((struct tipc_msg *)buf->data);
105 skb_trim(buf, size); 106 skb_trim(buf, size);
106 if (likely(buf->len == size)) { 107 if (likely(buf->len == size)) {
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 2124f32ef29f..5adfdfd49d61 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * net/tipc/link.c: TIPC link code 2 * net/tipc/link.c: TIPC link code
3 * 3 *
4 * Copyright (c) 1996-2006, Ericsson AB 4 * Copyright (c) 1996-2007, Ericsson AB
5 * Copyright (c) 2004-2006, Wind River Systems 5 * Copyright (c) 2004-2007, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -1260,7 +1260,7 @@ again:
1260 * (Must not hold any locks while building message.) 1260 * (Must not hold any locks while building message.)
1261 */ 1261 */
1262 1262
1263 res = msg_build(hdr, msg_sect, num_sect, sender->max_pkt, 1263 res = msg_build(hdr, msg_sect, num_sect, sender->publ.max_pkt,
1264 !sender->user_port, &buf); 1264 !sender->user_port, &buf);
1265 1265
1266 read_lock_bh(&tipc_net_lock); 1266 read_lock_bh(&tipc_net_lock);
@@ -1271,7 +1271,7 @@ again:
1271 if (likely(l_ptr)) { 1271 if (likely(l_ptr)) {
1272 if (likely(buf)) { 1272 if (likely(buf)) {
1273 res = link_send_buf_fast(l_ptr, buf, 1273 res = link_send_buf_fast(l_ptr, buf,
1274 &sender->max_pkt); 1274 &sender->publ.max_pkt);
1275 if (unlikely(res < 0)) 1275 if (unlikely(res < 0))
1276 buf_discard(buf); 1276 buf_discard(buf);
1277exit: 1277exit:
@@ -1299,12 +1299,12 @@ exit:
1299 * then re-try fast path or fragment the message 1299 * then re-try fast path or fragment the message
1300 */ 1300 */
1301 1301
1302 sender->max_pkt = link_max_pkt(l_ptr); 1302 sender->publ.max_pkt = link_max_pkt(l_ptr);
1303 tipc_node_unlock(node); 1303 tipc_node_unlock(node);
1304 read_unlock_bh(&tipc_net_lock); 1304 read_unlock_bh(&tipc_net_lock);
1305 1305
1306 1306
1307 if ((msg_hdr_sz(hdr) + res) <= sender->max_pkt) 1307 if ((msg_hdr_sz(hdr) + res) <= sender->publ.max_pkt)
1308 goto again; 1308 goto again;
1309 1309
1310 return link_send_sections_long(sender, msg_sect, 1310 return link_send_sections_long(sender, msg_sect,
@@ -1357,7 +1357,7 @@ static int link_send_sections_long(struct port *sender,
1357 1357
1358again: 1358again:
1359 fragm_no = 1; 1359 fragm_no = 1;
1360 max_pkt = sender->max_pkt - INT_H_SIZE; 1360 max_pkt = sender->publ.max_pkt - INT_H_SIZE;
1361 /* leave room for tunnel header in case of link changeover */ 1361 /* leave room for tunnel header in case of link changeover */
1362 fragm_sz = max_pkt - INT_H_SIZE; 1362 fragm_sz = max_pkt - INT_H_SIZE;
1363 /* leave room for fragmentation header in each fragment */ 1363 /* leave room for fragmentation header in each fragment */
@@ -1463,7 +1463,7 @@ error:
1463 goto reject; 1463 goto reject;
1464 } 1464 }
1465 if (link_max_pkt(l_ptr) < max_pkt) { 1465 if (link_max_pkt(l_ptr) < max_pkt) {
1466 sender->max_pkt = link_max_pkt(l_ptr); 1466 sender->publ.max_pkt = link_max_pkt(l_ptr);
1467 tipc_node_unlock(node); 1467 tipc_node_unlock(node);
1468 for (; buf_chain; buf_chain = buf) { 1468 for (; buf_chain; buf_chain = buf) {
1469 buf = buf_chain->next; 1469 buf = buf_chain->next;
diff --git a/net/tipc/port.c b/net/tipc/port.c
index bcd5da00737b..5d2b9ce84d0a 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * net/tipc/port.c: TIPC port code 2 * net/tipc/port.c: TIPC port code
3 * 3 *
4 * Copyright (c) 1992-2006, Ericsson AB 4 * Copyright (c) 1992-2007, Ericsson AB
5 * Copyright (c) 2004-2005, Wind River Systems 5 * Copyright (c) 2004-2007, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -239,6 +239,8 @@ u32 tipc_createport_raw(void *usr_handle,
239 } 239 }
240 240
241 tipc_port_lock(ref); 241 tipc_port_lock(ref);
242 p_ptr->publ.usr_handle = usr_handle;
243 p_ptr->publ.max_pkt = MAX_PKT_DEFAULT;
242 p_ptr->publ.ref = ref; 244 p_ptr->publ.ref = ref;
243 msg = &p_ptr->publ.phdr; 245 msg = &p_ptr->publ.phdr;
244 msg_init(msg, DATA_LOW, TIPC_NAMED_MSG, TIPC_OK, LONG_H_SIZE, 0); 246 msg_init(msg, DATA_LOW, TIPC_NAMED_MSG, TIPC_OK, LONG_H_SIZE, 0);
@@ -248,11 +250,9 @@ u32 tipc_createport_raw(void *usr_handle,
248 msg_set_importance(msg,importance); 250 msg_set_importance(msg,importance);
249 p_ptr->last_in_seqno = 41; 251 p_ptr->last_in_seqno = 41;
250 p_ptr->sent = 1; 252 p_ptr->sent = 1;
251 p_ptr->publ.usr_handle = usr_handle;
252 INIT_LIST_HEAD(&p_ptr->wait_list); 253 INIT_LIST_HEAD(&p_ptr->wait_list);
253 INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list); 254 INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list);
254 p_ptr->congested_link = NULL; 255 p_ptr->congested_link = NULL;
255 p_ptr->max_pkt = MAX_PKT_DEFAULT;
256 p_ptr->dispatcher = dispatcher; 256 p_ptr->dispatcher = dispatcher;
257 p_ptr->wakeup = wakeup; 257 p_ptr->wakeup = wakeup;
258 p_ptr->user_port = NULL; 258 p_ptr->user_port = NULL;
@@ -1243,7 +1243,7 @@ int tipc_connect2port(u32 ref, struct tipc_portid const *peer)
1243 res = TIPC_OK; 1243 res = TIPC_OK;
1244exit: 1244exit:
1245 tipc_port_unlock(p_ptr); 1245 tipc_port_unlock(p_ptr);
1246 p_ptr->max_pkt = tipc_link_get_max_pkt(peer->node, ref); 1246 p_ptr->publ.max_pkt = tipc_link_get_max_pkt(peer->node, ref);
1247 return res; 1247 return res;
1248} 1248}
1249 1249
diff --git a/net/tipc/port.h b/net/tipc/port.h
index 7ef4d64b32f7..e5f8c16429bd 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -1,8 +1,8 @@
1/* 1/*
2 * net/tipc/port.h: Include file for TIPC port code 2 * net/tipc/port.h: Include file for TIPC port code
3 * 3 *
4 * Copyright (c) 1994-2006, Ericsson AB 4 * Copyright (c) 1994-2007, Ericsson AB
5 * Copyright (c) 2004-2005, Wind River Systems 5 * Copyright (c) 2004-2007, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -81,7 +81,6 @@ struct user_port {
81 * @acked: 81 * @acked:
82 * @publications: list of publications for port 82 * @publications: list of publications for port
83 * @pub_count: total # of publications port has made during its lifetime 83 * @pub_count: total # of publications port has made during its lifetime
84 * @max_pkt: maximum packet size "hint" used when building messages sent by port
85 * @probing_state: 84 * @probing_state:
86 * @probing_interval: 85 * @probing_interval:
87 * @last_in_seqno: 86 * @last_in_seqno:
@@ -102,7 +101,6 @@ struct port {
102 u32 acked; 101 u32 acked;
103 struct list_head publications; 102 struct list_head publications;
104 u32 pub_count; 103 u32 pub_count;
105 u32 max_pkt;
106 u32 probing_state; 104 u32 probing_state;
107 u32 probing_interval; 105 u32 probing_interval;
108 u32 last_in_seqno; 106 u32 last_in_seqno;
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 45832fb75ea4..4a8f37f48764 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * net/tipc/socket.c: TIPC socket API 2 * net/tipc/socket.c: TIPC socket API
3 * 3 *
4 * Copyright (c) 2001-2006, Ericsson AB 4 * Copyright (c) 2001-2007, Ericsson AB
5 * Copyright (c) 2004-2006, Wind River Systems 5 * Copyright (c) 2004-2007, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
@@ -607,23 +607,24 @@ exit:
607static int send_stream(struct kiocb *iocb, struct socket *sock, 607static int send_stream(struct kiocb *iocb, struct socket *sock,
608 struct msghdr *m, size_t total_len) 608 struct msghdr *m, size_t total_len)
609{ 609{
610 struct tipc_port *tport;
610 struct msghdr my_msg; 611 struct msghdr my_msg;
611 struct iovec my_iov; 612 struct iovec my_iov;
612 struct iovec *curr_iov; 613 struct iovec *curr_iov;
613 int curr_iovlen; 614 int curr_iovlen;
614 char __user *curr_start; 615 char __user *curr_start;
616 u32 hdr_size;
615 int curr_left; 617 int curr_left;
616 int bytes_to_send; 618 int bytes_to_send;
617 int bytes_sent; 619 int bytes_sent;
618 int res; 620 int res;
619 621
620 if (likely(total_len <= TIPC_MAX_USER_MSG_SIZE)) 622 /* Handle special cases where there is no connection */
621 return send_packet(iocb, sock, m, total_len);
622
623 /* Can only send large data streams if already connected */
624 623
625 if (unlikely(sock->state != SS_CONNECTED)) { 624 if (unlikely(sock->state != SS_CONNECTED)) {
626 if (sock->state == SS_DISCONNECTING) 625 if (sock->state == SS_UNCONNECTED)
626 return send_packet(iocb, sock, m, total_len);
627 else if (sock->state == SS_DISCONNECTING)
627 return -EPIPE; 628 return -EPIPE;
628 else 629 else
629 return -ENOTCONN; 630 return -ENOTCONN;
@@ -648,17 +649,25 @@ static int send_stream(struct kiocb *iocb, struct socket *sock,
648 my_msg.msg_name = NULL; 649 my_msg.msg_name = NULL;
649 bytes_sent = 0; 650 bytes_sent = 0;
650 651
652 tport = tipc_sk(sock->sk)->p;
653 hdr_size = msg_hdr_sz(&tport->phdr);
654
651 while (curr_iovlen--) { 655 while (curr_iovlen--) {
652 curr_start = curr_iov->iov_base; 656 curr_start = curr_iov->iov_base;
653 curr_left = curr_iov->iov_len; 657 curr_left = curr_iov->iov_len;
654 658
655 while (curr_left) { 659 while (curr_left) {
656 bytes_to_send = (curr_left < TIPC_MAX_USER_MSG_SIZE) 660 bytes_to_send = tport->max_pkt - hdr_size;
657 ? curr_left : TIPC_MAX_USER_MSG_SIZE; 661 if (bytes_to_send > TIPC_MAX_USER_MSG_SIZE)
662 bytes_to_send = TIPC_MAX_USER_MSG_SIZE;
663 if (curr_left < bytes_to_send)
664 bytes_to_send = curr_left;
658 my_iov.iov_base = curr_start; 665 my_iov.iov_base = curr_start;
659 my_iov.iov_len = bytes_to_send; 666 my_iov.iov_len = bytes_to_send;
660 if ((res = send_packet(iocb, sock, &my_msg, 0)) < 0) { 667 if ((res = send_packet(iocb, sock, &my_msg, 0)) < 0) {
661 return bytes_sent ? bytes_sent : res; 668 if (bytes_sent != 0)
669 res = bytes_sent;
670 return res;
662 } 671 }
663 curr_left -= bytes_to_send; 672 curr_left -= bytes_to_send;
664 curr_start += bytes_to_send; 673 curr_start += bytes_to_send;
@@ -1600,33 +1609,6 @@ static int getsockopt(struct socket *sock,
1600} 1609}
1601 1610
1602/** 1611/**
1603 * Placeholders for non-implemented functionality
1604 *
1605 * Returns error code (POSIX-compliant where defined)
1606 */
1607
1608static int ioctl(struct socket *s, u32 cmd, unsigned long arg)
1609{
1610 return -EINVAL;
1611}
1612
1613static int no_mmap(struct file *file, struct socket *sock,
1614 struct vm_area_struct *vma)
1615{
1616 return -EINVAL;
1617}
1618static ssize_t no_sendpage(struct socket *sock, struct page *page,
1619 int offset, size_t size, int flags)
1620{
1621 return -EINVAL;
1622}
1623
1624static int no_skpair(struct socket *s1, struct socket *s2)
1625{
1626 return -EOPNOTSUPP;
1627}
1628
1629/**
1630 * Protocol switches for the various types of TIPC sockets 1612 * Protocol switches for the various types of TIPC sockets
1631 */ 1613 */
1632 1614
@@ -1636,19 +1618,19 @@ static struct proto_ops msg_ops = {
1636 .release = release, 1618 .release = release,
1637 .bind = bind, 1619 .bind = bind,
1638 .connect = connect, 1620 .connect = connect,
1639 .socketpair = no_skpair, 1621 .socketpair = sock_no_socketpair,
1640 .accept = accept, 1622 .accept = accept,
1641 .getname = get_name, 1623 .getname = get_name,
1642 .poll = poll, 1624 .poll = poll,
1643 .ioctl = ioctl, 1625 .ioctl = sock_no_ioctl,
1644 .listen = listen, 1626 .listen = listen,
1645 .shutdown = shutdown, 1627 .shutdown = shutdown,
1646 .setsockopt = setsockopt, 1628 .setsockopt = setsockopt,
1647 .getsockopt = getsockopt, 1629 .getsockopt = getsockopt,
1648 .sendmsg = send_msg, 1630 .sendmsg = send_msg,
1649 .recvmsg = recv_msg, 1631 .recvmsg = recv_msg,
1650 .mmap = no_mmap, 1632 .mmap = sock_no_mmap,
1651 .sendpage = no_sendpage 1633 .sendpage = sock_no_sendpage
1652}; 1634};
1653 1635
1654static struct proto_ops packet_ops = { 1636static struct proto_ops packet_ops = {
@@ -1657,19 +1639,19 @@ static struct proto_ops packet_ops = {
1657 .release = release, 1639 .release = release,
1658 .bind = bind, 1640 .bind = bind,
1659 .connect = connect, 1641 .connect = connect,
1660 .socketpair = no_skpair, 1642 .socketpair = sock_no_socketpair,
1661 .accept = accept, 1643 .accept = accept,
1662 .getname = get_name, 1644 .getname = get_name,
1663 .poll = poll, 1645 .poll = poll,
1664 .ioctl = ioctl, 1646 .ioctl = sock_no_ioctl,
1665 .listen = listen, 1647 .listen = listen,
1666 .shutdown = shutdown, 1648 .shutdown = shutdown,
1667 .setsockopt = setsockopt, 1649 .setsockopt = setsockopt,
1668 .getsockopt = getsockopt, 1650 .getsockopt = getsockopt,
1669 .sendmsg = send_packet, 1651 .sendmsg = send_packet,
1670 .recvmsg = recv_msg, 1652 .recvmsg = recv_msg,
1671 .mmap = no_mmap, 1653 .mmap = sock_no_mmap,
1672 .sendpage = no_sendpage 1654 .sendpage = sock_no_sendpage
1673}; 1655};
1674 1656
1675static struct proto_ops stream_ops = { 1657static struct proto_ops stream_ops = {
@@ -1678,19 +1660,19 @@ static struct proto_ops stream_ops = {
1678 .release = release, 1660 .release = release,
1679 .bind = bind, 1661 .bind = bind,
1680 .connect = connect, 1662 .connect = connect,
1681 .socketpair = no_skpair, 1663 .socketpair = sock_no_socketpair,
1682 .accept = accept, 1664 .accept = accept,
1683 .getname = get_name, 1665 .getname = get_name,
1684 .poll = poll, 1666 .poll = poll,
1685 .ioctl = ioctl, 1667 .ioctl = sock_no_ioctl,
1686 .listen = listen, 1668 .listen = listen,
1687 .shutdown = shutdown, 1669 .shutdown = shutdown,
1688 .setsockopt = setsockopt, 1670 .setsockopt = setsockopt,
1689 .getsockopt = getsockopt, 1671 .getsockopt = getsockopt,
1690 .sendmsg = send_stream, 1672 .sendmsg = send_stream,
1691 .recvmsg = recv_stream, 1673 .recvmsg = recv_stream,
1692 .mmap = no_mmap, 1674 .mmap = sock_no_mmap,
1693 .sendpage = no_sendpage 1675 .sendpage = sock_no_sendpage
1694}; 1676};
1695 1677
1696static struct net_proto_family tipc_family_ops = { 1678static struct net_proto_family tipc_family_ops = {
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index d70fa30d4294..65ebccc0a698 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -592,7 +592,8 @@ static struct sock * unix_create1(struct socket *sock)
592 u->dentry = NULL; 592 u->dentry = NULL;
593 u->mnt = NULL; 593 u->mnt = NULL;
594 spin_lock_init(&u->lock); 594 spin_lock_init(&u->lock);
595 atomic_set(&u->inflight, sock ? 0 : -1); 595 atomic_set(&u->inflight, 0);
596 INIT_LIST_HEAD(&u->link);
596 mutex_init(&u->readlock); /* single task reading lock */ 597 mutex_init(&u->readlock); /* single task reading lock */
597 init_waitqueue_head(&u->peer_wait); 598 init_waitqueue_head(&u->peer_wait);
598 unix_insert_socket(unix_sockets_unbound, sk); 599 unix_insert_socket(unix_sockets_unbound, sk);
@@ -1134,9 +1135,6 @@ restart:
1134 /* take ten and and send info to listening sock */ 1135 /* take ten and and send info to listening sock */
1135 spin_lock(&other->sk_receive_queue.lock); 1136 spin_lock(&other->sk_receive_queue.lock);
1136 __skb_queue_tail(&other->sk_receive_queue, skb); 1137 __skb_queue_tail(&other->sk_receive_queue, skb);
1137 /* Undo artificially decreased inflight after embrion
1138 * is installed to listening socket. */
1139 atomic_inc(&newu->inflight);
1140 spin_unlock(&other->sk_receive_queue.lock); 1138 spin_unlock(&other->sk_receive_queue.lock);
1141 unix_state_unlock(other); 1139 unix_state_unlock(other);
1142 other->sk_data_ready(other, 0); 1140 other->sk_data_ready(other, 0);
@@ -2048,7 +2046,7 @@ static int unix_seq_show(struct seq_file *seq, void *v)
2048 return 0; 2046 return 0;
2049} 2047}
2050 2048
2051static struct seq_operations unix_seq_ops = { 2049static const struct seq_operations unix_seq_ops = {
2052 .start = unix_seq_start, 2050 .start = unix_seq_start,
2053 .next = unix_seq_next, 2051 .next = unix_seq_next,
2054 .stop = unix_seq_stop, 2052 .stop = unix_seq_stop,
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
index f20b7ea7c555..406b6433e467 100644
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -62,6 +62,10 @@
62 * AV 1 Mar 1999 62 * AV 1 Mar 1999
63 * Damn. Added missing check for ->dead in listen queues scanning. 63 * Damn. Added missing check for ->dead in listen queues scanning.
64 * 64 *
65 * Miklos Szeredi 25 Jun 2007
66 * Reimplement with a cycle collecting algorithm. This should
67 * solve several problems with the previous code, like being racy
68 * wrt receive and holding up unrelated socket operations.
65 */ 69 */
66 70
67#include <linux/kernel.h> 71#include <linux/kernel.h>
@@ -84,10 +88,9 @@
84 88
85/* Internal data structures and random procedures: */ 89/* Internal data structures and random procedures: */
86 90
87#define GC_HEAD ((struct sock *)(-1)) 91static LIST_HEAD(gc_inflight_list);
88#define GC_ORPHAN ((struct sock *)(-3)) 92static LIST_HEAD(gc_candidates);
89 93static DEFINE_SPINLOCK(unix_gc_lock);
90static struct sock *gc_current = GC_HEAD; /* stack of objects to mark */
91 94
92atomic_t unix_tot_inflight = ATOMIC_INIT(0); 95atomic_t unix_tot_inflight = ATOMIC_INIT(0);
93 96
@@ -122,8 +125,16 @@ void unix_inflight(struct file *fp)
122{ 125{
123 struct sock *s = unix_get_socket(fp); 126 struct sock *s = unix_get_socket(fp);
124 if(s) { 127 if(s) {
125 atomic_inc(&unix_sk(s)->inflight); 128 struct unix_sock *u = unix_sk(s);
129 spin_lock(&unix_gc_lock);
130 if (atomic_inc_return(&u->inflight) == 1) {
131 BUG_ON(!list_empty(&u->link));
132 list_add_tail(&u->link, &gc_inflight_list);
133 } else {
134 BUG_ON(list_empty(&u->link));
135 }
126 atomic_inc(&unix_tot_inflight); 136 atomic_inc(&unix_tot_inflight);
137 spin_unlock(&unix_gc_lock);
127 } 138 }
128} 139}
129 140
@@ -131,182 +142,218 @@ void unix_notinflight(struct file *fp)
131{ 142{
132 struct sock *s = unix_get_socket(fp); 143 struct sock *s = unix_get_socket(fp);
133 if(s) { 144 if(s) {
134 atomic_dec(&unix_sk(s)->inflight); 145 struct unix_sock *u = unix_sk(s);
146 spin_lock(&unix_gc_lock);
147 BUG_ON(list_empty(&u->link));
148 if (atomic_dec_and_test(&u->inflight))
149 list_del_init(&u->link);
135 atomic_dec(&unix_tot_inflight); 150 atomic_dec(&unix_tot_inflight);
151 spin_unlock(&unix_gc_lock);
136 } 152 }
137} 153}
138 154
155static inline struct sk_buff *sock_queue_head(struct sock *sk)
156{
157 return (struct sk_buff *) &sk->sk_receive_queue;
158}
139 159
140/* 160#define receive_queue_for_each_skb(sk, next, skb) \
141 * Garbage Collector Support Functions 161 for (skb = sock_queue_head(sk)->next, next = skb->next; \
142 */ 162 skb != sock_queue_head(sk); skb = next, next = skb->next)
143 163
144static inline struct sock *pop_stack(void) 164static void scan_inflight(struct sock *x, void (*func)(struct sock *),
165 struct sk_buff_head *hitlist)
145{ 166{
146 struct sock *p = gc_current; 167 struct sk_buff *skb;
147 gc_current = unix_sk(p)->gc_tree; 168 struct sk_buff *next;
148 return p; 169
170 spin_lock(&x->sk_receive_queue.lock);
171 receive_queue_for_each_skb(x, next, skb) {
172 /*
173 * Do we have file descriptors ?
174 */
175 if (UNIXCB(skb).fp) {
176 bool hit = false;
177 /*
178 * Process the descriptors of this socket
179 */
180 int nfd = UNIXCB(skb).fp->count;
181 struct file **fp = UNIXCB(skb).fp->fp;
182 while (nfd--) {
183 /*
184 * Get the socket the fd matches
185 * if it indeed does so
186 */
187 struct sock *sk = unix_get_socket(*fp++);
188 if(sk) {
189 hit = true;
190 func(sk);
191 }
192 }
193 if (hit && hitlist != NULL) {
194 __skb_unlink(skb, &x->sk_receive_queue);
195 __skb_queue_tail(hitlist, skb);
196 }
197 }
198 }
199 spin_unlock(&x->sk_receive_queue.lock);
149} 200}
150 201
151static inline int empty_stack(void) 202static void scan_children(struct sock *x, void (*func)(struct sock *),
203 struct sk_buff_head *hitlist)
152{ 204{
153 return gc_current == GC_HEAD; 205 if (x->sk_state != TCP_LISTEN)
206 scan_inflight(x, func, hitlist);
207 else {
208 struct sk_buff *skb;
209 struct sk_buff *next;
210 struct unix_sock *u;
211 LIST_HEAD(embryos);
212
213 /*
214 * For a listening socket collect the queued embryos
215 * and perform a scan on them as well.
216 */
217 spin_lock(&x->sk_receive_queue.lock);
218 receive_queue_for_each_skb(x, next, skb) {
219 u = unix_sk(skb->sk);
220
221 /*
222 * An embryo cannot be in-flight, so it's safe
223 * to use the list link.
224 */
225 BUG_ON(!list_empty(&u->link));
226 list_add_tail(&u->link, &embryos);
227 }
228 spin_unlock(&x->sk_receive_queue.lock);
229
230 while (!list_empty(&embryos)) {
231 u = list_entry(embryos.next, struct unix_sock, link);
232 scan_inflight(&u->sk, func, hitlist);
233 list_del_init(&u->link);
234 }
235 }
154} 236}
155 237
156static void maybe_unmark_and_push(struct sock *x) 238static void dec_inflight(struct sock *sk)
157{ 239{
158 struct unix_sock *u = unix_sk(x); 240 atomic_dec(&unix_sk(sk)->inflight);
241}
159 242
160 if (u->gc_tree != GC_ORPHAN) 243static void inc_inflight(struct sock *sk)
161 return; 244{
162 sock_hold(x); 245 atomic_inc(&unix_sk(sk)->inflight);
163 u->gc_tree = gc_current;
164 gc_current = x;
165} 246}
166 247
248static void inc_inflight_move_tail(struct sock *sk)
249{
250 struct unix_sock *u = unix_sk(sk);
251
252 atomic_inc(&u->inflight);
253 /*
254 * If this is still a candidate, move it to the end of the
255 * list, so that it's checked even if it was already passed
256 * over
257 */
258 if (u->gc_candidate)
259 list_move_tail(&u->link, &gc_candidates);
260}
167 261
168/* The external entry point: unix_gc() */ 262/* The external entry point: unix_gc() */
169 263
170void unix_gc(void) 264void unix_gc(void)
171{ 265{
172 static DEFINE_MUTEX(unix_gc_sem); 266 static bool gc_in_progress = false;
173 int i;
174 struct sock *s;
175 struct sk_buff_head hitlist;
176 struct sk_buff *skb;
177 267
178 /* 268 struct unix_sock *u;
179 * Avoid a recursive GC. 269 struct unix_sock *next;
180 */ 270 struct sk_buff_head hitlist;
271 struct list_head cursor;
181 272
182 if (!mutex_trylock(&unix_gc_sem)) 273 spin_lock(&unix_gc_lock);
183 return;
184 274
185 spin_lock(&unix_table_lock); 275 /* Avoid a recursive GC. */
276 if (gc_in_progress)
277 goto out;
186 278
187 forall_unix_sockets(i, s) 279 gc_in_progress = true;
188 {
189 unix_sk(s)->gc_tree = GC_ORPHAN;
190 }
191 /* 280 /*
192 * Everything is now marked 281 * First, select candidates for garbage collection. Only
193 */ 282 * in-flight sockets are considered, and from those only ones
194 283 * which don't have any external reference.
195 /* Invariant to be maintained: 284 *
196 - everything unmarked is either: 285 * Holding unix_gc_lock will protect these candidates from
197 -- (a) on the stack, or 286 * being detached, and hence from gaining an external
198 -- (b) has all of its children unmarked 287 * reference. This also means, that since there are no
199 - everything on the stack is always unmarked 288 * possible receivers, the receive queues of these sockets are
200 - nothing is ever pushed onto the stack twice, because: 289 * static during the GC, even though the dequeue is done
201 -- nothing previously unmarked is ever pushed on the stack 290 * before the detach without atomicity guarantees.
202 */ 291 */
292 list_for_each_entry_safe(u, next, &gc_inflight_list, link) {
293 int total_refs;
294 int inflight_refs;
295
296 total_refs = file_count(u->sk.sk_socket->file);
297 inflight_refs = atomic_read(&u->inflight);
298
299 BUG_ON(inflight_refs < 1);
300 BUG_ON(total_refs < inflight_refs);
301 if (total_refs == inflight_refs) {
302 list_move_tail(&u->link, &gc_candidates);
303 u->gc_candidate = 1;
304 }
305 }
203 306
204 /* 307 /*
205 * Push root set 308 * Now remove all internal in-flight reference to children of
309 * the candidates.
206 */ 310 */
207 311 list_for_each_entry(u, &gc_candidates, link)
208 forall_unix_sockets(i, s) 312 scan_children(&u->sk, dec_inflight, NULL);
209 {
210 int open_count = 0;
211
212 /*
213 * If all instances of the descriptor are not
214 * in flight we are in use.
215 *
216 * Special case: when socket s is embrion, it may be
217 * hashed but still not in queue of listening socket.
218 * In this case (see unix_create1()) we set artificial
219 * negative inflight counter to close race window.
220 * It is trick of course and dirty one.
221 */
222 if (s->sk_socket && s->sk_socket->file)
223 open_count = file_count(s->sk_socket->file);
224 if (open_count > atomic_read(&unix_sk(s)->inflight))
225 maybe_unmark_and_push(s);
226 }
227 313
228 /* 314 /*
229 * Mark phase 315 * Restore the references for children of all candidates,
316 * which have remaining references. Do this recursively, so
317 * only those remain, which form cyclic references.
318 *
319 * Use a "cursor" link, to make the list traversal safe, even
320 * though elements might be moved about.
230 */ 321 */
322 list_add(&cursor, &gc_candidates);
323 while (cursor.next != &gc_candidates) {
324 u = list_entry(cursor.next, struct unix_sock, link);
231 325
232 while (!empty_stack()) 326 /* Move cursor to after the current position. */
233 { 327 list_move(&cursor, &u->link);
234 struct sock *x = pop_stack();
235 struct sock *sk;
236
237 spin_lock(&x->sk_receive_queue.lock);
238 skb = skb_peek(&x->sk_receive_queue);
239
240 /*
241 * Loop through all but first born
242 */
243 328
244 while (skb && skb != (struct sk_buff *)&x->sk_receive_queue) { 329 if (atomic_read(&u->inflight) > 0) {
245 /* 330 list_move_tail(&u->link, &gc_inflight_list);
246 * Do we have file descriptors ? 331 u->gc_candidate = 0;
247 */ 332 scan_children(&u->sk, inc_inflight_move_tail, NULL);
248 if(UNIXCB(skb).fp)
249 {
250 /*
251 * Process the descriptors of this socket
252 */
253 int nfd=UNIXCB(skb).fp->count;
254 struct file **fp = UNIXCB(skb).fp->fp;
255 while(nfd--)
256 {
257 /*
258 * Get the socket the fd matches if
259 * it indeed does so
260 */
261 if((sk=unix_get_socket(*fp++))!=NULL)
262 {
263 maybe_unmark_and_push(sk);
264 }
265 }
266 }
267 /* We have to scan not-yet-accepted ones too */
268 if (x->sk_state == TCP_LISTEN)
269 maybe_unmark_and_push(skb->sk);
270 skb=skb->next;
271 } 333 }
272 spin_unlock(&x->sk_receive_queue.lock);
273 sock_put(x);
274 } 334 }
335 list_del(&cursor);
275 336
337 /*
338 * Now gc_candidates contains only garbage. Restore original
339 * inflight counters for these as well, and remove the skbuffs
340 * which are creating the cycle(s).
341 */
276 skb_queue_head_init(&hitlist); 342 skb_queue_head_init(&hitlist);
343 list_for_each_entry(u, &gc_candidates, link)
344 scan_children(&u->sk, inc_inflight, &hitlist);
277 345
278 forall_unix_sockets(i, s) 346 spin_unlock(&unix_gc_lock);
279 {
280 struct unix_sock *u = unix_sk(s);
281 347
282 if (u->gc_tree == GC_ORPHAN) { 348 /* Here we are. Hitlist is filled. Die. */
283 struct sk_buff *nextsk; 349 __skb_queue_purge(&hitlist);
284 350
285 spin_lock(&s->sk_receive_queue.lock); 351 spin_lock(&unix_gc_lock);
286 skb = skb_peek(&s->sk_receive_queue);
287 while (skb &&
288 skb != (struct sk_buff *)&s->sk_receive_queue) {
289 nextsk = skb->next;
290 /*
291 * Do we have file descriptors ?
292 */
293 if (UNIXCB(skb).fp) {
294 __skb_unlink(skb,
295 &s->sk_receive_queue);
296 __skb_queue_tail(&hitlist, skb);
297 }
298 skb = nextsk;
299 }
300 spin_unlock(&s->sk_receive_queue.lock);
301 }
302 u->gc_tree = GC_ORPHAN;
303 }
304 spin_unlock(&unix_table_lock);
305 352
306 /* 353 /* All candidates should have been detached by now. */
307 * Here we are. Hitlist is filled. Die. 354 BUG_ON(!list_empty(&gc_candidates));
308 */ 355 gc_in_progress = false;
309 356
310 __skb_queue_purge(&hitlist); 357 out:
311 mutex_unlock(&unix_gc_sem); 358 spin_unlock(&unix_gc_lock);
312} 359}
diff --git a/net/wanrouter/wanproc.c b/net/wanrouter/wanproc.c
index 205106521ecb..236e7eaf1b7f 100644
--- a/net/wanrouter/wanproc.c
+++ b/net/wanrouter/wanproc.c
@@ -164,14 +164,14 @@ static int status_show(struct seq_file *m, void *v)
164 return 0; 164 return 0;
165} 165}
166 166
167static struct seq_operations config_op = { 167static const struct seq_operations config_op = {
168 .start = r_start, 168 .start = r_start,
169 .next = r_next, 169 .next = r_next,
170 .stop = r_stop, 170 .stop = r_stop,
171 .show = config_show, 171 .show = config_show,
172}; 172};
173 173
174static struct seq_operations status_op = { 174static const struct seq_operations status_op = {
175 .start = r_start, 175 .start = r_start,
176 .next = r_next, 176 .next = r_next,
177 .stop = r_stop, 177 .stop = r_stop,
diff --git a/net/x25/x25_proc.c b/net/x25/x25_proc.c
index 96001f0c64fc..7405b9c5b7f2 100644
--- a/net/x25/x25_proc.c
+++ b/net/x25/x25_proc.c
@@ -234,21 +234,21 @@ out:
234 return 0; 234 return 0;
235} 235}
236 236
237static struct seq_operations x25_seq_route_ops = { 237static const struct seq_operations x25_seq_route_ops = {
238 .start = x25_seq_route_start, 238 .start = x25_seq_route_start,
239 .next = x25_seq_route_next, 239 .next = x25_seq_route_next,
240 .stop = x25_seq_route_stop, 240 .stop = x25_seq_route_stop,
241 .show = x25_seq_route_show, 241 .show = x25_seq_route_show,
242}; 242};
243 243
244static struct seq_operations x25_seq_socket_ops = { 244static const struct seq_operations x25_seq_socket_ops = {
245 .start = x25_seq_socket_start, 245 .start = x25_seq_socket_start,
246 .next = x25_seq_socket_next, 246 .next = x25_seq_socket_next,
247 .stop = x25_seq_socket_stop, 247 .stop = x25_seq_socket_stop,
248 .show = x25_seq_socket_show, 248 .show = x25_seq_socket_show,
249}; 249};
250 250
251static struct seq_operations x25_seq_forward_ops = { 251static const struct seq_operations x25_seq_forward_ops = {
252 .start = x25_seq_forward_start, 252 .start = x25_seq_forward_start,
253 .next = x25_seq_forward_next, 253 .next = x25_seq_forward_next,
254 .stop = x25_seq_forward_stop, 254 .stop = x25_seq_forward_stop,
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index dfacb9c2a6e3..e070c3f938fb 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -686,6 +686,37 @@ out:
686 return x; 686 return x;
687} 687}
688 688
689struct xfrm_state *
690xfrm_stateonly_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
691 unsigned short family, u8 mode, u8 proto, u32 reqid)
692{
693 unsigned int h = xfrm_dst_hash(daddr, saddr, reqid, family);
694 struct xfrm_state *rx = NULL, *x = NULL;
695 struct hlist_node *entry;
696
697 spin_lock(&xfrm_state_lock);
698 hlist_for_each_entry(x, entry, xfrm_state_bydst+h, bydst) {
699 if (x->props.family == family &&
700 x->props.reqid == reqid &&
701 !(x->props.flags & XFRM_STATE_WILDRECV) &&
702 xfrm_state_addr_check(x, daddr, saddr, family) &&
703 mode == x->props.mode &&
704 proto == x->id.proto &&
705 x->km.state == XFRM_STATE_VALID) {
706 rx = x;
707 break;
708 }
709 }
710
711 if (rx)
712 xfrm_state_hold(rx);
713 spin_unlock(&xfrm_state_lock);
714
715
716 return rx;
717}
718EXPORT_SYMBOL(xfrm_stateonly_find);
719
689static void __xfrm_state_insert(struct xfrm_state *x) 720static void __xfrm_state_insert(struct xfrm_state *x)
690{ 721{
691 unsigned int h; 722 unsigned int h;